Introduction
In the past week I have been fortunate enough to present at both Black Hat USA and DEF CON. My topic was on leveraging Write-What-Where vulnerabilities for Windows 10 Creators Update. You can find the Black Hat slides here. In my DEF CON talk I mentioned additional KASLR bypasses, one of those uses the field Win32ThreadInfo from the TEB to leak a pointer to ntoskrnl.exe. This pointer can be used to achieve arbitrary kernel mode code execution as explained in my presentation.
A couple of months ago I did a blogpost on data only attacks in kernel exploitation, which you can find here. I used the tagWND object to locate the EPROCESS of the current thread, while that technique is still perfectly valid, I wanted to present another way of doing it which does not involve creating a tagWND object.
Finding EPROCESS
To start from the beginning, inspecting the TEB the Win32ThreadInfo pointer is found at offset 0x78 as seen below:
This pointer is to the ThreadInfo structure, which at offset 0 contains a pointer to the KTHREAD.
Offset 0x220 of the KTHREAD contains a pointer to the EPROCESS as shown in previous blogs. Additionally the EPROCESS contains the token for the current process, along with the Process ID of the parent process and a pointer to the linked lists of EPROCSSES. This is everything we need to find the token of the parent process and the SYSTEM process.
Using read/write primitives
As explained in my Black Hat USA and DEF CON presentations both the Bitmap and the tagWND objects can be used as read and write primitives if the size fields are overwritten. The method described above can be used with either primitive. Implemented it looks like this:
From here the token stealing code from my previous blog post can be reused, although offset changes in the EPROCESS on Creators Update should be noted. First locating the EPROCESS of the Parent Process is done
I use the parent process, since the exploit is launched from cmd.exe and the subsequent SYSTEM rights should be assigned to the cmd.exe. Next the EPROCESS of the SYSTEM process is located:
Finally, the SYSTEM token overwrites the token of the parent process:
Executing the code and simulating a Write-What-Where condition yields:
From this it is clear that data only attack are still possible as a means of privilege escalation. Furthermore, Virtual-Based Security along with HyperVisor Code Integrity blocks memory pages from being both writable and executable, thus blocking the option of obtaining arbitrary kernel code execution. This method would still work despite HVCI.