Look at this and tell me you still believe in a God
— vx-underground (@vxunderground) July 6, 2022
What?
Yeah you saw that right. Reaching Ring0 with a word document.
When?
Back in June 2022, while discussing Lockbit 3.0’s utilization of DeviceIoControl
with smelly from VX-Underground, I had an idea - what if somebody exploited drivers using VBA Macros? He thought it was a cool idea and wanted a paper on it, so I accepted it as a challenge.
Why?
Because why not? This is just a god-tier shitpost that I made in 10 days LOL
Okay okay here’s the actual reason. I wanted to demonstrate how devastating VBA can be when it comes down to offensive operations. But to tackle this challenge, I also had to learn how driver exploitation on Windows worked. This was a perfect opportunity to make something and learn about it in the process!
VBA comes default installed with any Office application, and it has the capabilities to call the Windows API. So calling DeviceIoControl
should be easy, right?
Turns out, yes.
How?
If you want a TL;DR - I basically ported CVE-2018-6606 to VBA.
But here’s my process :P
Environment
- Windows 10 21H2 (64-Bit)
- Microsoft Office Professional Plus 2019 (64-bit) The VBA Macro only works on 64-bit Office, as using 32-bit Office would involve using Heaven’s Gate, to escape WOW64. Heaven’s Gate in VBA? Sounds interesting ;)
Selecting the Driver
As a person who is novice to the driver exploitation scene, I was in a search for a driver which is very-easy to exploit. While on the search, I encountered Souhail Hammou’s really well written blogpost about how he exploited MalwareFox AntiMalware’s driver (zam64.sys) to escalate privileges.
Exploiting the Driver
I would recommend reading the blogpost, but here is the gist of it.
- The driver has a IOCTL call which can register a process as trusted by the driver.
- Then we use a special IOCTL call which is only accessible by a driver-trusted process.
- The call helps us to get a full access user-mode handle from the kernel.
Visual Basic for Applications Memery
Here is the VBA Macro. Quick rundown of what the code does:
- Creates a handle for the driver, so we can issue IOCTL calls
- Use IOCTL call 0x80002010 to register the
word.exe
process with the driver - Get the PID for winlogon.exe
- Use the IOCTL call 0x8000204c to get a full access handle on winlogon.exe
- Allocate memory in the process and write shellcode to the memory
- Create a remote thread using the written memory
The code is pretty self explanatory and can be easily read. Although I would recommend reading about “64-bit VBA Overview” to understand the extended datatypes and how it differs from 32-bit VBA.
Here are some things to note:
- In VBA, you can import functions from DLLs using
Private Declare PtrSafe Function <Function> Lib "<DLL>"
. ThePtrSafe
is important as we are dealing with 64-bit Office. Mentalis.org’s Apilist has example function imports for reference. - To make structures in VBA, we use
Type
. Using that we make structures for SECURITY_ATTRIBUTES and PROCESSENTRY32. These structures are essential for making sure that the Windows API functions are called properly and essential data is stored properly.
Conclusion
As smelly from VX-Undeground said, “Look at this and tell me you still believe in a God”.
This was a very fun project and I learned a lot about driver exploitation and how the Windows API worked. I would like to thank Coldzer0 and kasua for their encouragement and help.
Also thanks to ShitSecure for their fabulous repo OffensiveVBA. Helped me figure out how to work with CreateToolhelp32Snapshot
in VBA.