A security researcher from Tenable has discovered that is possible to bypass Windows’ User Account Control (UAC) by spoofing the execution path of a file in a trusted directory.
User Account Control (UAC) is a technology and security mechanism that aims to limit application software to standard user privileges until an administrator authorizes an increase or elevation.
Some programs can auto-elevate privileges bypassing UAC, to prevent abuses Windows implements a series of additional security checks to allow that only a specific group of trusted executables can auto-elevate.
Executables that can auto-elevate have specific configuration, need to be properly signed, and to run from a Trusted Directory (i.e. “C:\Windows\System32”).
David Wells researcher discovered the Appinfo.dll (AIS) will use RtlPrefixUnicodeString API to see if the target executable path begins with “C:\Windows\System32\” for one of the trusted directory checks.
Then the researcher created a directory called “C:\Windows \” (with a space after the word “Windows”) by using the CreateDirectory API and prepending a “\\?\” to the directory name and then created a “System32” directory in it.
“So for bypassing this check, I construct a directory called “C:\Windows \” (notice trailing space after “Windows”). This won’t pass the RtlPrefixUnicodeString check of course, and I’ll also mention that this is somewhat invalid (or in the very least “unfriendly”) directory name, as Windows does not allow trailing spaces when you create a directory (try it).” wrote the expert.
“Using the CreateDirectory API however, and prepending a “\\?\” to the directory name I want to create, we can bypass some of these naming filter rules and send the directory creation request directly to file system.”
Then the expert copied a signed, auto elevating executable from “C:\Windows\System32”, and discovered that upon its execution no UAC prompt is triggered.
“When this awkward path is sent to AIS for an elevation request, the path is passed to GetLongPathNameW, which converts it back to “C:\Windows\System32\winSAT.exe” (space removed). Perfect! This is now the string that trusted directory checks are performed against (using RtlPrefixUnicodeString) for the rest of the routine.” explained the expert.
“The beauty is that after the trusted directory check is done with this converted path string, it is then freed, and rest of checks (and final elevated execution request) are done with the original executable path name (with the trailing space). This allows all other checks to pass and results in appinfo.dll spawning my winSAT.exe copy as auto elevated (since it is both properly signed and whitelisted for auto elevation).”
The expert elevated a malicious code simply dropping a fake WINMM.dll (imported by winSAT.exe) in the current directory “C:\Windows \System32\” for a local dll hijack.
Wells published a proof-of-concept code on GitHub.
(Security Affairs – UAC bypass, hacking)