This repository contains an exploit for the BufferOverflowNonPagedPoolNx vulnerability in HackSys Extreme Vulnerable Driver (HEVD). The exploit targets Windows 10 Version 22H2 (OS Build 19045.5247) and demonstrates a technique to achieve privilege escalation from a low-integrity process to SYSTEM.
The exploit leverages the BufferOverflowNonPagedPoolNx vulnerability to create a "ghost chunk" through Aligned Chunk Confusion in the NonPagedPoolNx region. This ghost chunk is then manipulated to achieve arbitrary read and write primitives, which are subsequently used to elevate privileges.
Key techniques:
-
Creation of a ghost chunk using Aligned Chunk Confusion in NonPagedPoolNx, enabling leakage and manipulation of HEAP_VS_CHUNK_HEADER, POOL_HEADER, and NP_DATA_QUEUE_ENTRY structures via the previous chunk.
-
Establishment of an arbitrary read primitive by manipulating the NP_DATA_QUEUE_ENTRY structure within the ghost chunk to set up a fake IRP.
-
Establishment of an arbitrary decrement primitive by altering the POOL_HEADER structure within the ghost chunk to set a fake ProcessBilled.
-
Establishment of an arbitrary write primitive by zeroing the PreviousMode in the current thread's KTHREAD structure.
-
Elevation to SYSTEM privileges by modifying the Token in the current process's EPROCESS structure.
-
Stabilization of the system and avoidance of BSoD by manipulating the HEAP_VS_CHUNK_HEADER structures of the ghost chunk and its linked chunks to prevent detection of the corrupted chunk.
This exploit was tested in the following environment:
- Windows 10 Version 22H2 (OS Build 19045.5247)
- KVA Shadow: Enabled
- VBS/HVCI: Disabled
- Integrity Level: Low
-
Establish arbitrary read primitive:
- Exploit HEVD's NonPagedPoolNx buffer overflow to corrupt an adjacent chunk's POOL_HEADER, creating a ghost chunk:
- Set CacheAligned bit and manipulate PreviousSize to control chunk positioning.
- Upon freeing, this creates a ghost chunk overlapping with a previous chunk.
- The ghost chunk's HEAP_VS_CHUNK_HEADER, POOL_HEADER, and NP_DATA_QUEUE_ENTRY overlap with the previous chunk's data.
- Reading from the previous chunk's PipeQueue leaks the ghost chunk's structures.
- Writing to the previous chunk manipulates the ghost chunk's structures.
- Overwrite the ghost chunk with a fake NP_DATA_QUEUE_ENTRY, pointing linkedIRP to a user-mode fake IRP.
- Set fake IRP's SystemBuffer to the desired read address.
- Use PeekNamedPipe to trigger a read from the specified address.
- Exploit HEVD's NonPagedPoolNx buffer overflow to corrupt an adjacent chunk's POOL_HEADER, creating a ghost chunk:
-
- Use the arbitrary read primitive to obtain kernel base address, ExpPoolQuotaCookie, RtlpHpHeapGlobals, and other critical addresses.
- Find the EPROCESS and KTHREAD structures of the current process.
-
Establish arbitrary decrement primitive:
- Create a fake EPROCESS structure in NonPagedPoolNx by writing data to the pipe associated with the previous chunk.
- Modify the ghost chunk's POOL_HEADER by reallocating the previous chunk:
- Set the PoolQuota bit to make the kernel interpret part of the header as a ProcessBilled pointer.
- Configure a fake ProcessBilled pointer using the formula:
ProcessBilled = fake EPROCESS address ⊕ Ghost Chunk address ⊕ ExpPoolQuotaCookie
- Set up the fake EPROCESS structure with its PoolQuotaBlock pointing to (target address - 1).
- Set the BlockSize to 0x100 bytes.
- Trigger the freeing of the ghost chunk, causing the kernel to:
- Subtract 0x100 (BlockSize) from the PoolQuota at (target address - 1).
- This results in a decrement of 0x1 at the target address.
-
Establish arbitrary write primitive:
- Use the arbitrary decrement primitive to manipulate the PreviousMode field of the current thread's KTHREAD structure.
- Decrement PreviousMode from 1 (UserMode) to 0 (KernelMode).
- This manipulation bypasses address validation in native system service routines like NtWriteVirtualMemory:
- Normally, these routines perform checks to prevent writing to kernel space addresses when called from user mode.
- With PreviousMode set to KernelMode, these checks are skipped.
- As a result, the exploit gains the ability to write to arbitrary kernel memory addresses, establishing an arbitrary write primitive.
- Use the arbitrary decrement primitive to manipulate the PreviousMode field of the current thread's KTHREAD structure.
-
Elevate privileges (data-only attack):
- Use the arbitrary read primitive to locate the System process EPROCESS structure.
- Use the arbitrary write primitive to copy the System process token to the current process's token.
-
- Repair the HEAP_VS_CHUNK_HEADER structures of the ghost chunk and adjacent chunks:
- Use RtlpHpHeapGlobals (previously leaked) to decode and re-encode headers
decodedVsHeader = encodedVsHeader ⊕ addrof(encodedVsHeader) ⊕ RtlpHpHeapGlobals
- Update UnsafeSize and UnsafePrevSize to restore proper chunk linkage
- These repairs prevent detection of the corrupted heap structure, avoiding KERNEL MODE HEAP CORRUPTION and subsequent BSoD
- Use RtlpHpHeapGlobals (previously leaked) to decode and re-encode headers
- Restore PreviousMode to its original value of 1 (UserMode)
- Clean up the pipes used in the exploit
- Repair the HEAP_VS_CHUNK_HEADER structures of the ghost chunk and adjacent chunks:
To build the project:
- Open the solution file
HEVD-BufferOverflowNonPagedPoolNx-Win10-22H2.sln
in Visual Studio 2022. - Build the solution (F7 or Build > Build Solution).
Note: Steps for installing the HEVD driver can be found in the Installing the HEVD Driver section.
-
Load the HEVD driver on the target system. (If it is not already loaded).
-
Start a Low Integrity command prompt:
copy %systemroot%\system32\cmd.exe .\cmd-low-integrity.exe icacls .\cmd-low-integrity.exe /setintegritylevel low .\cmd-low-integrity.exe
Verify the integrity level:
whoami /groups | find "Mandatory Label"
This should show "Mandatory Label\Low Mandatory Level".
-
From the Low Integrity command prompt, run the compiled exploit.
-
If successful, a SYSTEM shell should spawn.
-
Download and extract the precompiled driver:
mkdir C:\temp powershell -Command "Invoke-WebRequest https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/releases/download/v3.00/HEVD.3.00.zip -OutFile C:\temp\HEVD.3.00.zip" powershell -Command "Expand-Archive -Path C:\temp\HEVD.3.00.zip -DestinationPath C:\temp\HEVD -Force"
-
Place
HEVD.sys
in your desired directory:copy C:\temp\HEVD\driver\vulnerable\x64\HEVD.sys C:\Windows\System32\drivers\HEVD.sys
-
Enable Test Signing Mode (reboot required):
bcdedit /set testsigning on shutdown /r /t 0
-
Create and start the driver service:
sc create HEVD type= kernel binPath= "C:\Windows\System32\drivers\HEVD.sys" start= auto sc start HEVD
-
Install WinDbg from the Microsoft Store:
-
Launch WinDbg from the Start menu and configure the kernel debugging connection:
- Click File > Attach to Kernel > Net.
- Enter a port number and a unique key of your choice. You will later specify the same
<PORT>
and<KEY>
on the target system usingbcdedit /dbgsettings
. - Click OK to start listening for the debuggee's connection.
Use the following commands on the target system, replacing:
<DEBUGGER_IP>
with the IP address of the host machine running WinDbg<PORT>
with the same port number you entered in WinDbg<KEY>
with the same key you entered in WinDbg
bcdedit /debug {default} on
bcdedit /dbgsettings net hostip:<DEBUGGER_IP> port:<PORT> key:<KEY>
shutdown /r /t 0
Once the target system reboots, it will attempt to connect to the debugger over the network.
This code is provided for educational purposes only. Use it responsibly and only on systems you have permission to test.