User Account Control (UAC) bypassing by spoofing trusted directories
Information security expert David Wells has published a way to bypass UAC account control in Windows 10
While researching some of the new UAC circumvention techniques (UAC), I discovered a completely new UAC circumvention method at the time of this writing. It is worth noting that Microsoft does not consider UAC a security boundary, however, we still report various bugs at Microsoft and I want to share the details of the vulnerability I found here. This method was successfully tested on Windows 10 Build 17134. Before I dive into the details of my find, I will first give you a little explanation on how the UAC service works.
When a user belonging to the Administrators group wants to start an application that requires elevated privileges, the UAC displays the corresponding request and the user who is a member of the Administrators group will need to confirm the action. However, this UAC request does not occur for ALL administratively executable files in Windows . There are a few exceptions that will “automatically” elevate the privileges of an executable file without causing a UAC request, bypassing UAC (much to the surprise!). This particular group of selected trusted executables passes additional system security checks to make sure that these files are in fact reliable, so information attackers usually do not abuse this function. This approach has been used in previous UAC workarounds and will be the basis of my new workaround. However, there are a few loopholes that we need to use in order for our attack to succeed. Let's look at the requirements that must be met if we want our executable file to be “automatically elevated in privileges.” For this, I will show a few pictures of the appinfo.dll disassembled library (the AIS service that processes requests for privilege escalation is one of the main components of UAC).
Requirement 1: The file is configured to automatically elevate privileges.
When a request for elevation of privileges for a program occurs, an RPC call is made in the AIS service (appinfo.dll) with the target executable path passed as an argument. This service will then match the target executable contents of the file for reading. In the manifest of the executable file, an attempt is made to read the value to obtain the key “autoElevate” (if it exists).
Figure 1 - Reading the manifest of the executable file to obtain the value of the “autoElevate” key.
If the value is received and this is “True”, the file will be treated as “automatic” elevated privileges by an executable file that will run with elevated privileges and not invoke the UAC service dialog box (provided that it has passed the following requirements mentioned below).
Figure 2 - call “bsearch” to check the name of the executable file in the list of executable files “auto elevating”
Some of these hard-programmed files in the whitelist system are:
'cttunesvr.exe', 'inetmgr.exe', 'migsetup.exe', 'mmc.exe', 'oobe.exe', 'pkgmgr.exe', 'provisionshare.exe', 'provisionstorage.exe', 'spinstall.exe', 'winsat.exe'
Requirement 2: Signed correctly
It is assumed that the second condition for “automatic” privilege escalation after sending a request to UAC is to perform signature verification using “wintrust! WTGetSignatureInfo.
This means that the attacker cannot simply create his own manifest or executable file needed for “automatic” privilege escalation and succeed, since the attacker's binary file is likely to be incorrectly signed and the last requirement from a trusted directory \ directory.
Requirement 3: Execution from a trusted directory \ directory
The final requirement for obtaining “automatic” privilege escalation is that the target executable file is in a “trusted directory”, for example “C: \ Windows \ System32”. Figure 3 shows that AIS performs this path check with a prompting request, in this case one of the paths considered “trusted” is “C: \ Windows \ System32”.
The title of this article is “User Account Control Bypass (UAC) by Parodying Trusted Directories”, so you can probably easily guess what will happen next.
As mentioned earlier in the UAC Primer section, autoprivilection (UAC bypass) will be performed for executable files that:
- Configured to receive “automatic” privilege escalation
- Correctly signed
- Runs from a trusted directory ("C: \ Windows \ System32")
Appinfo.dll (AIS) uses the RtlPrefixUnicodeString API to check if the executable path of the file with "C: \ Windows \ System32 \" matches one of the trusted directories. This is a fairly reinforced concrete check, considering its comparison with the canonical location of the file.
Therefore, to organize a crawl of this check, I create a directory called “C: \ Windows \” (note the space after “Windows”). Of course, using this action still cannot pass the RtlPrefixUnicodeString check, and I also mention that this is a somewhat invalid (or at least “unfriendly”) directory name, because Windows does not allow spaces at the end of the name when creating the directory (try ).
However, using the CreateDirectory API and adding “\\? \ ”To the name of the directory that I want to create, we can bypass some of these name filtering rules and send a request to create a directory directly to the file system.
This leads to the creation of an inconvenient directory that happily coexists in the file system along with the real “C: \ Windows \” (unless you are trying to do something with it in Windows Explorer).
Now that we have the “C: \ Windows \” directory, we can create the “System32” directory in it and copy one of the signed, executable files (which are allowed by the system for “automatic” privilege escalation) from the real “C: \ Windows \ System32.
To do this, I copied “winSAT.exe” (one of the files in the whitelist of Windows executable files with the system enabled “automatic” privilege elevation).
When we try to launch this file from our new directory “C: \ Windows \ System32 \ winSAT.exe”, it will go through the following APIs (see Figure 6) in appinfo.dll before performing the verification of the trusted directory. This is important, and the basis of why this bypass works.
When this inconvenient path with a space is sent to AIS for a request for privilege escalation, the path is passed to GetLongPathNameW, which converts it back to “C: \ Windows \ System32 \ winSAT.exe” (space is removed).
Now this is the string in which the valid directory was validated (using RtlPrefixUnicodeString) for the rest of the validation.
The beauty of my solution is that after checking the trusted directory, this converted path is executed, which is then released, and the remaining checks (and the final request for privilege escalation) are performed with the original name of the executable directory (with an extra space).
This allows all other checks to pass and causes appinfo.dll to accept my copy of winSAT.exe as with “automatic” privilege escalation (since it is correctly signed and added to the white list for “automatic” privilege escalation).
To actually use the malicious code, I simply copied the fake WINMM.dll (imported winSAT.exe) in my current directory “C: \ Windows \ System32 \” to replace the local dll. The complete concept can be seen in the figure below.
→ Link to Github