Protecting Windows Networks – UAC

In the good old days, users on Windows machines had admin access by default, so malware and hackers didn’t really have to work hard to get the system completely compromised – they really just needed to have a single vulnerability in any user or system application to get a fully privileged access to the system. Sure, you could use a standard user account, but since so many operations required admin privileges and there wasn’t any easy way for users to elevate from their current user session, it was commonplace to see that users being granted local admin rights. Another factor that contributed to this was developers assuming users would have admin privileges, which meant many programs simply didn’t work under standard user. But everything changed with the release of Windows Vista release that was equipped with UAC. It was a disaster at first, so people just disabled it – it broke apps(even Microsoft’s own apps), it annoyed users and was one of the contributing factors to Vista’s failed adoption. But in Windows 7, it was toned down and became a widespread system component.

What is UAC?

UAC (User Account Control) is an attempt by Microsoft to implement the least privilege principle into their Windows OS.

It enforces all user accounts including members of Administrators group to run as standard users all the time unless there is a need to run a program that requires admin privileges, at which point of time it prompts the user for confirmation (or admin user credentials) to run the command with elevated privilege. Many people do not consider it a security boundary or even a security feature, but I strongly disagree. UAC is much more than a simple sudo like application and is embedded deeply into the system.

How does it work?

UAC works by introducing the concept of integrity levels into processes and files in the system. Integrity levels is a classic implementation of the Bell-Lapadula model. It works with a top-down approach, which means that there is no “write-up” access. In practice this translates to processes of certain integrity level being able to only communicate with their own level or below. It is also applied system-wide and has priority over traditional ACLs. For example, if process has low integrity but full access over some system file via ACL, it would still be denied access because it is a untrusted process even though it was specifically allowed access via ACL. You can look up and control what integrity is assigned to each file using the icacls tool. You can also check process privileges with Process Explorer by selecting column Integrity to display.

The following integrity levels available in Windows:

Untrusted – processes that are logged on anonymously are automatically designated as Untrusted

Low – The Low integrity level is the level used by default for interaction with the Internet. As long as Internet Explorer is run in its default state, Protected Mode, all files and processes associated with it are assigned the Low integrity level. Some folders, such as the Temporary Internet Folder, are also assigned the Low integrity level by default.

Medium – Medium is the context that most objects will run in. Standard users receive the Medium integrity level, and any object not explicitly designated with a lower or higher integrity level is Medium by default.

High – Administrators are granted the High integrity level. This ensures that Administrators are capable of interacting with and modifying objects assigned Medium or Low integrity levels, but can also act on other objects with a High integrity level, which standard users can not do.

System – As the name implies, the System integrity level is reserved for the system. The Windows kernel and core services are granted the System integrity level. Being even higher than the High integrity level of Administrators protects these core functions from being affected or compromised even by Administrators.

Installer – The Installer integrity level is a special case and is the highest of all integrity levels. By virtue of being equal to or higher than all other WIC integrity levels, objects assigned the Installer integrity level are also able to uninstall all other objects.

AppContainer – Special case for sandboxed metro apps in Windows 8

UAC protection

So, what protection does it give us?

Well, since all user processes run in standard user context(medium integrity) it is no longer enough for attacker to compromise any user application and gain admin access, even if compromised user is an admin. So, the attacker needs to find a way to either bypass UAC or exploit some kind of local privilege escalation flaw to gain full access. Furthermore security of some applications also rely on UAC integrity levels such as Adobe Flash, IE Protected Mode and Office Protected View.

There is also a so called Remote UAC feature which prevents access to computer via admin shares, WMI and powershell remoting for local admin accounts effectively preventing lateral movement with compromised local admin account via pass-the-hash attack.

