A new technique uses a simplified process of DLL hijacking and mock directories to bypass Windows 10’s UAC security feature and run elevated commands without alerting a user.
Windows UAC is a protection mechanism introduced in Windows Vista and above, which asks the user to confirm if they wish to run a high-risk application before it is executed.
As users are repeatedly asked to authorize legitimate processes, which can get annoying fast, starting with Windows 7, Microsoft introduced inbuilt “exceptions” within the UAC framework.
This feature allows trusted system DLLs located under C:WindowsSystem32 to “auto elevate” to higher privileges without displaying a UAC prompt.
This allows system processes that need elevated permissions to execute DLLs and EXEs without requiring them to answer UAC prompts.
Last month BleepingComputer reported how security researcher Wietze Beukema found that 300 Windows executables were vulnerable to DLL hijacking that allows attackers to bypass the UAC security feature.
Building on the same technique, security researcher and pentester Daniel Gebert illustrates how Windows 10 User Account Control (UAC) can also be bypassed through a combination of DLL hijacking techniques and mock directories.
Introducing Windows 10 mock directories
A mock directory is an imitation directory with a trailing space. For example, whereas “C:WindowsSystem32” is a legitimate, trusted location on Windows machines, a mock directory would look like “C:Windows System32” (notice the trailing space after Windows).
When creating mock directories, there are two restrictions:
- Mock directories cannot be directly created from within the Windows Explorer UI, so you’d need a simple script to accomplish the task.
- Not all directories can be mocked:
“A mock directory must include a [subdirectory]. It is not possible to create ‘C:Windows ‘. But it is possible to create ‘C:Windows System32’,” Gebert explains in his blog post,
To make a mock directory, you can simply use a PowerShell command like:
New-Item "\?C:Windows System32" -ItemType Directory
When done, the C: root folder will now contain two Windows folders, but in reality, the second one has a trailing space, as shown below.
What makes mock folders so dangerous is that Windows, in some cases, like using File Explorer, treats “C:Windows” and “
C:Windows ” as the same folder, as illustrated below.
The treating of a mock folder as the actual folder it’s named after, is where directories come into play.
A twisted approach
Beukema’s original UAC bypass technique relied on finding system EXEs that would make ideal candidates for DLL hijacking. For example, “winstat.exe” is known to look for a bunch of DLLs (such as “d3d10.dll”, “d3d11.dll”, etc.) in trusted locations upon execution.
Should an attacker be able to rewrite one of these DLLs with a malicious one of their choice, “winstat.exe” would load that malicious DLL from the trusted directory, or a mock directory – depending on where is “winstat.exe” present.
However, to bypass UAC, Beukema’s technique required at least some form of rewriting and recompiling of an existing DLL with the attacker’s payload.
For many of these trusted DLLs that processes sideload, templates weren’t available that pentesters could use. Not to mention, there were also some limitations to the technique.
When searching for DLL hijacking candidates, Gebert started by searching for templates on the web for legitimate Windows DLLs present in trusted directories.
On discovering such templates on GitHub, he compiled one with an added payload to spawn an elevated command prompt.
The template Gebert picked for this PoC was for “version.dll” due to his prior experience using the file in DLL hijacking exploits.
After compiling this simple “version.dll”, he copied it to the mock directory (
C:Windows System32). He additionally copied all legitimate executables (.exe) from the real C:WindowsSystem32 folder into this mock directory.
Therefore, the mock directory now had upwards of 600 Windows EXEs, and the only DLL file, “version.dll”.
Then, hoping that one of the 600 EXEs would side-load “version.dll,” Gebert started launching these executables one at a time while closely monitoring them.
While none of the EXEs were actively loading “version.dll,” some of the EXEs had been looking for a “profapi.dll” file in the mock directory.
By merely renaming “version.dll” to “profapi.dll”, Gebert was able to accomplish the trick. In his example, launching the legitimate Windows process, ComputerDefaults.exe from his mock directory successfully launched the altered “profapi.dll” (previously “version.dll”) present in the same directory.
A video posted on Gebert’s blog also shows the PoC in action:
Gebert’s variation of the technique demonstrates an easier way to achieve UAC bypass without necessarily rewriting an existing Windows DLL.
A complete list of Windows executables which sideload the “profapi.dll” and “version.dll” files, and can be abused for UAC bypass has been provided on his blog.
Along the way, Gebert also discovered that Beukema’s method had mentioned specific Windows executables, e.g. ,taskmgr.exe, which are only capable of sideloading x86 (32-bit) DLLs.
“I tried some of the files Wietze described like Taskmgr.exe. But I was only able to load a DLL successfully when using x86 DLL files,” said Gebert.
“To get a working UAC bypass without using the files I had already tried I got these results. Please note that these files are usually located in “C:WindowsWinSxS” but they will also work in “C:Windows System32″ (mock folder),” he continued.
Gebert has mentioned numerous other examples on his blog describing how this UAC bypass technique can be abused, for example, to bypass Software Restriction Policies (SRP).
“Many vendors don’t see a problem when UAC is involved. But I [have shown] that this type of vulnerability affects all (non-enterprise) end-users. Malware can use a UAC bypass to run with the highest privileges incl. deactivation of Anti Virus products. With so many unpatched UAC bypass methods it is almost impossible for Anti Virus software to detect them all.”
Gebert’s straightforward mitigation advice to prevent UAC bypass attacks is setting UAC to “Always Notify.” Doing so will always show the user UAC prompts before high-risk applications are executed.