Admin Protection Bypasses via UIAccess
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Overview
- Windows AppInfo exposes
RAiLaunchAdminProcessto spawn UIAccess processes (intended for accessibility). UIAccess bypasses most User Interface Privilege Isolation (UIPI) message filtering so accessibility software can drive higher-IL UI. - Enabling UIAccess directly requires
NtSetInformationToken(TokenUIAccess)with SeTcbPrivilege, so low-priv callers rely on the service. The service performs three checks on the target binary before setting UIAccess: - Embedded manifest contains
uiAccess="true". - Signed by any certificate trusted by the Local Machine root store (no EKU/Microsoft requirement).
- Located in an administrator-only path on the system drive (e.g.,
C:\Windows,C:\Windows\System32,C:\Program Files, excluding specific writable subpaths). RAiLaunchAdminProcessperforms no consent prompt for UIAccess launches (otherwise accessibility tooling could not drive the prompt).
Token shaping and integrity levels
- If the checks succeed, AppInfo copies the caller token, enables UIAccess, and bumps Integrity Level (IL):
- Limited admin user (user is in Administrators but running filtered) ➜ High IL.
- Non-admin user ➜ IL increased by +16 levels up to a High cap (System IL is never assigned).
- If the caller token already has UIAccess, IL is left unchanged.
- “Ratchet” trick: a UIAccess process can disable UIAccess on itself, relaunch via
RAiLaunchAdminProcess, and gain another +16 IL increment. Medium➜High takes 255 relaunches (noisy, but works).
Why UIAccess enables an Admin Protection escape
- UIAccess lets a lower-IL process send window messages to higher-IL windows (bypassing UIPI filters). At equal IL, classic UI primitives like
SetWindowsHookExdo allow code injection/DLL loading into any process that owns a window (including message-only windows used by COM). - Admin Protection launches the UIAccess process under the limited user’s identity but at High IL, silently. Once arbitrary code runs inside that High-IL UIAccess process, the attacker can inject into other High-IL processes on the desktop (even belonging to different users), breaking the intended separation.
HWND-to-process handle primitive (GetProcessHandleFromHwnd / NtUserGetWindowProcessHandle)
- On Windows 10 1803+ the API moved into Win32k (
NtUserGetWindowProcessHandle) and can open a process handle using a caller-suppliedDesiredAccess. The kernel path usesObOpenObjectByPointer(..., KernelMode, ...), which bypasses normal user-mode access checks. - Preconditions in practice: the target window must be on the same desktop, and UIPI checks must pass. Historically, a caller with UIAccess could bypass UIPI failure and still get a kernel-mode handle (fixed as CVE-2023-41772).
- Impact: a window handle becomes a capability to obtain a powerful process handle (commonly
PROCESS_DUP_HANDLE,PROCESS_VM_READ,PROCESS_VM_WRITE,PROCESS_VM_OPERATION) that the caller could not normally open. This enables cross-sandbox access and can break Protected Process / PPL boundaries if the target exposes any window (including message-only windows). - Practical abuse flow: enumerate or locate HWNDs (e.g.,
EnumWindows/FindWindowEx), resolve the owning PID (GetWindowThreadProcessId), callGetProcessHandleFromHwnd, then use the returned handle for memory read/write or code-hijack primitives. - Post-fix behavior: UIAccess no longer grants kernel-mode opens on UIPI failure and allowed access rights are restricted to the legacy hook set; Windows 11 24H2 adds process-protection checks and feature-flagged safer paths. Disabling UIPI system-wide (
EnforceUIPI=0) weakens these protections.
Secure-directory validation weaknesses (AppInfo AiCheckSecureApplicationDirectory)
AppInfo resolves the supplied path via GetFinalPathNameByHandle and then applies string allow/deny checks against hardcoded roots/exclusions. Multiple bypass classes stem from that simplistic validation:
- Directory named streams: Excluded writable directories (e.g.,
C:\Windows\tracing) can be bypassed with a named stream on the directory itself, e.g.C:\Windows\tracing:file.exe. The string checks seeC:\Windows\and miss the excluded subpath. - Writable file/directory inside an allowed root:
CreateProcessAsUserdoes not require a.exeextension. Overwriting any writable file under an allowed root with an executable payload works, or copying a signeduiAccess="true"EXE into any writable subdirectory (e.g., update leftovers such asTasks_Migratedwhen present) lets it pass the secure-path check. - MSIX into
C:\Program Files\WindowsApps(fixed): Non-admins could install signed MSIX packages that landed inWindowsApps, which was not excluded. Packaging a UIAccess binary inside the MSIX then launching it viaRAiLaunchAdminProcessyielded a promptless High-IL UIAccess process. Microsoft mitigated by excluding this path; theuiAccessrestricted MSIX capability itself already requires admin install.
Attack workflow (High IL without a prompt)
- Obtain/build a signed UIAccess binary (manifest
uiAccess="true"). - Place it where AppInfo’s allowlist accepts it (or abuse a path-validation edge case/writable artifact as above).
- Call
RAiLaunchAdminProcessto spawn it silently with UIAccess + elevated IL. - From that High-IL foothold, target another High-IL process on the desktop using window hooks/DLL injection or other same-IL primitives to fully compromise the admin context.
Enumerating candidate writable paths
Run the PowerShell helper to discover writable/overwritable objects inside nominally secure roots from the perspective of a chosen token:
$paths = "C:\\Windows","C:\\Program Files","C:\\Program Files (x86)"
Get-AccessibleFile -Win32Path $paths -Access Execute,WriteData `
-DirectoryAccess AddFile -Recurse -ProcessId <PID>
- Exécuter en tant qu’administrateur pour une visibilité accrue ; définir
-ProcessIdsur un processus low-priv afin de refléter l’accès de ce token. - Filtrer manuellement pour exclure les sous-répertoires connus comme interdits avant d’utiliser les candidats avec
RAiLaunchAdminProcess.
Références
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