It is clearly a very useful security feature, but some people still advocate for disabling it because they don’t like to click a lot. Even if you get annoyed by clicking those dialog boxes you should never disable UAC. Why? Because disabling it disable the underlying integrity level system completely and all admin users will be granted full admin privileges just like in the good old days. In Vista UAC was configured with maximum settings by default and it was annoying, but in 7 and later it doesn’t spam you a lot and there isn’t really any reason to disable it anymore. Plus, it’s only the case in windows 7, in windows 8 and later disabling UAC no longer disables integrity system.

Let see what happens when we disable UAC:

Now let’s look at processes:

As you can see all user processes run with High integrity just like before UAC was introduced. Note how it also disables IE Protected Mode.

For comparison take a look when UAC is enabled:

Now let’s pretend to be an attacker trying to get SYSTEM privileges after getting an initial foothold.

Here is what happens when UAC is disabled:

Not really a challenge, right? Let’s see what happens when UAC is enabled:

Not so easy now, huh?

To make use of getsystem elevation of meterpreter you need to have admin privileges which we don’t have, since we only have standard user rights, even though our user is a local admin.

Bypassing UAC

Unfortunately, while Microsoft forced developers to fix applications to work with UAC they decided not to do so themselves which resulted in number of various bypasses for UAC over the years.

So yeah…

UAC bypasses fall into following categories:

Auto-elevated backdoor. For some reason MS allowed their own programs to auto-elevate themselves without prompt and turns out those programs were vulnerable to DLL hijacking. It works like this – you combine known dll hijacking tricks and invoke those trusted MS programs to load our DLL which will be executed with admin privileges. There is a big list of known auto-elevate programs which can be used to abuse this. It still works to date, even on Windows 10. Microsoft doesn’t seem to understand what the problem is, their response to one of the public bypass exploits was this:

</asmv3:application>
<!--
Specifically load these DLLs from the specified path. This
is done as a defence-in-depth approach to closing a known UAC
exploit related to Sysprep.exe being auto-elevated. The list
need not contain KnownDlls since those are always loaded
by the loader from the system directory.
-->
<file
loadFrom="%systemroot%\system32\actionqueue.dll"
name="actionqueue.dll"
/>
<file
loadFrom="%systemroot%\system32\bcryptprimitives.dll"
name="bcryptprimitives.dll"
/>
<file
loadFrom="%systemroot%\system32\cryptbase.dll"
name="cryptbase.dll"
/>
<file
loadFrom="%systemroot%\system32\unattend.dll"
name="unattend.dll"
/>
<file
loadFrom="%systemroot%\system32\wdscore.dll"
name="wdscore.dll"
/>

Well, people just moved on to different programs other than sysprep, so…

AppCompatShim. For compatibility MS created a shim database that could be used to patch apps on the fly. So bypass with this method works like this – you create a shim database with RedirectEXE patch for auto-elevated application and install it in the system, then you execute this app which would be intercepted via shim and run your payload instead. Since application was marked as auto-elevated, no UAC prompt was necessary and your payload will be run with admin privileges. Utility to install shim database sdbinst.exe is also auto-elevated, so you don’t need admin rights to install new shim database for this to work.

Social-Engineering. Well, you could always just ask nicely a user to elevate your program. This also include “Offer you can’t refuse” types where UAC prompt is on infinite loop unless you click Yes – see Dridex\Upatre malware. It can also be not so obviously malicious when invoked via some kind of installer or rundll32.exe.

There is also a tool called UACME which implements most of the popular bypasses if you want to play with it yourself.

Mitigation

Fortunately, all bypasses fail when UAC settings are set to maximum – “Always Notify”, but you need to pay attention to prompts. Even better use standard user accounts for your users and don’t hand out local admin rights like candy.

So it’s good idea to set UAC to “Always Notify” – if not for everyone, then at least for admins and on all critical systems.

You can do that via GPO by using the following settings:

Conclusion

UAC is a useful security feature and additional layer of defense against malware and hackers, but existence of various known bypasses cast a shadow over it. However, you can fix it easily by using maximum settings. Since the question nowadays is not if you are being breached but when, it’s all about raising cost for attackers, right? So stop disabling UAC because you annoyed by popups and start using max settings UAC.