Introduction to Windows Kernel Driver Exploitation (Pt. 1) - Environment Setup

September 02 2017

This is the first part of a series of posts I am going to do about Windows kernel exploitation, via vulnerable drivers.

The project I will be using for the exploit is HackSys Extreme Vulnerable Driver, which is a really cool little vulnerable windows driver which has a series of different exploit vectors which you can write IOCTL based exploits for to exploit the kernel.

The driver can be downloaded prebuilt for x86 and amd64 - I chose the x86 option just to make things a bit simpler.

To load the driver into Windows on the fly, HackSys recommends using the OSR Driver Loader. Which makes it really easy to hot-plug drivers into Windows.

Setting up VM communication

Since I am running Linux, I wasn't able to run WinDbg on my host and communicate with the vulnerable Windows 7 VM over VirtualBox's artificial serial port.

The setup I ended up going with was having two VM's (linked from the same clean Windows 7 SP1 x86 install) and I used VirtualBox to set up a serial connection between the two VM's over a file on my linux host.

When turned off, I set the Serial Port settings of the VM that would be running WinDBG and doing the debugging to the following:

And the settings of the VM that would have the HackSys driver installed and exploited as follows:

This allowed the machines to communicate of the temporary file /tmp/win_link. Excellent!

VM Debug Setup

Now that the VM's are setup, we have to do some configuration to get the communication actually working properly.

Boot up the debugger VM and install WinDbg. Once this is done we need to set an environment variable so that WinDbg will know where to source kernel symbols from. Set the _NT_SYMBOL_PATH environment variable to Done!

Now boot up the vulnerable VM, we need to enable the Windows debug boot option.

First we copy the current boot settings into a new entry that we will edit:

bcdedit /copy {current} /d "Debug"

This command will spit out a GUID that we will use to reference the new debug option we just created. Now we enable debug mode on the boot option we just created.

bcdedit /debug <GUID> on

And done! We now have a boot option on this VM to boot up windows with debug mode enabled - so it will send information over serial (to our communication file) so the debugger VM can read it!

Now we head back to the debugger VM and open WinDBG. Head to File -> Kernel Debug and enter 115200 as the Baud Rate for the serial connection, and com1 as the Port.


Reboot the vulnerable machine now, and select the "Debug" option at the boot menu. Let it boot into the desktop (takes a while) and when it does, create an interrupt by selecting Debug -> Break in WinDbg which will interrupt the vulnerable machine. If WinDbg gives you a kd> prompt at the bottom of the screen, and the vulnerable Windows VM won't let you interact with any windows any longer then the interrupt is successful!


Installing HackSys driver

Now that the VMs are configured for debugging, we want to install the HackSys driver on the vulnerable VM so we can start hacking away at it.

By default the drivers aren't very verbose, however we want as much information to be printed to the WinDbg console as possible while debugging the HackSys driver - so we have to enable verbose debug strings.

We can do this by altering the Default Mask in WinDbg by running the following command while the vulnerable machine has been interrupted:

ed nt!Kd_Default_Mask 8

It is recommended for speed considerations to not worry about this, and just run the DebugView application locally on the vulnerable machine to view the debug strings - I don't face any real slow down so I don't worry about this.

You can always continue the execution of the vulnerable machine by entering g at the kd> prompt. Which is what we want to do now so we can install the driver.

Assuming you have the OSR Driver Loader and the pre-built drivers downloaded onto the vulnerable machine, we can get to installing the driver. Opening OSR you can set browse to the driver path and set the service to be automatic start, then register the service. Once registered just start the service.

Doing so will print some debug strings out to the WinDbg console.

Now that the driver has been installed and is running, we want to install the HackSys driver symbols so WinDbg can be of more use to us.

We can find the HEVD module by running the following command in the WinDbg console.

1: kd> lm m H*
start    end        module name
8280b000 82842000   hal        (deferred)             
8c34c000 8c354000   hwpolicy   (deferred)             
91031000 91037480   HIDPARSE   (deferred)             
91173000 91192000   HDAudBus   (deferred)             
95c00000 95c0b000   hidusb     (deferred)             
95c0b000 95c1e000   HIDCLASS   (deferred)             
95d2a000 95d7a000   HdAudio    (deferred)             
99051000 990d7000   HTTP       (deferred)             
a1a00000 a1a08000   HEVD       (deferred) 

The last line is the HEVD driver, and by deferred we can see that WinDbg does not have any symbols loaded.

We can find the location to put the pdb for HEVD by enabling verbose path information about module symbols running the command:

1: kd> !sym noisy
noisy mode - symbol prompts on

Attempting to print all functions of HEVD we can see the path lookups that WinDbg is making to find the path where we must put the HEVD pdb file.

1: kd> x HEVD!*
SYMSRV: not found
SYMSRV:  C:\ProgramData\dbg\sym\HEVD.pdb\D241CC04CE0B472CB88B1476958369FB1\HEVD.pdb not found
DBGHELP: c:\hacksysextremevulnerabledriver\compile\drv\vulnerable\i386\HEVD.pdb - file not found
*** ERROR: Module load completed but symbols could not be loaded for HEVD.sys
DBGHELP: HEVD - no symbols loaded

It can't found online, so the path we want is the second choice - C:\ProgramData\dbg\sym\HEVD.pdb\D241CC04CE0B472CB88B1476958369FB1\HEVD.pdb.

Storing the pdb file for the same version of the driver you loaded (on the debugger VM) and running .reload again will reload the symbols. So now you can run:

0: kd> x HEVD!*
SYMSRV:  C:\ProgramData\dbg\sym\HEVD.pdb\D241CC04CE0B472CB88B1476958369FB1\HEVD.pdb - file not found
DBGHELP: HEVD - private symbols & lines 
a159f018          HEVD!g_UseAfterFreeObject = 0x00000000
a159f004          HEVD!__security_cookie_complement = 0x5ea60d27
a159e030          HEVD!KeTickCount = struct _KSYSTEM_TIME
a159e110          HEVD!__safe_se_handler_table = void *[]
a159e060          HEVD!_load_config_used = struct IMAGE_LOAD_CONFIG_DIRECTORY32
a159f000          HEVD!__security_cookie = 0xa159f2d8
a159f008          HEVD!__NLG_Destination = struct _NLG_INFO
a15a0006          HEVD!TriggerDoubleFetch (struct _DOUBLE_FETCH *)
a15a0be0          HEVD!TriggerNullPointerDereference (void *)
a159d059          HEVD!__SEH_epilog4 (void)
a159d3b1          HEVD!_NLG_Notify (void)
a159d014          HEVD!__SEH_prolog4 (void)

And get a full listing of the symbols available for HEVD. Success!

Testing the driver

Finally we can test the pre-written exploit for the driver to make sure everything is working, so we can begin to write our own exploit.


Seems fine, can launch cmd.exe as system from the pool overflow exploit. Now let's get reversing!