Welcome to the first part of Windows Kernel Exploitation series. In the first part, we are starting with a vanilla stack buffer overflow in the HackSysExtremeVulnerableDriver.
When a buffer present on stack gets more data than it can store (for e.g. Copying 20 bytes on a 16-byte buffer, which can be a character array or similar object), the remaining data gets written in nearby location, effectively overwriting or corrupting the stack.
The core idea is to control this overflow so that we can overwrite saved return address on the stack and after execution of current (vulnerable) function, it will return to our overwritten value, which contains our shellcode.
Note: After execution of our shellcode, the code execution must return to the application, kernel in this case, else it breaks the application. Usually, the application crashes and we can restart it but in case of kernel memory corruption, the kernel issues a kernel panic and it will give a Blue Screen of Death, which is the last thing we want.
To fix this, we need to restore the execution path so that after the execution of our shellcode, it returns to the function it was supposed to return after executing the vulnerable function.
Now we have got it cleared, let us have a look at the vulnerable code (function TriggerStackOverflow located in StackOverflow.c). Initially, the function creates an array of ULONGs which can hold 512 member elements (BufferSize is set to 512 in common.h header file).
The kernel then checks if the buffer resides in user land and then it allocates memory for it in Non-Paged Pool.
Once that has been done, the kernel then copies the data from user mode buffer to the kernel mode KernelBuffer, which essentially is an array of ULONGs.
Note the third parameter to RtlCopyMemory, which essentially is memcpy, the Size parameter is the size of user mode buffer and NOT the size of kernel mode buffer. This is the exact point where the buffer overflow is happening.
Verifying the bug
Now, to verify whether it is actually where the bug resides, we will write a function that calls the IOCTL of the function StackOverflowIoctlHandler. The IOCTL codes are given in the Exploit/common.h file.
Note: We could have obtained the IOCTL code from the compiled driver itself but since we have an advantage at our disposal, why not use it.
What is an IOCTL code?
“I/O control codes (IOCTLs) are used for communication between user-mode applications and drivers, or for communication internally among drivers in a stack. I/O control codes are sent using IRPs.” – Microsoft.com
Basically, you can directly invoke kernel functionality in a driver if that driver has IOCTL codes associated with it.
To use an IOCTL code, we use DeviceIoControl function, which can be found here.
The prototype for DeviceIoControl function is:
I wrote a function in C++ that calls DeviceIoControl to invoke StackOverflowIoctlHandler which in turn calls TriggerStackOverflow, which is the vulnerable function.
Since we know the buffer is of 512 ULONGs, that is certain, after that, we are appending 100-byte pattern generated by pattern_create.rb from Metasploit framework.
Finally, send this buffer to HEVD and see what happens.
Note: This function is in the header file StackOverflow.h and the main function calls it. You can find whole code in my code repo here.
After compiling and executing the binary on the Win7 machine, we get this in WinDbg:
We can see there was an access violation and EIP was pointing to 31624130.
After using pattern_offset.rb from Metasploit on this pattern, we find the offset it 32. Let us move ahead and exploit it.
Exploiting the Overflow
All now remains is to use overwrite the saved return address with the TokenStealingPayloadWin7 shellcode provided in HEVD and you are done.
Note: You may need to modify the shellcode a bit to save it from crashing. This is your homework.
Getting the Shell
Let us first verify whether I am a regular user or not.
As it can be seen, I am just a regular user.
After we run our exploit, I become nt authority/system.
That’s for this this part folks, see you in next part.