I wanted to test a number of kernel exploitation techniques that target vulnerable drivers.
To do this I wrote my own vulnerable driver to target.
These were tested on Windows 10 Pro Build 19045
This technique requires both read and write primitives in the target driver and assumes VBS protections are not enabled
Exploitation Steps:
- Write Shellcode to Kernel Space:
There is a static structure in the kernel space called KUSER_SHARED_DATA at 0xfffff78000000000. This structure only takes 0x71c bytes, meaning the rest of the 0x1000 byte page is unused and free to be modified. This gives an attacker an easy code cave to write data within the kernel memory space. - Modify KUSER_SHARED_DATA PTE:
By default, the page containing KUSER_SHARED_DATA is not executable. To fix this, an attack can locate the page table entry for this memory page and set the executable bit. - Modify HAL Dispatch Table:
The HAL Dispatch table holds a number of function pointers related to HAL operations. The pointer for HaliQuerySystemInformation is called by NtQueryIntervalProfile which can be easily called from usermode. NtQueryIntervalProfile is within ntdll.dll and must be found at runtime. - Trigger Payload and Cleanup:
To trigger the payload, call NtQueryIntervalProfile from usermode. This results in the HAL Dispatch table being referenced to find the location of HaliQuerySystemInformation. However, it instead points to our shellcode which is now marked as executable. It is important to restore the original pointer to HaliQuerySystemInformation so that Patch Guard does not check it and cause a crash.