uiaccess-admin-protection-bypass.md (8019B)
1 --- 2 title: "Admin Protection Bypasses via UIAccess" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/windows-local-privilege-escalation/uiaccess-admin-protection-bypass.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/windows-local-privilege-escalation/uiaccess-admin-protection-bypass.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Admin Protection Bypasses via UIAccess 14 15 ## Overview 16 - Windows AppInfo exposes the internal `RAiLaunchAdminProcess` path used to start UIAccess applications for accessibility. UIAccess permits selected interaction across User Interface Privilege Isolation (UIPI) boundaries; it is not a general bypass of every process-security boundary.<sup>[[1]](#references)[[3]](#references)</sup> 17 - 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: 18 - Embedded manifest contains `uiAccess="true"`. 19 - Signed by any certificate trusted by the Local Machine root store (no EKU/Microsoft requirement). 20 - Located in an administrator-only path on the system drive (e.g., `C:\Windows`, `C:\Windows\System32`, `C:\Program Files`, excluding specific writable subpaths). 21 - `RAiLaunchAdminProcess` performs no consent prompt for UIAccess launches (otherwise accessibility tooling could not drive the prompt).<sup>[[1]](#references)</sup> 22 23 ## Token shaping and integrity levels 24 - If the checks succeed, AppInfo **copies the caller token**, enables UIAccess, and bumps Integrity Level (IL): 25 - Limited admin user (user is in Administrators but running filtered) ➜ **High IL**. 26 - Non-admin user ➜ IL increased by **+16 levels** up to a **High** cap (System IL is never assigned). 27 - If the caller token already has UIAccess, IL is left unchanged. 28 - “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).<sup>[[1]](#references)</sup> 29 30 ## Why UIAccess enables an Admin Protection escape 31 - UIAccess lets a lower-IL process send window messages to higher-IL windows (bypassing UIPI filters). At **equal IL**, classic UI primitives like `SetWindowsHookEx` **do allow code injection/DLL loading** into any process that owns a window (including **message-only windows** used by COM). 32 - 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.<sup>[[1]](#references)</sup> 33 34 ## HWND-to-process handle primitive (`GetProcessHandleFromHwnd` / `NtUserGetWindowProcessHandle`) 35 - On Windows 10 1803+ the API moved into Win32k (`NtUserGetWindowProcessHandle`) and can open a process handle using a caller-supplied `DesiredAccess`. The kernel path uses `ObOpenObjectByPointer(..., KernelMode, ...)`, which bypasses normal user-mode access checks.<sup>[[2]](#references)</sup> 36 - 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). 37 - Historical impact: a window handle became a **capability** for process access such as `PROCESS_DUP_HANDLE`, `PROCESS_VM_READ`, `PROCESS_VM_WRITE`, or `PROCESS_VM_OPERATION` that the caller could not normally obtain. Before the documented fixes, this could cross sandbox and protected-process boundaries when a target exposed a window, including a message-only window.<sup>[[2]](#references)</sup> 38 - Practical abuse flow: enumerate or locate HWNDs (e.g., `EnumWindows`/`FindWindowEx`), resolve the owning PID (`GetWindowThreadProcessId`), call `GetProcessHandleFromHwnd`, then use the returned handle for memory read/write or code-hijack primitives. 39 - 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.<sup>[[2]](#references)</sup> 40 41 ## Secure-directory validation weaknesses (AppInfo `AiCheckSecureApplicationDirectory`) 42 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: 43 - **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 see `C:\Windows\` and miss the excluded subpath. 44 - **Writable file/directory inside an allowed root**: `CreateProcessAsUser` does **not require a `.exe` extension**. Overwriting any writable file under an allowed root with an executable payload works, or copying a signed `uiAccess="true"` EXE into any writable subdirectory (e.g., update leftovers such as `Tasks_Migrated` when present) lets it pass the secure-path check. 45 - **MSIX into `C:\Program Files\WindowsApps` (fixed)**: Non-admins could install signed MSIX packages that landed in `WindowsApps`, which was not excluded. Packaging a UIAccess binary inside the MSIX then launching it via `RAiLaunchAdminProcess` yielded a **promptless High-IL UIAccess process**. Microsoft mitigated by excluding this path; the `uiAccess` restricted MSIX capability itself already requires admin install.<sup>[[1]](#references)</sup> 46 47 ## Attack workflow (High IL without a prompt) 48 1. Obtain/build a **signed UIAccess binary** (manifest `uiAccess="true"`). For a realistic assessment, test with trust material and paths explicitly authorized for the lab; do not add an attacker certificate to a production machine's Local Machine root store. 49 2. Place it where AppInfo’s allowlist accepts it (or abuse a path-validation edge case/writable artifact as above). 50 3. Call `RAiLaunchAdminProcess` to spawn it **silently** with UIAccess + elevated IL. 51 4. 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.<sup>[[1]](#references)</sup> 52 53 ## Enumerating candidate writable paths 54 Run the PowerShell helper to discover writable/overwritable objects inside nominally secure roots from the perspective of a chosen token:<sup>[[1]](#references)</sup> 55 56 ```powershell 57 $paths = "C:\\Windows","C:\\Program Files","C:\\Program Files (x86)" 58 Get-AccessibleFile -Win32Path $paths -Access Execute,WriteData ` 59 -DirectoryAccess AddFile -Recurse -ProcessId <PID> 60 ``` 61 62 - Run as Administrator for broader visibility; set `-ProcessId` to a low-priv process to mirror that token’s access. 63 - Filter manually to exclude known disallowed subdirectories before using candidates with `RAiLaunchAdminProcess`. 64 65 ## Related 66 67 Secure Desktop accessibility registry propagation LPE (RegPwn): 68 69 [Secure Desktop Accessibility Registry Propagation Regpwn](/hacktricks/windows-hardening/windows-local-privilege-escalation/secure-desktop-accessibility-registry-propagation-regpwn) 70 71 ## References 72 73 - [1] [Bypassing Administrator Protection by Abusing UI Access](https://projectzero.google/2026/02/windows-administrator-protection.html) 74 - [2] [GetProcessHandleFromHwnd (GPHFH) Deep Dive](https://projectzero.google/2026/02/gphfh-deep-dive.html) 75 - [3] [Microsoft Learn — UIAccess applications](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control/how-it-works#uiaccess-applications)