User Account Control – What Penetration Testers Should Know

March 20, 2014

UAC is User Account Control. Introduced in Windows Vista, UAC is a collection of technologies that make it convenient possible to use Windows without administrator privileges and elevate your rights when needed. UAC has a lot of moving parts and encompasses a lot of things.

This post focuses on Windows Integrity levels and UAC elevation prompts. I will first explain some UAC concepts and then dive into three attacks to get past UAC.

Process Integrity Levels

In Windows Vista and later, processes run at three different levels of integrity: high, medium, and low. A high integrity process has administrator rights. A medium integrity process is one that runs with standard user rights. A low integrity process is very restricted.

A low integrity process can not write to the registry and it’s limited from writing to most locations in the current user’s profile. Protected Mode Internet Explorer runs with low integrity. The idea is to limit the amount of damage an attacker may do if they exploit the browser.

Most desktop applications run in a medium integrity process, even if the current user is a local administrator. Use Process Explorer to see which Integrity level your programs are running at.


UAC Settings

To perform a privileged action, a program must run another program and request the high integrity level at that time. If the user is an administrator, what happens next will depend on their UAC settings. There are four UAC settings:

Always Notify. This setting is the highest UAC setting. It will prompt the user when any program, including a built-in Windows program wants higher privileges.

Notify me only when programs try to make changes to my computer. This is the default UAC setting. This setting does not prompt the user when some built-in Windows program want higher privileges. It will prompt the user when any other program wants higher privileges. This distinction is important and it plays into the UAC bypass attack that we will cover in a moment.

Notify me only when programs try to make changes to my computer (do not dim my desktop). This is the same as the default setting, except the user’s desktop does not dim when the UAC elevation prompt comes up. This setting exists for computers that lack the computing power to dim the desktop and show a dialog on top of it.

Never notify. This option takes us back to life before Windows Vista. On Windows 7, if a user is an administrator, all of their programs will run with high integrity. On Windows 8, programs run at the medium integrity level, but anything run by an Administrator that requests elevated rights gets them without a prompt.

If the user is not an administrator, they will see a prompt that asks for the username and password of a privileged user when a program tries to elevate. Microsoft calls this “over the shoulder” elevation as someone is, presumably, standing over the shoulder of the user and typing in their password. If the UAC settings are set to Never Notify, the system will automatically deny any requests to elevate.

Who Am I?

When I get a foothold from a client-side attack, I have a few questions I like to answer right away. First, I like to know which user I’m currently executing code as. Second, I like to know which rights I have. With UAC this becomes especially complicated.

One way I like to sort myself out is with the Windows command: whoami /groups.

This command will print which groups my current user belongs to.

This command will also print which integrity level my command ran with. If my command ran in a high integrity context, I will see the group Mandatory Label\High Mandatory Level. This means I have administrator rights.

17.26.20 cmd_exe_2320_2

If my command ran in a medium integrity context, I will see the group Mandatory Label\Medium Mandatory Level. This means I have standard user rights.

17.26.31 cmd_exe_3588_1


If I find myself in a medium integrity process run by a user in an administrators group, there is potential to elevate from standard user rights to administrator user rights. One option is to use the ShellExecute function with the runas verb. This will run a program and request elevated rights.

If UAC is set to anything other than Never Notify, the user will see a prompt that asks them if they would like to allow the action to happen. This is not completely implausible. Oracle’s Java Updater randomly prompts me all of the time.

The Metasploit Framework’s exploit/windows/local/ask module by mubix implements this attack for you. Make sure you set EXE::Custom to avoid anti-virus!


If the user accepts the prompt, the system will run my program in a high integrity context. Remember, medium integrity is standard user rights. High integrity is administrator rights and this is what we’re after.

Bypass UAC

The RunAs option prompts the user and that’s an opportunity to get caught. We want a way to spawn a high integrity process from a medium integrity process without a prompt. Fortunately, there is a way to do this, it’s the bypass UAC attack.

This attack comes from Leo Davidson who made a proof-of-concept for it in 2009. David Kennedy and Kevin Mitnick popularized this attack in a 2011 DerbyCon talk. They also released the exploit/windows/local/bypassuac Metasploit Framework module that uses Leo’s proof-of-concept for the heavy lifting.

The bypass UAC attack requires that UAC is set to the default Notify me only when programs try to make changes to my computer. If UAC is set to Always Notify, this attack will not work. This attack also requires that our current user is in an administrators group.

Bypass UAC: How It Works

This is a fascinating attack whose inner workings are taken for granted. Please allow me the blog space to describe it in depth:

