首页
社区
课程
招聘
[原创] HEVD 前三题分析
发表于: 2天前 1295

[原创] HEVD 前三题分析

2天前
1295

本篇文章针对于对windows内核驱动漏洞感兴趣,在用户态有一定漏洞研究基础,能写简单驱动的师傅阅读,重点会放在内核态和用户态利用方法的不同,以及对驱动安全开发的思考。我尽量在一个月内,做完HEVD所有题目,以后的标题就像《HEVD03-05》了,每次三道题左右。感谢大家的支持。
让我们开始吧

这是一个非常典型的栈溢出漏洞,其根源在于内核代码过度信任了来自用户态的输入——Size 字段直接由用户控制,从而实现了内核栈溢出。
此外,目标模块未启用 GS 安全机制(栈溢出检测),这进一步降低了利用难度。
由于这是系列中的第一个题目,主要目的是直观感受内核态与用户态的差异,因此实验环境选择 Windows 7 x86 SP1,不考虑 SMEP 等内核防护机制的影响。

与用户态不同,内核里只要有一丁点错误,立刻就是蓝屏。用户态程序崩了,可能只是弹个报错对话框就结束了,后续没人管。但内核漏洞利用必须悄无声息地接管执行流程——不仅要完成提权,还得替原来的函数把该做的事做完,让系统感知不到异常。
以 shellcode 为例,它比用户态的 payload 多出了两部分关键内容:环境保存栈恢复

具体来说,调用链是这样的:
IrpDeviceIoCtlHandler → BufferOverflowStackIoctlHandler → TriggerBufferOverflowStack
我们劫持的是 TriggerBufferOverflowStack 的返回地址。因此,shellcode 执行完毕后,必须把自己伪装成 TriggerBufferOverflowStack 刚刚正常返回的状态——恢复栈帧,让执行流顺畅地回到上一层。
如果像用户态那样,执行完 shellcode 就拍屁股走人,内核会瞬间陷入未定义行为:要么当场蓝屏,要么当前线程卡死。更严重的是,内核资源是全局共享的,一个 IRP 请求没被正确完成,整个内核的处理链条都会受牵连。

所以,来看 _BufferOverflowStackIoctlHandler 的实现细节。其中 call _TriggerBufferOverflowStack@8 指令执行后,返回地址正好落在 ebp 链上,栈布局非常规整。我们只要在 shellcode 里同步恢复 ebp、整理好栈帧,就能让被利用的调用路径平稳返回。最终,提权在不知不觉中完成,原驱动程序乃至整个系统都毫无察觉。

跟上一题类似,也是栈溢出,但是这道题有GS检查,可以考虑覆盖SEH来进行利用

首先,让我们来看,一个正常的、触发一个异常的执行流程是什么(结合汇编分析)

真实执行流程(重点):

按照我们用户态的经验,我们需要覆盖__except_handler4劫持函数执行流程,但是,__except_handler4是一个通用的异常处理分发函数,执行到这里的时候,我们不能直接抄Truely Except(Yours),此时的ebpesp都是不正确的!
基于上面的解析,我们有三种方法伪装正常执行流程

在exp中我的实现是方法一,见Shellcode:

小技巧:在函数开头保存ecx的时候就记住他们的地址,方便调试

一个经典的任意地址写漏洞。

如果说前面费尽心思恢复栈、寄存器十分压抑的话,那么这个win7x86任意地址写就比较简单了,不仅轻松劫持执行流程,还不用考虑恢复寄存器,处理IRP请求等等
利用思路:

查了很多资料,都是讲的win7x86的利用。
在高版本有SMEP保护下,如果只有一次任意地址写的机会,甚至...连KASLR都绕不过,该怎么提权?
敬请期待我的下一篇文章《只有一次任意写,高版本win内核提权》

__declspec(safebuffers)
NTSTATUS
TriggerBufferOverflowStack(
    _In_ PVOID UserBuffer,
    _In_ SIZE_T Size
)
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG KernelBuffer[BUFFER_SIZE] = { 0 };

    PAGED_CODE();

    __try
    {
        ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(UCHAR));
        RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
#endif
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        Status = GetExceptionCode();
        DbgPrint("[-] Exception Code: 0x%X\n", Status);
    }

    return Status;
}

[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 10小时前 被AO031编辑 ,原因: 添加超链接
上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回