User account control is a security mechanism introduced in Windows Vista that aims to allow users to operate in Windows (most of the time) without administrative privileges. Raphael Mudge has a great overview of the mechanics of UAC and the attack against it. I won’t repeat what Raphael has already done a great job explaining, so if you’re unaware of what UAC is or how the BypassUAC attack works, check out his post.


Why does UAC matter? In pretty much all phishing attacks, you’re going to land in a medium integrity process (signed applets, macros, etc.). So even if you phish a user who is a local administrator on their machine, you won’t be able to execute many privileged commands such as privileged registry writes, LSASS reading/manipulation, etc. Fun bonus: PowerUp now checks if a current user is a local administrator but the current process is medium integrity, signaling you to run a BypassUAC attack.

For Empire, it became obvious to @sixdub and myself that we would need to implement BypassUAC in straight PowerShell for our agent to be taken seriously. Thankfully, most of the groundwork had already been laid by PowerSploit and several Metasploit authors.

Metasploit already implements the elevator .dlls (source here) that instantiate the self-elevating COM objects, as well as lay out the hijack locations for Windows 7 and Windows 8.1. If we combine this with code from the PowerSploit project, we can inject an elevator .dll that grants us the one privileged write. But the Metasploit project uses a hijackable .dll that spawns a new process and injects shellcode. Since we’re not injecting shellcode, we have two options. We can drop the ReflectivePick .dll that loads up .NET/PowerShell, but that would involve dropping a fairly complex and “malicious” looking .dll (temporarily) to disk. Or we can go with a generalized hijackable .dll that launches a specific .bat file from $env:Temp or a specifiable location. This .bat file will execute a command we specify (in a high integrity process) and then delete itself automatically after running. We felt that this approach was the most flexible, as it allows us to easily change the series of commands executed by simply modifying the written .bat file.

This code, Invoke-BypassUAC.ps1, launched with Empire and is wrapped up nicely into the privesc/bypassuac module. For the module, you just need to specify a listener name, and Empire will take care of the rest. There’s also a bypassuac alias in the agent menu, which lets you execute this attack with bypassuac <ListenerName>. Your new high-integrity agent will have a * next to it in the agent list.


As Microsoft doesn’t consider UAC a security boundary, there’s also another bypass attack that works on Windows 7. We first saw it discussed on and the first PoC code on Vozzie’s Github (please correct me if these are not the original sources). It abuses the lack of an embedded manifest in wscript.exe to execute .VBS with elevated privileges. My workmate @enigma0x3 was able to port the .VBS PoC to PowerShell, and this was integrated into Empire as a module. This approach was also integrated into MSF by Ben Campbell. It’s an interesting approach, but restricted due to the number of platforms it works on.

This general .dll hijack method method was also implemented recently into PowerUp. The Write-HijackDll function will take a given command, build a self-deleting .bat, and and hot patch that path into into a hijackable .dll embedded in the script. The system architecture is auto-determined (but also specifiable), and a hijackable .dll is written out to a specified path.

Hopefully some people find this useful, and let us know if anyone encounters any issues.

4 thoughts on “Invoke-BypassUAC”

  1. hi, is there any way that we can make bypassuac opsec? since the remote machine will have windows popping up (click yes to process) if we were to do it the non-opsec way. thanks!

    1. I’m assuming you’re meaning “can we make bypassuac opsec-safe” to remove the prompt you’re seeing. Our implementation of BypassUAC, if used correctly, does not prompt the user but does temporarily drop a DLL to disk. If you’re seeing a prompt, that means that either 1) you’re not running the attack from someone who’s a local administrator or 2) UAC settings are turned up to ‘always notify’, meaning you’re out of luck.

      1. Sorry, yup that’s what I meant :) Guess I’m out of luck to escalate my privilege since I’m running as a standard user and the UAC settings are controlled by the domain administrator.

        My network sensor picked up the callback from Empire. It’s labelled as malicious. Probably due to the URIs like /admin/get.php, /news.asp, /login/? I saw that there are some profiles in data/profiles, but aren’t those malicious useragent and would also be picked up by sensors?


Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.