Our story starts with COM, the Component Object Model in Windows. COM is a way of writing components that other programs may use and re-use. One of the benefits of COM is that it’s language neutral. I find it extremely complicated and unappealing to work with. I suspect others share my feelings.

Some COM objects automatically elevate themselves to a high integrity context when run from a program signed with Microsoft’s code signing certificate. If the same COM object is instantiated from a program that was not signed by Microsoft, it runs with the same integrity as the current process.

The COM distinction between Microsoft and non-Microsoft programs has little meaning though. I can’t create a COM object in a high integrity context  because my programs are not signed with Microsoft’s certificate. I can spawn a Microsoft-signed program (e.g., notepad.exe) and inject a DLL into it though. From this DLL, I may instantiate a self-elevating COM object of my choice. When this COM object performs an action, it will do so from a high integrity context.

Leo’s Bypass UAC attack creates an instance of the IFileOperation COM object. This object has methods to copy and delete files on the system. Run from a high integrity context, this object allows us to perform a privileged file copy to any location on the system.

We’re not done yet! We need to go from a privileged file copy to code execution in a high integrity process. Before we can make this leap, I need to discuss another Windows 7 fun fact.

Earlier, we went over the different UAC settings. The default UAC setting will not prompt the user when some built-in Windows programs try to elevate themselves. More practically, this means that some built-in Windows programs always run in a high integrity context.

These programs that automatically elevate have a few properties. They are signed with Microsoft’s code signing certificate. They are located in a “secure” folder (e.g., c:\windows\system32). And, they request the right to autoElevate in their manifest.

We can find which programs autoElevate themselves with a little strings magic:

cd c:\windows\
strings –s *.exe | findstr /i autoelevate

Now, we know which programs automatically run in a high integrity context AND we have the ability to perform an arbitrary copy on the file system. How do we get code execution?

We get code execution through DLL search order hijacking. The public versions of the bypass UAC attack copy a CRYPTBASE.dll file to c:\windows\system32\sysprep and run c:\windows\system32\sysprep.exe. When sysprep.exe runs it will search for CRYPTBASE.dll and find the malicious one first.

Because sysprep.exe automatically runs in a high integrity context (when UAC is set to default), the code in the attacker controlled CRYPTBASE.dll will execute in this high integrity context too. From there, we’re free to do whatever we like. We have our administrator privileges.

Holy Forensic Artifacts Batman!

I mentioned earlier that the Metasploit Framework’s bypassuac module uses Leo Davidson’s proof-of-concept. This module drops several files to disk. It uses Leo’s bypassuac-x86.exe (and bypassuac-x64.exe) to perform the privileged file copy from a medium integrity context. It also drops a CRYPTBASE.dll file to disk and  the executable we want to run.

This module, when run, also creates a tior.exe and several w7e_*.tmp files in the user’s temp folder. I have no idea what the purpose of these files are.

When you use this module, you control the executable to run through the EXE::Custom option. The other artifacts are put on disk without obfuscation. For a long time, these other artifacts were caught by anti-virus products. A recent commit to the Metasploit Framework strips several debug and logging messages from these artifacts. This helps them get past the ire of anti-virus, for now.


A better approach is to use a module that has as little on-disk footprint as possible. Fortunately, Metasploit contributor Ben Campbell (aka Meatballs) is here to save the day. A recent addition to the Metasploit Framework is the exploit/windows/local/bypassuac_inject module.  This module compiles the UAC bypass logic into a reflective DLL. It spawns a Microsoft-signed program and injects the UAC bypass logic directly into it. The only thing that needs to touch disk is the CRYPTBASE.dll file.

Bypass UAC on Windows 8.1

In this post, I’ve focused heavily on Windows 7. Leo’s proof-of-concept and the bypassuac modules in the Metasploit Framework do not work on Windows 8.1. This is because the DLL hijacking opportunity against sysprep.exe does not work in Windows 8.1. The Bypass UAC attack is still possible though.

A few releases ago, I added bypassuac to Cobalt Strike’s Beacon. I do not invest in short-term features, so I had to convince myself that this attack had a viable future. I audited all of the autoElevate programs on a stock Windows 8.1 to find another DLL hijacking opportunity. I had to find a program that would load my DLL before displaying anything to the user. There were quite a few false starts. In the end, I found my candidate.

Beacon’s Bypass UAC command is similar to Ben Campbell’s, it performs all of the UAC bypass logic in memory. Beacon’s UAC bypass also generates an anti-virus safe DLL from Cobalt Strike’s Artifact Kit. Beacon’s UAC bypass checks the system it’s running on too. If it’s Windows 7, Beacon uses sysprep.exe to get code execution in a high integrity context. If it’s Windows 8, it uses another opportunity.

If you’re having trouble with the alternatives, Beacon’s version of this attack is an option.

Bypass UAC on Windows Vista

The Bypass UAC attack does not work on Windows Vista. In Windows Vista, the user has to acknowledge every privileged action. This is the same as the Always Notify option in Windows 7 and later. The UAC settings in Windows 7 came about because UAC became a symbol of what was “wrong” with Windows Vista. Microsoft created UAC settings and made some of their built-in programs auto-elevate by default to prompt the user less often. These changes for user convenience created the loophole described in this post.

Lateral Movement and UAC

The concept of process integrity level only applies to the current system. When you interact with a network resource, your access token is all that matters. If your current user is a domain user and your domain user is a local administrator on another system, you can get past UAC. Here’s how this works:

You may use your token to interact with another system as an administrator. This means you may copy an executable to that other system and schedule it to run. If you get access to another system this way, you may repeat the same process to regain access to your current system with full rights.

You may use the Metasploit Framework’s exploit/windows/local/current_user_psexec to do this.


These UAC bypass attacks are among my favorite hacker techniques. They’re a favorite because they take advantage of a design loophole rather than a fixed-with-the-next-update memory corruption flaw. In theory, we will have these attacks for a long time.


  1. This blog post generated a bit of discussion in other places. Rather than amend the post, I’d like to share a few notes from these discussions. You can call this comment the things I didn’t know I should address or things I left out for the sake of brevity….

    1. There are other UAC settings beyond what I’ve listed here. I’ve listed what’s available in the UAC settings dialog. If you go into your local security policy settings, there are several other options:


    Use secpol.msc to navigate to these settings. Go to Security Settings -> Local Policies -> Security Options and scroll to the bottom. How each of these settings may or may not affect what this post describes, I leave as an exercise to you.:)

    2. If you want to escalate from a Low Integrity context to a Medium integrity context, take a look at the Metasploit Framework’s exploit/windows/local/ms13_005_hwnd_broadcast. If you tend to rely on browser exploits(?), then this is an option to look at. Make sure you set the module’s options correctly and run it when the user is idle. This attack does pop open new windows and type stuff on your behalf.

    3. I have no doubt that this post is incomplete in terms of other UAC features or bypass opportunities. At 2,000+ words, my goal is to explain UAC enough that anyone can understand the concept of an integrity level, how to check the level they’re running at, and some options to escalate from one level to another. I put a special emphasis on the bypass UAC attack, because it’s a very nice solution to escalate. One take away–it’s not enough to know which user you’re running as–you should also know which integrity level you’re running at as well.

  2. Another tweak to the runas technique is to use a powershell one liner so the user gets a prompt with a known signed exe rather than an unknown yellow warning prompt.

  3. For Windows 8.1 there is a NEW Auditing option that would catch the use of this at the command line logging the exact command line execution of say “sysprep cryptbase.dll” or “whoami /groups, etc..”. So it would be prudent in 8.1 to enable this by default on all systems, assuming Win2012 as well at some point.

    Enable it by GPO or set:
    Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit\ProcessCreationIncludeCmdLine_Enabled to REG-DWORD = 1.


  4. I’m surprised no-one has commented explaining that this isn’t in fact an escalation of privilege. It’s a common misunderstanding – UAC *feels* like a security feature. But it’s not. It’s a compatibility feature.

    Try running this attack from a standard user account. It won’t work. Why? Because there’s no escalation – you need to be an admin user to start with.

    As you mention, it also doesn’t work with UAC at the highest setting. That’s because Microsoft didn’t choose the most secure option for UAC as default. They knew if they did everyone would get sick of the constant prompts and would just turn off UAC altogether.

    The ‘exploit’ detailed in this post just shows the difference between the most secure UAC setting and the default. If anyone is concerned about this it’s easily fixed – turn UAC to the highest setting. Or better yet, run as a standard user.

    • I’m aware of Microsoft’s stance that UAC is not a security boundary. I continue to see this as an escalation though.

      As an attacker, context matters. I send a phishing email and I now have a lifeline into a target’s network. Let’s say the user who clicked my link is a local admin. Great. My malware is running on the target, but I can’t use Mimikatz, recover password hashes, or do other nifty hacker things. Why? Because I am in a medium integrity process. To benefit from the user’s admin rights, I must elevate to a high integrity level.

      The loophole discovered by Leo Davidson makes it possible for me to elevate medium -> high integrity without a UAC prompt, so long as the registry settings are at their default and the current user is a local admin. Even though there are conditions attached to when it’s possible, this attack is a change in what the attacker can do from one context to another.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 18,598 other followers