<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parag Mali - tag: uac</title><description>Posts tagged uac.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:09 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/uac/rss.xml" rel="self" type="application/rss+xml"/><item><title>The Integrity-Level Stack: MIC, UIPI, and Twenty Years of UAC&apos;s Quiet Plumbing</title><link>https://paragmali.com/blog/the-integrity-level-stack-mic-uipi-and-twenty-years-of-uacs-/</link><guid isPermaLink="true">https://paragmali.com/blog/the-integrity-level-stack-mic-uipi-and-twenty-years-of-uacs-/</guid><description>What UAC actually is beneath the consent prompt: Mandatory Integrity Control, UIPI, the split-token model, and twenty years of bypass research as proof.</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate><content:encoded>
**UAC has never been the consent prompt.** Two Vista-era primitives, Mandatory Integrity Control (MIC) and User Interface Privilege Isolation (UIPI), add an integrity axis to the access check and a windowing-layer analog that blocks cross-IL message injection. The split-token model gives every administrator a Medium-IL filtered token at logon and holds the full admin token dormant. The yellow dialog is the smallest part of the system. Its architect, Mark Russinovich, publicly disclaimed it as &quot;not a security boundary&quot; in February 2007, and twenty years of bypass research has been the empirical confirmation. In November 2024, Microsoft finally moved the boundary line with Administrator Protection. The MIC + UIPI plumbing outlived UAC itself: it is still the substrate of every browser sandbox, every AppContainer, and the Adminless successor in 2026.
&lt;h2&gt;1. Two whoami Outputs, Sixty Seconds Apart&lt;/h2&gt;
&lt;p&gt;Open an unelevated PowerShell on a Windows 11 administrator account. Run &lt;code&gt;whoami /groups /priv&lt;/code&gt;. Click &quot;Yes&quot; on the yellow prompt. Open an elevated PowerShell on the &lt;em&gt;same&lt;/em&gt; account. Run the same command. The two outputs are different lists of SIDs. Sixty seconds have passed. The consent prompt did not move a single bit of OS state on its own. The operating system did, because of a stack of primitives that ship with every Windows install and that almost no Windows user has ever heard the names of. This article is a tour of that stack, and of what twenty years of bypass research has taught us about it.&lt;/p&gt;
&lt;p&gt;Place the two outputs side by side. The user is the same. The session is the same. The clock has barely moved. Read them carefully.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;PS C:\Users\admin&amp;gt; whoami /groups /priv | findstr /i &quot;Mandatory Administrators SeDebug&quot;
BUILTIN\Administrators                Group used for deny only
Mandatory Label\Medium Mandatory Level Label
(SeDebugPrivilege not present)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;PS C:\Users\admin&amp;gt; whoami /groups /priv | findstr /i &quot;Mandatory Administrators SeDebug&quot;
BUILTIN\Administrators                Enabled by default, Enabled group, Group owner
Mandatory Label\High Mandatory Level   Label
SeDebugPrivilege                       Disabled
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Four facts fall out of those two outputs, and each one of them is a foothold for the rest of this article.&lt;/p&gt;
&lt;p&gt;The first fact is that the administrator group SID is &lt;em&gt;present in both tokens&lt;/em&gt;. It is not added by the elevation. In the filtered token it carries the flag &lt;code&gt;SE_GROUP_USE_FOR_DENY_ONLY&lt;/code&gt;, which means the access-check algorithm consults it only when matching a deny ACE and otherwise pretends it is absent [@uac-how-it-works]. In the elevated token, the same SID is fully enabled. The dialog did not add a SID; it changed which token Windows uses.&lt;/p&gt;
&lt;p&gt;The second fact is the integrity level. In the filtered token, the mandatory label reads &lt;code&gt;Mandatory Label\Medium Mandatory Level&lt;/code&gt;. In the elevated token, the same label reads &lt;code&gt;Mandatory Label\High Mandatory Level&lt;/code&gt;. That label corresponds to a well-known SID under the &lt;code&gt;S-1-16-X&lt;/code&gt; family (&lt;code&gt;S-1-16-8192&lt;/code&gt; for Medium and &lt;code&gt;S-1-16-12288&lt;/code&gt; for High) [@well-known-sids]. The integrity level is not a regular group SID. It is a separate field on the token, and as we will see in §4, it drives a separate access-check evaluator that runs &lt;em&gt;before&lt;/em&gt; the discretionary access check [@mic-doc].&lt;/p&gt;
&lt;p&gt;The third fact is the privilege set. The filtered token holds a small set of user-mode privileges (&lt;code&gt;SeChangeNotifyPrivilege&lt;/code&gt;, &lt;code&gt;SeShutdownPrivilege&lt;/code&gt;, a handful of others). The elevated token holds the full administrator privilege set, including the named ones the security press writes about: &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, &lt;code&gt;SeTakeOwnershipPrivilege&lt;/code&gt;, &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt;, &lt;code&gt;SeBackupPrivilege&lt;/code&gt;, &lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt;, and twenty or so others, depending on the Windows build [@russinovich-tnm-2007].&lt;/p&gt;
&lt;p&gt;The fourth fact is the most subtle, and the one this whole article exists to make rigorous. The yellow dialog did not &lt;em&gt;create&lt;/em&gt; the elevated token. The OS created it at logon, almost half an hour before the prompt ever rendered, and held it dormant in the LSA. The prompt asked the user a single question: &lt;em&gt;may I, the operating system, use the token I already have?&lt;/em&gt; It did not ask: &lt;em&gt;may I, the operating system, mint a more privileged token now?&lt;/em&gt; That distinction is the difference between how every Windows user &lt;em&gt;talks&lt;/em&gt; about UAC and how UAC actually works.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The yellow dialog moves no bits. It asks permission to use authority that was already constructed at logon and held dormant. The integrity primitives, MIC and UIPI, do the bounding work whether or not a prompt ever renders.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The four primitives we are about to tour are the substrate beneath everything in those two &lt;code&gt;whoami&lt;/code&gt; outputs. Mandatory Integrity Control (MIC) is the access-check evaluator that decided your Medium-IL PowerShell could not write into &lt;code&gt;%SystemRoot%\System32&lt;/code&gt; before any DACL was consulted. User Interface Privilege Isolation (UIPI) is the windowing-layer analog that prevented your Medium-IL Edge tab from injecting &lt;code&gt;WM_SETTEXT&lt;/code&gt; into the High-IL elevated PowerShell next to it. The split-token model is the LSA policy that decided your interactive shell should hold the Medium-IL token instead of the High-IL one. The Application Information service (Appinfo) is the SYSTEM-trusted broker that mediated the token swap when you clicked &quot;Yes.&quot;&lt;/p&gt;
&lt;p&gt;This article walks every one of those layers, then ends at the empirical proof: twenty years of &quot;UAC bypasses,&quot; and Microsoft&apos;s own quiet acknowledgement, from week one, that the dialog was never the security boundary [@russinovich-blog-2007]. Why did Microsoft build this stack in the first place? What was wrong with how Windows XP did it?&lt;/p&gt;
&lt;h2&gt;2. The XP Problem and the Vista Bet&lt;/h2&gt;
&lt;p&gt;On the overwhelming majority of consumer Windows XP installs in 2003, every process the user launched ran as Administrator, because the first interactive account XP provisioned at setup was an Administrator and the typical user never created a separate Limited User account [@margosis-archive]. Every browser tab. Every embedded Word macro. Every drive-by download. The operational vulnerability surface was the entire OS, because authority on Windows is carried in the access token, and the access token of those XP-era user processes held the full administrator SID set.&lt;/p&gt;
&lt;p&gt;Sysinternals co-founder Mark Russinovich, then a Microsoft engineer following the 2006 Winternals acquisition, framed the problem precisely in the June 2007 issue of &lt;em&gt;TechNet Magazine&lt;/em&gt;: &quot;Most users of Windows XP run with full administrative rights all the time, allowing all software they run, including malware, to have unrestricted access to the system&quot; [@russinovich-tnm-2007]. The sentence reads like a confession, and it was. The OS shipped with a sound access-control model and an operational policy that defeated it from the first reboot.&lt;/p&gt;
&lt;p&gt;Two distinct threat models drove the architectural response Vista shipped four years later.&lt;/p&gt;
&lt;h3&gt;Threat model one: the runaway admin&lt;/h3&gt;
&lt;p&gt;The first threat model was the &lt;em&gt;runaway admin&lt;/em&gt;. Default-admin consumer installs meant malware silently inherited admin authority because the user &lt;em&gt;was&lt;/em&gt; the admin. A drive-by exploit in Internet Explorer ran as the user, the user was an admin, and the malware was an admin. There was no point in the OS where a least-privilege boundary could intervene, because the token never carried a least-privilege bound to begin with. The DACLs were correct; the policy that filled the tokens was the failure.&lt;/p&gt;
&lt;h3&gt;Threat model two: the shatter-attack class&lt;/h3&gt;
&lt;p&gt;The second threat model was the &lt;em&gt;shatter-attack class&lt;/em&gt;. In August 2002, security researcher Chris Paget published a paper titled &quot;Exploiting design flaws in the Win32 API for privilege escalation&quot; on the Bugtraq mailing list, immediately mirrored on Help Net Security [@helpnet-paget]. The paper coined the term &lt;em&gt;shatter attack&lt;/em&gt; and demonstrated that on Windows NT, 2000, and XP, any process running on a user&apos;s interactive desktop could send a &lt;code&gt;WM_TIMER&lt;/code&gt; message carrying a callback function pointer to any other process&apos;s message loop on the same desktop. The receiving process would invoke the callback in its own address space, at its own privilege level [@shatter-wiki].&lt;/p&gt;
&lt;p&gt;The shatter-attack term is sometimes attributed to Brett Moore alone. Paget&apos;s August 2002 Bugtraq paper actually coined the term; Moore&apos;s Black Hat USA 2004 talk &lt;em&gt;Shoot The Messenger: Win32 Shatter Attacks&lt;/em&gt; productised the technique class and brought it to a wider conference audience. Both attributions are correct for different artifacts.&lt;/p&gt;
&lt;p&gt;This was an architectural defect. The receiving process did not authenticate the message origin. It could not, because the Win32 messaging system was designed in the late 1980s under the assumption that all windows on a desktop belonged to one trust principal. By 2002, that assumption had been false for a decade: services ran on the user&apos;s interactive desktop with &lt;code&gt;LocalSystem&lt;/code&gt; authority, and the user&apos;s browser could send them messages.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s December 2002 patch (security bulletin MS02-071) fixed individual services that exposed the most exploitable callbacks. It did not fix the architectural class, because the class was a property of the Win32 messaging design, not of any one service [@shatter-wiki].&lt;/p&gt;

The popular history of the shatter-attack class collapses two separate authorship events into one. Chris Paget&apos;s August 2002 Bugtraq paper coined the term and produced the original demonstration tool (which Paget called &quot;Shatter&quot;) [@helpnet-paget]. Brett Moore&apos;s Black Hat USA 2004 talk *Shoot The Messenger: Win32 Shatter Attacks*, eighteen months later, productised the technique into a conference-grade reference talk and contributed additional disclosure work at Security-Assessment.com.&lt;p&gt;Both attributions are accurate for different artifacts: Paget for the term and the August 2002 paper, Moore for the Black Hat 2004 productisation. The Wikipedia &lt;em&gt;Shatter attack&lt;/em&gt; article preserves both authorships verbatim [@shatter-wiki]. The reason the disambiguation matters: any historical account of Vista&apos;s UIPI design decision must attribute the threat-model framing correctly, because Microsoft cited Paget&apos;s 2002 paper, not Moore&apos;s 2004 talk, in the internal architectural discussions Russinovich later summarised [@russinovich-blog-2007].
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The Vista bet, stated as four design decisions&lt;/h3&gt;
&lt;p&gt;Between 2005 and 2006, Microsoft made four decisions about how Vista would respond. The first was to split the administrator&apos;s authority by default: an admin user would not hold a single admin token at logon, but a filtered token plus a dormant linked one. The second was to mediate the recombination through an OS-controlled UI surface, so the user could see and consent to the moment authority crossed an integrity boundary. The third was to add a second access-check axis (integrity) that the DACL could not override. The fourth was to add a windowing-layer analog to close the cross-IL variant of the shatter-attack class.&lt;/p&gt;
&lt;p&gt;All four shipped together. Vista RTM&apos;d on November 8, 2006 to OEMs and businesses, and Microsoft launched it to consumers on January 30, 2007 [@vista-press-release]. The press release called it &quot;the most significant product launch in Microsoft Corp.&apos;s history.&quot;&lt;/p&gt;
&lt;p&gt;The architectural canon was published five months later, in the June 2007 issue of &lt;em&gt;TechNet Magazine&lt;/em&gt; under the title &lt;em&gt;Security: Inside Windows Vista User Account Control&lt;/em&gt; [@russinovich-tnm-2007]. The author was Russinovich, and the article became the single most-cited primary on UAC in the Windows-security literature. Five months &lt;em&gt;earlier&lt;/em&gt;, however, in a TechNet Blogs post about PsExec, the same author had quietly written something the entire later debate would rest on, and almost no one read it for what it actually said [@russinovich-blog-2007]. We will return to that post in §7. First, the harder question: why couldn&apos;t NT&apos;s existing access-control model handle any of this on its own?&lt;/p&gt;
&lt;h2&gt;3. Why the DACL and the Privilege Were Not Enough&lt;/h2&gt;
&lt;p&gt;Windows NT had the &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;access-control model&lt;/a&gt; from day one. It had Security Identifiers (SIDs), access tokens, discretionary access control lists (DACLs), privileges, and an access-check algorithm with a name (&lt;code&gt;SeAccessCheck&lt;/code&gt;) that the kernel exposed and documented [@access-control][@windows-internals]. The model was correct in theory and broken in practice. To see why, watch what happens when an XP administrator opens a malicious Word document.&lt;/p&gt;
&lt;p&gt;The user double-clicks the document. Word starts. Word loads the document&apos;s embedded macro. The macro calls &lt;code&gt;URLDownloadToFile&lt;/code&gt; and writes &lt;code&gt;evil.exe&lt;/code&gt; into &lt;code&gt;%TEMP%&lt;/code&gt;. Then it calls &lt;code&gt;CreateProcess&lt;/code&gt; on &lt;code&gt;evil.exe&lt;/code&gt;. The new process inherits its parent&apos;s primary access token, which is the user&apos;s interactive token, which carries the administrator group SID, enabled, with the full administrator privilege set. The DACL on &lt;code&gt;HKLM\SYSTEM\CurrentControlSet\Services&lt;/code&gt; grants Full Control to &lt;code&gt;BUILTIN\Administrators&lt;/code&gt;. The malware writes a new service entry. The malware now persists across reboots, all without a single elevation prompt, because there was no elevation transition to prompt at. The user was already the administrator [@russinovich-tnm-2007].&lt;/p&gt;
&lt;p&gt;The first problem is in the &lt;em&gt;D&lt;/em&gt; of DACL. Discretionary access control lists are &lt;em&gt;discretionary&lt;/em&gt; by definition: the owning principal of an object decides who has access [@dacls-control]. An attacker running as the user can rewrite any DACL the user owns. That is not a bug; it is the meaning of the word &lt;em&gt;discretionary&lt;/em&gt;. Mandatory access-control models (Bell-LaPadula 1973 [@blp-wiki], Biba 1977 [@biba-wiki]) exist precisely because discretionary models cannot defend against principals running with the owner&apos;s authority.&lt;/p&gt;
&lt;p&gt;The second problem is in the privilege model. A Windows access token carries a list of named &lt;em&gt;privileges&lt;/em&gt; such as &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, &lt;code&gt;SeTakeOwnershipPrivilege&lt;/code&gt;, &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt;. Each privilege is a per-token authorisation to bypass some specific DACL check. An admin token holds them all. There is no way in the NT 4.0 / 2000 / XP design to say &quot;this Word process holds the admin&apos;s identity but should not be trusted to use &lt;code&gt;SeDebugPrivilege&lt;/code&gt;.&quot; Privileges are granted to tokens at logon, and the only way to remove them from a downstream process is to construct a restricted token explicitly, by hand, with &lt;code&gt;CreateRestrictedToken&lt;/code&gt; [@createrestrictedtoken].&lt;/p&gt;
&lt;h3&gt;Generation 1: the seven-year failure to make least-privilege voluntary&lt;/h3&gt;
&lt;p&gt;Between 1999 and 2006, Microsoft and the Windows security community tried five different ways to make least privilege voluntary. None of them worked at consumer scale.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CreateRestrictedToken&lt;/code&gt; is a Win32 API, documented since Windows XP and Server 2003, that produces a copy of an existing access token with selected SIDs marked deny-only, selected privileges removed, and an optional list of restricting SIDs added [@createrestrictedtoken]. It is the kernel primitive every later sandbox (Chromium&apos;s renderer sandbox, AppContainer, Office Protected View) is built on. It was a primitive, not a policy. A consumer install with default-admin logons could not use it without an opt-in from every application vendor.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;runas.exe&lt;/code&gt;, shipped in Windows 2000, let a user explicitly launch a process under a different identity. The user was supposed to log in as a standard user and &lt;code&gt;runas&lt;/code&gt; an administrator account when needed. In practice, the user logged in as the administrator and forgot the standard account existed.&lt;/p&gt;
&lt;p&gt;Software Restriction Policies (SRP), shipped with Windows XP, let a domain admin define hash, path, certificate, or zone rules that the OS enforced at process creation [@srp-2003]. SRP was a policy mechanism on top of the SAFER substrate [@winsafer]. It worked when configured. On consumer Windows it was off by default; on enterprise Windows it was configured by the few who knew it existed.&lt;/p&gt;
&lt;p&gt;Aaron Margosis, then a Microsoft consultant, ran a years-long blog campaign called &quot;Non-Admin&quot; arguing that ordinary users should log in as standard users and only elevate when necessary. His tooling included LUA Buglight (which diagnosed which OS calls a misbehaving application made that required admin privilege), MakeMeAdmin (a &lt;code&gt;runas&lt;/code&gt; shim), and PrivBar (a status-bar widget that displayed the IL of the current process) [@margosis-archive]. The blog became required reading inside Microsoft and the Windows-admin community.&lt;/p&gt;

Margosis&apos;s writing documents the daily friction of being a non-admin on XP. A printer-driver installer fails because it writes a per-user setting to `HKLM`. A game launcher fails because it writes save files to `%ProgramFiles%`. A 1998 line-of-business app fails because it stores its INI file under its install directory. Each failure was the application&apos;s fault; in aggregate, the application population rendered non-admin operation untenable for the typical user [@margosis-archive].&lt;p&gt;Margosis&apos;s own pattern, openly discussed on the blog, was to give up on per-application diagnosis and log in as Administrator full-time, while documenting the friction professionally so Microsoft could harvest the data for Vista&apos;s compatibility shims. The primitives existed (&lt;code&gt;CreateRestrictedToken&lt;/code&gt;, SRP, the SAFER substrate). The third-party software base rendered them unusable. That dataset is the reason Vista shipped file and registry virtualisation as a built-in shim [@russinovich-tnm-2007]: the only alternative was for every application vendor to fix their software, and Margosis&apos;s blog had documented for half a decade that this was not happening.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The lesson Microsoft took from the 1999-2006 experience was that voluntary least privilege does not scale. You cannot solve the runaway-admin problem with policy and exhortation. You need an architectural primitive that runs by default, bounds authority by integrity rather than by identity, and absorbs the legacy of applications written for unrestricted admin without breaking them. All four primitives of the Vista bet shipped together in November 2006 [@vista-press-release].&lt;/p&gt;
&lt;p&gt;What does an integrity primitive look like, and how is it different from &quot;another ACE&quot;?&lt;/p&gt;
&lt;h2&gt;4. The Twin Primitives: MIC and UIPI&lt;/h2&gt;
&lt;h3&gt;4.1 Mandatory Integrity Control&lt;/h3&gt;

An access-check evaluator that compares the integrity level of a subject token to the integrity level of a target object before consulting the object&apos;s DACL. MIC denials short-circuit the access check; a Low-IL principal cannot write to a Medium-IL object regardless of what the DACL says.
&lt;p&gt;The load-bearing fact about MIC is in a single sentence on the Microsoft Learn reference page, and the entire architectural difference between MIC and &quot;just another ACE&quot; lives in that sentence. MIC &quot;evaluates access before access checks against an object&apos;s discretionary access control list (DACL) are evaluated&quot; [@mic-doc].&lt;/p&gt;
&lt;p&gt;Pause on that ordering. &lt;em&gt;Before&lt;/em&gt; the DACL. Not &lt;em&gt;together with&lt;/em&gt; it. Not &lt;em&gt;after&lt;/em&gt; it. The integrity-level check is a separate evaluator that runs first, and its denial is final. If the IL check denies access, the DACL is never consulted, no matter what the DACL says. That is what the word &lt;em&gt;mandatory&lt;/em&gt; in &lt;em&gt;Mandatory Integrity Control&lt;/em&gt; means.&lt;/p&gt;

A well-known SID, carried on every Windows access token and every securable object, that orders subjects and objects on a seven-level integrity lattice (Untrusted, Low, Medium, Medium Plus, High, System, Protected Process).
&lt;p&gt;The seven well-known integrity-level SIDs are defined in the &lt;em&gt;Well-known SIDs&lt;/em&gt; reference page on Microsoft Learn [@well-known-sids].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Integrity level&lt;/th&gt;
&lt;th&gt;RID (S-1-16-X)&lt;/th&gt;
&lt;th&gt;Typical use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Untrusted&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Most-restricted sandboxes; rare on consumer Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-4096&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IE Protected Mode, AppContainer, Edge / Chrome renderers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-8192&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default for interactive user processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium Plus&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-8448&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;UI-Access processes (&lt;code&gt;uiAccess=true&lt;/code&gt; manifest, Windows 7+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-12288&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Elevated administrative processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-16384&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kernel-mode and &lt;code&gt;LocalSystem&lt;/code&gt; services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protected Process&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-20480&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PPL-protected processes (LSASS with &lt;code&gt;RunAsPPL&lt;/code&gt;, antimalware)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The Microsoft Learn MIC reference page describes the operational set as four integrity levels (low, medium, high, system) [@mic-doc]. The Well-known SIDs reference page enumerates seven [@well-known-sids]. Both framings are correct: Untrusted is rare on consumer systems, Medium Plus is a UI-Access-only quirk used by accessibility software, and Protected Process overlaps with Protected Process Light signing-level semantics rather than the canonical IL pipeline. The four-vs-seven discrepancy is a documentation artifact, not an inconsistency in the kernel.&lt;/p&gt;
&lt;p&gt;The IL lives on a token in the &lt;code&gt;TokenIntegrityLevel&lt;/code&gt; field, retrievable through &lt;code&gt;GetTokenInformation&lt;/code&gt; and the &lt;code&gt;TOKEN_MANDATORY_LABEL&lt;/code&gt; structure [@mic-doc]. The IL lives on an object in the system access control list (SACL) as a &lt;code&gt;SYSTEM_MANDATORY_LABEL_ACE&lt;/code&gt;, a special ACE type that carries the object&apos;s IL SID and a mandatory-policy mask [@mandatory-label-ace]. Three policy bits are defined in the &lt;code&gt;winnt.h&lt;/code&gt; header [@mandatory-label-ace].&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_WRITE_UP&lt;/code&gt; (0x1) -- default. A subject at lower IL cannot write to this object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_READ_UP&lt;/code&gt; (0x2) -- opt-in. A subject at lower IL cannot read this object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP&lt;/code&gt; (0x4) -- opt-in. A subject at lower IL cannot execute this object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Object authors who do not specify a mandatory label inherit the default, which is &lt;code&gt;NO_WRITE_UP&lt;/code&gt; only [@mic-doc]. The opt-in policies are exactly that: opt-in. A High-IL process that wants its files invisible to a Medium-IL process must explicitly request &lt;code&gt;NO_READ_UP&lt;/code&gt; on the SACL. By default, MIC bounds writes, not reads, and that is one of the structural shapes Forshaw&apos;s 2017 &quot;Reading Your Way Around UAC&quot; series exploited [@forshaw-reading-uac].&lt;/p&gt;
&lt;p&gt;The &quot;regardless of DACL&quot; property is the part to read slowly. A Low-IL principal cannot write to a Medium-IL object &quot;even if that object&apos;s DACL allows write access to the principal,&quot; because the IL check runs first and short-circuits the access decision before the DACL evaluator ever sees the request [@mic-doc]. This is the difference between adding &quot;another ACE&quot; for integrity and adding a separate evaluator that runs first. An integrity ACE in the DACL would have been overridable by the object owner, because DACLs are discretionary. A mandatory-label ACE in the SACL is enforced by &lt;code&gt;SeAccessCheck&lt;/code&gt; itself, independently of any other ACE in the DACL.&lt;/p&gt;

flowchart TD
    A[&quot;Subject requests access&lt;br /&gt;(SID set, IL, desired access)&quot;] --&amp;gt; B[&quot;MIC evaluator&lt;br /&gt;compares subject IL to object IL&lt;br /&gt;against NO_WRITE_UP / NO_READ_UP policy&quot;]
    B --&amp;gt; C{&quot;IL check allows&lt;br /&gt;requested access?&quot;}
    C -- &quot;No&quot; --&amp;gt; D[&quot;ACCESS_DENIED&lt;br /&gt;(DACL not consulted)&quot;]
    C -- &quot;Yes&quot; --&amp;gt; E[&quot;DACL evaluator&lt;br /&gt;walks ACEs in order&lt;br /&gt;(deny first, then allow)&quot;]
    E --&amp;gt; F{&quot;DACL grants&lt;br /&gt;requested access?&quot;}
    F -- &quot;Yes&quot; --&amp;gt; G[&quot;ACCESS_GRANTED&quot;]
    F -- &quot;No&quot; --&amp;gt; H[&quot;ACCESS_DENIED&quot;]
&lt;p&gt;The architectural payoff is in the pseudocode of the access-check decision itself. Strip the API noise away and the decision reduces to two evaluators in series. The conceptual ordering is exact.&lt;/p&gt;
&lt;p&gt;{`
// Pseudocode of the Windows access-check ordering (Vista+).
// See Microsoft Learn: Mandatory Integrity Control.&lt;/p&gt;
&lt;p&gt;function seAccessCheck(subjectToken, object, desiredAccess) {
  // Step 1: Mandatory Integrity Control. Runs before the DACL.
  const subjectIL = subjectToken.integrityLevel;     // e.g. Medium = 0x2000
  const objectIL  = object.mandatoryLabel.integrityLevel; // e.g. High = 0x3000
  const policy    = object.mandatoryLabel.policy;    // bitmask&lt;/p&gt;
&lt;p&gt;  if (subjectIL &amp;lt; objectIL) {
    if ((policy &amp;amp; NO_WRITE_UP)   &amp;amp;&amp;amp; (desiredAccess &amp;amp; WRITE_BITS))   return &apos;ACCESS_DENIED&apos;;
    if ((policy &amp;amp; NO_READ_UP)    &amp;amp;&amp;amp; (desiredAccess &amp;amp; READ_BITS))    return &apos;ACCESS_DENIED&apos;;
    if ((policy &amp;amp; NO_EXECUTE_UP) &amp;amp;&amp;amp; (desiredAccess &amp;amp; EXECUTE_BITS)) return &apos;ACCESS_DENIED&apos;;
  }&lt;/p&gt;
&lt;p&gt;  // Step 2: only if MIC allowed do we consult the DACL.
  for (const ace of object.dacl.aces) {
    if (ace.sid in subjectToken.sids) {
      if (ace.type === &apos;DENY&apos;  &amp;amp;&amp;amp; (ace.mask &amp;amp; desiredAccess)) return &apos;ACCESS_DENIED&apos;;
      if (ace.type === &apos;ALLOW&apos;) desiredAccess &amp;amp;= ~ace.mask;
      if (desiredAccess === 0) return &apos;ACCESS_GRANTED&apos;;
    }
  }
  return &apos;ACCESS_DENIED&apos;; // implicit deny if no ACE grants
}
`}&lt;/p&gt;
&lt;p&gt;The naive reading of MIC is &quot;they added another ACE for integrity.&quot; The correct reading is that they added a separate axis with its own evaluator that the DACL cannot override. The reader who internalises that ordering can re-derive almost every subsequent design decision Vista made about UAC, AppContainer, IE Protected Mode, and Administrator Protection. A MIC denial is final. The DACL is not consulted. That is what &lt;em&gt;mandatory&lt;/em&gt; means.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; MIC adds a second axis to the access check. The first axis is identity (DACL plus token SIDs); the second is integrity (IL). The two axes are evaluated in order: integrity first, identity second. A failure on the integrity axis short-circuits the entire check, regardless of what the identity axis would have said.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MIC bounds file, registry, and most other securable-object writes across IL boundaries. But the XP-era shatter attacks Paget published in 2002 were not about file writes. They were about cross-desktop message injection in the Win32 windowing layer, and MIC cannot help with that, because window messages do not pass through &lt;code&gt;SeAccessCheck&lt;/code&gt;. So Vista shipped a second primitive specifically for the windowing layer.&lt;/p&gt;
&lt;h3&gt;4.2 User Interface Privilege Isolation&lt;/h3&gt;

The windowing-layer analog of MIC. UIPI blocks a defined subset of window messages and hook APIs sent from a lower-IL process to a window owned by a higher-IL process on the same desktop, terminating the cross-IL variant of the shatter-attack class.
&lt;p&gt;If MIC is mandatory integrity for &lt;em&gt;objects&lt;/em&gt;, UIPI is mandatory integrity for &lt;em&gt;windows&lt;/em&gt;. Same idea, different layer of the OS. Same principle: a separate evaluator that runs in the window manager and blocks cross-IL operations regardless of the window&apos;s own configuration [@uipi-wiki].&lt;/p&gt;
&lt;p&gt;The canonical failed-shatter scenario is short and exact. A Medium-IL malware process calls &lt;code&gt;SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)&quot;some-attacker-controlled-string&quot;)&lt;/code&gt; against a window handle (&lt;code&gt;hwnd&lt;/code&gt;) belonging to a High-IL elevated PowerShell on the same desktop. On Windows XP, the message would arrive and the elevated PowerShell&apos;s edit control would update its text, with no authentication check anywhere in the path. On Vista and every subsequent Windows release, the call returns zero. &lt;code&gt;GetLastError&lt;/code&gt; returns &lt;code&gt;ERROR_ACCESS_DENIED&lt;/code&gt;. The message is silently dropped by &lt;code&gt;win32k.sys&lt;/code&gt; before the receiving process&apos;s window procedure ever sees it. The window manager noticed that the sender&apos;s IL was lower than the receiver&apos;s IL and dropped the message [@uipi-wiki][@russinovich-blog-2007].&lt;/p&gt;
&lt;p&gt;The &quot;silently dropped&quot; part matters operationally. Legacy applications written before Vista did not check the return value of &lt;code&gt;SendMessage&lt;/code&gt;. When Vista shipped UIPI, those applications kept &quot;working&quot; in the sense that they did not crash. They just stopped being effective at any cross-IL interaction they may have previously relied on. This is the same compatibility shape Microsoft used everywhere in Vista: the new bound was real, but the API surface returned plausible failure codes rather than raising new errors that broke legacy callers.&lt;/p&gt;
&lt;h3&gt;What UIPI blocks, precisely&lt;/h3&gt;
&lt;p&gt;UIPI does not block every window message. It blocks a specific dangerous subset, and a complete reading of the article requires reading the list slowly.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;UIPI behaviour from lower IL to higher IL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SendMessage&lt;/code&gt; / &lt;code&gt;PostMessage&lt;/code&gt; for &lt;code&gt;WM_SETTEXT&lt;/code&gt;, edit-control mutators, combo-box mutators&lt;/td&gt;
&lt;td&gt;Blocked; returns 0 / &lt;code&gt;ERROR_ACCESS_DENIED&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Posted messages above &lt;code&gt;WM_USER&lt;/code&gt; (0x0400)&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WM_TIMER&lt;/code&gt; with a callback function pointer&lt;/td&gt;
&lt;td&gt;Blocked (the original Paget vector)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetWindowsHookEx&lt;/code&gt; against a higher-IL thread or process&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AttachThreadInput&lt;/code&gt; to a higher-IL thread&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SendInput&lt;/code&gt; targeting a higher-IL window&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Journal record / journal playback hooks&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mouse and most keyboard input from the OS itself&lt;/td&gt;
&lt;td&gt;Allowed (the user is the principal)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Most paint messages (&lt;code&gt;WM_PAINT&lt;/code&gt;, &lt;code&gt;WM_ERASEBKGND&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read-only window queries (&lt;code&gt;GetWindowText&lt;/code&gt;, &lt;code&gt;EnumWindows&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Allowed (return empty / minimal data rather than failing)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&quot;UIPI blocks all &lt;code&gt;WM_*&lt;/code&gt; messages&quot; is one of the most common misconceptions in Windows-security literature. It does not. It blocks the &lt;em&gt;dangerous subset&lt;/em&gt;: the messages and hooks that allow a sender to alter the receiving process&apos;s state or execute code in it [@russinovich-blog-2007][@uipi-wiki].&lt;/p&gt;

sequenceDiagram
    participant M as Medium-IL malware
    participant W as win32k.sys
    participant P as High-IL PowerShell
    M-&amp;gt;&amp;gt;W: SendMessage(hwnd, WM_SETTEXT, ...)
    W-&amp;gt;&amp;gt;W: Compare sender IL (Medium) to target window IL (High)
    Note over W: Sender IL lower than target IL, WM_SETTEXT in dangerous subset
    W--&amp;gt;&amp;gt;M: Returns 0, ERROR_ACCESS_DENIED
    Note over P: Window procedure never invoked, text unchanged
&lt;p&gt;The Microsoft Learn page that opens &quot;Modifies the User Interface Privilege Isolation (UIPI) message filter for a specified window&quot; is the &lt;code&gt;ChangeWindowMessageFilterEx&lt;/code&gt; function reference [@changewindowfilter]. It is the closest thing to a first-party UIPI conceptual page on Microsoft Learn. There is no standalone Microsoft Learn page titled &quot;User Interface Privilege Isolation&quot; at the &lt;code&gt;winmsg&lt;/code&gt; path: the Wikipedia UIPI article is the standard secondary anchor for the concept itself [@uipi-wiki], and Russinovich&apos;s February 2007 TechNet Blogs post introduces UIPI by name in the original architectural canon [@russinovich-blog-2007].&lt;/p&gt;
&lt;h3&gt;The opt-in exemption: &lt;code&gt;ChangeWindowMessageFilterEx&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The UIPI block is per-window and per-message. When a higher-IL window has a legitimate reason to accept a specific message from lower-IL senders (for example, a developer tool that needs to receive &lt;code&gt;WM_COPYDATA&lt;/code&gt; from a Medium-IL client), the higher-IL process can call &lt;code&gt;ChangeWindowMessageFilterEx&lt;/code&gt; to add the specific message to its window&apos;s allow-list [@changewindowfilter].&lt;/p&gt;
&lt;p&gt;The action constants are documented as &lt;code&gt;MSGFLT_ALLOW&lt;/code&gt; (add the message to the allow-list), &lt;code&gt;MSGFLT_RESET&lt;/code&gt; (remove explicit policy and inherit defaults), and &lt;code&gt;MSGFLT_DISALLOW&lt;/code&gt; (explicitly block the message even if defaults would allow it) [@changewindowfilter]. The function returns &lt;code&gt;BOOL&lt;/code&gt;; failure is non-fatal and the caller is expected to validate the result.&lt;/p&gt;
&lt;p&gt;A High-IL window that opts &lt;code&gt;WM_SETTEXT&lt;/code&gt; into the cross-IL allowed list inherits the responsibility to validate the contents of every message it then receives. The filter is the gate. It is not the validator. A higher-IL process that takes attacker-controlled text and pastes it into a system shell has bypassed UIPI in the same way a service that takes attacker-controlled input and passes it to &lt;code&gt;system()&lt;/code&gt; has bypassed least privilege. The mechanism cannot make the higher-IL process safe; it can only make the higher-IL process &lt;em&gt;aware&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;The &lt;code&gt;uiAccess=true&lt;/code&gt; carve-out&lt;/h3&gt;
&lt;p&gt;The single largest residual exemption from UIPI is the &lt;code&gt;uiAccess=true&lt;/code&gt; manifest flag, designed to support accessibility software (screen readers, on-screen keyboards, remote-control tools) that needs to interact with windows above its own IL [@uia-security]. A process that asserts &lt;code&gt;uiAccess=true&lt;/code&gt; in its application manifest gets, at process creation, a token flag (&lt;code&gt;TokenUIAccess&lt;/code&gt;) that exempts the process from UIPI&apos;s cross-IL blocks for the &lt;em&gt;outbound&lt;/em&gt; direction. A Medium-IL UI-Access process can post &lt;code&gt;WM_SETTEXT&lt;/code&gt; to a High-IL elevated PowerShell window, because the Medium-IL process is acting on behalf of an accessibility client.&lt;/p&gt;
&lt;p&gt;The gating conditions for &lt;code&gt;uiAccess=true&lt;/code&gt; are tight, by design. Microsoft Learn enumerates three [@uia-security]. The manifest must assert &lt;code&gt;uiAccess=&quot;true&quot;&lt;/code&gt; in the &lt;code&gt;requestedExecutionLevel&lt;/code&gt; element. The binary must carry a valid Authenticode signature. The binary must reside in a directory writable only by administrators, which in practice means &lt;code&gt;%SystemRoot%\System32&lt;/code&gt;, &lt;code&gt;%ProgramFiles%&lt;/code&gt;, or a similarly admin-only path. The three conditions together are intended to bound &lt;code&gt;uiAccess&lt;/code&gt; to vetted, signed, install-time-protected binaries.&lt;/p&gt;
&lt;p&gt;We will return to the &lt;code&gt;uiAccess&lt;/code&gt; carve-out in §9, because Forshaw&apos;s February 2026 Project Zero retrospective documents that five of nine pre-GA Administrator Protection bypasses operated entirely through this surface [@forshaw-adminprot-feb26]. The Vista-era exemption inherited unchanged into 2026 is, nearly twenty years later, the single largest residual cross-IL attack class in the Windows integrity stack.&lt;/p&gt;
&lt;h3&gt;What UIPI killed, precisely&lt;/h3&gt;
&lt;p&gt;UIPI killed the &lt;em&gt;cross-IL&lt;/em&gt; variant of the Brett-Moore-2002 shatter-attack class. Same-IL shatter attacks (two Medium-IL processes on the user&apos;s &lt;code&gt;Default&lt;/code&gt; desktop, both belonging to the same user, both running with the user&apos;s authority) are not blocked by UIPI, because UIPI is an IL-based filter. Two same-IL processes can still send each other arbitrary window messages, and this is exactly why every modern browser sandbox layers &lt;a href=&quot;https://paragmali.com/blog/appcontainer-and-lowbox-tokens-windowss-capability-sandbox/&quot; rel=&quot;noopener&quot;&gt;AppContainer&lt;/a&gt; and a restricted-token sandbox on top of MIC [@appcontainer-isolation]: the integrity primitives are correct, but they are integrity primitives, not identity primitives, and same-IL same-desktop processes need a different isolation mechanism.&lt;/p&gt;
&lt;p&gt;Together, MIC and UIPI provide an integrity bound on &lt;em&gt;access&lt;/em&gt; (objects) and on &lt;em&gt;user-interface manipulation&lt;/em&gt; (windows). Both are mandatory, default-on, and constant-overhead. They are the load-bearing primitive pair of the entire integrity-level stack. But how does the OS decide which processes get which IL? When you log in as Administrator and open a PowerShell, why is that PowerShell Medium and not High?&lt;/p&gt;
&lt;h2&gt;5. The Split-Token Breakthrough&lt;/h2&gt;
&lt;p&gt;The integrity-level pair (MIC plus UIPI) is the access-control primitive. The split-token model is the &lt;em&gt;policy decision&lt;/em&gt; that wires those primitives into the administrator&apos;s everyday experience. Without the split-token policy, an administrator&apos;s interactive shell would hold a High-IL token at logon and UAC would never need to exist. With it, every administrator on Windows 11 today has &lt;em&gt;two&lt;/em&gt; tokens. One is in use. The other is dormant. The yellow dialog is the negotiation that toggles between them.&lt;/p&gt;

The Vista policy in which an Administrators-group user logging on receives a Medium-IL filtered token plus a dormant High-IL linked token. The filtered token becomes the primary token of the interactive shell; the linked token is used only after consent or auto-elevation, and only when the Application Information service brokers a process creation with it.
&lt;h3&gt;What the LSA does at logon&lt;/h3&gt;
&lt;p&gt;When &lt;code&gt;EnableLUA=1&lt;/code&gt; in &lt;code&gt;HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System&lt;/code&gt; (the default since Vista), and an Administrators-group user logs on, the Local Security Authority subsystem (&lt;code&gt;LSASS&lt;/code&gt;) constructs three things during logon processing [@uac-how-it-works].&lt;/p&gt;
&lt;p&gt;The first is the &lt;em&gt;full token&lt;/em&gt;: an access token that contains all of the user&apos;s administrator group SIDs (enabled, not deny-only), all of the privileges the user is authorised to hold, and an integrity level of High. This is the token that, on XP, would have been the user&apos;s primary token from logon onward.&lt;/p&gt;
&lt;p&gt;The second is the &lt;em&gt;filtered token&lt;/em&gt;: a copy of the full token with all administrator-equivalent group SIDs marked &lt;code&gt;SE_GROUP_USE_FOR_DENY_ONLY&lt;/code&gt;, all privileges except a small user-mode subset removed, and the integrity level reduced to Medium. The administrator group SIDs are not removed; they are marked deny-only so they still match deny ACEs but do not satisfy allow ACEs. The privileges are not zeroed; the powerful ones (&lt;code&gt;SeDebug&lt;/code&gt;, &lt;code&gt;SeTakeOwnership&lt;/code&gt;, &lt;code&gt;SeLoadDriver&lt;/code&gt;, &lt;code&gt;SeAssignPrimaryToken&lt;/code&gt;, and others) are dropped from the filtered token entirely.&lt;/p&gt;
&lt;p&gt;The third is the &lt;em&gt;linked relationship&lt;/em&gt;: the LSA stamps each token with a reference to the other via the &lt;code&gt;TokenLinkedToken&lt;/code&gt; information class, so that a holder of the filtered token can, with the right privileges, retrieve a handle to the dormant full token by calling &lt;code&gt;NtQueryInformationToken(filteredToken, TokenLinkedToken, &amp;amp;linkedToken, ...)&lt;/code&gt; [@uac-how-it-works].&lt;/p&gt;
&lt;p&gt;The filtered token then becomes the primary access token of the user&apos;s interactive shell (&lt;code&gt;explorer.exe&lt;/code&gt;). Every process the user launches by clicking, by &lt;code&gt;Win+R&lt;/code&gt;, by typing in a console, inherits the filtered token as its primary token. The dormant full token sits in the LSA, addressable through &lt;code&gt;TokenLinkedToken&lt;/code&gt;. The verbatim Microsoft Learn statement is exact: &quot;When an administrator logs on, two separate access tokens are created for the user: a standard user access token and an administrator access token&quot; [@uac-how-it-works].&lt;/p&gt;

flowchart TD
    A[&quot;User authenticates&lt;br /&gt;as a member of Administrators&quot;] --&amp;gt; B[&quot;LSA logon processing&lt;br /&gt;(LsaLogonUser)&quot;]
    B --&amp;gt; C[&quot;Full token&lt;br /&gt;(admin SIDs enabled, all privileges, IL = High)&quot;]
    B --&amp;gt; D[&quot;Filtered token&lt;br /&gt;(admin SIDs deny-only, privileges stripped, IL = Medium)&quot;]
    C -.-&amp;gt;|&quot;linked via TokenLinkedToken&quot;| D
    D --&amp;gt; E[&quot;Primary token of explorer.exe&lt;br /&gt;and all interactive child processes&quot;]
    C --&amp;gt; F[&quot;Dormant in LSA, used only by Appinfo after consent or auto-elevation&quot;]
&lt;h3&gt;The TokenElevationType API surface&lt;/h3&gt;
&lt;p&gt;Three values of the &lt;code&gt;TOKEN_ELEVATION_TYPE&lt;/code&gt; enumeration describe what state the current process is in [@token-elevation-type].&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TokenElevationTypeDefault&lt;/code&gt; (1) -- no split-token policy is in effect for this token. This is the legacy case (&lt;code&gt;EnableLUA=0&lt;/code&gt;) or the case where the user is not a member of any administrators-equivalent group at all. The single token &lt;em&gt;is&lt;/em&gt; the only token, and no linked token exists. On a default consumer or enterprise Windows 11 install with an admin account, this value is rare.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TokenElevationTypeFull&lt;/code&gt; (2) -- the current process is running with the unfiltered admin token. Admin Approval Mode is in force; this process either was launched via elevation (and holds the linked full token) or was created in a context where the filtered/full distinction is collapsed (some service contexts).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TokenElevationTypeLimited&lt;/code&gt; (3) -- the current process is running with the filtered token, Admin Approval Mode is in force, and a dormant full token exists. This is the typical state of an interactive admin shell on Windows 11.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;TokenElevationTypeDefault&lt;/code&gt; (value 1) is the legacy or domain-controller case in which &lt;code&gt;EnableLUA=0&lt;/code&gt; and the user has no filtered token at all. On a default consumer Windows install, administrators are always &lt;code&gt;TokenElevationTypeLimited&lt;/code&gt; or &lt;code&gt;TokenElevationTypeFull&lt;/code&gt;, never &lt;code&gt;Default&lt;/code&gt;. The &lt;code&gt;Default&lt;/code&gt; case is what reverting &lt;code&gt;EnableLUA&lt;/code&gt; to 0 produces, and it is the configuration the FAQ in §11 warns against.&lt;/p&gt;
&lt;h3&gt;What the consent prompt actually does&lt;/h3&gt;
&lt;p&gt;The behaviour of the consent prompt now resolves to a single operation, and the operation is not &quot;elevate.&quot; When the user invokes &quot;Run as administrator&quot; on a binary, the shell calls &lt;code&gt;ShellExecuteEx&lt;/code&gt; with the &lt;code&gt;&quot;runas&quot;&lt;/code&gt; verb [@shellexecuteexa]. The Application Information service (the topic of §6.2) receives the request via RPC. Appinfo, running as &lt;code&gt;LocalSystem&lt;/code&gt;, retrieves the linked full token of the calling user via &lt;code&gt;TokenLinkedToken&lt;/code&gt;. Appinfo shows the consent prompt on the Secure Desktop (§6.1). If the user clicks &quot;Yes,&quot; Appinfo creates a new process using the full token as the new process&apos;s primary token, by calling &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with the privileges Appinfo holds because it is &lt;code&gt;LocalSystem&lt;/code&gt; [@russinovich-tnm-2007].&lt;/p&gt;
&lt;p&gt;The bits that move are the kernel-level handle for the new process and the assignment of the linked token as that process&apos;s primary token. The bits the prompt itself moves are zero. The prompt is the consent surface; the token swap is the primitive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The consent prompt does not create authority. It uses authority that was already constructed at logon and held dormant in the linked token. The same primitive can move bits without the prompt -- that is exactly what auto-elevation does.&lt;/p&gt;
&lt;/blockquote&gt;

sequenceDiagram
    participant U as User
    participant E as explorer.exe (Medium IL)
    participant A as Appinfo (LocalSystem)
    participant C as consent.exe (Secure Desktop)
    participant P as New process (High IL)
    U-&amp;gt;&amp;gt;E: Right-click, Run as administrator
    E-&amp;gt;&amp;gt;A: RPC: request elevation of target.exe
    A-&amp;gt;&amp;gt;A: Look up TokenLinkedToken of caller&apos;s filtered token
    A-&amp;gt;&amp;gt;C: Show consent prompt
    U-&amp;gt;&amp;gt;C: Click Yes
    C--&amp;gt;&amp;gt;A: Consent granted
    A-&amp;gt;&amp;gt;P: CreateProcessAsUser(linked full token, target.exe)
    Note over P: New process runs at High IL, full admin SIDs enabled, full privileges

Split-token administrator in UAC just means MS get to annoy you with prompts unnecessarily but serves very little, if not zero security benefit. -- James Forshaw, *Reading Your Way Around UAC (Part 1)*, Tyranid&apos;s Lair, May 2017
&lt;p&gt;Forshaw&apos;s 2017 critique is the load-bearing observation that frames the rest of the article [@forshaw-reading-uac]. Even with the elegant split-token policy in place, there is a structural problem the design did not solve. The filtered token and the linked token share the &lt;em&gt;same user SID&lt;/em&gt;. They write to the &lt;em&gt;same &lt;code&gt;%USERPROFILE%&lt;/code&gt;&lt;/em&gt;. They consult the &lt;em&gt;same &lt;code&gt;HKCU&lt;/code&gt; registry hive&lt;/em&gt;. They live in the &lt;em&gt;same logon-session LUID&lt;/em&gt;. From an integrity-isolation point of view, the two tokens are bounded against each other; from an identity-isolation point of view, they are the same user.&lt;/p&gt;
&lt;p&gt;That shared-identity property is what made the bypass-research industry possible, and what Administrator Protection finally attacks in 2024 (§9). We will return to it. First, let us tour the rest of the stack the consent prompt sits on. If Appinfo is the SYSTEM-trusted broker that does the token swap, where does it live? And what stops malware from spoofing the consent prompt itself?&lt;/p&gt;
&lt;h2&gt;6. The Full UAC Stack on a Modern Windows Box&lt;/h2&gt;
&lt;p&gt;The reader now knows the four load-bearing primitives. This section walks every supporting piece that surrounds them on a 2026 Windows install, in the order needed to follow an elevation event end-to-end. There are four pieces: the Secure Desktop the prompt renders on, the Appinfo service that brokers the token swap, the two distinct activation surfaces that trigger an elevation, and the auto-elevation allowlist that shaped fifteen years of bypass research.&lt;/p&gt;
&lt;h3&gt;6.1 The Secure Desktop, not Session 0&lt;/h3&gt;

A separate desktop object at the Object-Manager path `\Sessions\\Windows\WindowStations\WinSta0\Winlogon`, within the user&apos;s interactive session, on which `consent.exe` runs the UAC prompt. Isolated from the user&apos;s `Default` desktop by Object-Manager DACL and the `SwitchDesktop` API.
&lt;p&gt;When you click &quot;Run as administrator&quot; and the screen dims and the prompt appears, the screen dims because you have just been switched to a different &lt;em&gt;desktop&lt;/em&gt;. Not a different session, not Session 0, not a different window station. A different desktop within the same window station, accessed through the &lt;code&gt;SwitchDesktop&lt;/code&gt; API [@russinovich-tnm-2007].&lt;/p&gt;
&lt;p&gt;The Object-Manager path is exact. Inside the user&apos;s interactive session (Session 1 if the user is the first interactive logon, higher numbers for subsequent users), there is a window station named &lt;code&gt;WinSta0&lt;/code&gt;. Inside &lt;code&gt;WinSta0&lt;/code&gt; there are several desktop objects: &lt;code&gt;Default&lt;/code&gt; (where the user&apos;s normal interactive processes paint), &lt;code&gt;Winlogon&lt;/code&gt; (where &lt;code&gt;consent.exe&lt;/code&gt; runs the prompt), and &lt;code&gt;Disconnect&lt;/code&gt; and &lt;code&gt;Screen-saver&lt;/code&gt; for related uses. The full path of the Secure Desktop is &lt;code&gt;\Sessions\&amp;lt;n&amp;gt;\Windows\WindowStations\WinSta0\Winlogon&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Winlogon&lt;/code&gt; desktop is protected by an Object-Manager DACL that the user&apos;s normal interactive processes (running on &lt;code&gt;Default&lt;/code&gt;) cannot open for &lt;code&gt;DESKTOP_CREATEWINDOW&lt;/code&gt; or &lt;code&gt;DESKTOP_HOOKCONTROL&lt;/code&gt;. A Medium-IL malware process on &lt;code&gt;Default&lt;/code&gt; cannot draw into the &lt;code&gt;Winlogon&lt;/code&gt; desktop, cannot enumerate its windows, and cannot send messages to them. The OS performs the desktop switch in &lt;code&gt;win32k.sys&lt;/code&gt; and renders &lt;code&gt;consent.exe&lt;/code&gt;&apos;s window on the new desktop with a snapshot of the previous desktop as a dimmed background, so the user has visual continuity but &lt;code&gt;consent.exe&lt;/code&gt; is the only process accepting input [@russinovich-tnm-2007].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Secure Desktop is &lt;em&gt;not&lt;/em&gt; in Session 0. Session 0 Isolation is a different Vista feature that moved all Windows services off the interactive desktop into a non-interactive session (Session 0), separately from the per-user interactive sessions (Sessions 1, 2, ...). The Secure Desktop is &lt;em&gt;within&lt;/em&gt; the user&apos;s interactive session: a different desktop object inside the same window station, not a different session. The two features ship together in Vista and are constantly confused, because they are both 2006-era hardening primitives. They are architecturally independent: Session 0 Isolation prevents services from drawing on the user&apos;s desktop, and the Secure Desktop prevents the user&apos;s processes from drawing on the prompt&apos;s desktop. Conflating them mis-describes how either one works. The corpus&apos;s &lt;a href=&quot;https://paragmali.com/blog/the-object-manager-namespace/&quot; rel=&quot;noopener&quot;&gt;Object Manager Namespace&lt;/a&gt; article (#46) covers Session 0 Isolation directly; this article treats only the Secure Desktop.&lt;/p&gt;
&lt;/blockquote&gt;

A separate Vista feature, architecturally independent of the Secure Desktop, that moved all Windows services off the interactive desktop and into Session 0. The two features ship together in Vista and are constantly confused, but they live at different layers of the Object Manager hierarchy.

flowchart TD
    A[&quot;Session 1&lt;br /&gt;(interactive logon for user &apos;admin&apos;)&quot;] --&amp;gt; B[&quot;WinSta0&lt;br /&gt;interactive window station&quot;]
    A --&amp;gt; C[&quot;Service-0x0-3e7$&lt;br /&gt;non-interactive WinSta (services)&quot;]
    B --&amp;gt; D[&quot;Default desktop&lt;br /&gt;explorer.exe, browsers, console windows&lt;br /&gt;(Medium IL processes)&quot;]
    B --&amp;gt; E[&quot;Winlogon desktop&lt;br /&gt;consent.exe renders here&lt;br /&gt;(Secure Desktop)&quot;]
    B --&amp;gt; F[&quot;Disconnect / Screen-saver&lt;br /&gt;desktops&quot;]
    D -. &quot;blocked by Object-Manager DACL&lt;br /&gt;and SwitchDesktop&quot; .-&amp;gt; E
&lt;p&gt;The Secure Desktop addresses UI spoofing and input injection against the prompt itself. It does not address whether elevation can happen &lt;em&gt;without&lt;/em&gt; a Secure Desktop prompt; that is the territory of the auto-elevation allowlist (§6.4) and of the bypass-research class (§7).&lt;/p&gt;
&lt;h3&gt;6.2 The Application Information service (Appinfo)&lt;/h3&gt;

The SYSTEM-trusted Windows service (`appinfo.dll`, hosted in `svchost.exe`, runs under `LocalSystem`) that mediates the token swap between filtered and linked tokens at elevation time. Required service: &quot;Run as administrator&quot; fails without it. The modern process-creation entry point is `RAiLaunchAdminProcess`.
&lt;p&gt;Every UAC elevation on Windows goes through one service: Appinfo (display name &quot;Application Information&quot;). Its image is &lt;code&gt;C:\Windows\System32\appinfo.dll&lt;/code&gt;, loaded into a shared &lt;code&gt;svchost.exe&lt;/code&gt; host process, running as &lt;code&gt;LocalSystem&lt;/code&gt; [@russinovich-tnm-2007].&lt;/p&gt;
&lt;p&gt;The job is single-purpose: be the SYSTEM-trusted broker that performs the token swap. A Medium-IL caller cannot, by definition, create a process holding a token the caller does not possess. Creating a process under a token with privileges the caller lacks requires two privileges Medium-IL filtered admin tokens do not hold: &lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt; and &lt;code&gt;SeIncreaseQuotaPrivilege&lt;/code&gt;. &lt;code&gt;LocalSystem&lt;/code&gt; has both [@russinovich-tnm-2007]. The broker therefore has to run as &lt;code&gt;LocalSystem&lt;/code&gt;, and that is what Appinfo is for.&lt;/p&gt;
&lt;p&gt;The modern entry point on &lt;a href=&quot;https://paragmali.com/blog/every-uac-prompt-is-an-alpc-handshake-a-field-guide-to-windo/&quot; rel=&quot;noopener&quot;&gt;Appinfo&apos;s RPC interface&lt;/a&gt; is &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt;, documented verbatim in Forshaw&apos;s February 2026 Project Zero post on Administrator Protection [@forshaw-adminprot-feb26]. The Medium-IL caller invokes &lt;code&gt;ShellExecuteEx&lt;/code&gt; with &lt;code&gt;&quot;runas&quot;&lt;/code&gt;; the shell marshalls the request across to Appinfo; Appinfo retrieves the caller&apos;s &lt;code&gt;TokenLinkedToken&lt;/code&gt;; if a prompt is needed, Appinfo shows &lt;code&gt;consent.exe&lt;/code&gt; on the Secure Desktop; if the user clicks &quot;Yes,&quot; Appinfo calls &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; to create the new process under the linked full token.&lt;/p&gt;
&lt;p&gt;Disable Appinfo and &quot;Run as administrator&quot; returns an error. It is the single point of trust in the elevation pipeline, which is exactly why the bypass-research industry pays attention to it: anything that can trick Appinfo into auto-elevating an attacker-influenced binary, without the consent prompt, becomes a fileless UAC bypass (§7.1).&lt;/p&gt;
&lt;h3&gt;6.3 Two activation surfaces&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When you say &quot;elevate a thing,&quot; the operating system understands &lt;em&gt;two&lt;/em&gt; distinct primitives, not one. &lt;code&gt;ShellExecuteEx &quot;runas&quot;&lt;/code&gt; is whole-process elevation: the OS launches a new process and runs the entire process at High IL. The COM Elevation Moniker is per-object elevation: the OS spins up an isolated &lt;code&gt;dllhost.exe&lt;/code&gt; that exposes exactly one COM CLSID&apos;s methods at High IL while the caller stays at Medium. The bypass-research literature attacks these two surfaces in very different ways. Conflating them mis-describes both the attack surface and the fix surface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first activation surface is &lt;code&gt;ShellExecuteEx&lt;/code&gt; with the &lt;code&gt;&quot;runas&quot;&lt;/code&gt; verb. The OS launches &lt;code&gt;consent.exe&lt;/code&gt;, asks the user, and if approved, Appinfo creates a brand-new process under the caller&apos;s linked full token. The new process is High-IL for its entire lifetime, with the entire administrator privilege set and all the admin group SIDs enabled. The Windows Explorer &quot;Run as administrator&quot; context menu uses this verb. So does the &lt;code&gt;runas /trustlevel:&lt;/code&gt; command. So does any program that calls &lt;code&gt;ShellExecuteEx&lt;/code&gt; and sets the &lt;code&gt;lpVerb&lt;/code&gt; member of &lt;code&gt;SHELLEXECUTEINFO&lt;/code&gt; to the string &lt;code&gt;&quot;runas&quot;&lt;/code&gt; [@shellexecuteexa].&lt;/p&gt;

A COM activation surface (`Elevation:Administrator!new:{CLSID}`) that asks the OS to instantiate a single COM out-of-process server in a new elevated `dllhost.exe`, exposing only that one CLSID&apos;s methods at High IL. Per-object elevation, distinct from `ShellExecuteEx &quot;runas&quot;` whole-process elevation.
&lt;p&gt;The second activation surface is the COM Elevation Moniker. A Medium-IL caller invokes &lt;code&gt;CoGetObject&lt;/code&gt; (or &lt;code&gt;CoCreateInstance&lt;/code&gt; via a moniker) with the display name &lt;code&gt;&quot;Elevation:Administrator!new:{CLSID}&quot;&lt;/code&gt; (or &lt;code&gt;&quot;Elevation:Highest!new:{CLSID}&quot;&lt;/code&gt;). This asks the OS to instantiate a &lt;em&gt;single COM out-of-process server&lt;/em&gt; in a new elevated &lt;code&gt;dllhost.exe&lt;/code&gt; host process, exposing only that one CLSID&apos;s methods at High IL. The caller stays at Medium. Only the COM object&apos;s host process is elevated, and only for the lifetime of the object [@com-elevation-moniker].&lt;/p&gt;
&lt;p&gt;The semantics are deliberately narrow. The COM Elevation Moniker requires the target CLSID to opt in via two registry values under &lt;code&gt;HKCR\CLSID\{CLSID}&lt;/code&gt;: &lt;code&gt;Elevation\Enabled = 1&lt;/code&gt; and an &lt;code&gt;LocalizedString&lt;/code&gt; value that names the elevation prompt&apos;s display string. Not every COM class is moniker-eligible; the registry enables elevation per CLSID.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ShellExecuteEx &quot;runas&quot;&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;COM Elevation Moniker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Granularity&lt;/td&gt;
&lt;td&gt;Whole process&lt;/td&gt;
&lt;td&gt;One COM object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifetime&lt;/td&gt;
&lt;td&gt;Entire process lifetime&lt;/td&gt;
&lt;td&gt;Object lifetime only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caller IL after&lt;/td&gt;
&lt;td&gt;Caller stays Medium; new process High&lt;/td&gt;
&lt;td&gt;Caller stays Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New process&lt;/td&gt;
&lt;td&gt;Target executable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dllhost.exe&lt;/code&gt; host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authority surface&lt;/td&gt;
&lt;td&gt;All admin SIDs and privileges, broad&lt;/td&gt;
&lt;td&gt;Methods of one CLSID, narrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use&lt;/td&gt;
&lt;td&gt;&quot;Run as administrator&quot; context menu, MSI installers&lt;/td&gt;
&lt;td&gt;Programmatic file copy, Wmi management, registry edits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary canonical bypass class&lt;/td&gt;
&lt;td&gt;DLL-search-order against the new process&lt;/td&gt;
&lt;td&gt;Auto-elevated COM behaviour abuse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The distinction matters because most of the canonical UAC bypasses do not touch &lt;code&gt;ShellExecuteEx &quot;runas&quot;&lt;/code&gt; at all. Leo Davidson&apos;s December 2009 essay attacked the COM Elevation Moniker by invoking the &lt;code&gt;IFileOperation&lt;/code&gt; COM class (auto-elevation-eligible, registered under the right CLSID) from a Medium-IL caller, and using its &lt;code&gt;CopyItem&lt;/code&gt; method to overwrite a system file at High IL [@davidson-2009][@ifileoperation]. The &lt;code&gt;ICMLuaUtil&lt;/code&gt; and &lt;code&gt;IColorDataProxy&lt;/code&gt; interfaces follow the same shape: a Medium-IL caller instantiates an auto-elevatable COM class via the moniker, and then calls a method on the High-IL object that performs an attacker-chosen action [@uacme].&lt;/p&gt;
&lt;p&gt;Both surfaces share the same backend: Appinfo brokers the token swap, and &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; (or its COM equivalent) creates the new process. The difference is whether the elevated child is a whole new process (broad authority for a long time) or a COM object&apos;s host (narrow authority for a single activation). The bypass-research literature exploits the second class far more than the first, because the second class exposes a narrower, more abusable &lt;em&gt;behavioural&lt;/em&gt; surface: the CLSID&apos;s methods.&lt;/p&gt;
&lt;h3&gt;6.4 The auto-elevation allowlist&lt;/h3&gt;
&lt;p&gt;Vista&apos;s prompt fatigue was a usability disaster. Beta reviewers described users clicking through three or four prompts per common task. Windows 7, shipped in October 2009, tried to cut the noise by quietly elevating a curated set of Microsoft-signed binaries with no prompt at all. That single decision shaped the next fifteen years of UAC bypass research, because every &quot;bypass&quot; you have ever read about lives inside the gap between &lt;em&gt;which binary&lt;/em&gt; gets elevated and &lt;em&gt;what the binary does after elevation&lt;/em&gt;.&lt;/p&gt;

The set of Microsoft-signed binaries in trusted system directories on Appinfo&apos;s internal allowlist that elevate without a consent prompt. Four gating conditions: `autoElevate=true` manifest element, Microsoft Authenticode signature, trusted directory path, and an internal Appinfo allowlist entry enforced inside `appinfo.dll`.
&lt;p&gt;The manifest element is a single string. Inside the application&apos;s side-by-side manifest, under the &lt;code&gt;&amp;lt;trustInfo&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;security&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;requestedPrivileges&amp;gt;&lt;/code&gt; element, the binary asserts &lt;code&gt;&amp;lt;autoElevate&amp;gt;true&amp;lt;/autoElevate&amp;gt;&lt;/code&gt; [@app-manifests]. That assertion was discovered and publicly documented by independent UK developer Leo Davidson in December 2009 [@davidson-2009].&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;autoElevate=true&lt;/code&gt; manifest assertion is &lt;em&gt;necessary but not sufficient&lt;/em&gt;. Appinfo enforces three additional gating conditions before honouring an auto-elevation request [@davidson-2009].&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The binary must carry a valid Authenticode signature chained to a Microsoft root certificate.&lt;/li&gt;
&lt;li&gt;The binary&apos;s path must reside under a trusted system directory, in practice &lt;code&gt;%SystemRoot%\System32&lt;/code&gt; or &lt;code&gt;%SystemRoot%\SysWOW64&lt;/code&gt; (or the localized variants for non-English locales).&lt;/li&gt;
&lt;li&gt;The binary&apos;s name must appear on an internal allowlist enforced in code in &lt;code&gt;appinfo.dll&lt;/code&gt;, not in any user-visible policy file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The fourth gate (the internal allowlist) is the one that surprises practitioners. A binary can be Microsoft-signed, located in &lt;code&gt;System32&lt;/code&gt;, and carry &lt;code&gt;autoElevate=true&lt;/code&gt; in its manifest, and Appinfo can still refuse to auto-elevate it, because the binary&apos;s name is not on the hard-coded allowlist inside &lt;code&gt;appinfo.dll&lt;/code&gt;. There is no public Microsoft-published file enumerating the allowlist; the only way to enumerate it operationally is to scan the manifests of every binary in &lt;code&gt;System32&lt;/code&gt; and cross-check which ones actually auto-elevate.&lt;/p&gt;

The community-standard way to enumerate the manifest-asserting subset of the allowlist is to run Sysinternals `sigcheck -m C:\Windows\System32\*.exe` and pipe the output to `findstr /i autoelevate`. That gives you every binary in `System32` whose embedded manifest asserts `autoElevate=true`. On a Windows 11 25H2 install, the list runs to thirty to forty binaries: `mmc.exe`, `eventvwr.exe`, `fodhelper.exe`, `ComputerDefaults.exe`, `sdclt.exe`, `slui.exe`, and others.&lt;p&gt;The list of &lt;em&gt;names&lt;/em&gt; in the manifest is not the same as the set Appinfo actually auto-elevates. UACMe&apos;s research README enumerates the operational subset: which manifest-asserting binaries Appinfo actually honours, by Windows build, with the technique class and the catalogued bypass method [@uacme]. The canonical observation is that of the manifest-asserting list, only the operationally-allowlisted subset is exploitable, and the operational subset changes silently across feature updates without any security bulletin because none of the resulting bypasses are classified as security vulnerabilities.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;{`
// Pseudocode of Appinfo&apos;s auto-elevation decision (Win7+).
// All four gates must pass for auto-elevation without a consent prompt.&lt;/p&gt;
&lt;p&gt;function shouldAutoElevate(binaryPath) {
  // Gate 1: the application manifest must assert autoElevate=true.
  const manifest = readEmbeddedManifest(binaryPath);
  if (manifest?.requestedPrivileges?.autoElevate !== true) return false;&lt;/p&gt;
&lt;p&gt;  // Gate 2: the binary must carry a valid Microsoft Authenticode signature.
  const sig = verifyAuthenticodeSignature(binaryPath);
  if (sig.status !== &apos;valid&apos; || sig.rootCA !== &apos;Microsoft&apos;) return false;&lt;/p&gt;
&lt;p&gt;  // Gate 3: the binary must reside under a trusted system directory.
  const trustedDirs = [&apos;C:\\Windows\\System32\\&apos;, &apos;C:\\Windows\\SysWOW64\\&apos;];
  if (!trustedDirs.some(d =&amp;gt; binaryPath.toLowerCase().startsWith(d.toLowerCase()))) return false;&lt;/p&gt;
&lt;p&gt;  // Gate 4: the binary name must appear on Appinfo&apos;s internal allowlist.
  // This is the one enforced in code in appinfo.dll, not exposed as policy.
  if (!APPINFO_INTERNAL_ALLOWLIST.includes(baseName(binaryPath).toLowerCase())) return false;&lt;/p&gt;
&lt;p&gt;  return true;
}
`}&lt;/p&gt;
&lt;p&gt;Four gating conditions. Three of them constrain &lt;em&gt;which binary&lt;/em&gt; gets elevated. None of them constrain &lt;em&gt;what the binary does after elevation&lt;/em&gt;. The fourth gap, the behavioural one, is the space the bypass-research industry has occupied for fifteen years. That is §7.&lt;/p&gt;
&lt;h2&gt;7. Twenty Years of Bypass Research as Empirical Test&lt;/h2&gt;
&lt;p&gt;In February 2007, eleven days after Vista&apos;s consumer launch, Mark Russinovich published a TechNet Blogs post titled &lt;em&gt;PsExec, User Account Control and Security Boundaries&lt;/em&gt;. The post walked through a quirk of how PsExec&apos;s &lt;code&gt;-l&lt;/code&gt; switch interacted with restricted tokens on Windows XP, used the walkthrough to introduce Vista&apos;s integrity-level model, and then dropped a single sentence the entire later debate would rest on [@russinovich-blog-2007].&lt;/p&gt;

Neither UAC elevations nor Protected Mode IE define new Windows security boundaries... potential avenues of attack, regardless of ease or scope, are not security bugs. -- Mark Russinovich, *PsExec, User Account Control and Security Boundaries*, TechNet Blogs, February 12, 2007
&lt;p&gt;That sentence, in the public record from week one, is the architectural reason every &quot;UAC bypass&quot; published from 2009 onward was classified by Microsoft as a non-vulnerability. The bypass-research literature is the empirical proof of the disclaimer, not a counterargument to it. Three durable bypass classes carry the empirical weight.&lt;/p&gt;
&lt;h3&gt;7.1 The &lt;code&gt;ms-settings&lt;/code&gt; / &lt;code&gt;DelegateExecute&lt;/code&gt; registry-hijack class&lt;/h3&gt;
&lt;p&gt;The first durable class is the registry-hijack bypass of auto-elevated binaries. Mechanism: an auto-elevated binary (&lt;code&gt;eventvwr.exe&lt;/code&gt;, &lt;code&gt;fodhelper.exe&lt;/code&gt;, &lt;code&gt;ComputerDefaults.exe&lt;/code&gt;, certain &lt;code&gt;sdclt.exe&lt;/code&gt; variants) executes a handler for a custom file extension or URL protocol on launch. The relevant handler mapping is in &lt;code&gt;HKCR&lt;/code&gt;, but Windows resolves &lt;code&gt;HKCR&lt;/code&gt; by first consulting &lt;code&gt;HKCU\Software\Classes&lt;/code&gt; and only falling back to &lt;code&gt;HKLM\Software\Classes&lt;/code&gt; if no per-user mapping exists. A Medium-IL user can write to &lt;code&gt;HKCU&lt;/code&gt; without elevation. So the user writes a &lt;code&gt;HKCU\Software\Classes\&amp;lt;scheme&amp;gt;\shell\open\command&lt;/code&gt; key whose default value is an arbitrary command line and whose &lt;code&gt;DelegateExecute&lt;/code&gt; value is the empty string. Then the user launches the auto-elevated binary. The binary loads, Appinfo elevates it to High IL, the binary resolves its registered handler, walks &lt;code&gt;HKCU\Software\Classes&lt;/code&gt; first, finds the attacker-controlled command line, and executes it. The attacker&apos;s command runs at High IL [@enigma-eventvwr][@mitre-t1548002].&lt;/p&gt;
&lt;p&gt;The first public canonical demonstration was Matt Nelson&apos;s August 15, 2016 post &lt;em&gt;Fileless UAC Bypass Using eventvwr.exe and Registry Hijacking&lt;/em&gt;, published on his blog under the handle &lt;code&gt;enigma0x3&lt;/code&gt;. Nelson hijacked the &lt;code&gt;mscfile&lt;/code&gt; association by writing &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt; with &lt;code&gt;cmd.exe&lt;/code&gt; as the default value, then launched &lt;code&gt;eventvwr.exe&lt;/code&gt;. The Event Viewer auto-elevates because of its manifest, resolves the &lt;code&gt;mscfile&lt;/code&gt; association to load &lt;code&gt;eventvwr.msc&lt;/code&gt;, walks the HKCU mapping first, finds &lt;code&gt;cmd.exe&lt;/code&gt; instead of &lt;code&gt;mmc.exe&lt;/code&gt;, and launches an attacker-controlled &lt;code&gt;cmd.exe&lt;/code&gt; at High IL [@enigma-eventvwr]. The technique required no file on disk except the registry value itself; this is what &lt;em&gt;fileless&lt;/em&gt; means in this context.&lt;/p&gt;
&lt;p&gt;Nelson productised the class through 2017. The March 14, 2017 &lt;em&gt;Bypassing UAC Using App Paths&lt;/em&gt; post generalised to &lt;code&gt;HKCU:\Software\Microsoft\Windows\CurrentVersion\App Paths\control.exe&lt;/code&gt;, exploited by &lt;code&gt;sdclt.exe&lt;/code&gt; [@enigma-apppaths]. The March 17, 2017 &lt;em&gt;&apos;Fileless&apos; UAC Bypass Using sdclt.exe&lt;/em&gt; post showed a fileless variant of the same attack using the &lt;code&gt;IsolatedCommand&lt;/code&gt; REG_SZ value on &lt;code&gt;HKCU:\Software\Classes\Folder\shell\open\command&lt;/code&gt;, with &lt;code&gt;sdclt.exe /KickOffElev&lt;/code&gt; as the trigger [@enigma-sdclt]. The same post referenced WikiLeaks&apos;s March 2017 Vault7 disclosures, in which the CIA&apos;s &quot;Vault7&quot; cache contained operationalised versions of the technique, confirming nation-state adoption of the bypass class [@enigma-sdclt].&lt;/p&gt;
&lt;p&gt;The fodhelper variant was published on May 12, 2017 under the title &lt;em&gt;Bypassing UAC Using fodhelper.exe&lt;/em&gt;. The canonical URL &lt;code&gt;enigma0x3.net/2017/05/12/bypassing-uac-using-fodhelper-exe/&lt;/code&gt; currently returns HTTP 404; the technique is anchored by UACMe Method 33 and MITRE ATT&amp;amp;CK T1548.002, both of which preserve the date, author, and registry path verbatim [@uacme][@mitre-t1548002].&lt;/p&gt;

sequenceDiagram
    participant U as User (Medium IL)
    participant R as HKCU registry
    participant F as fodhelper.exe (auto-elevated)
    participant A as Appinfo (LocalSystem)
    participant C as Attacker payload (High IL)
    U-&amp;gt;&amp;gt;R: Write HKCU Software Classes ms-settings shell open command with attacker cmd
    U-&amp;gt;&amp;gt;F: ShellExecute(&quot;fodhelper.exe&quot;)
    F-&amp;gt;&amp;gt;A: Request elevation (autoElevate gate passes)
    A-&amp;gt;&amp;gt;F: New process at High IL, no consent prompt
    F-&amp;gt;&amp;gt;R: Resolve ms-settings handler via HKCU first
    R--&amp;gt;&amp;gt;F: Returns attacker command
    F-&amp;gt;&amp;gt;C: Spawn attacker payload at High IL
&lt;p&gt;Microsoft&apos;s response to the eventvwr bypass was to ship a fix in the Windows 10 Creators Update (1703) that made &lt;code&gt;eventvwr.exe&lt;/code&gt; not consult the registered association the technique exploited. The fix was &lt;em&gt;technique-specific&lt;/em&gt;, not class-specific: the &lt;code&gt;ms-settings&lt;/code&gt; (fodhelper), App Paths (sdclt), and &lt;code&gt;IsolatedCommand&lt;/code&gt; (sdclt) variants remained exploitable through subsequent Windows 10 builds and into Windows 11 [@uacme][@mitre-t1548002]. None of these were patched as security vulnerabilities, because, per Russinovich 2007, UAC is not a security boundary [@russinovich-blog-2007].&lt;/p&gt;
&lt;h3&gt;7.2 The DLL-search-order class&lt;/h3&gt;
&lt;p&gt;The second durable class is the DLL-search-order attack against auto-elevated binaries. Mechanism: an auto-elevated binary calls &lt;code&gt;LoadLibrary&lt;/code&gt; on a DLL name resolved via the standard Windows search order: the application directory, the system directory, the current directory, the &lt;code&gt;PATH&lt;/code&gt; environment variable, and so on. If any path on that search order earlier than the legitimate one is writable by the Medium-IL caller, the caller can plant an attacker DLL at that path. When the auto-elevated binary loads the legitimate name, the search order returns the attacker&apos;s DLL first, and the DLL is loaded at the binary&apos;s elevated IL [@davidson-2009].&lt;/p&gt;
&lt;p&gt;The foundational canonical example is the December 2009 Leo Davidson essay &lt;em&gt;Windows 7 UAC whitelist: Code injection issue (and more)&lt;/em&gt;. Davidson demonstrated that &lt;code&gt;sysprep.exe&lt;/code&gt; (Microsoft-signed, in &lt;code&gt;System32&lt;/code&gt;, auto-elevation-allowlisted) loads &lt;code&gt;cryptbase.dll&lt;/code&gt; from its working directory before the system directory. By copying &lt;code&gt;sysprep.exe&lt;/code&gt; and a malicious &lt;code&gt;cryptbase.dll&lt;/code&gt; into a writable directory and launching &lt;code&gt;sysprep.exe&lt;/code&gt; from there, an attacker could load the malicious DLL into a High-IL process [@davidson-2009]. The same essay introduced the &lt;code&gt;IFileOperation&lt;/code&gt; COM-object technique that founded the second durable class (§7.3), making the December 2009 Davidson essay the single most-cited primary in the entire UAC bypass literature.&lt;/p&gt;
&lt;p&gt;Coverage in the trade press confirmed the class&apos;s significance immediately. In February 2009, &lt;em&gt;The Register&lt;/em&gt; reported on a related Long Zheng / Rafael Rivera disclosure that demonstrated piggybacking on auto-elevation via &lt;code&gt;rundll32.exe&lt;/code&gt; [@register-2009], establishing that the auto-elevation surface had been understood as exploitable from the moment Windows 7 shipped.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s mitigations against the DLL-search-order class have been incremental. &lt;code&gt;SafeDllSearchMode&lt;/code&gt; was made the default in Windows XP SP2 and reshuffled the search order so the application directory came before the current directory. The &lt;code&gt;LOAD_LIBRARY_SEARCH_*&lt;/code&gt; flags introduced in Windows Vista let applications opt into stricter search behaviour. Side-by-side manifest pinning and the &lt;code&gt;KnownDLLs&lt;/code&gt; mechanism shrink the surface further. All of these are application-author opt-ins; an auto-elevated binary that does not use them remains exploitable, and UACMe&apos;s catalogue of 81 methods includes numerous DLL-search-order entries across Windows versions [@uacme].&lt;/p&gt;
&lt;h3&gt;7.3 The auto-elevated COM-object behaviour-abuse class&lt;/h3&gt;
&lt;p&gt;The third durable class abuses the &lt;em&gt;behaviour&lt;/em&gt; of auto-elevation-eligible COM classes. Mechanism: a COM class registered as auto-elevation-eligible (the &lt;code&gt;IFileOperation&lt;/code&gt; / &lt;code&gt;ICMLuaUtil&lt;/code&gt; / &lt;code&gt;IColorDataProxy&lt;/code&gt; family historically, then the explicit &lt;code&gt;COMAutoApprovalList&lt;/code&gt; registry surface introduced in Windows 10 RS1 / build 14393 in August 2016) can be instantiated High-IL by a Medium-IL caller via the COM Elevation Moniker. Once instantiated, the High-IL object exposes methods (file copy, registry write, executable launch) that perform actions at High IL using whatever parameters the caller passes [@davidson-2009][@ifileoperation].&lt;/p&gt;
&lt;p&gt;Davidson&apos;s &lt;code&gt;IFileOperation&lt;/code&gt; proof of concept from December 2009 is the canonical example. A Medium-IL caller instantiates &lt;code&gt;IFileOperation&lt;/code&gt; via the COM Elevation Moniker. The resulting &lt;code&gt;dllhost.exe&lt;/code&gt; runs at High IL and exposes &lt;code&gt;IFileOperation::CopyItem&lt;/code&gt; and related methods. The caller invokes &lt;code&gt;CopyItem(&quot;evil.dll&quot;, &quot;C:\\Windows\\System32\\&quot;)&lt;/code&gt;. The High-IL &lt;code&gt;dllhost.exe&lt;/code&gt; performs the copy, because the High-IL token has write access to &lt;code&gt;%SystemRoot%\System32&lt;/code&gt;. The caller has now planted a DLL in &lt;code&gt;System32&lt;/code&gt; without ever holding a High-IL token itself [@davidson-2009][@ifileoperation].&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;COMAutoApprovalList&lt;/code&gt; era began in August 2016 with the Windows 10 Anniversary Update (RS1, build 14393). Microsoft added a dedicated registry surface at &lt;code&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList&lt;/code&gt; enumerating which CLSIDs &lt;code&gt;consent.exe&lt;/code&gt; would auto-elevate without a prompt. The change was unannounced: there is no Microsoft-published security bulletin naming the introduction. The community anchor is UACMe Method 49, whose fix-note carries the verbatim &quot;Side effect of consent.exe COMAutoApprovalList introduction&quot; against the &lt;code&gt;TpmInit.exe&lt;/code&gt; &lt;code&gt;ICreateNewLink&lt;/code&gt; technique, dated to RS1 / build 14393 [@uacme]. Method 27 captures the subsequent narrowing in RS3 / 16299, when Microsoft removed the &lt;code&gt;UninstallStringLauncher&lt;/code&gt; interface from the list.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;Canonical research&lt;/th&gt;
&lt;th&gt;Microsoft response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Registry-hijack (DelegateExecute)&lt;/td&gt;
&lt;td&gt;Auto-elevated binary resolves user-writable HKCU handler&lt;/td&gt;
&lt;td&gt;Nelson, eventvwr Aug 2016; sdclt and fodhelper 2017&lt;/td&gt;
&lt;td&gt;Patched individual binaries; class never classified as security vulnerability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DLL-search-order&lt;/td&gt;
&lt;td&gt;Auto-elevated binary loads attacker DLL via standard search path&lt;/td&gt;
&lt;td&gt;Davidson, December 2009 (sysprep + cryptbase)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SafeDllSearchMode&lt;/code&gt;, &lt;code&gt;LOAD_LIBRARY_SEARCH_*&lt;/code&gt;, KnownDLLs; shrunk but not eliminated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto-elevated COM behaviour&lt;/td&gt;
&lt;td&gt;Medium-IL caller invokes High-IL methods via moniker&lt;/td&gt;
&lt;td&gt;Davidson, December 2009 (IFileOperation); COMAutoApprovalList RS1 Aug 2016&lt;/td&gt;
&lt;td&gt;Curated allowlist; entries added or removed in feature updates without CVEs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;7.4 The doctrine and the aha&lt;/h3&gt;
&lt;p&gt;The two distinct 2007 sources need precise attribution, because the citation chain is the load-bearing artifact of the entire UAC-as-not-a-boundary argument.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The verbatim &quot;Neither UAC elevations nor Protected Mode IE define new Windows security boundaries&quot; sentence lives in the &lt;em&gt;PsExec, User Account Control and Security Boundaries&lt;/em&gt; TechNet Blogs post by Mark Russinovich, dated February 12, 2007 [@russinovich-blog-2007]. The architectural reference that most practitioners cite, &lt;em&gt;Security: Inside Windows Vista User Account Control&lt;/em&gt;, was published in the June 2007 issue of &lt;em&gt;TechNet Magazine&lt;/em&gt; and is the canonical reference for the integrity model, file/registry virtualisation, and the elevation pipeline [@russinovich-tnm-2007]. The architectural article does not contain the &quot;not a security boundary&quot; sentence; the February blog post does. Conflating the two is a citation error and gives the wrong impression of when Microsoft committed to the boundary classification.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Microsoft Security Response Center&apos;s &lt;a href=&quot;https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/&quot; rel=&quot;noopener&quot;&gt;published servicing criteria&lt;/a&gt; define a security boundary as one that &quot;provides a logical separation between the code and data of security domains with different levels of trust&quot; [@msrc-criteria]. The MSRC servicing-criteria page enumerates which Windows boundaries qualify under that definition. Through the Vista-through-Windows-10 era (2007-2024), UAC was explicitly classified as a security &lt;em&gt;feature&lt;/em&gt;, not a boundary, in the enumeration table on that page. The enumeration is rendered client-side (in JavaScript) and not visible through static fetches; the canonical confirmation for the classification is the Russinovich February 2007 sentence above, repeated and re-affirmed in Microsoft public statements throughout the period [@russinovich-blog-2007].&lt;/p&gt;
&lt;p&gt;Forshaw&apos;s January 2026 Project Zero post on Administrator Protection reads the doctrine clearly in retrospect: &quot;due to the way it was designed, it was quickly apparent it didn&apos;t represent a hard security boundary, and Microsoft downgraded it to a security feature&quot; [@forshaw-adminprot-jan26]. The &quot;downgraded&quot; framing is exact. UAC was &lt;em&gt;promoted&lt;/em&gt; to a security feature, &lt;em&gt;not&lt;/em&gt; a security boundary, from the moment it shipped. The reclassification in November 2024 was a &lt;em&gt;re-promotion&lt;/em&gt; with new architecture, not a fix to the old architecture.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The twenty-year UAC bypass-research record is empirical confirmation, not counterargument, of the architect&apos;s 2007 disclaimer. Microsoft did not fix the bypasses as security vulnerabilities because Russinovich had already said in writing that there was nothing to &quot;fix&quot;: the consent prompt was a convenience, not a boundary. The bypass record is the proof that the disclaimer was honest from week one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For the Windows administrator who has watched the bypass-research industry produce a new fileless bypass every six to twelve months, the reframing is the load-bearing aha of the entire article. The bypasses are not bugs Microsoft has failed to fix. They are the empirical map of the access-control versus information-flow gap that any access-control primitive runs into in a backward-compatible OS. The empirical record from 2009 forward (Davidson, Nelson, hfiref0x, Forshaw) is the cumulative confirmation that the disclaimer was honest.&lt;/p&gt;
&lt;p&gt;If MIC, UIPI, and the split-token model are sound primitives, and the bypasses do not violate Microsoft&apos;s own classification of them, what are the actual theoretical limits of integrity-level systems? What can MIC and UIPI never do, by design?&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits: What MIC and UIPI Cannot Do, by Design&lt;/h2&gt;
&lt;p&gt;The 2007 disclaimer was not just an admission of weakness. It was an accurate statement of the theoretical limits of any access-control primitive in a backward-compatible operating system. The bypass-research industry of 2009 to 2026 has empirically traced out those limits one technique at a time, and a careful reading of the theory tells us why the trace looks the way it does.&lt;/p&gt;
&lt;h3&gt;Biba 1977 and the three rules&lt;/h3&gt;
&lt;p&gt;The integrity model MIC implements comes from Kenneth J. Biba&apos;s 1977 MITRE technical report MTR-3153 [@biba-wiki]. Biba&apos;s model is the integrity-side mirror of the better-known Bell-LaPadula confidentiality model [@blp-wiki]: where Bell-LaPadula&apos;s &quot;no read up&quot; prevents confidentiality leaks, Biba&apos;s &quot;no write up&quot; prevents integrity contamination. The Biba model defines three rules.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simple Integrity Property&lt;/strong&gt; (&lt;em&gt;no read down&lt;/em&gt;): a subject at integrity level $I_s$ cannot read an object at integrity level $I_o &amp;lt; I_s$. A High-IL subject cannot read Low-IL data, because Low-IL data may have been written by an untrusted source and might contaminate the subject&apos;s state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Star Integrity Property&lt;/strong&gt; (&lt;em&gt;no write up&lt;/em&gt;): a subject at integrity level $I_s$ cannot write an object at integrity level $I_o &amp;gt; I_s$. A Low-IL subject cannot write to a High-IL object, because the Low-IL subject&apos;s writes would degrade the High-IL object&apos;s integrity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invocation Property&lt;/strong&gt;: a subject at integrity level $I_s$ cannot invoke (call, request services from) a subject at integrity level $I_o &amp;gt; I_s$. A Low-IL caller cannot ask a High-IL server to perform an action on the caller&apos;s behalf, because the High-IL server would then act on Low-IL inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MIC implements the Star Integrity Property as the &lt;em&gt;default&lt;/em&gt; &lt;code&gt;NO_WRITE_UP&lt;/code&gt; policy. Every object that does not explicitly request a different policy is protected against lower-IL writes [@mic-doc][@mandatory-label-ace]. That is the one Biba rule MIC actually enforces.&lt;/p&gt;
&lt;p&gt;MIC does &lt;em&gt;not&lt;/em&gt; implement Biba&apos;s Simple Integrity Property at all. There is no &lt;code&gt;NO_READ_DOWN&lt;/code&gt; policy in the &lt;code&gt;winnt.h&lt;/code&gt; mandatory-label-policy enumeration. The opt-in &lt;code&gt;NO_READ_UP&lt;/code&gt; bit MIC exposes points the other way: it stops a &lt;em&gt;lower&lt;/em&gt;-IL subject from reading a &lt;em&gt;higher&lt;/em&gt;-IL object, which is structurally Bell-LaPadula&apos;s Simple Security Property (no read up for confidentiality) repurposed onto an integrity SID rather than a confidentiality label [@blp-wiki][@mandatory-label-ace]. By default, a Low-IL process can read a High-IL file. This is the design choice Forshaw&apos;s &lt;em&gt;Reading Your Way Around UAC&lt;/em&gt; series turned into a research program in 2017 [@forshaw-reading-uac].&lt;/p&gt;
&lt;p&gt;MIC does &lt;em&gt;not&lt;/em&gt; implement the Invocation Property either. A Medium-IL process can invoke a High-IL service via the COM Elevation Moniker, via &lt;code&gt;ShellExecuteEx &quot;runas&quot;&lt;/code&gt;, via any of the auto-elevated binaries, via RPC to Appinfo. The absence of the Invocation Property is exactly what makes UAC operationally usable: a strict reading of Biba would forbid every brokered elevation surface in Windows, and the OS would be unbearable to use. The omission is deliberate, and it is the theoretical reason why every &quot;bypass&quot; of UAC is technically a &lt;em&gt;use&lt;/em&gt; of an architectural surface, not a violation of it.&lt;/p&gt;

flowchart LR
    subgraph BIBA [&quot;Biba 1977 -- integrity model&quot;]
        A[&quot;Biba 1977&lt;br /&gt;integrity model&quot;] --&amp;gt; B[&quot;Simple Integrity&lt;br /&gt;(no read down)&quot;]
        A --&amp;gt; C[&quot;Star Integrity&lt;br /&gt;(no write up)&quot;]
        A --&amp;gt; D[&quot;Invocation Property&lt;br /&gt;(no invoke up)&quot;]
        B --&amp;gt; E[&quot;MIC: not implemented&lt;br /&gt;(no NO_READ_DOWN policy in winnt.h)&quot;]
        C --&amp;gt; F[&quot;MIC: default NO_WRITE_UP&lt;br /&gt;(on by default)&quot;]
        D --&amp;gt; G[&quot;MIC: not implemented&lt;br /&gt;(COM moniker, runas verb, Appinfo)&quot;]
    end
    subgraph BLP [&quot;Bell-LaPadula 1973 -- confidentiality model&quot;]
        H[&quot;Bell-LaPadula 1973&lt;br /&gt;confidentiality model&quot;] --&amp;gt; I[&quot;Simple Security&lt;br /&gt;(no read up)&quot;]
        I --&amp;gt; J[&quot;MIC: opt-in NO_READ_UP&lt;br /&gt;(off by default, repurposed onto IL)&quot;]
    end

Strict Biba would forbid every brokered-elevation primitive in Vista. The COM Elevation Moniker, `ShellExecuteEx &quot;runas&quot;`, the entire RPC interface to Appinfo, the `IFileOperation`-class auto-elevated COM objects, the manifest-based elevation request: all of these are explicitly *invocations* by a lower-IL caller of a higher-IL server [@biba-wiki].&lt;p&gt;Microsoft&apos;s architectural decision was that brokered elevation is the operationally usable workaround. A Medium-IL caller cannot invoke a High-IL server directly, but a Medium-IL caller can ask the SYSTEM-trusted Appinfo broker to create a High-IL process whose initial state the broker controls. The broker is the mediation point. The brokered model is structurally weaker than strict Biba, and that weakness is exactly the surface the bypass-research industry has operated in for sixteen years. Every COM-elevation moniker bypass, every auto-elevation registry hijack, every DLL-search-order attack is a refinement of the same observation: brokered elevation lets Medium-IL inputs influence High-IL outputs in ways the broker cannot fully validate.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The access-control versus information-flow gap&lt;/h3&gt;
&lt;p&gt;The deeper bound is information-flow. Dorothy Denning&apos;s May 1976 &lt;em&gt;Communications of the ACM&lt;/em&gt; paper &lt;em&gt;A lattice model of secure information flow&lt;/em&gt; established the formal framework [@denning-1976]. Denning&apos;s result is fundamental: information-flow enforcement is undecidable in the general case, because verifying that a program never leaks information from class $A$ to class $B$ requires deciding properties of arbitrary programs, which reduces to the halting problem.&lt;/p&gt;
&lt;p&gt;MIC enforces access control, not information flow. The distinction is essential. Access control answers &lt;em&gt;&quot;can this subject perform this operation on this object?&quot;&lt;/em&gt; in O(1) at operation time. Information flow asks &lt;em&gt;&quot;does the final state of this system contain any information derived from data the subject was not authorised to read?&quot;&lt;/em&gt; That is undecidable.&lt;/p&gt;
&lt;p&gt;What this means for UAC: even when MIC perfectly enforces &lt;code&gt;NO_WRITE_UP&lt;/code&gt;, a Low-IL process can still &lt;em&gt;influence&lt;/em&gt; a High-IL process via shared state the High-IL process reads. Forshaw&apos;s January 2026 lazy DOS device directory hijack [@forshaw-adminprot-jan26] is exactly such an attack: it places attacker-controlled state in a location a High-IL process will later read, without ever writing up directly. MIC cannot prevent this; no access-control primitive can. Closing the gap requires information-flow analysis, which is provably undecidable for arbitrary code.&lt;/p&gt;
&lt;h3&gt;The five concrete limits&lt;/h3&gt;
&lt;p&gt;The theoretical bounds map onto five concrete limits any practitioner can observe on a default Windows 11 install.&lt;/p&gt;
&lt;p&gt;The first limit is that no-write-up does not imply no-influence-up. A Low-IL process cannot write to High-IL objects directly, but it can place state (registry keys, files, environment variables, named objects) that a High-IL process will subsequently read or be influenced by. Every fileless UAC bypass in §7.1 walks through this gap.&lt;/p&gt;
&lt;p&gt;The second limit is that &lt;code&gt;NO_READ_UP&lt;/code&gt; is opt-in [@mic-doc]. By default, a Low-IL process can read a High-IL file. This is intentional: accessibility tools, antivirus, and diagnostic utilities depend on cross-IL reads. The cost is that any High-IL data placed at a default-policy location is readable by every Medium-IL or lower process on the system.&lt;/p&gt;
&lt;p&gt;The third limit is that UIPI covers only the windowing layer. Sockets, named pipes, COM, RPC, shared memory, MIDL-defined RPC interfaces, and every other inter-process channel that does not go through &lt;code&gt;win32k.sys&lt;/code&gt; is out of scope [@uipi-wiki]. UIPI is necessary, but it is not sufficient for cross-IL isolation; the full bound requires MIC on the file system, the registry, and every named object the higher-IL process might consume.&lt;/p&gt;
&lt;p&gt;The fourth limit is the same-IL same-desktop attack surface. Two Medium-IL processes on the user&apos;s &lt;code&gt;Default&lt;/code&gt; desktop are not isolated from each other by either MIC or UIPI. They have the same IL (no MIC bound) and they own windows on the same desktop with the same IL (no UIPI bound). Every modern browser sandbox addresses this separately, by combining MIC (the renderer runs at Low IL or Untrusted IL) with AppContainer (capability-based identity isolation) and restricted tokens (&lt;code&gt;CreateRestrictedToken&lt;/code&gt;-style SID denial) [@chromium-sandbox][@appcontainer-isolation]. Where MIC alone is insufficient, the stack layers additional primitives, but those primitives are &lt;em&gt;additions&lt;/em&gt; to MIC, not replacements for it.&lt;/p&gt;
&lt;p&gt;The fifth limit is the auto-elevated-binary surface. As long as a Medium-IL process can cause a High-IL process to come into existence executing user-controllable inputs (registry handlers, DLL search-order resolution, COM moniker activation, command-line arguments), the bypass-research industry has architectural space to operate. The fix would be to apply the Invocation Property strictly, which would break elevation.&lt;/p&gt;
&lt;h3&gt;Why MIC has to be a separate evaluator&lt;/h3&gt;
&lt;p&gt;The Harrison-Ruzzo-Ullman 1976 result is the theoretical reason MIC could not be implemented as discretionary ACEs [@hru-1976]. HRU prove that the &lt;em&gt;safety question&lt;/em&gt; (given an initial access matrix, will any future sequence of operations cause subject $s$ to acquire permission $p$ on object $o$?) is undecidable for the general access-matrix model. That undecidability is what makes mandatory policy necessary as a &lt;em&gt;separate&lt;/em&gt; evaluator: if integrity were encoded as discretionary ACEs, the safety of an object&apos;s integrity label would inherit HRU undecidability through every principal with rights over the ACE.&lt;/p&gt;
&lt;p&gt;By making MIC a separate evaluator with non-discretionary semantics, Windows answers the integrity-safety question in O(1) per access check: compare two SIDs, consult three policy bits, decide. The decidability comes from the separation. MIC is bounded because it is structurally simpler.&lt;/p&gt;
&lt;p&gt;None of the bypass classes in §7 violate any of these limits. They all operate within them. The registry-hijack class places Low-IL state where a High-IL reader will consume it (limit #1). The DLL-search-order class abuses the auto-elevated-binary surface (limit #5). The COM-behaviour-abuse class operates on the absent Invocation Property. Microsoft&apos;s response, repeated for sixteen years, was to acknowledge these as architectural realities of the design rather than as bugs to fix. The bypass-research literature is the empirical map of the access-control versus information-flow gap that no mainstream OS has closed.&lt;/p&gt;
&lt;p&gt;Did Microsoft ever try to actually move the boundary? What does it look like when a security feature finally becomes a security boundary?&lt;/p&gt;
&lt;h2&gt;9. The Adminless Successor and the Open Problems&lt;/h2&gt;
&lt;p&gt;In November 2024, Microsoft did something it had not done in seventeen years. It moved the security-boundary line. &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Administrator Protection&lt;/a&gt;, announced as a Windows 11 platform feature, became the first generation in the integrity-level lineage that Microsoft classifies as a security boundary [@admin-protection][@msft-devblog-adminprot]. The reclassification is structurally substantial. It is not Microsoft renaming UAC; it is Microsoft adding the architectural primitives a boundary classification requires.&lt;/p&gt;
&lt;h3&gt;What the split-token model shared, and what Administrator Protection separates&lt;/h3&gt;
&lt;p&gt;The four shared properties between the filtered token and the linked token were the structural reason UAC could not be a security boundary. They are listed verbatim in Forshaw&apos;s May 2017 &lt;em&gt;Reading Your Way Around UAC&lt;/em&gt; framing [@forshaw-reading-uac]: same user SID, same &lt;code&gt;%USERPROFILE%&lt;/code&gt;, same &lt;code&gt;HKCU&lt;/code&gt; hive, same logon-session LUID. Administrator Protection attacks all four.&lt;/p&gt;

The per-user separate identity Windows 11 Administrator Protection provisions at first elevation. Has a different SID, `%USERPROFILE%`, `HKCU` hive, and LUID from the calling user, defeating the registry-hijack class of UAC bypasses by structurally separating elevated-process state from the caller&apos;s state.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;2007 Split-Token (UAC)&lt;/th&gt;
&lt;th&gt;2024 Administrator Protection&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;User SID&lt;/td&gt;
&lt;td&gt;Same as caller&lt;/td&gt;
&lt;td&gt;Different (per-user System Managed Administrator Account, SMAA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%USERPROFILE%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as caller&lt;/td&gt;
&lt;td&gt;Different: &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HKCU&lt;/code&gt; registry hive&lt;/td&gt;
&lt;td&gt;Same hive as caller&lt;/td&gt;
&lt;td&gt;Different hive (per-SMAA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logon session LUID&lt;/td&gt;
&lt;td&gt;Same session as caller&lt;/td&gt;
&lt;td&gt;Fresh logon session per elevation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;Consent click only&lt;/td&gt;
&lt;td&gt;Windows Hello integrated authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Classification&lt;/td&gt;
&lt;td&gt;Security feature, not boundary&lt;/td&gt;
&lt;td&gt;Security boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;SMAA expands as &quot;System Managed Administrator Account&quot; per the May 19, 2025 Microsoft Windows Developer Blog explainer &lt;em&gt;Enhance your application security with Administrator protection&lt;/em&gt; [@msft-devblog-adminprot]. Earlier Microsoft Learn documentation from 2024 used the working name &quot;Adminless&quot; without the SMAA acronym. The corpus&apos;s Adminless / Administrator Protection article (#52) covers the SMAA lifecycle and the Insider-Preview timeline in more depth than this article does.&lt;/p&gt;
&lt;p&gt;The concrete operational consequence of the SMAA identity change is structural defeat of the entire registry-hijack class. When an attacker writes the canonical fodhelper bypass key to &lt;code&gt;HKCU\Software\Classes\ms-settings\shell\open\command&lt;/code&gt;, the attacker writes to the &lt;em&gt;caller&apos;s&lt;/em&gt; HKCU hive. When &lt;code&gt;fodhelper.exe&lt;/code&gt; is then elevated under Administrator Protection, the elevated process runs under the SMAA identity, with the SMAA&apos;s own HKCU hive, which does not contain the attacker&apos;s key. The auto-elevated binary resolves the &lt;code&gt;ms-settings&lt;/code&gt; association via the SMAA&apos;s HKCU, falls through to HKLM, and gets the legitimate handler. The attacker&apos;s bypass is structurally defeated by the identity change, not by a per-binary fix [@admin-protection][@forshaw-adminprot-jan26].&lt;/p&gt;
&lt;h3&gt;The 2025 timeline&lt;/h3&gt;
&lt;p&gt;Administrator Protection&apos;s rollout has been incremental. Microsoft released it as an opt-in toggle in early 2024 Insider Preview builds, then shipped a generally-available implementation in optional update KB5067036 on October 28, 2025 [@forshaw-adminprot-jan26]. The Microsoft Learn &lt;em&gt;Administrator protection&lt;/em&gt; page acknowledges a temporary revert on December 1, 2025 &quot;while an application compatibility issue is dealt with&quot; [@admin-protection][@forshaw-adminprot-jan26]. The expected re-enablement is in 2026.&lt;/p&gt;
&lt;p&gt;Forshaw&apos;s January 26, 2026 Project Zero post &lt;em&gt;Bypassing Windows Administrator Protection&lt;/em&gt; documents the application-compatibility revert with verbatim precision. He notes that &quot;the issue is unlikely to be related to anything described in this blog post,&quot; meaning that the December 2025 revert was a third-party application compatibility regression rather than a security issue with the feature itself [@forshaw-adminprot-jan26]. The revert is operational, not architectural.&lt;/p&gt;
&lt;h3&gt;The 2026 retrospective: nine bypasses, five via UI Access&lt;/h3&gt;
&lt;p&gt;Forshaw&apos;s January and February 2026 Project Zero pair is the canonical modern retrospective on Administrator Protection&apos;s architectural maturity. The January post documents nine separate Administrator Protection bypasses Forshaw reported to Microsoft during the Insider Preview cycle, all of which were fixed before general availability [@forshaw-adminprot-jan26]. The post details one in depth (the lazy DOS device directory hijack) and summarises the rest.&lt;/p&gt;

If the weaknesses in UAC can be mitigated then it can be made a secure boundary. -- James Forshaw, *Bypassing Windows Administrator Protection*, Project Zero, January 26, 2026
&lt;p&gt;The February 2026 follow-on post, &lt;em&gt;Bypassing Administrator Protection by Abusing UI Access&lt;/em&gt;, is the more architecturally significant of the pair. It documents that &lt;strong&gt;five of the nine&lt;/strong&gt; pre-GA Administrator Protection bypasses operated entirely through the &lt;code&gt;uiAccess=true&lt;/code&gt; exemption, the long-standing UIPI carve-out for accessibility software inherited unchanged from Vista 2007 [@forshaw-adminprot-feb26].&lt;/p&gt;
&lt;p&gt;The reading is structural. Administrator Protection successfully closes the bypass surface that the split-token model&apos;s shared identity created (limit #1 through limit #4 in §8). It does &lt;em&gt;not&lt;/em&gt; close the bypass surface created by the UI Access carve-out, because UI Access is a &lt;em&gt;deliberate&lt;/em&gt; exemption from UIPI. Closing UI Access would break screen readers, on-screen keyboards, remote-control tools, and every accessibility utility that depends on cross-IL window-message access. The exemption is necessary; the residual attack surface is the cost of accessibility.&lt;/p&gt;
&lt;p&gt;The three gating conditions for &lt;code&gt;uiAccess=true&lt;/code&gt; (manifest assertion, valid Authenticode signature, admin-only install location) are documented in the &lt;em&gt;Security Considerations for Assistive Technologies&lt;/em&gt; Microsoft Learn page [@uia-security]. Forshaw&apos;s February 2026 post enumerates them verbatim and describes the &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; Appinfo RPC entry point the UI-Access bypasses operate through [@forshaw-adminprot-feb26]. The trade press picked up the story immediately: &lt;em&gt;The Register&lt;/em&gt; covered Forshaw&apos;s January 2026 post under the headline &quot;Google researcher sits on UAC bypass for ages, only for it to become valid with new security feature&quot; on January 28, 2026 [@register-2026].&lt;/p&gt;
&lt;h3&gt;The downstream legacy&lt;/h3&gt;
&lt;p&gt;MIC and UIPI outlived UAC. The integrity-SID primitive is the connective tissue of every later sandbox model on Windows.&lt;/p&gt;

flowchart TD
    A[&quot;Integrity-SID primitive&lt;br /&gt;(MIC + UIPI, Vista 2006/2007)&quot;] --&amp;gt; B[&quot;AppContainer&lt;br /&gt;(Windows 8, 2012)&quot;]
    A --&amp;gt; C[&quot;IE Protected Mode&lt;br /&gt;(IE7, Vista 2006)&quot;]
    A --&amp;gt; D[&quot;Edge / Chrome / Firefox sandbox tiers&lt;br /&gt;(2008-present)&quot;]
    A --&amp;gt; E[&quot;Protected Process Light&lt;br /&gt;(Windows 8.1, 2013)&quot;]
    A --&amp;gt; F[&quot;Administrator Protection / SMAA&lt;br /&gt;(Windows 11, 2024)&quot;]
    A --&amp;gt; G[&quot;RunAsPPL for LSASS&lt;br /&gt;(Windows 8.1, 2013)&quot;]
    A --&amp;gt; H[&quot;Office Protected View&lt;br /&gt;(Office 2010+)&quot;]
&lt;p&gt;AppContainer (Windows 8, 2012) layers package SIDs above the integrity SID and rides the same &lt;code&gt;SeAccessCheck&lt;/code&gt; infrastructure [@appcontainer-isolation]. IE Protected Mode (Windows Vista IE7, 2006) was the first non-UAC consumer of Low IL, running browser-rendered content as a Low-IL process before the user&apos;s Medium-IL interactive shell. Modern browser sandbox tiers (Chrome, Edge, Firefox content processes) use Low-IL or Untrusted-IL sandbox processes, layered with AppContainer and restricted tokens [@chromium-sandbox]. &lt;a href=&quot;https://paragmali.com/blog/protected-process-light-when-the-administrator-isnt-enough/&quot; rel=&quot;noopener&quot;&gt;Protected Process Light&lt;/a&gt; (Windows 8.1, 2013) is a signature-based generalisation of the integrity-SID concept that PPL-protects LSASS against &lt;code&gt;OpenProcess&lt;/code&gt; by lower-IL callers. Administrator Protection itself uses the integrity-SID primitive: SMAA processes run at High IL while the calling Medium-IL admin shell stays Medium [@admin-protection].&lt;/p&gt;
&lt;p&gt;The twenty-year experiment was a success. The integrity-level stack did exactly what it was designed to do: bound integrity, not authority. The consent prompt was honestly never the security boundary. Microsoft&apos;s November 2024 reclassification finally promotes a feature to a boundary by adding the architectural support the boundary classification requires (separate identity, separate profile, separate hive, separate LUID, Windows Hello-mediated transition). The bypass-research literature is the empirical proof that the 2007 disclaimer was honest, and the proof that the architecture worked exactly as architected.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; MIC and UIPI outlived UAC. The integrity-SID primitive is the connective tissue of AppContainer, every modern browser sandbox, Protected Mode, Protected Process Light, and the Administrator Protection successor. The yellow dialog is the smallest, most replaceable piece of the system.&lt;/p&gt;
&lt;/blockquote&gt;

On December 1, 2025, Microsoft temporarily reverted Administrator Protection in KB5067036 pending an application-compatibility fix [@admin-protection][@forshaw-adminprot-jan26]. Forshaw&apos;s exact framing matters: &quot;the issue is unlikely to be related to anything described in this blog post.&quot; The revert was *not* a security regression; it was a third-party application-compatibility issue, with re-enablement expected in 2026. As of May 2026, Administrator Protection can be enabled manually on Windows 11 24H2 and later but is not the default on consumer or enterprise SKUs pending re-enablement [@admin-protection].
&lt;h2&gt;10. Inspecting the Stack on a Real Box&lt;/h2&gt;
&lt;p&gt;Every primitive in this article is observable on the Windows install you are reading on. Here are the five commands and the two tools that will let you walk the stack yourself.&lt;/p&gt;
&lt;h3&gt;Inspecting integrity levels&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;whoami /groups | findstr Mandatory&lt;/code&gt; prints the mandatory label of the current process token. From an unelevated PowerShell on an administrator account, it will read &lt;code&gt;Mandatory Label\Medium Mandatory Level&lt;/code&gt;. From an elevated PowerShell, it will read &lt;code&gt;Mandatory Label\High Mandatory Level&lt;/code&gt;. From a renderer-process command inside a Chromium-based browser, it would read &lt;code&gt;Mandatory Label\Low Mandatory Level&lt;/code&gt; or &lt;code&gt;Untrusted Mandatory Level&lt;/code&gt;, depending on the sandbox tier.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;whoami /all&lt;/code&gt; is the longer view. It prints every group SID, every privilege, and the full mandatory label.Process Explorer (and System Informer) will show you the same data graphically, but &lt;code&gt;whoami&lt;/code&gt; is the canonical first-party command for getting at the same kernel information from the shell. Run it twice -- once from an unelevated PowerShell, once from an elevated PowerShell on the same admin account -- and diff the outputs to see what the elevation actually changed. That is the empirical re-creation of §1&apos;s hook.&lt;/p&gt;
&lt;p&gt;Sysinternals&apos; Process Explorer has an Integrity column you can add via View / Select Columns / Process Image. Once enabled, it shows the IL of every running process at a glance. System Informer (the open-source Process Explorer successor) supports the same column plus richer SACL inspection. The &lt;code&gt;accesschk -e -l &amp;lt;object&amp;gt;&lt;/code&gt; Sysinternals command prints the mandatory label of a file, registry key, or other securable object: &lt;code&gt;accesschk -e -l C:\Windows\System32\drivers\&lt;/code&gt; reveals the System-IL label that protects the driver directory.&lt;/p&gt;

The PowerShell-native equivalent of `whoami /all` that programs can consume is:&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;[System.Security.Principal.WindowsIdentity]::GetCurrent() |
  Select-Object -ExpandProperty Groups |
  ForEach-Object { $_.Translate([System.Security.Principal.NTAccount]) }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces the same SID-to-account-name resolution &lt;code&gt;whoami /groups&lt;/code&gt; does, and is useful inside automation that needs to test deny-only group membership programmatically.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Inspecting UIPI&lt;/h3&gt;
&lt;p&gt;UIPI is harder to observe directly because the OS does not log dropped messages. The practical demonstration is to run Spy++ (the Visual Studio windowing inspector) from a Medium-IL process and attempt to subclass a window owned by an elevated High-IL process. The subclass call silently fails. &lt;code&gt;SendMessage&lt;/code&gt; returns 0 with &lt;code&gt;GetLastError&lt;/code&gt; reading &lt;code&gt;ERROR_ACCESS_DENIED&lt;/code&gt;. The &lt;code&gt;ChangeWindowMessageFilterEx&lt;/code&gt; documentation page is the Microsoft Learn entry point for understanding the per-window, per-message exemption surface [@changewindowfilter].&lt;/p&gt;
&lt;h3&gt;Enumerating the auto-elevation list&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sigcheck -m C:\Windows\System32\*.exe | findstr /i autoelevate&lt;/code&gt; walks every executable in &lt;code&gt;System32&lt;/code&gt; and prints the manifest of each. The &lt;code&gt;findstr&lt;/code&gt; filter narrows to lines containing &lt;code&gt;autoElevate&lt;/code&gt;, surfacing the binaries that assert the manifest flag. On a Windows 11 25H2 install, the resulting list runs to thirty to forty binaries. Remember that the manifest-asserting list is &lt;em&gt;not&lt;/em&gt; the same as Appinfo&apos;s internal operational allowlist; the operational subset is what UACMe enumerates [@uacme].&lt;/p&gt;
&lt;h3&gt;Watching Appinfo in action&lt;/h3&gt;
&lt;p&gt;Procmon (Sysinternals Process Monitor) filtered on &lt;code&gt;consent.exe&lt;/code&gt; shows every elevation event: the registry reads against the manifest, the SACL reads on the binary, the token-information queries against the caller&apos;s filtered token. The Windows Event Viewer&apos;s &lt;em&gt;Applications and Services Logs / Microsoft / Windows / User Account Control&lt;/em&gt; channel logs elevation events at the OS level. The combination of Procmon (mechanism) and the Event Viewer (audit trail) is the standard observability surface for elevation operations.&lt;/p&gt;
&lt;h3&gt;A safe lab for the bypass classes&lt;/h3&gt;
&lt;p&gt;UACMe is the community catalogue of 81 documented UAC bypass methods, each with author, technique, target binary, and Windows-version applicability annotations [@uacme]. For inspection of the integrity-level state of running processes from an analyst&apos;s workstation, James Forshaw&apos;s &lt;em&gt;sandbox-attacksurface-analysis-tools&lt;/em&gt; repository (the NtObjectManager, TokenViewer, and NtCoreLib PowerShell modules) is the standard research toolchain [@forshaw-tools]. The UACMe reference implementations (&lt;code&gt;akagi32.exe&lt;/code&gt;, &lt;code&gt;akagi64.exe&lt;/code&gt;) are flagged by Microsoft Defender as &lt;code&gt;HackTool:Win32/Welevate&lt;/code&gt;, the detection name Davidson noted as early as 2009 [@davidson-2009]. This is research tooling, not endpoint operations: run UACMe only on a snapshot VM with Defender exclusions documented, and treat the output as an empirical confirmation of the bypass-research record rather than as an offensive primitive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The minimum five commands a reader can run on their own Windows box to verify everything in this article: 1. &lt;code&gt;whoami /all&lt;/code&gt; (run twice: once unelevated, once elevated; diff the outputs) 2. &lt;code&gt;whoami /groups | findstr Mandatory&lt;/code&gt; (inspect the IL of the current token) 3. &lt;code&gt;sigcheck -m C:\Windows\System32\eventvwr.exe&lt;/code&gt; (read the autoElevate manifest) 4. &lt;code&gt;tasklist /v /fi &quot;imagename eq svchost.exe&quot; | findstr Appinfo&lt;/code&gt; (confirm the Appinfo service host) 5. Process Explorer with the Integrity column enabled, sorted by IL (the entire stack at a glance) The whole tour takes ten minutes. By the end you will have seen the split-token model, the integrity-level lattice, the auto-elevation allowlist, the Appinfo broker, and the Medium-vs-High distribution of your interactive desktop, with your own eyes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;11. Five Misconceptions That Will Not Die&lt;/h2&gt;
&lt;p&gt;Five UAC misconceptions come up so often in practitioner discussions that any complete treatment owes the reader explicit corrections. Two practical questions round out the FAQ.&lt;/p&gt;

No, and Microsoft&apos;s own documentation has said so since February 2007. The canonical &quot;Neither UAC elevations nor Protected Mode IE define new Windows security boundaries&quot; sentence appears in the *PsExec, User Account Control and Security Boundaries* TechNet Blogs post by Mark Russinovich, dated February 12, 2007 -- see §7.4 for the full quote and the citation-chain disambiguation against the *Inside Windows Vista User Account Control* TechNet Magazine architectural article [@russinovich-blog-2007][@russinovich-tnm-2007]. The boundary line was finally moved in November 2024 with Administrator Protection, which Microsoft does classify as a security boundary [@admin-protection][@forshaw-adminprot-jan26]. The original split-token UAC was never a boundary, by design, and the bypass-research record from 2009 to 2024 is the empirical confirmation that the disclaimer was honest.

No. The Secure Desktop is on the `Winlogon` desktop within `WinSta0`, *within* the user&apos;s interactive session (Session 1, 2, ...) -- §6.1 walks the full Object-Manager hierarchy and contrasts it with the separate Vista Session 0 Isolation feature that moved Windows services into a non-interactive Session 0 [@russinovich-tnm-2007]. The two features ship together in Vista and are constantly confused, but they live at different layers of the Object Manager hierarchy and address different threats.

No. The manifest entry is necessary but not sufficient. Appinfo enforces three additional gates: the binary must carry a valid Microsoft Authenticode signature, the binary must reside under a trusted system directory (`%SystemRoot%\System32` or `%SystemRoot%\SysWOW64`), and the binary&apos;s name must appear on an internal allowlist enforced in code in `appinfo.dll`, not in any user-visible policy file [@davidson-2009][@app-manifests]. Copying `autoElevate=true` into your own binary&apos;s manifest does nothing on its own. The community-standard enumeration technique is `sigcheck -m C:\Windows\System32\*.exe | findstr /i autoelevate`, but that enumerates the manifest-asserting set, not the operational allowlist.

No -- UIPI blocks a specific dangerous subset (window-state mutators, hooks, input injection, journal record / playback); mouse messages, most paint messages, and read-only window queries pass. The complete row-by-row enumeration of blocked vs allowed vs degraded-but-passes message classes is in the §4.2 table. The &quot;blocks all `WM_*`&quot; misconception is one of the most common errors in Windows-security literature [@uipi-wiki][@russinovich-blog-2007].

No. `ShellExecuteEx` with the `&quot;runas&quot;` verb is whole-process elevation: Appinfo creates a new process under the caller&apos;s linked full token, and the new process runs at High IL for its entire lifetime [@shellexecuteexa]. The COM Elevation Moniker is per-object elevation: a Medium-IL caller instantiates a single COM object in a new elevated `dllhost.exe` exposing only that one CLSID&apos;s methods at High IL [@com-elevation-moniker]. The caller stays Medium; only the COM object&apos;s host process is elevated. The bypass-research literature attacks the second surface far more than the first, because per-object elevation exposes a narrower, more abusable *behavioural* surface (the methods of one CLSID), while whole-process elevation requires a path-class bypass like DLL-search-order to weaponise.

Partially. The registry-hijack class (the eventvwr / fodhelper / sdclt / ComputerDefaults family from 2016-2017) is structurally defeated by the SMAA identity change: the attacker writes to the caller&apos;s HKCU hive, but the elevated process runs under the SMAA&apos;s different HKCU hive and never consults the attacker&apos;s key [@admin-protection]. The DLL-search-order class is partially mitigated by the SMAA&apos;s different `%USERPROFILE%` and different working directory. The UI Access class is *not* mitigated: it is the long-standing carve-out for accessibility software, inherited unchanged from Vista 2007, and Forshaw&apos;s February 2026 Project Zero post documents that this carve-out carried five of nine pre-GA Administrator Protection bypasses [@forshaw-adminprot-feb26]. UACMe remains the canonical operational catalogue for the bypass classes that survive Administrator Protection.

No. Setting `EnableLUA=0` in `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System` reverts the OS to the pre-Vista posture: no split-token model, every admin-account process running High-IL by default, every interactive shell holding the full admin SID set and the complete privilege list. The integrity-level *primitive* (MIC) remains in the kernel; the *policy* that makes it operationally useful (the default-Medium-IL filtered token for interactive admins) is disabled. Browser sandbox tiers still function, because they construct restricted Low-IL tokens explicitly. The admin&apos;s daily shell does not benefit, and a malware drop in any process under the admin&apos;s interactive session immediately holds High IL [@uac-how-it-works]. This is structurally the XP situation. Leaving `EnableLUA=1` (the default) is correct on every modern Windows install.
&lt;h2&gt;12. The Plumbing Outlived the Yellow Dialog&lt;/h2&gt;
&lt;p&gt;Return to the two &lt;code&gt;whoami&lt;/code&gt; outputs from §1. The user is the same. The session is the same. The clock has barely moved. Read them again, and now read what each line means.&lt;/p&gt;
&lt;p&gt;The administrator group SID was present in both tokens, marked deny-only on the filtered token and enabled on the elevated token. The integrity level changed from Medium (&lt;code&gt;S-1-16-8192&lt;/code&gt;) to High (&lt;code&gt;S-1-16-12288&lt;/code&gt;). The privilege set expanded from the small user-mode subset to the full administrator set. The bits that moved were the kernel-level token-assignment bits in the new process Appinfo created via &lt;code&gt;CreateProcessAsUser&lt;/code&gt;, using the dormant linked token that LSA had constructed thirty minutes earlier at logon. The yellow dialog was the consent surface on top of a token-swap primitive that existed before the dialog rendered and that can move bits without the dialog (via auto-elevation).&lt;/p&gt;
&lt;p&gt;Four primitives carried the work. Mandatory Integrity Control added an axis to the access check that runs before the DACL and short-circuits on a Low-to-High write attempt, regardless of what the DACL says. User Interface Privilege Isolation closed the cross-IL variant of the shatter-attack class that Paget published in 2002, by dropping the dangerous subset of window messages and hook calls from lower-IL senders to higher-IL receivers. The split-token model gave every administrator a Medium-IL filtered token at logon and held the full token dormant. The Appinfo SYSTEM-trusted broker mediated the token swap when consent or auto-elevation called for it.&lt;/p&gt;
&lt;p&gt;The bypass-research industry of 2009 to 2024 was the empirical confirmation of the architect&apos;s 2007 disclaimer. Davidson&apos;s December 2009 essay opened the auto-elevation surface; Nelson&apos;s 2016-2017 series productised the registry-hijack class; hfiref0x&apos;s UACMe catalogued 81 methods and counting; Forshaw&apos;s 2017 &lt;em&gt;Reading Your Way Around UAC&lt;/em&gt; series named the read-side surface; the cumulative record was a sixteen-year demonstration that UAC was not a security boundary, exactly as Russinovich had publicly stated in February 2007. Microsoft never classified any of these as security vulnerabilities, because the architectural commitment from week one had been that they would not be [@russinovich-blog-2007][@msrc-criteria].&lt;/p&gt;
&lt;p&gt;The November 2024 Administrator Protection reclassification is the line finally moving. The split-token model&apos;s four shared properties between filtered and linked tokens (same SID, same &lt;code&gt;%USERPROFILE%&lt;/code&gt;, same &lt;code&gt;HKCU&lt;/code&gt;, same LUID) are replaced by an SMAA identity that differs on all four dimensions, plus Windows Hello-mediated authentication for every elevation [@admin-protection][@msft-devblog-adminprot]. The registry-hijack class is structurally defeated; the residual surface is the UI Access carve-out inherited unchanged from Vista 2007, which Forshaw&apos;s February 2026 Project Zero post documents as the source of five of nine pre-GA bypasses [@forshaw-adminprot-feb26].&lt;/p&gt;
&lt;p&gt;The yellow dialog is the only piece of UAC most users will ever see. It is also the one piece the OS could replace tomorrow without changing what UAC &lt;em&gt;is&lt;/em&gt;. MIC and UIPI outlived UAC. AppContainer, every modern browser sandbox, IE Protected Mode, Office Protected View, Protected Process Light, and Administrator Protection itself all ride on the integrity-SID and &lt;code&gt;WinSta0&lt;/code&gt; primitives that shipped on January 30, 2007 [@vista-press-release][@appcontainer-isolation][@chromium-sandbox]. The quiet plumbing did the work.&lt;/p&gt;
&lt;p&gt;Next time you click &quot;Yes&quot; on the consent prompt, the bits that move are the same bits that move when Edge spawns a renderer at Low IL, when Defender protects LSASS as PPL, and when a SMAA process shadows your administrator identity on a Windows 11 25H2 install with Administrator Protection enabled. The dialog is the smallest part of the system. Twenty years of empirical research proved the architect right: UAC was never the boundary. The integrity-level stack was, and is [@russinovich-blog-2007][@admin-protection].&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;integrity-level-stack-mic-uipi-uac&quot; keyTerms={[
  { term: &quot;Mandatory Integrity Control (MIC)&quot;, definition: &quot;An access-check evaluator that compares the integrity level of a subject token to the integrity level of a target object before consulting the object&apos;s DACL. Denials short-circuit the access check; integrity beats identity.&quot; },
  { term: &quot;Integrity Level (IL)&quot;, definition: &quot;A well-known SID under S-1-16-X carried on every token and securable object. Seven values: Untrusted, Low, Medium, Medium Plus, High, System, Protected Process.&quot; },
  { term: &quot;User Interface Privilege Isolation (UIPI)&quot;, definition: &quot;The windowing-layer analog of MIC. Blocks dangerous window messages, hooks, and input injection from lower-IL processes targeting higher-IL windows on the same desktop.&quot; },
  { term: &quot;Split-token model&quot;, definition: &quot;Admin Approval Mode: an administrator&apos;s logon produces a Medium-IL filtered token plus a dormant High-IL linked token. The filtered token runs the interactive shell.&quot; },
  { term: &quot;Secure Desktop&quot;, definition: &quot;A separate desktop object (Winlogon) within WinSta0 in the user&apos;s interactive session, on which consent.exe renders the UAC prompt. Not Session 0.&quot; },
  { term: &quot;Application Information service (Appinfo)&quot;, definition: &quot;The SYSTEM-trusted Windows service that mediates the filtered-to-linked token swap at elevation time. Exposes RAiLaunchAdminProcess.&quot; },
  { term: &quot;Auto-elevation allowlist&quot;, definition: &quot;The internal Appinfo allowlist of Microsoft-signed binaries in trusted directories whose manifests assert autoElevate=true. Four gates: manifest, signature, path, allowlist entry.&quot; },
  { term: &quot;COM Elevation Moniker&quot;, definition: &quot;Per-object elevation via Elevation:Administrator!new:{CLSID}. Spins up a single CLSID in an isolated High-IL dllhost.exe while the caller stays Medium.&quot; },
  { term: &quot;System Managed Administrator Account (SMAA)&quot;, definition: &quot;The per-user separate identity Administrator Protection provisions at first elevation. Different SID, profile, HKCU, LUID from the calling user.&quot; },
  { term: &quot;Biba Star Integrity Property&quot;, definition: &quot;No write up: a subject at integrity level Is cannot write an object at integrity level Io &amp;gt; Is. MIC implements this as the default NO_WRITE_UP policy.&quot; }
]} questions={[
  { q: &quot;Why is MIC a separate evaluator rather than another ACE in the DACL?&quot;, a: &quot;Because DACLs are discretionary by definition; an object owner can rewrite the DACL. MIC&apos;s mandatory semantics require an evaluator that runs before the DACL and cannot be overridden by it. The HRU 1976 undecidability of the access-matrix safety question is the formal reason mandatory policy cannot be encoded as discretionary ACEs and remain decidable.&quot; },
  { q: &quot;Why doesn&apos;t the consent prompt elevate?&quot;, a: &quot;Because the elevated token was constructed at logon by LSA, not at consent time by the prompt. The prompt asks the user whether the OS may use the already-existing linked full token to launch a new process. The token swap is performed by Appinfo, not by consent.exe; the prompt is the consent surface on top of a token-swap primitive.&quot; },
  { q: &quot;Why does UIPI block WM_SETTEXT but not WM_PAINT?&quot;, a: &quot;Because WM_SETTEXT mutates the receiving window&apos;s state (the message replaces the window&apos;s text), and an attacker who can mutate a higher-IL window&apos;s state has gained influence over the higher-IL process. WM_PAINT only asks the window to redraw itself; it carries no attacker-controlled mutation, so allowing it from lower-IL senders is safe.&quot; },
  { q: &quot;Which Biba rules does MIC actually implement?&quot;, a: &quot;Just one. MIC implements the Star Integrity Property (NO_WRITE_UP) as the default policy on every object that does not specify otherwise. MIC does not implement Biba&apos;s Simple Integrity Property (no read down) at all -- there is no NO_READ_DOWN policy in winnt.h. The opt-in NO_READ_UP bit MIC exposes is structurally a Bell-LaPadula simple-security analog applied to integrity SIDs, not a Biba rule. MIC does not implement the Invocation Property either; brokered elevation (COM Elevation Moniker, ShellExecuteEx &apos;runas&apos;, Appinfo) is the operationally usable workaround.&quot; },
  { q: &quot;What changed in November 2024 that turned UAC&apos;s elevation transition into a security boundary?&quot;, a: &quot;Administrator Protection replaced the split-token model&apos;s four shared properties (same SID, same %USERPROFILE%, same HKCU, same LUID) with a System Managed Administrator Account that differs on all four dimensions, and required Windows Hello integrated authentication for every elevation. The structural identity separation defeats the entire registry-hijack bypass class. The residual surface is the UI Access carve-out inherited unchanged from Vista 2007.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>uac</category><category>mandatory-integrity-control</category><category>uipi</category><category>integrity-levels</category><category>access-control</category><category>split-token</category><category>administrator-protection</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Eight Primitives, One Worm: The Windows Security Wars Part 2 (2002-2008)</title><link>https://paragmali.com/blog/eight-primitives-one-worm-the-windows-security-wars-part-2-2/</link><guid isPermaLink="true">https://paragmali.com/blog/eight-primitives-one-worm-the-windows-security-wars-part-2-2/</guid><description>How Microsoft re-engineered Windows around security between January 2002 and October 2009 -- and why a wormable RCE patched on October 23, 2008 still infected nine to fifteen million machines.</description><pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate><content:encoded>
Between Bill Gates&apos;s January 15, 2002 Trustworthy Computing memo and Windows 7&apos;s October 22, 2009 general availability, Microsoft executed the largest single security re-architecture in Windows&apos;s history -- and shipped most of it inside Windows Vista, one of the most poorly received consumer Windows releases ever made.&lt;p&gt;This is the story of what that re-architecture built (UAC, Mandatory Integrity Control, UIPI, ASLR, mandatory x64 driver signing, Service Hardening, BitLocker, the Windows Filtering Platform, Windows Resource Protection, and -- inherited from an April 2005 x64-only release that Vista did not introduce -- Kernel Patch Protection), and what Vista broke for compatibility and goodwill along the way.&lt;/p&gt;
&lt;p&gt;Then Conficker (late November 2008, twenty-nine days after the MS08-067 patch) proved that deployment velocity, not discovery latency, is the binding constraint on Internet security. Windows 7&apos;s polished re-release of substantially the same security architecture is the article&apos;s evidence that the user-hostility tax is payable -- if the work is done.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;1. The Patch Was Already a Month Old&lt;/h2&gt;
&lt;p&gt;On Thursday, October 23, 2008, the Microsoft Security Response Center shipped MS08-067 out of band -- not on the next Patch Tuesday, because the analysts who triaged the bug believed a wormable exploit was weeks away, not months [@s-ms08-067]. They were right about the direction and wrong about the calendar. Roughly twenty-nine days later, anchored to November 20, 2008 in SRI International&apos;s technical analysis, Conficker.A began walking the IPv4 address space on TCP/445 [@s-sri-conficker-c-addendum]. Within four months the worm had infected somewhere between nine and fifteen million machines on a vulnerability whose patch had existed the entire time [@s-cwg-lessons-learned-2019].&lt;/p&gt;

The October 23, 2008 Microsoft Security Bulletin patching CVE-2008-4250, a stack buffer overflow in the path-handling code reachable through the Server service&apos;s `srvsvc` RPC interface on TCP/445 (and TCP/139 in NetBT environments). The bulletin text warns the vulnerability &quot;could be used in the crafting of a wormable exploit&quot; -- a prediction that Conficker.A confirmed twenty-nine days later [@s-ms08-067].

A Microsoft security update released outside the regular monthly Patch Tuesday cadence (the second Tuesday of the month). Microsoft reserves out-of-band releases for vulnerabilities whose risk profile -- active exploitation, imminent worm potential, or critical pre-authentication remote code execution -- does not survive the wait until the next monthly bulletin window [@s-msft-secupdates-index].
&lt;p&gt;This article is the story of what Microsoft built between January 15, 2002 (the Trustworthy Computing memo) and October 22, 2009 (Windows 7 general availability), the architectural and cultural costs of that build, and the operational lesson Conficker forced everyone to acknowledge.&lt;/p&gt;
&lt;p&gt;The architectural defenses that Trustworthy Computing produced -- Data Execution Prevention, Address Space Layout Randomization, the Windows Firewall on by default, Service Hardening, the integrity-level stack -- could only protect machines that ran the new code. The installed base did not run the new code. Server 2003 and Windows XP were still the working majority on TCP/445-reachable subnets in late 2008, and Vista&apos;s DEP and ASLR materially raised exploitation cost on Vista without raising it on the systems the worm actually walked.&lt;/p&gt;
&lt;p&gt;Confusing the October-2008 in-the-wild MS08-067 exploitation with Conficker is the most common single error in retellings of this period. The NVD entry for CVE-2008-4250 is explicit: the October-2008 in-the-wild exploitation was Gimmiv.A, a narrower non-self-propagating Trojan, not Conficker [@s-nvd-cve-2008-4250]. Conficker.A first appeared on the Internet on November 20, 2008 per SRI International [@s-sri-conficker-c-addendum].&lt;/p&gt;

sequenceDiagram
    autonumber
    participant MSRC as Microsoft Security Response Center
    participant SRV as Server service over TCP/445
    participant VISTA as Vista with DEP and ASLR
    participant XP as XP and Server 2003 installed base
    participant CONF as Conficker.A
    MSRC-&amp;gt;&amp;gt;SRV: Oct 23, 2008 out-of-band MS08-067 patch
    Note over MSRC,SRV: Bulletin warns &quot;wormable exploit&quot; possible
    SRV--&amp;gt;&amp;gt;XP: Patch must propagate via Automatic Updates or WSUS
    SRV--&amp;gt;&amp;gt;VISTA: Patch applied, DEP and ASLR raise exploit cost
    Note over XP,VISTA: Late October, in-the-wild Gimmiv.A Trojan uses CVE-2008-4250 narrowly
    CONF-&amp;gt;&amp;gt;XP: Nov 20, 2008 Conficker.A scans TCP/445 across IPv4
    Note over CONF,XP: Unpatched XP and Server 2003 are the dominant targets
    XP--&amp;gt;&amp;gt;CONF: Successful exploitation, lateral spread, DGA callback
    Note over CONF,XP: Jan to Apr 2009, 9 to 15 million infections worldwide
&lt;p&gt;By the end of the article you will be able to name every XP SP2 and Vista mitigation, the attack class it broke, the compatibility cost it imposed, and which Windows release inherited or smoothed it. You will know why the most important Trustworthy Computing lesson was not architectural at all -- it was operational.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The patch existed the entire time. Deployment did not. Every Trustworthy Computing mitigation in this article is a partial answer to the question &quot;what reaches the installed base on time?&quot; Conficker is the era&apos;s answer to the question &quot;what does not?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How did we get from the Code Red era to a Trustworthy-Computing world where a wormable RCE could still infect millions? Start with one memo and a stand-down.&lt;/p&gt;
&lt;h2&gt;2. Where Part 1 Left Off&lt;/h2&gt;
&lt;p&gt;On the morning of January 16, 2002, the engineers who worked on Windows came back to work and could not check in code. Bill Gates&apos;s memo had gone out the previous afternoon and reading it took about eleven minutes. The order in the building was the simple part: stop everything, sit through retraining, do not commit until you can argue your changes against a threat model.&lt;/p&gt;
&lt;p&gt;The slower part was naming what had just happened. It was not a campaign. It was a directive that quietly changed the unit of work at Microsoft from &quot;ship the feature&quot; to &quot;ship the feature you can prove will not get someone exploited.&quot;&lt;/p&gt;
&lt;p&gt;The memo itself was the institutional charter for everything in this article. It opened in plain prose -- &quot;Every few years I have sent out a memo talking about the highest priority for the company&quot; -- and arrived at its load-bearing sentence in the fifth sentence of the first paragraph: &quot;Trustworthy Computing is the highest priority for all the work we are doing&quot; [@s-gates-twc-wired]. The line read in 2002 as a corporate goal-setting exercise. In retrospect it read as a contract.&lt;/p&gt;
&lt;p&gt;The Wired and CNET reproductions of the memo carry the same body but differ on the timestamp in the &quot;Sent:&quot; header. Wired records &quot;Sent: Tuesday, January 15, 2002 5:22 PM&quot; [@s-gates-twc-wired]; CNET&apos;s parallel reproduction shows &quot;Sent: Tuesday, January 15, 2002 2:22 PM&quot; [@s-gates-twc-cnet]. The three-hour delta is the Eastern-vs-Pacific wall-clock difference, consistent with Wired having an Eastern copy and CNET reproducing a Pacific one. The article renders the send time as &quot;2:22 PM Pacific / 5:22 PM Eastern.&quot;&lt;/p&gt;

Trustworthy Computing is the highest priority for all the work we are doing. -- Bill Gates, internal Microsoft memo, January 15, 2002 [@s-gates-twc-wired]
&lt;p&gt;The next two months turned the memo into engineering. From roughly February through March 2002, Microsoft ran the Windows security stand-down: approximately 8,500 Windows engineers were pulled off feature work to read Howard and LeBlanc&apos;s &lt;em&gt;Writing Secure Code&lt;/em&gt;, 2nd edition (Microsoft Press, 2002) [@s-howard-leblanc-wsc2e] and to be retrained on threat modeling, input validation, integer-overflow defense, secure default selection, and the privilege-reduction patterns the book named explicitly. Three Microsoft Press security titles served as the canonical training corpus for the next several years; &lt;em&gt;Writing Secure Code 2e&lt;/em&gt; was the one that lived on every desk.&lt;/p&gt;
&lt;p&gt;But the stand-down was a one-time event. The thing that had to outlast it was the process. The Trustworthy Computing Security Development Lifecycle, formally adopted as a mandatory company-wide engineering process in 2004 and described at the Annual Computer Security Applications Conference that December, is the right pivot to point to.&lt;/p&gt;
&lt;p&gt;The canonical paper, Lipner and Howard&apos;s &quot;The Trustworthy Computing Security Development Lifecycle,&quot; ran in the ACSAC 2004 proceedings [@s-lipner-howard-acsac2004-doi]; the IEEE Xplore PDF is paywalled in 2026, so the 2006 Microsoft Press book &lt;em&gt;The Security Development Lifecycle&lt;/em&gt; is the cite-when-possible substitute [@s-howard-lipner-sdl-book]. The SDL is what made every later Windows release feasible: each new version&apos;s threat model, security design review, fuzzing budget, and security push had a name and a sign-off list.&lt;/p&gt;

Microsoft&apos;s formal process specification for security engineering across the product lifecycle. The SDL mandates threat modeling, secure design review, security training, banned-API enforcement, fuzzing, attack-surface review, and a final security push before any product ships. Mandatory company-wide at Microsoft starting in 2004; the definitive ACSAC 2004 paper is the formal record [@s-lipner-howard-acsac2004-doi], and the 2006 Microsoft Press book is the publicly accessible canonical reference [@s-howard-lipner-sdl-book].
&lt;p&gt;The two-and-a-half years between the memo and XP Service Pack 2 were not quiet. MS03-026 in July 2003 led to Blaster three weeks later [@s-msft-ms03-026]; MS03-039 in August 2003 led to Welchia [@s-msft-ms03-039]; MS04-011 in April 2004 led to Sasser [@s-msft-ms04-011]. Each worm was, by the standards of late 2003, a public referendum on whether the &quot;patch fast&quot; model could work for an installed base of hundreds of millions of machines whose users never opened Windows Update. The pattern is worth a small table.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Why it mattered&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Jan 15, 2002&lt;/td&gt;
&lt;td&gt;Gates Trustworthy Computing memo&lt;/td&gt;
&lt;td&gt;Institutional charter for the next eight years of Windows security work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feb-Mar 2002&lt;/td&gt;
&lt;td&gt;Windows security stand-down&lt;/td&gt;
&lt;td&gt;About 8,500 engineers retrained on secure-coding patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jul 16, 2003&lt;/td&gt;
&lt;td&gt;MS03-026 patches DCOM RPC&lt;/td&gt;
&lt;td&gt;Patch ships about three weeks before Blaster (Aug 11)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 11, 2003&lt;/td&gt;
&lt;td&gt;Blaster worm&lt;/td&gt;
&lt;td&gt;Patched RPC vulnerability exploited in the wild; deployment lag obvious&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 2003&lt;/td&gt;
&lt;td&gt;Welchia &quot;good worm&quot;&lt;/td&gt;
&lt;td&gt;Nematode-style attempt to push the patch; spreads exactly as fast as Blaster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 13, 2004&lt;/td&gt;
&lt;td&gt;MS04-011 patches LSASS&lt;/td&gt;
&lt;td&gt;Patch ships about two weeks before Sasser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 30, 2004&lt;/td&gt;
&lt;td&gt;Sasser worm&lt;/td&gt;
&lt;td&gt;Hits ATMs, banks, airlines; the second wormable post-patch event in a year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dec 2004&lt;/td&gt;
&lt;td&gt;SDL formalised at ACSAC&lt;/td&gt;
&lt;td&gt;Process becomes a paper; mandatory across Microsoft engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;What Microsoft was about to ship in August 2004 was not a service pack. It was a feature release with a service-pack number on it -- and it would prove that the right unit of analysis for OS-level security is not the mitigation itself but the deployment threshold the default reaches.&lt;/p&gt;
&lt;h2&gt;3. Why XP SP2 Was Treated as a Major OS Release&lt;/h2&gt;
&lt;p&gt;By the end of 2003 the SP1-era model had collapsed. The bulletin cadence was monthly; the patch was per-CVE; the deployment mechanism was opt-in; and Blaster and Sasser had both shipped while that model was running [@s-msft-secupdates-index]. None of the four design decisions individually was unreasonable. Together they had produced a Windows world in which a worm could outrun a patch by weeks, sometimes months, and the only thing standing between a Class B subnet and an exploitation rate close to 100% was whether enough users had clicked &quot;Install.&quot;&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response was a year-long slip. XP Service Pack 2, internally codenamed &quot;Springboard,&quot; moved from a planned H2 2003 release to August 6, 2004, and along the way it was upgraded from &quot;service pack&quot; to &quot;feature release with a service-pack number on it.&quot;&lt;/p&gt;
&lt;p&gt;The bundle that shipped that day did five things that no prior Windows release had ever done in a single update. The Windows Firewall arrived on by default and active during the boot sequence, closing the Blaster-window race condition. Data Execution Prevention shipped with default-on policy for Windows binaries.&lt;/p&gt;
&lt;p&gt;The Attachment Execution Service became the system-wide enforcement substrate of the &lt;code&gt;Zone.Identifier&lt;/code&gt; NTFS Alternate Data Stream. Internet Explorer 6 SP2 got a pop-up blocker on by default plus an ActiveX opt-in framework and a Local Machine Zone lockdown. Security Center became the first centralized Control Panel surface that aggregated firewall, Automatic Updates, and antivirus state into a single place a non-technical user could understand.&lt;/p&gt;
&lt;p&gt;James Forshaw&apos;s Project Zero retrospective on Windows network access is blunt about how thin the pre-SP2 firewall story was [@s-forshaw-projectzero-wfp]. The Internet Connection Firewall in XP RTM was technically present, but it was off by default, scoped to the Internet-facing interface, and the first thing most OEM imaging scripts disabled.&lt;/p&gt;

Prior to XP SP2 Windows didn&apos;t have a built-in firewall, and you would typically install a third-party firewall such as ZoneAlarm. -- James Forshaw, Google Project Zero [@s-forshaw-projectzero-wfp]
&lt;p&gt;The conceptual move underneath SP2 is the one that matters for the rest of the article. Microsoft did not invent a single new mitigation in SP2. Software firewalls, NX-style memory protection, file-provenance tagging, pop-up blockers, and centralized policy notifications all existed somewhere already in 2003 -- in third-party products, in PaX on Linux, in OpenBSD, in academic research. What SP2 did was take those mitigations off the customer&apos;s optional configuration menu and put them in the default install.&lt;/p&gt;

A security control whose default configuration on a freshly installed or upgraded system is &quot;active,&quot; not &quot;available to be enabled.&quot; On-by-default mitigations reach approximately the entire installed base of a release; opt-in mitigations reach approximately the small fraction of users who actively configure them. The asymmetry is roughly two orders of magnitude in deployment reach, which is the engineering reason XP SP2 was treated as a re-release rather than as a service pack [@s-forshaw-projectzero-wfp].
&lt;p&gt;The &quot;5%/95%&quot; framing is shorthand for the on-by-default-vs-opt-in asymmetry -- a two-orders-of-magnitude reach gap [@s-forshaw-projectzero-wfp] that motivated default-on Firewall, default-on DEP for system binaries, default-on Automatic Updates, and default-on UAC.&lt;/p&gt;
&lt;p&gt;Here is the SP2 bundle as a table. The third column is the load-bearing one: every default-on choice in SP2 came with a real compatibility cost, and the article&apos;s later sections are partly the story of those costs being paid down.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SP2 mitigation&lt;/th&gt;
&lt;th&gt;Attack class broken&lt;/th&gt;
&lt;th&gt;Compatibility cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Windows Firewall on by default&lt;/td&gt;
&lt;td&gt;Worm-style unauthenticated TCP/445, TCP/135 RPC&lt;/td&gt;
&lt;td&gt;Apps binding listening ports without firewall exception manifest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Execution Prevention&lt;/td&gt;
&lt;td&gt;Stack and heap shellcode execution&lt;/td&gt;
&lt;td&gt;First-generation JITs that wrote executable code into RW pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES + Zone.Identifier ADS&lt;/td&gt;
&lt;td&gt;Outlook and IE auto-launch of attachments&lt;/td&gt;
&lt;td&gt;Legitimate self-extracting installers from network shares&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IE6 SP2 hardening&lt;/td&gt;
&lt;td&gt;Drive-by ActiveX install, pop-up ad layers, MIME confusion&lt;/td&gt;
&lt;td&gt;Line-of-business intranet ActiveX apps; legacy webmail pop-ups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Center&lt;/td&gt;
&lt;td&gt;Status invisibility for non-technical users&lt;/td&gt;
&lt;td&gt;Third-party AV vendors objected to display of competing status&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Once the 5%/95% threshold becomes the unit of analysis, the question changes. The question is no longer &quot;what is the best mitigation we could ship?&quot; It is &quot;what mitigation will the user not turn off?&quot; Every Vista feature in the next chapter is an answer to that question -- and every Vista feature that broke compatibility is the price the answer cost.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;XP SP2 reached the broad public via Automatic Updates by late August 2004. By the end of the year Microsoft had pushed the largest single security update in the operating system&apos;s history onto roughly the entire XP installed base. The five mitigations that landed that day deserve their own catalogue.&lt;/p&gt;
&lt;h2&gt;4. The XP SP2 Mitigation Catalogue&lt;/h2&gt;
&lt;p&gt;XP SP2 shipped on August 6, 2004 and reached the broad public via Automatic Updates by late August. The five mitigations below are not equally famous, but they are equally load-bearing for what came next in Vista. Each subsection opens with what the mitigation broke (the attack class) and ends with what it broke (the compatibility cost).&lt;/p&gt;
&lt;h3&gt;4.1 Windows Firewall on by default&lt;/h3&gt;
&lt;p&gt;Pre-SP2, XP had something called the Internet Connection Firewall. It was off by default; it bound only to the interface flagged as the Internet connection during setup; and any application that wanted a listening port could simply listen on a different interface and never trigger it. The Blaster window -- the moment between a fresh XP installing on a network and Automatic Updates pulling MS03-026 -- was open for as long as DHCP plus the first reboot took, which on a 2003-era cable modem was about ninety seconds. Welchia exploited the same window in reverse.&lt;/p&gt;
&lt;p&gt;The fix in SP2 was structural. The renamed Windows Firewall came on by default on every interface, was active during the boot sequence (before user-mode services finished initialising), and ran during a brief boot-time stateful inspection window before the regular policy engine took over [@s-forshaw-projectzero-wfp].&lt;/p&gt;
&lt;p&gt;What this broke for compatibility: every legitimate application that bound a listening port without registering a firewall exception manifest. Domain join, the older SMB RPC paths, and a long list of corporate management tools needed exception entries pushed via Group Policy before they would work on freshly joined SP2 machines. The forward link is to Vista&apos;s Windows Filtering Platform in section 6.6, which gave third-party firewalls and IDS/IPS vendors a supported extension surface instead of forcing them to keep hooking NDIS.&lt;/p&gt;
&lt;h3&gt;4.2 Data Execution Prevention&lt;/h3&gt;
&lt;p&gt;Data Execution Prevention is the Windows trade name for refusing to execute instructions from pages marked as data. Hardware-enforced DEP uses the AMD NX bit (&quot;No-eXecute&quot;) or the Intel XD bit (&quot;eXecute Disable&quot;), both shipped in commodity x86 silicon by 2004 -- the AMD64 Athlon 64 launched with the NX bit on September 23, 2003 [@s-wp-athlon-64], and Intel followed with XD on the Prescott Pentium 4 stepping in mid-2004.&lt;/p&gt;
&lt;p&gt;Software-enforced DEP on CPUs without the bit relied on SafeSEH-based exception-handler validation, which closed the most common shellcode-staging pattern of the era (overwrite a saved exception handler on the stack, trigger an exception, jump into shellcode) without actually marking pages non-executable [@s-msft-sehop-kb956607]. SP2 introduced four configurations -- &lt;code&gt;OptIn&lt;/code&gt;, &lt;code&gt;OptOut&lt;/code&gt;, &lt;code&gt;AlwaysOn&lt;/code&gt;, &lt;code&gt;AlwaysOff&lt;/code&gt; -- selectable via &lt;code&gt;boot.ini&lt;/code&gt; and later via BCD; the default on consumer XP was &lt;code&gt;OptIn&lt;/code&gt; (system DLLs only) [@s-windows-internals-5e].&lt;/p&gt;

A defense that refuses to fetch and execute instructions from memory pages whose protection bits mark them as non-executable. Hardware-enforced DEP uses the NX page-table bit on x86 / x64 silicon (AMD&apos;s branding) or the XD bit (Intel&apos;s branding). Software-enforced DEP without the page bit relies on safe exception handlers (SafeSEH) to close the dominant stack-overflow exploitation pattern [@s-msft-sehop-kb956607]. Shipped in XP SP2 in August 2004 and refined repeatedly through Windows 10 [@s-windows-internals-5e].

A single bit in an x86 / x64 page table entry that, when set, instructs the CPU to fault on an instruction fetch from that page. AMD&apos;s name is NX (No-eXecute) and shipped first in 2003 on the Opteron; Intel&apos;s equivalent is XD (eXecute Disable). The bit is the hardware substrate for DEP and for the W^X (Write XOR Execute) memory policy that OpenBSD and PaX had pioneered earlier in the decade [@s-pax-aslr-live, @s-openbsd-3-4-wayback].
&lt;p&gt;The academic prior art is older than DEP by six years. Crispin Cowan&apos;s StackGuard paper at the 7th USENIX Security Symposium in January 1998 [@s-cowan-stackguard] introduced the canary-based stack-overflow detector that the Visual C++ &lt;code&gt;/GS&lt;/code&gt; flag adopted in 2002 with Visual Studio .NET [@s-msft-gs-buffer-security-check, @s-wp-vs] and that DEP complemented rather than replaced. On the Linux side, the PaX project had shipped W^X plus mmap-base randomization in 2003 [@s-pax-aslr-live, @s-pax-docs-index]. OpenBSD 3.4, released on November 1, 2003, was the first general-purpose operating system to ship integrated W^X plus library-load-order randomization default-on [@s-openbsd-3-4-wayback]. Vista&apos;s ASLR three years later was, by mainstream-OS standards, late.&lt;/p&gt;
&lt;p&gt;The DEP-versus-JIT compatibility breakage is the canonical &quot;good security default that breaks shipping software&quot; story of the SP2 era. JavaScript engines, Java, .NET, and Flash all generated executable code into RW pages at runtime and ran headlong into DEP&apos;s first-generation policy. The modern fix is the explicit &lt;code&gt;VirtualProtect&lt;/code&gt; transition (RW into RX and back) that every JIT now uses, but the engineering took years to converge across vendors. The next pass through the same problem -- W^X enforced by CPU mode in Apple silicon -- finally made the explicit-transition pattern a first-class API.&lt;/p&gt;
&lt;h3&gt;4.3 Attachment Execution Service and the Zone.Identifier ADS&lt;/h3&gt;
&lt;p&gt;This is the subsection that most retellings of XP SP2 get backwards. The &lt;a href=&quot;https://paragmali.com/blog/mark-of-the-web-smartscreen-catalog-of-trust/&quot; rel=&quot;noopener&quot;&gt;Mark-of-the-Web&lt;/a&gt; -- the HTML comment of the form &lt;code&gt;&amp;lt;!-- saved from url=... --&amp;gt;&lt;/code&gt; that Internet Explorer reads on a saved web page to decide which security zone to apply -- did not ship with SP2. It shipped two years earlier in Internet Explorer 6 Service Pack 1 in 2002.&lt;/p&gt;
&lt;p&gt;What SP2 added is the Attachment Execution Service: the system-wide enforcement substrate that, when a file arrives via Outlook, Outlook Express, Internet Explorer, Windows Messenger, or any caller of the &lt;code&gt;IAttachmentExecute&lt;/code&gt; shell API [@s-msft-iattachmentexecute], writes a &lt;code&gt;Zone.Identifier&lt;/code&gt; NTFS Alternate Data Stream tagging the file with its originating security zone.&lt;/p&gt;

The XP SP2 shell service that, on attachment download from a recognised zone-aware caller (Outlook, IE, Messenger, the `IAttachmentExecute` API [@s-msft-iattachmentexecute]), writes a `Zone.Identifier` NTFS Alternate Data Stream tagging the file with its originating zone (Internet, Restricted, Trusted, Local Intranet). AES is the system-wide enforcement substrate that materialised the existing Mark-of-the-Web concept into a persistent file-system record the Shell consults at execute time. Substrate, not ancestor.

An NTFS Alternate Data Stream named `Zone.Identifier`, attached to a file by the Attachment Execution Service or its callers. The ADS body is a small INI file with a `[ZoneTransfer]` section whose `ZoneId` value (3 for Internet, 4 for Restricted, 2 for Trusted, 1 for Local Intranet, 0 for Local Machine) the Shell reads on execute attempts. The ADS persists with the file across copies on NTFS volumes; copying to FAT32 or onto a non-NTFS share strips it -- which is why USB sticks and consumer file-sharing services have historically been laundering paths for web-originated executables.
&lt;p&gt;{&lt;code&gt; // Illustrative parser. The real call is to CreateFileW on a path of // the form &quot;C:\\\\downloads\\\\foo.exe:Zone.Identifier&quot;, reading the // resulting stream as a tiny INI file. const adsContent = [   &quot;[ZoneTransfer]&quot;,   &quot;ZoneId=3&quot;,   &quot;ReferrerUrl=example.com/&quot;,   &quot;HostUrl=example.com/downloads/foo.exe&quot;, ].join(&quot;\\n&quot;); const zoneNames = { 0: &quot;Local Machine&quot;, 1: &quot;Local Intranet&quot;,                     2: &quot;Trusted&quot;, 3: &quot;Internet&quot;, 4: &quot;Restricted&quot; }; const lines = adsContent.split(&quot;\\n&quot;); const kv = Object.fromEntries(   lines.filter(l =&amp;gt; l.includes(&quot;=&quot;)).map(l =&amp;gt; l.split(&quot;=&quot;))); const zone = parseInt(kv.ZoneId, 10); console.log(\&lt;/code&gt;File originated from zone ${zone} (${zoneNames[zone]})`);
console.log(`Referrer: ${kv.ReferrerUrl}`);
`}&lt;/p&gt;
&lt;p&gt;The architectural property the substrate produces is the one downstream tools cannot live without. Office Protected View opens with restricted privileges precisely when the document&apos;s Zone.Identifier reports Internet origin. SmartScreen warns on first execute of any binary whose ADS says Internet. Microsoft Defender Application Control treats Zone.Identifier as a first-class file attribute in its policy language. None of those tools would work the way they do if AES had not made the zone tag a persistent file-system property in 2004.&lt;/p&gt;
&lt;h3&gt;4.4 Internet Explorer 6 SP2 hardening&lt;/h3&gt;
&lt;p&gt;The IE6 SP2 hardening pass is the largest browser security delta in any service-pack-era Windows update before or since. The pop-up blocker on by default plus the Information Bar gave the browser a way to defer execution of script-launched popups behind an explicit user click. MIME-handling lockdown closed the MIME-sniffing attacks the Outlook MHTML class had enabled (an attacker could serve a binary as &lt;code&gt;Content-Type: text/plain&lt;/code&gt; and have IE sniff and execute it anyway).&lt;/p&gt;
&lt;p&gt;The Local Machine Zone lockdown blocked script execution from the LMZ by default for IE-rendered documents, closing the cross-zone elevation path that several earlier IE vulnerabilities had taught attackers to chain through &lt;code&gt;mhtml:&lt;/code&gt; and &lt;code&gt;file://&lt;/code&gt; URL tricks. The ActiveX opt-in framework required user confirmation before any controls were installed from the Internet. The compatibility cost was real and immediate: legitimate ActiveX line-of-business intranet apps, legacy webmail pop-ups, and corporate intranet portals all required exemption configuration before they would keep working as before.&lt;/p&gt;
&lt;h3&gt;4.5 Security Center&lt;/h3&gt;
&lt;p&gt;Security Center is easy to underestimate because its UI looked like a Control Panel applet. It was the first centralised surface that aggregated three previously invisible state signals -- firewall status, Automatic Updates status, antivirus status (presence, definitions currency, real-time protection enabled) -- into a single interface a non-technical user could read.&lt;/p&gt;
&lt;p&gt;The balloon-tip notification UI surfaced negative states aggressively; the visible degradation was the entire point. The third-party AV vendors -- Symantec and McAfee in particular -- objected publicly to Microsoft&apos;s display of competing status, and the resulting friction previewed the 2009 European Union agreement that constrained Microsoft&apos;s default-bundled-AV options for the rest of the era.&lt;/p&gt;
&lt;p&gt;Three of these five mitigations made it into Vista substantially unchanged. Two of them -- the firewall and the ADS-based zone tagging -- were re-architected because Vista&apos;s threat model went past the application-on-the-network and into the application-on-the-desktop. To see why, we have to leave XP behind and walk year by year through what happened next.&lt;/p&gt;
&lt;h2&gt;5. Year by Year, 2005 Through 2009&lt;/h2&gt;
&lt;p&gt;If XP SP2 was the proof of concept for on-by-default mitigations, the next four years were the proof of work. Microsoft was shipping kernel self-protection, anti-exploit defenses, and the first real attempt at a privilege model the consumer would actually use. The security research community was learning faster than the shipping cadence could absorb. Two industry coordination moments and one wormable RCE close the period.&lt;/p&gt;

gantt
    dateFormat YYYY-MM-DD
    axisFormat %b %Y
    section Memos and process
    Trustworthy Computing memo :a1, 2002-01-15, 7d
    Security stand-down :a2, 2002-02-01, 60d
    SDL mandated at Microsoft :a3, 2004-09-01, 120d
    Mojave Experiment :a4, 2008-07-01, 30d
    section Windows releases
    XP SP2 :b1, 2004-08-06, 90d
    XP x64 and Server 2003 x64 :b2, 2005-04-25, 30d
    Vista RTM :b3, 2006-11-08, 14d
    Vista consumer GA :b4, 2007-01-30, 14d
    Vista SP1 RTM :b5, 2008-02-04, 14d
    Vista SP1 GA :b6, 2008-03-18, 14d
    Windows 7 RTM :b7, 2009-07-22, 14d
    Windows 7 GA :b8, 2009-10-22, 14d
    section Attacks
    Blaster :c1, 2003-08-11, 30d
    Welchia :c2, 2003-08-18, 30d
    Sasser :c3, 2004-04-30, 30d
    MS08-067 out-of-band patch :c4, 2008-10-23, 7d
    Conficker.A first detected :c5, 2008-11-20, 30d
    Conficker.C DGA expansion :c6, 2009-03-04, 30d
    section Research
    Cowan StackGuard USENIX :d1, 1998-01-26, 7d
    PaX ASLR design doc :d2, 2003-03-15, 7d
    OpenBSD 3.4 W^X plus library randomization :d3, 2003-11-01, 7d
    Shacham et al CCS 2004 ASLR analysis :d4, 2004-10-25, 7d
    Hoglund and Butler Rootkits book :d5, 2005-06-01, 7d
    skape and Skywing Uninformed Vol 3 :d6, 2005-12-01, 7d
    Symantec McAfee public PatchGuard objection :d7, 2006-10-01, 30d
    Ferguson BitLocker whitepaper :d8, 2006-08-01, 30d
    Shacham ROP CCS 2007 :d9, 2007-10-29, 7d
    Halderman cold-boot USENIX 2008 :d10, 2008-07-28, 7d
    Conficker Working Group forms :d11, 2009-02-12, 14d
    CWG Lessons Learned final :d12, 2010-06-17, 7d
&lt;h3&gt;5.1 April 2005: XP Professional x64 Edition and Server 2003 x64&lt;/h3&gt;
&lt;p&gt;Windows XP Professional x64 Edition and Windows Server 2003 x64 Edition were the first Windows releases to ship &lt;a href=&quot;https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/&quot; rel=&quot;noopener&quot;&gt;Kernel Patch Protection&lt;/a&gt; -- the kernel self-defense mechanism widely known as PatchGuard. The common version of the story moves PatchGuard&apos;s debut to Vista by twenty months. It did not debut on Vista.&lt;/p&gt;
&lt;p&gt;Microsoft Security Advisory 932596 (published August 14, 2007, updated April 23, 2008) is unambiguous: &quot;An update is available for Kernel Patch Protection included with x64-based Windows operating systems&quot; [@s-msft-adv-932596]. The x64-based qualifier is load-bearing. Vista x64 inherited PatchGuard v2 in November 2006; Vista SP1 x64 shipped v3 in February 2008. The x86 editions of Vista never got PatchGuard.&lt;/p&gt;

Microsoft&apos;s kernel-mode self-protection feature on x64 Windows. PatchGuard periodically verifies the integrity of a fixed list of kernel data structures (SSDT, IDT, GDT, MSRs, system images, the kernel&apos;s own code pages) and bug-checks the system on detected modification. Shipped first in April 2005 in Windows XP Professional x64 Edition and Windows Server 2003 x64 Edition. Vista x64 inherited it (v2 in Vista RTM, v3 in Vista SP1). Vista did NOT introduce PatchGuard [@s-msft-adv-932596].
&lt;p&gt;The architectural target of PatchGuard is the 2003-era rootkit class catalogued in Hoglund and Butler&apos;s &lt;em&gt;Rootkits: Subverting the Windows Kernel&lt;/em&gt; (Addison-Wesley, 2005) [@s-hoglund-butler-rootkits]: SSDT hooks, IDT hooks, inline patches of function prologues, modifications to the System Service Descriptor Table, manipulation of the Object Manager&apos;s namespace. The same April 2005 release also introduced advisory (warnings, not enforcement) kernel-mode driver signing. Mandatory kernel-mode driver signing arrived with Vista x64 a year and a half later [@s-msft-driver-signing].&lt;/p&gt;
&lt;h3&gt;5.2 October 2006: Symantec and McAfee object to PatchGuard in public&lt;/h3&gt;
&lt;p&gt;The first major public clash between kernel self-defense and the kernel-extension model that the antivirus industry had built businesses on came in October 2006, weeks before Vista RTM. Symantec and McAfee both took the position that PatchGuard would make their products materially less effective by closing off the kernel-mode hooking patterns their behavioural detection engines depended on [@s-wp-kpp].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response was to formalise the existing &lt;code&gt;Cm&lt;/code&gt;, &lt;code&gt;Ob&lt;/code&gt;, and &lt;code&gt;Ps&lt;/code&gt; notification routines (registry, object-manager, and process callbacks) and the Filter Manager and Windows Filtering Platform callout architectures as supported extension surfaces. The pattern -- a kernel-integrity feature pressed up against existing AV business models, followed by a published callback API that gives the AV industry a supported path -- recurs with Driver Signature Enforcement in Vista x64, with Early Launch Antimalware in Windows 8, with HVCI in Windows 10 and 11, and with the Microsoft Vulnerable Driver Block list rollout from 2020 onward.&lt;/p&gt;
&lt;h3&gt;5.3 December 1, 2005: skape and Skywing&apos;s &quot;Bypassing PatchGuard on Windows x64&quot;&lt;/h3&gt;
&lt;p&gt;In December 2005, eight months after PatchGuard&apos;s debut, skape (Matt Miller) and Skywing (Ken Johnson) published &quot;Bypassing PatchGuard on Windows x64&quot; in &lt;em&gt;Uninformed&lt;/em&gt; Vol. 3 [@s-skape-skywing-patchguard]. The paper is widely mis-cited: it is dated December 1, 2005 (the &lt;em&gt;Uninformed&lt;/em&gt; volume publication is January 2006); it is co-authored, not single-authored; it has no subtitle. Upstream secondary references occasionally attribute the paper to Skywing alone with a July 2006 date and the subtitle &quot;Bypassing Kernel Patch Protection on Windows x64.&quot; The corrected metadata is what the article uses.&lt;/p&gt;

The structural observation that any defense which runs at a given privilege level cannot fundamentally constrain an attacker who also runs at that privilege level. PatchGuard runs at ring 0; rootkits run at ring 0; therefore PatchGuard is bypassable in principle from a sufficiently privileged kernel-mode attacker. skape and Skywing&apos;s December 2005 *Uninformed* paper demonstrated three concrete bypass technique classes [@s-skape-skywing-patchguard]. The genuine architectural fix waits for hypervisor-protected mechanisms (HVCI in Windows 10 Anniversary Update, August 2016; VBS and Pluton in Windows 11) that run the integrity verifier from a more privileged execution mode than the attacker.

Any defense that runs at the same privilege level as the attacker is fundamentally bypassable. -- paraphrased from the load-bearing conclusion of skape and Skywing, *Uninformed* Vol. 3, December 1, 2005 [@s-skape-skywing-patchguard]
&lt;h3&gt;5.4 November 8, 2006: Vista RTM&lt;/h3&gt;
&lt;p&gt;Windows Vista released to manufacturing on November 8, 2006. Volume-license availability via the Microsoft Volume Licensing portal began &quot;sometime before Nov. 30, 2006&quot; per the same-day Computerworld press-conference coverage [@s-lai-computerworld-vista-rtm]. Consumer general availability was January 30, 2007. Keep these as three distinct dates: the gap between RTM and consumer GA is where most enterprise IT departments tested compatibility, and where the volume-license customers who later complained loudest about Vista actually first encountered it.&lt;/p&gt;
&lt;h3&gt;5.5 January 30, 2007: Vista consumer GA and the reception&lt;/h3&gt;
&lt;p&gt;The pivot from technical release to cultural event happened in the first six months of 2007. Apple&apos;s &quot;Get a Mac&quot; television-spot series ran &quot;Security&quot; and &quot;Cancel or Allow&quot; through the summer, dramatizing UAC prompt fatigue for a mass audience [@s-wp-get-a-mac].&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Kelley v. Microsoft Corp.&lt;/em&gt; lawsuit (No. 2:07-cv-00475-MJP, W.D. Wash.) was filed on March 29, 2007 and certified as a class action in February 2008 [@s-cw-vista-capable-class], alleging that Microsoft had marketed machines as &quot;Vista Capable&quot; that could only run Home Basic without the Aero compositor or many of the security features the launch had highlighted. The Mojave Experiment in July 2008 -- Microsoft showing Vista to focus groups under a different name and getting positive reactions -- was the era&apos;s confession that the perceptual layer mattered as much as the architectural layer [@s-msft-mojave-experiment, @s-wp-mojave-experiment].&lt;/p&gt;
&lt;p&gt;The Vista Capable case is &lt;em&gt;Kelley v. Microsoft Corp.&lt;/em&gt;, No. 2:07-cv-00475-MJP, W.D. Wash., filed March 29, 2007 and certified February 22, 2008 [@s-cw-vista-capable-class]. Coverage that condenses the timeline to &quot;Vista launched and was sued&quot; tends to misstate the filing month as April or May.&lt;/p&gt;
&lt;p&gt;Was Vista the most-hated Windows release? Windows ME and Windows 8 have competing claims, and any honest treatment needs to acknowledge them. Call Vista one of the most poorly received Windows consumer releases of its era. The reception was uniquely consequential -- the SP1-era enterprise inertia, the consumer skipping that left a large XP-to-7 leap, and the marketing problem Windows 7&apos;s launch had to solve. The substantive argument does not depend on the superlative.&lt;/p&gt;
&lt;h3&gt;5.6 February 4, 2008: Vista SP1 RTM&lt;/h3&gt;
&lt;p&gt;Vista Service Pack 1 released to manufacturing on February 4, 2008, with broad availability starting March 18, 2008 [@s-msft-news-vista-sp1-rtm]. This is the &quot;real Vista&quot; enterprise IT deployed. PatchGuard v3 shipped with SP1. The file-copy engine got the performance fix that Vista&apos;s reviewers had spent a year complaining about. Windows Search was refactored to reduce IO contention with foreground work. A set of compatibility shims relaxed UAC on several common operations that had been hitting too many false-positive prompts.&lt;/p&gt;
&lt;p&gt;Vista SP1 RTM is February 4, 2008 (build 6001.18000); broad GA is March 18, 2008 [@s-msft-news-vista-sp1-rtm]. Upstream summaries sometimes mis-state the RTM as November 2007 -- that date is actually the SP1 Release Candidate 1 milestone, not RTM.&lt;/p&gt;
&lt;h3&gt;5.7 October 23, 2008: MS08-067 out-of-band&lt;/h3&gt;
&lt;p&gt;The vulnerability behind MS08-067 is a stack buffer overflow in the path-handling code (the function commonly named &lt;code&gt;NetprPathCanonicalize&lt;/code&gt; in the NetAPI library), reachable through the Server service&apos;s &lt;code&gt;srvsvc&lt;/code&gt; RPC interface over SMB on TCP/445 (and TCP/139 in NetBT environments) without authentication. CVE-2008-4250 [@s-nvd-cve-2008-4250]. The patch is out-of-band because the MSRC analysts who reviewed the bug believed weaponisation was weeks away.&lt;/p&gt;
&lt;p&gt;Vista&apos;s DEP and ASLR materially raised the cost of exploitation on Vista compared to XP -- the bulletin rates the issue Critical on Windows 2000, XP, and Server 2003 but Important on Vista and Server 2008 [@s-ms08-067]. The October 2008 installed base, however, was overwhelmingly Server 2003 and XP. The first in-the-wild MS08-067 exploitation in October 2008 was Gimmiv.A, a narrower non-self-propagating Trojan, per NVD [@s-nvd-cve-2008-4250]. Conficker was three weeks away.&lt;/p&gt;
&lt;h3&gt;5.8 Late November 2008: Conficker.A is first detected&lt;/h3&gt;
&lt;p&gt;Conficker.A was first detected in late November 2008, anchored to November 20, 2008 in SRI International&apos;s &quot;An Analysis of Conficker C&quot; addendum, whose introductory paragraph reads: &quot;Conficker malware family, which first appeared on the Internet on 20 November 2008&quot; [@s-sri-conficker-c-addendum]. The gap from MS08-067 to Conficker.A is approximately twenty-nine days. The October-2008 in-the-wild MS08-067 exploitation was Gimmiv.A; Conficker is a separate, later, much larger event.&lt;/p&gt;
&lt;p&gt;The audit-mandated date correction: Conficker.A first detected in late November 2008, with November 20, 2008 as the canonical SRI anchor [@s-sri-conficker-c-addendum]. The October-2008 in-the-wild MS08-067 exploitation reported in NVD is Gimmiv.A, not Conficker [@s-nvd-cve-2008-4250].&lt;/p&gt;
&lt;h3&gt;5.9 December 2008 through April 2009: Conficker.B, C, E&lt;/h3&gt;
&lt;p&gt;The variant taxonomy matters because it is the evidence base for how quickly the worm&apos;s authors learned, and how the Conficker Working Group&apos;s coordinated defense responded. Conficker.B in late December 2008 added removable-drive autorun spreading, a dictionary attack against weak shares, and a fallback exploit path against the older MS06-040 vulnerability for the small fraction of targets that were still unpatched against it.&lt;/p&gt;
&lt;p&gt;Conficker.A already had a 250-domain-per-day Domain Generation Algorithm; what Conficker.C added on March 4, 2009 at 6 p.m. PST (March 5 UTC) was a 50,000-domain-per-day rendezvous-pool expansion across 110 top-level domains &lt;em&gt;and&lt;/em&gt; a peer-to-peer coordination channel that no longer required successful DNS rendezvous -- two functional additions of the same variant, not two sequential revisions. The SRI &quot;An Analysis of Conficker C&quot; addendum is explicit on this: variant C &quot;incorporates a major restructuring of B&apos;s previous thread architecture and program logic, including major functional additions such as a new peer-to-peer (P2P) coordination channel, and a revision of the domain generation algorithm (DGA)&quot; [@s-sri-conficker-c-addendum]. Conficker.E, in April 2009, added payload-delivery for scareware and the Waledac spam botnet; the in-era variant chain runs A to B to C to E, matching both the SRI primary and the CWG taxonomy.&lt;/p&gt;
&lt;p&gt;Conficker.B&apos;s MS06-040 fallback exploit path was scoped to Windows 2000 targets only -- the older bulletin&apos;s RCE vector did not reach the post-2003 SMB stack the same way. The Conficker Working Group taxonomy is sometimes summarised in ways that imply the MS06-040 fallback was a broader secondary attack vector; it was not.&lt;/p&gt;
&lt;h3&gt;5.10 February 12, 2009: Conficker Working Group and the $250,000 bounty&lt;/h3&gt;
&lt;p&gt;On February 12, 2009 Microsoft posted a US$250,000 bounty for information leading to the arrest and conviction of Conficker&apos;s authors, and the Conficker Working Group formally constituted itself as a coordinated industry response -- Microsoft, ICANN, F-Secure, Symantec, Verisign, Georgia Tech, and roughly 120 other participating organisations [@s-cwg-lessons-learned-2019].&lt;/p&gt;
&lt;p&gt;The CWG&apos;s &quot;Lessons Learned&quot; final report (June 17, 2010) is the canonical post-mortem primary that the rest of this article relies on for variant taxonomy, infection-count framing, and the deployment-velocity-ceiling argument [@s-cwg-lessons-learned-2019]. The 9-to-15-million infected machines figure is the report&apos;s own range; counts varied with measurement methodology and with which Conficker variants the counter included.SRI International&apos;s per-country infection table from the same period shows the geographic distribution: China (about 2.65M observed bots), Brazil (about 1.02M), Russia (about 836K), India (about 607K), Argentina (about 569K) topping the list [@s-sri-conficker-resources]. The distribution tracked installed-base size of unpatched XP and Server 2003 closely.&lt;/p&gt;
&lt;p&gt;Vista shipped on November 8, 2006 and the world made up its mind about the reception by mid-2007. To understand why the architecture survived the reception, we have to look at what the architecture actually was -- feature by feature -- and what each feature defended against.&lt;/p&gt;
&lt;h2&gt;6. The Vista Security Catalogue&lt;/h2&gt;
&lt;p&gt;Open &lt;em&gt;Windows Internals&lt;/em&gt;, 5th edition (Russinovich, Solomon, and Ionescu, Microsoft Press, 2009) [@s-windows-internals-5e] to the security chapter and the table of contents reads like a list of features Microsoft did not have eighteen months earlier. Eight features in particular form the Vista security architecture, not because they were the only changes, but because every other Vista security improvement either depends on one of these or polishes one of these.&lt;/p&gt;
&lt;h3&gt;6.1 The integrity-level stack: UAC, MIC, and UIPI&lt;/h3&gt;
&lt;p&gt;User Account Control is the consumer-visible part. Underneath sit two architectural primitives that do almost all the work: Mandatory Integrity Control and User Interface Privilege Isolation.&lt;/p&gt;
&lt;p&gt;UAC&apos;s split-token model works like this. When an interactive user logs on whose group membership includes Administrators, the Local Security Authority issues two access tokens, not one. The filtered token has Administrators removed (more precisely, marked deny-only) and the high-privilege list stripped down to the standard-user set; the full token retains everything.&lt;/p&gt;
&lt;p&gt;The user session starts running under the filtered token by default. When a program tries to perform an operation that requires the full token -- writing under &lt;code&gt;%ProgramFiles%&lt;/code&gt;, modifying &lt;code&gt;HKLM&lt;/code&gt;, loading a driver -- the Application Information service displays a Secure Desktop consent prompt. On consent, the full token is released for that process only; the rest of the session continues on the filtered token.&lt;/p&gt;

The Vista feature that runs interactive administrator accounts under a filtered standard-user token by default and prompts for explicit consent before releasing the full administrator token to a specific process. The Secure Desktop switch isolates the consent prompt from window-message injection by lower-integrity processes. Russinovich is explicit in the load-bearing primary: elevations were introduced as a convenience, and their existence &quot;prevents OTS elevations from being a security boundary&quot; [@s-russinovich-uac-technet]. The boundary classification arrives much later with Administrator Protection in the 2024 to 2026 Windows 11 era.
&lt;p&gt;Mandatory Integrity Control adds the second axis the discretionary-access-control model never had. Every process token carries an integrity-level SID drawn from a small set -- Untrusted &lt;code&gt;S-1-16-0&lt;/code&gt;, Low &lt;code&gt;S-1-16-4096&lt;/code&gt;, Medium &lt;code&gt;S-1-16-8192&lt;/code&gt;, High &lt;code&gt;S-1-16-12288&lt;/code&gt;, System &lt;code&gt;S-1-16-16384&lt;/code&gt; -- and every securable object carries an integrity-level access control entry indicating the minimum integrity required to write (and optionally read or execute). The kernel&apos;s access check evaluates integrity before the discretionary ACL [@s-msft-mic-win32]. A Low-integrity process holding a handle to a Medium-integrity registry key cannot write to it regardless of what the DACL says.&lt;/p&gt;

Vista&apos;s mandatory-access-control primitive added to the Windows access-check pipeline. MIC attaches an integrity-level SID to every process token and an integrity-level ACE to every securable object, then evaluates the integrity comparison before the discretionary access control list. MIC is the architectural substrate every later Windows containment story (AppContainer, Modern Apps, browser sandbox, Office Protected View, WDAG, VBS) inherits [@s-msft-mic-win32].
&lt;p&gt;User Interface Privilege Isolation closes the third class of cross-integrity attack: window-message injection. Before UIPI, any process in the same desktop could send window messages (SendMessage, PostMessage, WM_TIMER, SetWindowsHookEx) to any other process&apos;s windows, including elevated ones. Chris Paget&apos;s 2002 &quot;shatter attack&quot; paper had walked through the attack surface methodically. UIPI prevents a lower-integrity process from sending most messages to higher-integrity windows; the Secure Desktop completes the closure for the consent UI itself by drawing it on a separate desktop the user-session processes cannot reach.&lt;/p&gt;

Vista&apos;s mechanism preventing lower-integrity processes from sending window messages (SendMessage, PostMessage, SetWindowsHookEx, WM_TIMER, etc.) to higher-integrity windows on the same desktop. Closes the shatter-attack class documented by Chris Paget in 2002. Together with the Secure Desktop, UIPI is the closure that makes the UAC consent prompt actually resistant to programmatic dismissal from a malware process running in the same user session.

flowchart TD
    A[Interactive logon as Administrator] --&amp;gt; B[LSA splits token]
    B --&amp;gt; C[Filtered standard-user token]
    B --&amp;gt; D[Full administrator token held aside]
    C --&amp;gt; E[User session starts under filtered token]
    E --&amp;gt; F[Program requests admin operation]
    F --&amp;gt; G[Application Information service intercepts]
    G --&amp;gt; H[Secure Desktop switch]
    H --&amp;gt; I[UAC consent prompt]
    I --&amp;gt; J{&quot;Consent?&quot;}
    J -- Yes --&amp;gt; K[Full token released to this process only]
    J -- No --&amp;gt; L[Operation denied]
    K --&amp;gt; M[Process runs at High integrity]
    L --&amp;gt; E
&lt;p&gt;Russinovich&apos;s &quot;Inside Windows Vista User Account Control&quot; in &lt;em&gt;TechNet Magazine&lt;/em&gt; June 2007 is the canonical primary on design intent [@s-russinovich-uac-technet]; a separate Mark&apos;s-Blog post dated February 12, 2007 anchored the multi-part TechNet &lt;em&gt;blog&lt;/em&gt; series on PsExec and the restricted-token discussion [@s-russinovich-psexec-blog]. The two are distinct primaries and the article does not conflate them.&lt;/p&gt;
&lt;p&gt;The TechNet Magazine UAC article is a single standalone piece at asset id &lt;code&gt;cc138019&lt;/code&gt; [@s-russinovich-uac-technet]. There is a separately numbered Magazine asset at &lt;code&gt;cc162493&lt;/code&gt; that is sometimes mis-cited as &quot;Part 2&quot; of the UAC series; live fetches of that URL return an unrelated Raymond Chen column. The article cites &lt;code&gt;cc138019&lt;/code&gt; only and treats the February 12, 2007 blog post as the start of the distinct multi-part blog series.&lt;/p&gt;
&lt;h3&gt;6.2 Anti-exploit mitigations: ASLR and Vista-era DEP refinements&lt;/h3&gt;
&lt;p&gt;Vista is the first Windows release to ship Address Space Layout Randomization. Vista&apos;s ASLR randomizes the load address of system DLLs and of executables linked with &lt;code&gt;/DYNAMICBASE&lt;/code&gt;; it is opt-in for user code. Mandatory ASLR for all images is a later-Windows feature, with Force ASLR appearing in EMET and in Windows 8, and full enforcement landing in Windows 10. The randomization is per-boot for system images and per-process-load for user images. Entropy on x86 is roughly 8 bits (256 possible base addresses), and considerably more on x64.&lt;/p&gt;

A defense that randomizes the base addresses of executable images, libraries, the stack, and the heap so attackers cannot predict the location of useful code or data. Vista (January 2007) was the first Windows release to ship ASLR; Vista&apos;s implementation randomized system DLLs and `/DYNAMICBASE`-linked user images, with per-boot randomization for system images and per-process-load randomization for user images. The Linux-side prior art is PaX [@s-pax-aslr-live, @s-pax-docs-index], and OpenBSD 3.4 (November 1, 2003) was the first general-purpose OS to ship integrated W^X plus library-load-order randomization default-on [@s-openbsd-3-4-wayback]. The brute-force entropy bound is the Shacham et al. CCS 2004 result [@s-shacham-asrandom-ccs2004].
&lt;p&gt;The Shacham et al. CCS 2004 paper showed that 8 bits of ASLR entropy yields an expected $2^{7} = 128$ attempts to brute-force the base on a target process that respawns after crash [@s-shacham-asrandom-ccs2004]. The result is why x64 ASLR (with substantially more bits of entropy) is qualitatively different and why Force ASLR in Windows 8 was a categorical improvement over Vista&apos;s opt-in model.&lt;/p&gt;
&lt;p&gt;The DEP refinements in Vista are mostly about loader cooperation. Vista&apos;s PE loader respects the &lt;code&gt;IMAGE_DLLCHARACTERISTICS_NX_COMPAT&lt;/code&gt; flag, so binaries that opt in to DEP get the policy applied without per-process configuration. SEHOP (Structured Exception Handler Overwrite Protection) precursor work also lands.&lt;/p&gt;
&lt;p&gt;Three years later, Hovav Shacham&apos;s CCS 2007 paper on Return-Oriented Programming will show that DEP alone is necessary but not sufficient: an attacker who cannot inject and execute new code can still chain together existing executable-code &quot;gadgets&quot; from already-loaded modules to construct functional payloads [@s-shacham-rop-geometry-ccs2007]. That insight is what drives the next generation of Windows mitigations -- &lt;a href=&quot;https://paragmali.com/blog/control-flow-integrity-on-windows-cfg-xfg-and-the-cet-shadow/&quot; rel=&quot;noopener&quot;&gt;CFG, CET&lt;/a&gt;, /GUARD:EH -- but those are out of era.&lt;/p&gt;
&lt;h3&gt;6.3 Kernel self-protection on x64: inherited PatchGuard, new mandatory KMCS&lt;/h3&gt;
&lt;p&gt;Vista did not introduce PatchGuard; it inherited the April 2005 x64 mechanism. What Vista x64 did introduce is &lt;em&gt;mandatory&lt;/em&gt; kernel-mode driver signing. Unsigned drivers do not load on Vista x64 under the Kernel-Mode Code Signing policy.&lt;/p&gt;
&lt;p&gt;The documented escape hatch for development is &lt;code&gt;bcdedit /set testsigning on&lt;/code&gt;, which causes the boot loader to honour test-signing-rooted certificates and which displays a permanent desktop watermark to make the state of the machine visible. Together with the inherited PatchGuard, the combination foreclosed the dominant 2003-era rootkit installation path: drop a &lt;code&gt;.sys&lt;/code&gt;, register it via SCM, kernel loads it with no signature check, kernel hooks become trivial [@s-msft-driver-signing].&lt;/p&gt;

The Vista x64 policy that refuses to load kernel-mode drivers unless they carry a digital signature rooted in a Microsoft-trusted certificate chain (Microsoft WHQL, a cross-certified third-party CA, or a Microsoft Hardware certificate). `bcdedit /set testsigning on` is the documented development-time escape hatch. Vista x86 never received mandatory KMCS, which is one of the structural reasons x64 became the dominant Windows architecture during the next decade [@s-msft-driver-signing].
&lt;p&gt;x86 Vista did not get mandatory KMCS, because the installed-base compatibility cost was deemed too high; the x86 / x64 asymmetry is one reason x64 became the dominant Windows architecture by 2010. The post-2010 afterlife is &quot;Bring Your Own Vulnerable Driver&quot; attacks: KMCS forecloses unsigned drivers but does not address the case of a legitimately signed driver containing a vulnerability the attacker exploits to gain kernel-mode code execution. BYOVD became the dominant rootkit-loading path from approximately 2010 onward, and the Microsoft Vulnerable Driver Block list (2020 onward) is the architectural response.&lt;/p&gt;

The post-KMCS attack pattern in which an attacker installs a legitimately signed kernel-mode driver that contains an exploitable vulnerability, then exploits the driver to gain ring-0 code execution. KMCS forecloses the unsigned-driver path but does not prevent loading of signed drivers, so attackers brought their own. Architectural closure waits for the Microsoft Vulnerable Driver Block list and Hypervisor-Protected Code Integrity, both of which post-date this article&apos;s era.
&lt;h3&gt;6.4 Service Hardening&lt;/h3&gt;
&lt;p&gt;Service Hardening is the Vista feature that most reduced the blast radius of a service-level exploit even when exploitation succeeded. Three changes did the work. Per-service SIDs of the form &lt;code&gt;NT SERVICE\&amp;lt;servicename&amp;gt;&lt;/code&gt; give every service a distinct security principal -- the previous model was that every service running as &lt;code&gt;LocalSystem&lt;/code&gt; shared the same identity.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NT AUTHORITY\WRITE RESTRICTED&lt;/code&gt; tokens constrain a service to writing only to resources whose DACL explicitly grants its per-service SID, even when the service token nominally has higher privileges. Minimum-privilege configuration replaces the historical &lt;code&gt;LocalSystem&lt;/code&gt; superset; the SCM lets services declare exactly which privileges they require. And Windows Firewall rules can be authored per-service-SID, so a compromised service can be blocked from reaching the network even if the rest of the box can. The print primary is &lt;em&gt;Windows Internals&lt;/em&gt;, 5th edition (Russinovich, Solomon, Ionescu, Microsoft Press, 2009) [@s-windows-internals-5e].&lt;/p&gt;

A security identifier of the form `NT SERVICE\` distinct to each Windows service, automatically derived from the service short name. Per-service SIDs are the primitive that lets a host firewall rule, a `WRITE RESTRICTED` token policy, or a registry-key DACL constrain a single service without affecting any other service in the same `svchost.exe` process or any other principal sharing the same logon SID.
&lt;h3&gt;6.5 Windows Resource Protection&lt;/h3&gt;
&lt;p&gt;Windows Resource Protection replaces Windows File Protection (the Windows 2000-era SFC mechanism), whose model was &quot;the OS keeps a hidden catalog of canonical copies and silently replaces tampered system files.&quot; WRP is ACL-based instead. Protected files and registry keys are owned by the &lt;code&gt;TrustedInstaller&lt;/code&gt; SID; the DACL grants modify rights only to &lt;code&gt;TrustedInstaller&lt;/code&gt;. Administrators retain read access and can take ownership, but they cannot modify protected resources directly without that ownership transfer. The protection extends to registry keys, which WFP/SFC did not cover [@s-windows-internals-5e].&lt;/p&gt;

Vista&apos;s replacement for the Windows 2000 to XP-era Windows File Protection / SFC catalog-and-replace mechanism. WRP is ACL-based: protected files and registry keys are owned by `TrustedInstaller` and the DACL restricts modify access to `TrustedInstaller` itself; administrators can take ownership but cannot modify protected resources directly without that step. The protection also covers registry keys, which the older WFP did not. Note: the acronym &quot;WFP&quot; in this paragraph (Windows File Protection) is unrelated to the &quot;WFP&quot; (Windows Filtering Platform) in section 6.6.
&lt;h3&gt;6.6 Windows Filtering Platform&lt;/h3&gt;
&lt;p&gt;Vista and Server 2008 replace the prior NDIS-IM, TDI, and firewall-hook stack-extension architecture with the &lt;a href=&quot;https://paragmali.com/blog/windows-filtering-platform-the-kernel-mode-firewall-you-dont/&quot; rel=&quot;noopener&quot;&gt;Windows Filtering Platform&lt;/a&gt;: a kernel-mode framework of filtering layers (transport, network, application-layer enforcement), shims, and callout drivers giving third-party firewalls, IDS/IPS, and content filters a supported extension surface. The Base Filtering Engine in user mode centralises policy. Windows Firewall in Vista and every release thereafter sits on top of WFP.&lt;/p&gt;
&lt;p&gt;Forshaw&apos;s Project Zero post documents the three-tier architecture directly: &quot;MPSSVC converts its ruleset to the lower-level WFP firewall filters and sends them over RPC to the Base Filtering Engine (BFE) service. These filters are then uploaded to the TCP/IP driver (TCPIP.SYS) in the kernel which is where the firewall processing is handled&quot; [@s-forshaw-projectzero-wfp].&lt;/p&gt;

Vista&apos;s kernel-mode replacement for the NDIS-IM, TDI, and firewall-hook stack-extension architecture that prior third-party firewalls had hooked into. WFP exposes filtering layers (transport, network, application-layer enforcement) plus a callout-driver API, with the user-mode Base Filtering Engine centralising policy and the Microsoft Protection Service service translating Windows Firewall rules into WFP filters. Note: the acronym &quot;WFP&quot; in this paragraph (Windows Filtering Platform) is unrelated to the &quot;WFP&quot; (Windows File Protection) in section 6.5; they are two unrelated three-letter abbreviations that happen to share initials [@s-forshaw-projectzero-wfp].

flowchart LR
    A[Windows Firewall policy] --&amp;gt; B[MPSSVC user-mode service]
    B --&amp;gt; C[Base Filtering Engine BFE user mode]
    C --&amp;gt; D[TCPIP.SYS kernel-mode filter]
    E[Third-party firewall or IDS] --&amp;gt; C
    F[Callout drivers] --&amp;gt; D
    D --&amp;gt; G[Network packets in or out]
&lt;h3&gt;6.7 BitLocker Drive Encryption&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/bitlocker-on-windows-architecture-attacks-and-the-limits-of-/&quot; rel=&quot;noopener&quot;&gt;BitLocker&lt;/a&gt; shipped in Windows Vista Enterprise and Ultimate editions on January 30, 2007, and in Windows Server 2008. Protector modes were TPM-only (seal-to-PCR), TPM+PIN, TPM+startup-key, and recovery-key. The cipher was AES-CBC with the Elephant Diffuser, an additional diffusion layer Niels Ferguson designed specifically for the disk-encryption setting and documented in his August 2006 Microsoft whitepaper &quot;AES-CBC + Elephant Diffuser: A Disk Encryption Algorithm for Windows Vista&quot; [@s-ferguson-bitlocker]. The SKU limitation materially constrained deployment reach -- most Vista consumers ran Home Basic or Home Premium, neither of which included BitLocker at all.&lt;/p&gt;

Microsoft&apos;s full-volume encryption feature, first shipped in Windows Vista Enterprise and Ultimate (January 30, 2007) and in Windows Server 2008. Original Vista cipher: AES in CBC mode with Niels Ferguson&apos;s Elephant Diffuser overlay [@s-ferguson-bitlocker]. Protector modes: TPM-only (seal-to-PCR), TPM+PIN, TPM+startup-key, and recovery-key. The Vista release was edition-gated, which limited deployment reach materially across the consumer Vista base.
&lt;p&gt;The era&apos;s load-bearing known weakness for TPM-only mode is the cold-boot attack documented in Halderman et al., &quot;Lest We Remember: Cold Boot Attacks on Encryption Keys,&quot; USENIX Security 2008 [@s-halderman-coldboot-jhalderm]. DRAM remanence after power-off plus low-temperature imaging let an attacker reconstruct AES keys from a system whose disk was seal-to-PCR-decrypted at boot. The architectural answer -- TPM+PIN as the configuration for any threat model that includes physical access -- is the same in 2026 as it was in 2008.&lt;/p&gt;
&lt;h3&gt;6.8 Auxiliary hardening that landed quietly&lt;/h3&gt;
&lt;p&gt;Several Vista security features did not make front-page reviews but matter for the modern stack. Session-0 isolation moved services out of the interactive user session, closing the cross-session shatter attack on services. Protected Processes for DRM media paths became the precursor of PPL (&lt;a href=&quot;https://paragmali.com/blog/protected-process-light-when-the-administrator-isnt-enough/&quot; rel=&quot;noopener&quot;&gt;Protected Process Light&lt;/a&gt;), which is the substrate for LSA Protection and Credential Guard.&lt;/p&gt;
&lt;p&gt;Windows Defender shipped as built-in antimalware (originally GIANT AntiSpyware, which Microsoft acquired in December 2004) [@s-msft-giant-press-2004]. Network Access Protection (NAP) provided the framework for posture-checking machines before allowing network access -- later superseded by conditional access and never broadly deployed. Cryptography Next Generation (CNG) replaced CryptoAPI and is the substrate every modern Windows crypto operation runs on top of. The Volume Shadow Copy refactor enabled Previous Versions in the file Properties dialog.&lt;/p&gt;
&lt;h3&gt;The Vista feature table&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vista feature&lt;/th&gt;
&lt;th&gt;Attack class defended&lt;/th&gt;
&lt;th&gt;Compatibility cost&lt;/th&gt;
&lt;th&gt;Status in 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;UAC + MIC + UIPI&lt;/td&gt;
&lt;td&gt;Cross-integrity write, cross-integrity UI injection&lt;/td&gt;
&lt;td&gt;Prompt fatigue; admin scripts requiring elevation&lt;/td&gt;
&lt;td&gt;ACTIVE (MIC is the substrate of every modern Windows sandbox)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASLR + DEP refinements&lt;/td&gt;
&lt;td&gt;Predictable-address shellcode, stack/heap execution&lt;/td&gt;
&lt;td&gt;JIT compilers; non-DYNAMICBASE third-party DLLs&lt;/td&gt;
&lt;td&gt;ACTIVE (Force ASLR mandatory in Windows 10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inherited PatchGuard + mandatory x64 KMCS&lt;/td&gt;
&lt;td&gt;Unsigned-driver rootkits, kernel inline patching&lt;/td&gt;
&lt;td&gt;x86/x64 split; test-signing escape hatch&lt;/td&gt;
&lt;td&gt;ACTIVE (BYOVD response is post-era; HVCI in Win 10 Anniversary)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service Hardening&lt;/td&gt;
&lt;td&gt;Service-exploit blast radius&lt;/td&gt;
&lt;td&gt;LocalSystem-assuming legacy services&lt;/td&gt;
&lt;td&gt;ACTIVE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Resource Protection&lt;/td&gt;
&lt;td&gt;Direct overwrite of OS files and registry&lt;/td&gt;
&lt;td&gt;Administrators cannot directly modify system files&lt;/td&gt;
&lt;td&gt;ACTIVE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Filtering Platform&lt;/td&gt;
&lt;td&gt;NDIS hooking, unsupported third-party network filters&lt;/td&gt;
&lt;td&gt;Third-party firewalls and AV had to port to WFP&lt;/td&gt;
&lt;td&gt;ACTIVE (every Windows network filter sits on WFP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BitLocker Drive Encryption&lt;/td&gt;
&lt;td&gt;Data-at-rest exposure on lost / stolen devices&lt;/td&gt;
&lt;td&gt;SKU limited to Enterprise + Ultimate; TPM-only is cold-boot-vulnerable&lt;/td&gt;
&lt;td&gt;ACTIVE (cipher modernised to AES-XTS in Windows 10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session-0 isolation + Protected Processes + Defender + NAP + CNG&lt;/td&gt;
&lt;td&gt;Cross-session shatter on services, weak crypto primitives, etc.&lt;/td&gt;
&lt;td&gt;Service authors had to handle no-interactive-desktop case&lt;/td&gt;
&lt;td&gt;ACTIVE (CNG, Defender); NAP SUPERSEDED-BY conditional access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Eight features. Three audit-mandated corrections. One architectural shift the consumer noticed -- a prompt. The next chapter argues that the prompt the consumer hated is not the breakthrough; the integrity-level stack underneath it is.&lt;/p&gt;
&lt;h2&gt;7. UAC Is the Surface; MIC Is the Substrate&lt;/h2&gt;
&lt;p&gt;Every Vista user remembers the prompt. Almost no Vista user can describe what the prompt was actually a prompt for. The prompt is the consumer-visible surface of the integrity-level stack. The integrity-level stack is the architectural achievement -- the first OS-level Windows mechanism to recognise that the discretionary-access-control model of Cutler-era NT could not express the policy that mattered.&lt;/p&gt;
&lt;p&gt;Recall the integrity-level SIDs from section 6.1, organised as a small table:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Integrity level&lt;/th&gt;
&lt;th&gt;SID&lt;/th&gt;
&lt;th&gt;Operational use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Untrusted&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anonymous, deeply isolated processes (rare in default Windows)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-4096&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sandboxed processes (IE Protected Mode tab, AppContainer in Windows 8+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-8192&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default for normal user processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-12288&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Elevated processes after UAC consent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-1-16-16384&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kernel-mode and the most privileged service hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The argument is this. Discretionary access control could not distinguish &quot;Administrator the user&quot; from &quot;Administrator&apos;s freshly downloaded script&quot; because both ran with the same access token, and a DACL only encodes which principals can perform which operations. MIC can distinguish them.&lt;/p&gt;
&lt;p&gt;The downloaded script runs at Low integrity (web-zone provenance, set by AES and inherited by the spawned process). The user shell runs at Medium or High. The integrity-level check evaluates &lt;em&gt;before&lt;/em&gt; the DAC and blocks the cross-integrity write regardless of what the DAC would have permitted. UIPI then closes the second class of cross-integrity attack -- window-message injection -- so the same Low-integrity process cannot use SendMessage to puppet a Medium-integrity window into doing what its DAC would not allow it to do directly.&lt;/p&gt;
&lt;p&gt;{`
// Illustrative parser. The real PowerShell command is:
//   whoami /groups /priv
// which dumps the SIDs and privileges in the current token. The
// &quot;Mandatory Label\\Medium Mandatory Level&quot; line carries the integrity SID.&lt;/p&gt;
&lt;p&gt;const sampleWhoamiOutput = `
Mandatory Label\\High Mandatory Level     Label            S-1-16-12288
BUILTIN\\Administrators                   Alias            S-1-5-32-544
SeLoadDriverPrivilege                  Load and unload device drivers       Enabled
SeShutdownPrivilege                    Shut down the system                 Enabled
`;
const intLineRe = /Mandatory Label\\\\(Low|Medium|High|System) Mandatory Level\\s+\\S+\\s+(S-1-16-\\d+)/;
const m = sampleWhoamiOutput.match(intLineRe);
const elevatedPrivs = [&quot;SeLoadDriverPrivilege&quot;,&quot;SeTcbPrivilege&quot;,&quot;SeBackupPrivilege&quot;];
const has = p =&amp;gt; sampleWhoamiOutput.includes(p + &quot; &quot;) &amp;amp;&amp;amp; sampleWhoamiOutput.includes(&quot;Enabled&quot;);
if (m) console.log(`Integrity level: ${m[1]} (${m[2]})`);
console.log(&quot;Likely elevated:&quot;, elevatedPrivs.some(has) ? &quot;yes&quot; : &quot;no&quot;);
`}&lt;/p&gt;
&lt;p&gt;Here is what the Aha lands on. Without MIC, every later Windows containment story -- &lt;a href=&quot;https://paragmali.com/blog/appcontainer-and-lowbox-tokens-windowss-capability-sandbox/&quot; rel=&quot;noopener&quot;&gt;AppContainer&lt;/a&gt; (Windows 8 Modern Apps), the Chromium and Edge browser sandboxes, IE Protected Mode, Office Protected View, Adobe Reader&apos;s sandbox, Windows Defender Application Guard, Virtualization-Based Security and Credential Guard -- would have had to invent the per-process trust-level primitive from scratch. Every one of them inherits MIC. The prompt is throwaway; the substrate is permanent. The full integrity-level-stack history through Administrator Protection is traced in the &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Adminless&lt;/a&gt; companion post.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; UAC is the prompt the user saw. MIC is the substrate every later Windows containment story inherits. The Vista security story is not the UI consent flow most reviewers focused on -- it is the integrity-level SID on every process token and the integrity-level ACE on every securable object, evaluated before the DAC, in the access-check pipeline of every Windows release since.&lt;/p&gt;
&lt;/blockquote&gt;

The prompt the consumer hated is not the breakthrough; the integrity-level stack underneath it is.
&lt;p&gt;If Vista&apos;s architecture was right, why was Vista&apos;s reception wrong? The answer is not the prompt. The answer is what the prompt interrupted -- the everyday workflow that, on XP, had been a long-uninterrupted sequence of operations the user did not realise required administrative authority. The next chapter is the polish.&lt;/p&gt;
&lt;h2&gt;8. Windows 7 as the Vista Polish&lt;/h2&gt;
&lt;p&gt;Windows 7 reached general availability on October 22, 2009. Reviews were positive in a way Vista&apos;s never were. The security architecture underneath had barely changed.&lt;/p&gt;
&lt;p&gt;The Vista security architecture is preserved almost entirely in Windows 7. UAC, MIC, and UIPI carry forward. BitLocker carries forward, gaining BitLocker To Go for removable drives. Both WFPs (the Filtering Platform and Resource Protection) carry forward. ASLR and DEP carry forward. Service Hardening carries forward, with additional per-service-SID coverage for previously-overlooked service hosts. Mandatory x64 KMCS carries forward. The Security Center is reborn as Action Center with an aggregated maintenance surface alongside the security surface.&lt;/p&gt;
&lt;p&gt;Windows 7 did change the integration. UAC gained a four-level slider in Control Panel -- Always Notify, Notify when programs try to make changes (the default), Notify but don&apos;t dim the desktop, and Never Notify -- and an &quot;auto-elevate&quot; whitelist for signed Microsoft binaries that the system trusted to elevate themselves without a consent prompt. The slider made the prompt fatigue UI-tunable for the first time. The auto-elevate whitelist, however, is the load-bearing UAC-bypass surface for the next decade.&lt;/p&gt;
&lt;p&gt;The auto-elevate whitelist is the surface Leo Davidson&apos;s December 2009 essay (sysprep.exe loading &lt;code&gt;CRYPTBASE.dll&lt;/code&gt; from &lt;code&gt;%SystemRoot%\System32&lt;/code&gt; after a bind directory redirection) attacked first, and the UACMe catalogue on GitHub maintained an ongoing inventory of roughly 70 distinct UAC-bypass techniques over the following decade. The exact count grows over time -- the GitHub repository is the authoritative reference -- and the order-of-magnitude figure should be read as engineering-folklore shorthand rather than as instrumented telemetry. See the &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Adminless&lt;/a&gt; companion post for the full bypass-technique history and for the 2024 to 2026 Administrator Protection redesign.&lt;/p&gt;
&lt;p&gt;AppLocker arrived in Windows 7, replacing the Software Restriction Policies of Windows XP and Server 2003 with a richer rule-collection model: executable rules, MSI rules, script rules, packaged-app rules, and DLL rules, each authorable by path, file hash, or publisher [@s-msft-applocker-overview]. DirectAccess shipped as a pre-VPN seamless remote-access protocol -- ahead of its time and not widely deployed. The reason it was ahead of its time and the reason it failed to deploy widely were the same: DirectAccess required native IPv6 connectivity (with Teredo or 6to4 tunneling as the fallback for IPv4-only networks) and per-machine certificate enrollment for every endpoint and gateway, and in the 2009-to-2014 window most enterprises ran neither IPv6 nor a mature PKI, so the prerequisite stack alone disqualified the protocol from broad rollout.&lt;/p&gt;

Microsoft&apos;s application-control feature, first shipped in Windows 7 (and Server 2008 R2). AppLocker supersedes Software Restriction Policies with a rule-collection model spanning executables, MSIs, scripts, packaged apps, and DLLs, with each rule authorable by path, file hash, or publisher (Authenticode-signed publisher and product) [@s-msft-applocker-overview].
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vista feature&lt;/th&gt;
&lt;th&gt;Windows 7 change&lt;/th&gt;
&lt;th&gt;What the change cost or enabled&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;UAC&lt;/td&gt;
&lt;td&gt;Four-level slider; auto-elevate whitelist for signed MS binaries&lt;/td&gt;
&lt;td&gt;Less prompt fatigue; new bypass surface via whitelist abuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIC + UIPI&lt;/td&gt;
&lt;td&gt;Unchanged&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASLR + DEP&lt;/td&gt;
&lt;td&gt;Loader and policy refinements&lt;/td&gt;
&lt;td&gt;Slightly more user-image coverage; not yet mandatory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PatchGuard + KMCS&lt;/td&gt;
&lt;td&gt;Unchanged on x64&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service Hardening&lt;/td&gt;
&lt;td&gt;Coverage extended to additional service hosts&lt;/td&gt;
&lt;td&gt;Smaller residual blast radius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Resource Protection&lt;/td&gt;
&lt;td&gt;Unchanged&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Filtering Platform&lt;/td&gt;
&lt;td&gt;Refinements for VPN providers&lt;/td&gt;
&lt;td&gt;Cleaner third-party integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BitLocker&lt;/td&gt;
&lt;td&gt;BitLocker To Go for removable drives&lt;/td&gt;
&lt;td&gt;Encrypted USB sticks become practical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Center&lt;/td&gt;
&lt;td&gt;Reborn as Action Center&lt;/td&gt;
&lt;td&gt;Aggregated maintenance + security surface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(new) AppLocker&lt;/td&gt;
&lt;td&gt;Replaces Software Restriction Policies&lt;/td&gt;
&lt;td&gt;Richer application control for enterprises&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The argument is the obvious one. Windows 7&apos;s reception was broadly positive and Vista&apos;s reception was broadly negative running on substantially the same security architecture. This is the article&apos;s evidence that &quot;user-hostile integration of a correct architecture&quot; is a distinct failure mode from &quot;wrong architecture,&quot; and that the integration tax is payable -- if the work is done.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Vista-era integrity-level architecture is still load-bearing on Windows 11. Every modern sandbox -- browser tab process, AppContainer for a UWP app, the Office Protected View host, the Windows Defender Application Guard container -- builds on the MIC primitive Vista shipped in January 2007. If you maintain a Windows desktop fleet, treat UAC, MIC, and per-service SIDs as the foundational defenses they are, not as legacy artifacts. Companion posts: &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Adminless&lt;/a&gt; on the integrity-level-stack arc through Administrator Protection, and &lt;a href=&quot;https://paragmali.com/blog/process-mitigation-policies-cfg-acg-cig-and-the-layer-betwee/&quot; rel=&quot;noopener&quot;&gt;Process Mitigation Policies&lt;/a&gt; on the post-era process-mitigations layer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If Windows 7 proved the architecture, the era&apos;s two structural limits proved how much was left to do. The next chapter is humility.&lt;/p&gt;
&lt;h2&gt;9. Three Operating Systems, Three Answers&lt;/h2&gt;
&lt;p&gt;Microsoft was not the only operating-system vendor trying to answer the privilege-model question in this window. The same years that produced UAC produced Mac OS X 10.5 Leopard&apos;s sandbox and mainlined SELinux on Linux. Each answered the question &quot;which operations get the elevation primitive interposed on them?&quot; with a different default.&lt;/p&gt;
&lt;h3&gt;macOS 10.5 Leopard, October 2007&lt;/h3&gt;
&lt;p&gt;Apple shipped Leopard&apos;s &quot;seatbelt&quot; sandbox in October 2007, built on Robert Watson&apos;s TrustedBSD MAC framework -- the same FreeBSD-derived Mandatory Access Control plumbing that becomes App Sandbox in OS X 10.7 (Lion, 2011) and the sandbox primitive every signed Mac App Store application now runs inside. The sandbox profile language is a Scheme dialect (SBPL); a representative four-line profile reads:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(version 1)
(deny default)
(allow file-read* (subpath &quot;/usr/lib&quot;))
(allow network-outbound (remote tcp &quot;*:443&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apple&apos;s &lt;code&gt;authopen&lt;/code&gt; and Authorization Services APIs are closer to per-operation elevation than Vista&apos;s per-process-token model. A typical Authorization Services flow elevates a single file-modification operation -- the canonical example is editing &lt;code&gt;/private/etc/hosts&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;authopen -w /private/etc/hosts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The macOS model is &quot;the user is prompted at the moment of the protected operation, the elevation is scoped to that operation, and the rest of the process continues at the user&apos;s normal privileges.&quot; Vista&apos;s model is &quot;the user is prompted at the moment a process needs the high token, the full token is released to the entire process, and the rest of the user session continues under the filtered token.&quot;&lt;/p&gt;
&lt;h3&gt;Linux: SELinux, AppArmor, and sudo&lt;/h3&gt;
&lt;p&gt;SELinux (originally developed by the U.S. National Security Agency, released to the open-source community in December 2000, mainlined in Linux 2.6.0 in December 2003, and championed downstream by Red Hat in RHEL 4 from February 2005 onwards) is the most thoroughly developed example of Type Enforcement on a mainstream OS. The policy language uses Access Vector rules with security labels:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-selinux&quot;&gt;allow httpd_t httpd_content_t : file { read getattr open };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The semantics are explicit: a process in domain &lt;code&gt;httpd_t&lt;/code&gt; may perform &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;getattr&lt;/code&gt;, and &lt;code&gt;open&lt;/code&gt; on a file with label &lt;code&gt;httpd_content_t&lt;/code&gt;. The labels travel with the file (extended attributes on disk) and the rules live in a single compiled policy. The model is label-based MAC.&lt;/p&gt;
&lt;p&gt;AppArmor (Immunix, then Novell, mainlined in Linux 2.6.36 on October 20, 2010 [@s-linux-2-6-36-kernelnewbies]) takes the opposite philosophical position. A profile is a list of path-based rules:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-apparmor&quot;&gt;/usr/sbin/dnsmasq {
  /etc/dnsmasq.conf r,
  /var/lib/misc/dnsmasq.leases rw,
  network inet dgram,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The model is path-based MAC: rules apply to filesystem paths rather than to inode labels. &lt;code&gt;sudo&lt;/code&gt; persists across both as the practical per-operation elevation primitive, and most production Linux deployments use a mix.&lt;/p&gt;

The SELinux-vs-AppArmor distinction is a real architectural disagreement, not a stylistic preference. Label-based MAC ties policy to the data (extended attributes follow the file) but requires that every filesystem operation preserve the labels and that the labels start correct. Path-based MAC ties policy to the file path (a path is a profile lookup key) but means the same data accessed through two different paths can get two different policy verdicts. Both forms ship in mainstream Linux distributions in 2026; the choice is usually a function of which distribution&apos;s tooling you started with.
&lt;p&gt;AppArmor&apos;s mainline Linux merge is Linux 2.6.36, October 20, 2010 [@s-linux-2-6-36-kernelnewbies]. Upstream secondary references occasionally date the mainline merge to 2009, which is wrong -- 2009 was the announcement-of-intent year; the actual &lt;code&gt;git&lt;/code&gt; merge into Linus&apos;s tree is October 20, 2010.&lt;/p&gt;
&lt;h3&gt;Three OSes, three privilege models&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OS / year&lt;/th&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Granularity&lt;/th&gt;
&lt;th&gt;Policy authoring&lt;/th&gt;
&lt;th&gt;Origin lineage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Vista UAC + MIC + UIPI (Jan 2007)&lt;/td&gt;
&lt;td&gt;Per-process token, integrity-level SID&lt;/td&gt;
&lt;td&gt;Per-process&lt;/td&gt;
&lt;td&gt;Manifest + UAC consent + ACL/MIC ACE&lt;/td&gt;
&lt;td&gt;Cutler-era NT access tokens + new MIC layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leopard sandbox + Authorization Services (Oct 2007)&lt;/td&gt;
&lt;td&gt;Per-operation profile + per-operation auth&lt;/td&gt;
&lt;td&gt;Per-operation&lt;/td&gt;
&lt;td&gt;SBPL Scheme profile + &lt;code&gt;authopen&lt;/code&gt; call&lt;/td&gt;
&lt;td&gt;TrustedBSD MAC framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux SELinux / AppArmor + sudo (2003 / 2010 / forever)&lt;/td&gt;
&lt;td&gt;MAC domain rules + path/label policies&lt;/td&gt;
&lt;td&gt;Per-operation via MAC + per-command via sudo&lt;/td&gt;
&lt;td&gt;AV rules / profiles / sudoers&lt;/td&gt;
&lt;td&gt;NSA / Immunix / BSD-flavour &lt;code&gt;sudo&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The point is not which model is &quot;better.&quot; Vista&apos;s UAC is structurally closer to &lt;code&gt;sudo&lt;/code&gt; than its critics admitted -- the difference is that &lt;code&gt;sudo&lt;/code&gt; is invoked explicitly by the user from a shell, while UAC interposes on operations the user expected to just work. The contrast is about &lt;em&gt;which operations the platform forces through the elevation primitive&lt;/em&gt;, and operating systems that pick different answers end up with different reception narratives even when the underlying mechanisms are similar.&lt;/p&gt;
&lt;p&gt;If the privilege model is choosable -- if reasonable operating systems pick different answers -- what are the structural limits NONE of the three could escape? That is the next chapter.&lt;/p&gt;
&lt;h2&gt;10. Theoretical Limits and Era-Specific Lessons&lt;/h2&gt;
&lt;p&gt;Four structural limits the era revealed. Three of the four were proved in the literature; one was proved by Conficker. None of the four were closed by 2009. Two are closed today; two are not.&lt;/p&gt;
&lt;h3&gt;Limit 1: The same-privilege paradox&lt;/h3&gt;
&lt;p&gt;PatchGuard runs at ring 0. Rootkits run at ring 0. PatchGuard is therefore fundamentally bypassable from a sufficiently privileged attacker -- and skape and Skywing&apos;s December 1, 2005 &lt;em&gt;Uninformed&lt;/em&gt; paper demonstrated three concrete bypass technique classes against the v1 implementation [@s-skape-skywing-patchguard]. PatchGuard v2 (Vista RTM) and v3 (Vista SP1) patched the specific v1 bypasses but could not address the structural issue. The genuine architectural fix waits for Hypervisor-Protected Code Integrity in Windows 10 Anniversary Update (August 2016) and for the VBS, Pluton, and Secured-core PC architectures of Windows 11. All out of era. Part 4 of this series traces them.&lt;/p&gt;
&lt;h3&gt;Limit 2: The deployment-velocity ceiling (the Conficker bound)&lt;/h3&gt;
&lt;p&gt;Aggregate installed-base security is bounded by patch-to-field-deployment latency on the slowest cohort, not by patch-release latency. Conficker&apos;s 9-to-15-million infections in early 2009 exploited a vulnerability that had been patched for one to four months across the variants [@s-cwg-lessons-learned-2019].&lt;/p&gt;
&lt;p&gt;This is the era-closing operational lesson. It motivates Automatic Updates becoming opt-out-by-default (XP SP2, 2004), the mature Patch Tuesday cadence, and -- much later -- the Windows-as-a-Service cumulative-update model of Windows 10 that removes the user&apos;s ability to decline updates indefinitely. All-cohort closure remains structurally unattainable as of 2026; this is the era&apos;s defining residual.&lt;/p&gt;

The structural upper bound on aggregate installed-base security set by patch-to-field-deployment latency on the slowest cohort of machines. A vulnerability becomes safe at population scale only when the patch has propagated to every reachable system, and the slowest cohort&apos;s propagation rate dominates the aggregate. Conficker proved that on-by-default architectural mitigations on Vista did not raise the ceiling for the XP and Server 2003 installed base; only patch propagation could. The post-era architectural response is the Windows 10 cumulative-update model.
&lt;h3&gt;Limit 3: The compatibility tax on defaults&lt;/h3&gt;
&lt;p&gt;Every Vista security default that broke an application became a UAC bypass surface (the auto-elevate whitelist), a driver-signing escape hatch (test-signing), or a compatibility shim (DEP OptIn). Defaults that cannot break shipping software cannot be tightened. This is the era&apos;s productive failure mode -- it explains why post-Vista security features ship with deprecation runways: mandatory ASLR took until Windows 10 to fully land, mandatory KMCS on x86 never landed at all, and Driver Signature Enforcement on x64 had to coexist with the test-signing escape hatch for the foreseeable future.&lt;/p&gt;
&lt;h3&gt;Limit 4: The user-hostility tax on correct architecture&lt;/h3&gt;
&lt;p&gt;UAC was architecturally correct and operationally hated. The Mojave Experiment (July 2008) is the era&apos;s confession that the perceptual layer matters as much as the architectural layer. Windows 7&apos;s smoothing is the article&apos;s evidence that the tax can be paid, if the work is done -- but it has to be paid every time, because the perceptual layer is not learned-once. Windows 8&apos;s Modern UI, Windows 11&apos;s UAC behaviour adjustments, and the 2024-to-2026 &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Administrator Protection&lt;/a&gt; redesign are all replays of the same question on different sets of users.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The era&apos;s binding constraints were not the UI. They were architectural -- you cannot defend ring 0 from ring 0, and skape and Skywing proved this in December 2005 -- and operational -- you cannot patch the slowest cohort faster than the worm cadence, and Conficker proved this in late November 2008. The prompt was the symptom. The constraints were the disease. Both were unsolved when Windows 7 shipped.&lt;/p&gt;
&lt;/blockquote&gt;

The Conficker Working Group&apos;s June 2010 post-mortem named the binding constraint directly: it is not whether a patch exists, but whether deployment reaches the slowest cohort before the worm does [@s-cwg-lessons-learned-2019].
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Era limit&lt;/th&gt;
&lt;th&gt;Era-end state (Oct 2009)&lt;/th&gt;
&lt;th&gt;2026 state&lt;/th&gt;
&lt;th&gt;Forward link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Same-privilege paradox&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;CLOSED for kernel integrity via HVCI / VBS / Pluton&lt;/td&gt;
&lt;td&gt;Part 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment-velocity ceiling&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;NARROWED via Windows-as-a-Service cumulative updates&lt;/td&gt;
&lt;td&gt;Part 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compatibility tax on defaults&lt;/td&gt;
&lt;td&gt;OPEN (per-feature deprecation runways)&lt;/td&gt;
&lt;td&gt;OPEN; managed via mitigation slow-ramp deployment&lt;/td&gt;
&lt;td&gt;Part 3, Part 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User-hostility tax on correct architecture&lt;/td&gt;
&lt;td&gt;OPEN (Windows 7 smoothed Vista)&lt;/td&gt;
&lt;td&gt;RECURRING (re-paid each major release)&lt;/td&gt;
&lt;td&gt;Part 6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;If the era closed with two structural limits unsolved, what stayed open for the next decade to answer?&lt;/p&gt;
&lt;h2&gt;11. Open Problems at the End of the Era&lt;/h2&gt;
&lt;p&gt;Stand at an engineer&apos;s desk on Friday, October 23, 2009 -- the day after Windows 7 GA. The previous twelve months had shipped a polished consumer OS, contained Conficker (mostly), and formed an industry-coordination body for the next worm. What does the agenda look like on Monday?&lt;/p&gt;
&lt;h3&gt;Q1: How do you make the patching cadence faster than the worm cadence?&lt;/h3&gt;
&lt;p&gt;The era-end answer was a mature Patch Tuesday cadence plus the Microsoft Active Protections Program (MAPP, which gave AV vendors early access to patch details) plus Automatic Updates default-on, but the slowest-cohort lag remained. The post-era answer is the cumulative-update and Windows-as-a-Service model of Windows 10 (July 2015) plus enterprise WSUS scale-out plus the out-of-band cadence the era proved was sometimes necessary. The in-era out-of-band releases were three: the bulletin commonly cited from January 2006 patching the Windows Metafile vulnerability (MS06-001) [@s-msft-ms06-001], the April 2007 out-of-band patching the animated-cursor (.ANI) GDI parsing vulnerability (MS07-017) [@s-msft-ms07-017], and MS08-067 [@s-ms08-067].&lt;/p&gt;
&lt;p&gt;The April 2004 LSASS bulletin (the patch that preceded Sasser) was a regular Patch Tuesday release on April 13, 2004 [@s-msft-ms04-011], not an out-of-band release. The in-era out-of-band Microsoft Security Bulletins for wormable-class or actively-exploited-class RCEs are three: the January 2006 Windows Metafile bulletin (MS06-001) [@s-msft-ms06-001], the April 3, 2007 animated-cursor (.ANI) GDI bulletin (MS07-017, patching CVE-2007-0038, which was being actively exploited via drive-by web pages) [@s-msft-ms07-017], and MS08-067 in October 2008 [@s-ms08-067]. The May 8, 2007 Windows DNS RPC RCE bulletin (MS07-029) is sometimes misremembered as an out-of-band release; it shipped on the regular Patch Tuesday cadence [@s-msft-secupdates-index].&lt;/p&gt;
&lt;p&gt;The architectural shift the era did not make is the one Windows 10 made: removing the user&apos;s ability to indefinitely decline updates on consumer machines. This was politically impossible in 2009 and remains contested in 2026; deferred to Part 3.&lt;/p&gt;
&lt;h3&gt;Q2: How do you protect kernel integrity from kernel-level attackers?&lt;/h3&gt;
&lt;p&gt;Era-end answer: PatchGuard runs at the same ring as the attacker; structural bypassability remains. Post-era answer: Hypervisor-Protected Code Integrity in Windows 10 Anniversary Update (August 2016); Virtualization-Based Security and Credential Guard; the Microsoft Vulnerable Driver Block list (2020 onward) for the BYOVD afterlife. Deferred to Part 4.&lt;/p&gt;
&lt;h3&gt;Q3: How do you separate trust principals more finely than user accounts and integrity levels?&lt;/h3&gt;
&lt;p&gt;Era-end answer: MIC offered five integrity levels; the granularity is per-process, not per-capability. Post-era answer: AppContainer (Windows 8, which introduces capability SIDs inside a LowBox token so a process can be denied or granted individual platform capabilities such as &lt;code&gt;internetClient&lt;/code&gt; independently of its user account); the Modern Apps and Universal Windows Platform manifest-permission model (declarative capability gating at app install time, with the manifest itself authored alongside the app and reviewed at Store submission); and the Windows Subsystem for Linux and Android trust-isolation architectures (per-distribution and per-app isolation contracts that scope filesystem, network, and IPC access to a single guest OS instance). The integrity-level primitive remains the substrate every one of these builds on. Deferred to Part 3 and Part 4.&lt;/p&gt;
&lt;h3&gt;Q4: How do you ship a security architecture without breaking the user experience?&lt;/h3&gt;
&lt;p&gt;Era-end answer: Windows 7&apos;s polish proves it can be done for one release. Post-era answer: it recurred with Windows 8&apos;s Modern UI debacle, the Windows 11 UAC behaviour adjustments, and the 2024 to 2026 Administrator Protection rollout that finally promotes UAC to a security-boundary classification -- traced in the &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Adminless&lt;/a&gt; companion post. The question is recurring -- it is solved per-release, not in principle.&lt;/p&gt;

Part 3 picks up the morning after Windows 7 GA with Stuxnet, Operation Aurora, the Enhanced Mitigation Experience Toolkit, and the Process Mitigations era. Part 4 traces the VBS / HVCI / Pluton / Secured-core PC arc that closes the same-privilege paradox. Part 5 covers the credential-theft and Active Directory escalation era (Mimikatz, Pass-the-Hash, the Protected Users group, Credential Guard). Part 6 covers the Administrator Protection redesign and the long arc back to UAC as a security boundary. The shared spine of all five remaining articles is the integrity-level stack Vista shipped.
&lt;p&gt;Four questions on the Monday whiteboard. Three of the four have answers in Parts 3 through 6 of this series. The fourth will outlast the operating system.&lt;/p&gt;
&lt;h2&gt;12. Reading 2002 to 2008 Windows Documentation in 2026&lt;/h2&gt;
&lt;p&gt;If you inherit a Vista- or Server 2008-era environment in 2026, or maintain a kernel driver whose support matrix still includes the Vista lineage, or pick up Russinovich, Solomon, and Ionescu&apos;s &lt;em&gt;Windows Internals&lt;/em&gt;, 5th edition [@s-windows-internals-5e] off the shelf, what should you know that the documentation will not tell you directly?&lt;/p&gt;
&lt;h3&gt;Reading a &lt;code&gt;whoami /groups /priv&lt;/code&gt; output on a Vista-or-later machine&lt;/h3&gt;
&lt;p&gt;The split-token model means the elevated and unelevated tokens differ in their group memberships and privilege lists, not in a single flag. The integrity-level SID line -- &lt;code&gt;Mandatory Label\Medium Mandatory Level&lt;/code&gt; or &lt;code&gt;Mandatory Label\High Mandatory Level&lt;/code&gt; -- is the right place to look first. Practitioner tip: if the integrity label says High and the privilege list shows &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; enabled, the token is elevated. If the integrity label says Medium and the privilege list lacks &lt;code&gt;SeBackupPrivilege&lt;/code&gt; and &lt;code&gt;SeTakeOwnershipPrivilege&lt;/code&gt;, the token is filtered. The Microsoft Learn &lt;code&gt;windows/win32/secauthz/mandatory-integrity-control&lt;/code&gt; page is the canonical integrity-level reference [@s-msft-mic-win32].&lt;/p&gt;
&lt;h3&gt;Reading a Security event-log entry from this era&lt;/h3&gt;
&lt;p&gt;The Event ID schema changed between XP (5xx range) and Vista (4xxx range); a Vista Event 4624 logon-success entry is not the same as an XP Event 528. The Microsoft Learn &lt;code&gt;windows-security/threat-protection/auditing/&lt;/code&gt; index is the canonical reference for Vista-and-later events. The closest thing to a canonical XP-to-Vista mapping table that Microsoft still publishes is the &lt;code&gt;Appendix L: Events to Monitor&lt;/code&gt; page in the Windows Server / Active Directory documentation, whose &quot;Current Windows Event ID&quot; and &quot;Legacy Windows Event ID&quot; columns map post-Vista 4xxx-range identifiers back to their pre-Vista 5xx-range equivalents -- for example, 4624 successful logon mapping to 528/540, 4625 failed logon mapping to 529-537/539, 4634 logoff (kernel-generated when the logon session is destroyed) mapping to 538, 4647 user-initiated logoff mapping to 551, and 1102 audit log cleared mapping to 517 -- for practitioners inheriting mixed XP-and-Vista log estates [@s-msft-events-to-monitor]. Old documentation that uses the 5xx-range numbering is talking about XP and Server 2003.&lt;/p&gt;
&lt;h3&gt;Reading the MS-bulletin archive&lt;/h3&gt;
&lt;p&gt;The original &lt;code&gt;microsoft.com/technet/security/bulletin/MS08-067.mspx&lt;/code&gt; URL scheme has migrated twice. The current canonical form is &lt;code&gt;learn.microsoft.com/en-us/security-updates/securitybulletins/2008/ms08-067&lt;/code&gt; [@s-ms08-067]. The parent landing URL &lt;code&gt;learn.microsoft.com/en-us/security-updates/&lt;/code&gt; is the working index [@s-msft-secupdates-index]; the legacy &lt;code&gt;/securitybulletins/&lt;/code&gt; URL returns HTTP 404 in 2026 and is one of the reasons cross-references in older books need patient redirection.&lt;/p&gt;
&lt;h3&gt;Identifying an era-shaped misconfiguration in a modern audit&lt;/h3&gt;
&lt;p&gt;Three worked examples readers can run on a Windows 10 or 11 fleet today.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A service running as &lt;code&gt;LocalSystem&lt;/code&gt; instead of as its per-service SID. The service inventory in &lt;code&gt;sc.exe qc&lt;/code&gt; output or &lt;code&gt;Get-Service | ForEach-Object&lt;/code&gt; queries should show &lt;code&gt;NT SERVICE\&amp;lt;servicename&amp;gt;&lt;/code&gt; in the principal column for any post-Vista service; if it shows &lt;code&gt;LocalSystem&lt;/code&gt;, the service is either pre-Vista in its configuration or has been deliberately escalated. Either case warrants explanation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An unsigned third-party kernel driver loading via the test-signing escape hatch (&lt;code&gt;bcdedit /set testsigning on&lt;/code&gt;). Test-signing should never be enabled on production machines; the desktop watermark exists exactly to make this visible. The audit query is &lt;code&gt;bcdedit /enum {current} | findstr testsigning&lt;/code&gt; from an elevated prompt.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A BitLocker volume without TPM+PIN protection on a system whose threat model includes physical access. TPM-only mode is vulnerable to the cold-boot attack documented in Halderman et al., USENIX Security 2008 [@s-halderman-coldboot-jhalderm]. The query is &lt;code&gt;manage-bde -protectors -get C:&lt;/code&gt; from an elevated prompt; the output should list a numerical password recovery key plus a TPM+PIN protector for any laptop that leaves the office.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;bcdedit /set testsigning on&lt;/code&gt; is documented for driver development. It is not appropriate for production systems. A production machine with test-signing enabled accepts kernel drivers signed by certificates the system does not normally trust -- exactly the rootkit-installation path Vista x64&apos;s mandatory KMCS was designed to close [@s-msft-driver-signing]. Audit for the watermark and for the &lt;code&gt;bcdedit&lt;/code&gt; value; if either is present on a server or end-user machine, treat it as a finding.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The reading list&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Parts 3 through 6 of this series each pick up where this one ends: - Part 3: Stuxnet, Operation Aurora, the Enhanced Mitigation Experience Toolkit, the cumulative-update model - Part 4: VBS, HVCI, Pluton, Secured-core PC, the closure of the same-privilege paradox - Part 5: Credential theft, Mimikatz, Pass-the-Hash, Credential Guard - Part 6: Administrator Protection and the long arc back to UAC as a security boundary Companion posts: &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;Windows Access Control: 25 Years of Attacks&lt;/a&gt;, &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Adminless&lt;/a&gt;, &lt;a href=&quot;https://paragmali.com/blog/bitlocker-on-windows-architecture-attacks-and-the-limits-of-/&quot; rel=&quot;noopener&quot;&gt;BitLocker on Windows&lt;/a&gt;, &lt;a href=&quot;https://paragmali.com/blog/beyond-bitlocker-the-three-file-level-encryption-layers-micr/&quot; rel=&quot;noopener&quot;&gt;Beyond BitLocker&lt;/a&gt;, &lt;a href=&quot;https://paragmali.com/blog/process-mitigation-policies-cfg-acg-cig-and-the-layer-betwee/&quot; rel=&quot;noopener&quot;&gt;Process Mitigation Policies&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

Given the line `Mandatory Label\Medium Mandatory Level     Label            S-1-16-8192` and a privilege list that includes `SeShutdownPrivilege Enabled`, `SeChangeNotifyPrivilege Enabled`, `SeUndockPrivilege Enabled`, `SeTimeZonePrivilege Enabled` -- and that does NOT include `SeLoadDriverPrivilege`, `SeBackupPrivilege`, `SeTakeOwnershipPrivilege`, or `SeDebugPrivilege` -- the token is the filtered standard-user token. The user is an administrator interactively logged on, but the running shell is operating with the filtered token. To verify, open an elevated PowerShell from the same session and re-run `whoami /groups /priv`: the integrity label will read `High Mandatory Level`, the SID will be `S-1-16-12288`, and the elevated privilege set will be present.
&lt;p&gt;The era is closed. The architecture is not.&lt;/p&gt;
&lt;h2&gt;13. Frequently Asked Questions&lt;/h2&gt;
&lt;p&gt;Eight common misconceptions about the era, each anchored to a corrected primary source.&lt;/p&gt;

No. PatchGuard shipped first in Windows XP Professional x64 Edition and Windows Server 2003 x64 Edition in April 2005 -- twenty months before Vista RTM. Vista x64 inherited PatchGuard v2; Vista SP1 shipped v3. The cite-ready primary is Microsoft Security Advisory 932596, which states explicitly that PatchGuard is &quot;included with x64-based Windows operating systems&quot; and reads back through XP x64 and Server 2003 x64 [@s-msft-adv-932596]. x86 editions of Vista never received PatchGuard at all.

No. MS08-067 was patched out-of-band on October 23, 2008 [@s-ms08-067]. Conficker.A was first detected in late November 2008, anchored to November 20, 2008 in SRI International&apos;s technical analysis [@s-sri-conficker-c-addendum]. The first in-the-wild MS08-067 exploitation in October 2008 was Gimmiv.A, a narrower non-self-propagating Trojan, per the NVD CVE-2008-4250 entry -- not Conficker [@s-nvd-cve-2008-4250]. The patch-to-weaponisation gap is approximately twenty-nine days and is the article&apos;s load-bearing thesis evidence.

No. The HTML-comment Mark-of-the-Web (``) shipped in Internet Explorer 6 Service Pack 1 in 2002. The Attachment Execution Service, two years later in XP SP2, is the system-wide enforcement substrate of the `Zone.Identifier` NTFS Alternate Data Stream -- the persistent file-system anchor that downstream tools (Office Protected View, SmartScreen, Microsoft Defender Application Control) consult to gate execution [@s-msft-iattachmentexecute]. Substrate, not ancestor.

No. Russinovich&apos;s June 2007 *TechNet Magazine* article states explicitly that &quot;elevations were introduced as a convenience&quot; and that this very fact &quot;prevents OTS elevations from being a security boundary&quot; [@s-russinovich-uac-technet]. The chronologically first published Microsoft-principal record of the same disclaimer is the February 12, 2007 Mark&apos;s Blog post that anchors the multi-part TechNet blog series on the restricted-token / integrity-level discussion [@s-russinovich-psexec-blog]. The boundary classification arrives with Administrator Protection in the 2024 to 2026 Windows 11 era; see the [Adminless](/blog/adminless-how-windows-finally-made-elevation-a-security-boun/) companion post.

No. Vista&apos;s ASLR was opt-in for user code via the `/DYNAMICBASE` linker flag; only system images and `/DYNAMICBASE`-linked binaries were randomised. Full mandatory ASLR for all images is a later-Windows feature -- Force ASLR in EMET and Windows 8, mandatory in Windows 10. The Shacham et al. CCS 2004 paper had already established the brute-force bound: with $n$ bits of entropy, an attacker needs expected $2^{n-1}$ attempts against a process that respawns after crash [@s-shacham-asrandom-ccs2004]; on x86 Vista&apos;s 8 bits this is roughly 128 attempts, which is why x64 ASLR (qualitatively more entropy) was the more durable defense.

No. BitLocker shipped in Windows Vista Enterprise and Ultimate editions only, plus Windows Server 2008. Most Vista consumers ran Home Basic or Home Premium and got no BitLocker at all. The cipher in Vista was AES-CBC with Niels Ferguson&apos;s Elephant Diffuser, documented in his August 2006 Microsoft whitepaper [@s-ferguson-bitlocker]; later Windows releases moved to AES-XTS. The SKU limitation materially limited deployment reach for the era.

No. KMCS foreclosed the dominant 2003-era unsigned-driver installation path catalogued in Hoglund and Butler [@s-hoglund-butler-rootkits] but did not address the signed-driver-with-vulnerability case. The &quot;Bring Your Own Vulnerable Driver&quot; afterlife became the dominant rootkit-loading path from approximately 2010 onward. Architectural closure waits for the Microsoft Vulnerable Driver Block list (Windows 10 and 11) -- post-era; Part 4 [@s-msft-driver-signing].

Windows ME and Windows 8 have competing claims. The honest framing is that Vista was one of the most poorly received Windows consumer releases of its era, and that the reception was uniquely consequential because the SP1-era enterprise inertia, the consumer-skipping that produced a large XP-to-7 leap, and the marketing problem Windows 7&apos;s launch had to solve all compounded each other. The substantive argument of this article -- that Vista&apos;s architecture was correct and Vista&apos;s integration was not, and that Windows 7 proved the integration tax is payable -- does not depend on the cross-history superlative.
&lt;p&gt;Below the FAQ, a final pointer: this is Part 2 of six. Part 3 picks up the morning after Windows 7 GA with Stuxnet, Operation Aurora, the Enhanced Mitigation Experience Toolkit, and the process-mitigations era. The integrity-level stack Vista shipped in January 2007 is what every Part from here forward is built on top of.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;windows-security-wars-part-2&quot; keyTerms={[
  { term: &quot;MS08-067&quot;, definition: &quot;October 23, 2008 out-of-band Microsoft Security Bulletin patching CVE-2008-4250, a stack buffer overflow in the path-canonicalization code reachable through the Server service&apos;s srvsvc RPC interface on TCP/445 and TCP/139.&quot; },
  { term: &quot;UAC (User Account Control)&quot;, definition: &quot;Vista feature that runs interactive Administrator accounts under a filtered standard-user token by default and prompts for explicit consent before releasing the full token to a specific process. Convenience feature per Russinovich, not a security boundary until Administrator Protection (2024-2026).&quot; },
  { term: &quot;MIC (Mandatory Integrity Control)&quot;, definition: &quot;Vista&apos;s mandatory-access-control primitive. Attaches an integrity-level SID to every process token and an integrity-level ACE to every securable object; evaluates integrity before the discretionary ACL in the access check.&quot; },
  { term: &quot;UIPI (User Interface Privilege Isolation)&quot;, definition: &quot;Vista mechanism preventing lower-integrity processes from sending window messages to higher-integrity windows. Closes the shatter-attack class documented by Chris Paget in 2002.&quot; },
  { term: &quot;ASLR (Address Space Layout Randomization)&quot;, definition: &quot;Defense randomising base addresses of executables, libraries, stack, and heap. Vista (Jan 2007) was the first Windows release to ship ASLR; opt-in for user code via /DYNAMICBASE in Vista, mandatory in Windows 10.&quot; },
  { term: &quot;DEP (Data Execution Prevention)&quot;, definition: &quot;Defense refusing to execute instructions from pages marked non-executable. Hardware-enforced using the NX/XD bit; software-enforced via SafeSEH on CPUs without the bit. Shipped in XP SP2 (Aug 2004).&quot; },
  { term: &quot;PatchGuard / KPP (Kernel Patch Protection)&quot;, definition: &quot;Microsoft&apos;s kernel-mode self-protection on x64 Windows. Periodically verifies the integrity of kernel data structures and bug-checks the system on detected modification. Shipped first in April 2005 in XP x64 and Server 2003 x64.&quot; },
  { term: &quot;KMCS (Kernel-Mode Code Signing)&quot;, definition: &quot;Vista x64 policy refusing to load kernel-mode drivers unless they carry a Microsoft-trusted certificate chain. bcdedit /set testsigning on is the documented development escape hatch. Vista x86 never received mandatory KMCS.&quot; },
  { term: &quot;BYOVD (Bring Your Own Vulnerable Driver)&quot;, definition: &quot;Post-KMCS attack pattern using a legitimately signed kernel driver with an exploitable vulnerability to gain ring-0 code execution. Closure waits for the Microsoft Vulnerable Driver Block list, post-era.&quot; },
  { term: &quot;AES + Zone.Identifier ADS&quot;, definition: &quot;XP SP2 Attachment Execution Service plus the NTFS Alternate Data Stream it writes on attachment download. System-wide enforcement substrate of Mark-of-the-Web, not its ancestor.&quot; },
  { term: &quot;WFP (Windows Filtering Platform)&quot;, definition: &quot;Vista&apos;s kernel-mode replacement for the NDIS-IM / TDI / firewall-hook stack-extension architecture. Note: this WFP is unrelated to Windows File Protection.&quot; },
  { term: &quot;WRP (Windows Resource Protection)&quot;, definition: &quot;Vista&apos;s ACL-based replacement for the WFP/SFC catalog-and-replace mechanism. Protected files and registry keys are owned by TrustedInstaller; administrators cannot directly modify them.&quot; },
  { term: &quot;Per-service SID&quot;, definition: &quot;Security identifier of the form NT SERVICE\ distinct to each Windows service. Lets DACLs, firewall rules, and WRITE RESTRICTED tokens constrain a single service independently of others sharing the same logon SID.&quot; },
  { term: &quot;Same-privilege paradox&quot;, definition: &quot;Structural observation that any defense running at a given privilege level cannot fundamentally constrain an attacker at the same level. skape and Skywing demonstrated this against PatchGuard in December 2005.&quot; },
  { term: &quot;Deployment-velocity ceiling&quot;, definition: &quot;Structural upper bound on aggregate installed-base security set by patch-to-field-deployment latency on the slowest cohort. Conficker proved this bound in late November 2008.&quot; }
]} flashcards={[
  { front: &quot;When did Conficker.A first appear?&quot;, back: &quot;November 20, 2008 (SRI International) -- approximately 29 days after MS08-067 was patched.&quot; },
  { front: &quot;Which Windows release first shipped PatchGuard?&quot;, back: &quot;Windows XP Professional x64 Edition and Windows Server 2003 x64 Edition, April 2005. NOT Vista.&quot; },
  { front: &quot;When did Mark-of-the-Web first ship?&quot;, back: &quot;Internet Explorer 6 Service Pack 1, 2002. The XP SP2 Attachment Execution Service is the substrate, not the ancestor.&quot; },
  { front: &quot;What is the integrity-level SID for Medium?&quot;, back: &quot;S-1-16-8192. Medium is the default for normal user processes; the filtered UAC token runs at Medium.&quot; },
  { front: &quot;What did Russinovich call UAC elevations?&quot;, back: &quot;A convenience feature, explicitly NOT a security boundary, per the June 2007 TechNet Magazine article. The boundary classification arrives only with Administrator Protection in the 2024-2026 Windows 11 era.&quot; },
  { front: &quot;When did Vista SP1 RTM?&quot;, back: &quot;February 4, 2008. Broad availability March 18, 2008. (November 2007 was the SP1 RC1 milestone, not RTM.)&quot; },
  { front: &quot;Who authored &apos;Bypassing PatchGuard on Windows x64&apos;?&quot;, back: &quot;skape (Matt Miller) and Skywing (Ken Johnson), Uninformed Vol. 3, dated December 1, 2005.&quot; }
]} questions={[
  { q: &quot;Why is the article&apos;s central claim that &apos;deployment velocity, not discovery latency, is the binding constraint on Internet security&apos;?&quot;, a: &quot;Because MS08-067 had been patched for approximately 29 days when Conficker.A first appeared, and the worm still infected 9 to 15 million machines drawn overwhelmingly from the un-updated XP and Server 2003 cohort. The architectural mitigations in Vista raised exploitation cost on Vista but could not protect machines running older code.&quot; },
  { q: &quot;What is the structural reason PatchGuard was bypassable in 2005, and what is the post-era architectural answer?&quot;, a: &quot;PatchGuard runs at ring 0; rootkits run at ring 0; same-privilege defenses are bypassable in principle. The post-era answer is to move the integrity check into a more privileged execution mode -- HVCI / VBS in Windows 10 (Aug 2016), Pluton and Secured-core PC architectures in Windows 11.&quot; },
  { q: &quot;Distinguish UAC from MIC. Which is the consumer-visible UI and which is the architectural substrate?&quot;, a: &quot;UAC is the consumer-visible UI -- the Secure Desktop consent prompt that releases the full token to a single process. MIC is the architectural substrate -- the integrity-level SID on every process token, the integrity-level ACE on every object, and the access-check pipeline that evaluates integrity before the DAC. Every later Windows containment story inherits MIC.&quot; },
  { q: &quot;Why was Vista&apos;s reception so much worse than Windows 7&apos;s when the security architecture was substantially the same?&quot;, a: &quot;User-hostile integration of a correct architecture is a distinct failure mode from wrong architecture. Vista&apos;s UAC threw too many prompts on common workflows; Windows 7&apos;s auto-elevate whitelist plus the four-level slider tuned the prompt frequency to a tolerable rate. Same architecture, smoothed integration -- and the integration tax was payable when the work was done.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>history</category><category>vista</category><category>uac</category><category>patchguard</category><category>conficker</category><category>trustworthy-computing</category><category>aslr</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Windows Security Boundaries: The Document That Decides What Gets a CVE</title><link>https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/</link><guid isPermaLink="true">https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/</guid><description>Microsoft maintains a single public document that decides which Windows vulnerability reports receive a CVE, a Patch Tuesday bulletin, and a bounty payout. Here is how to read it.</description><pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Microsoft maintains a single public document that decides which Windows vulnerability reports receive a CVE, a Patch Tuesday bulletin, and a bounty payout, and which receive &quot;by design.&quot;** The *Security Servicing Criteria for Windows* enumerates nine security **boundaries** (network, process, kernel, session, user, AppContainer, virtual machine, Virtual Trust Level, and as of 2025, the Administrator Protection elevation path) and seven security **features** (UAC, Microsoft Defender, HVCI, Driver Signing, Protected Process Light, admin-to-kernel privilege escalation, same-user post-authentication). A two-question triage rule generates every MSRC disposition, including every &quot;by design -- UAC is not a security boundary&quot; reply you have ever read. Reading the doctrine is the difference between filing a useful MSRC report and getting back one polite sentence.
&lt;h2&gt;1. A UAC Bypass Walks Into MSRC&lt;/h2&gt;
&lt;p&gt;Three weeks of reverse engineering. A clean video of &lt;code&gt;consent.exe&lt;/code&gt; being skipped via a registry-hijack technique. A report filed through &lt;code&gt;msrc.microsoft.com/report&lt;/code&gt;. Two business days later, the Microsoft Security Response Center replies in one sentence: &lt;em&gt;&quot;Thank you for the report. UAC is not a security boundary; please refer to the Microsoft Security Servicing Criteria for Windows. This issue is by design.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That sentence has been Microsoft&apos;s consistent position since June 2007 [@russinovich-vista-uac-wayback]. It is the operational anchor of every Windows vulnerability disposition made in the last nineteen years, and it routes through a single public document most researchers have never read.&lt;/p&gt;
&lt;p&gt;The document is called the &lt;em&gt;Microsoft Security Servicing Criteria for Windows&lt;/em&gt; [@msrc-criteria]. Twenty-eight paragraphs and two enumerated tables live on a single MSRC web page. Those paragraphs decide which Windows findings get a CVE number, which get a Patch Tuesday bulletin, which get a bounty payout, and which get a polite &quot;by design&quot; reply that closes the ticket without a fix. Every other operational artifact in Microsoft&apos;s security response -- the bounty schedule, the monthly bulletin calendar, the per-finding severity ratings -- is downstream of this one taxonomy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &quot;by design&quot; reply is not boilerplate. Every MSRC triage engineer who issues it is applying a specific clause of a specific document. The reply means: we read your finding, mapped it against our published classification, and the primitive you attacked is on our security-feature list rather than our security-boundary list. We may still harden the feature in a future build, but we are not going to assign a CVE or ship a Patch Tuesday bulletin for it. The classification is published. The disposition follows from the classification.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The researcher&apos;s first reaction is the natural one. Three weeks of work. A working bypass. A Microsoft binary skipped. And the reply is &lt;em&gt;one sentence&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;It is right, and the rest of this article is the explanation of why. We will walk the document&apos;s history from a single June 2007 TechNet article through the November 2024 Administrator Protection announcement, decode the two-question triage rule that generates every MSRC disposition, take each of the nine boundaries and each of the seven features in turn, and finish with a checklist for filing a report that does not come back &quot;by design.&quot;&lt;/p&gt;
&lt;p&gt;To understand why the reply was operationally correct, not a cop-out, we have to walk the document&apos;s history back to its origin: a single article published in &lt;em&gt;TechNet Magazine&lt;/em&gt; in June 2007, by an author Microsoft had named a Technical Fellow just five months before.&lt;/p&gt;
&lt;h2&gt;2. The Pre-Doctrine Era&lt;/h2&gt;
&lt;p&gt;For the first fourteen years of Windows NT, there was no servicing-criteria document. There did not need to be.&lt;/p&gt;
&lt;p&gt;Windows NT 3.1 (July 1993) shipped with the architectural pieces every later boundary entry would rest on: the user-mode/kernel-mode privilege split enforced by the CPU&apos;s ring transitions, securable kernel objects mediated by the reference monitor&apos;s &lt;code&gt;SeAccessCheck&lt;/code&gt; primitive, the Security Account Manager (SAM) database with per-user Security Identifiers (SIDs), discretionary access control lists, and access tokens that travelled with every thread [@openlib-custer-nt]. The kernel boundary -- user-mode code MUST NOT execute kernel code without a syscall transition -- and the user boundary -- one user&apos;s process MUST NOT read another user&apos;s data without permission -- were born here as primitives, two decades before either would be enumerated in a vendor-disclosure document.&lt;/p&gt;
&lt;p&gt;But the architecture was not a doctrine. The boundaries sat &lt;em&gt;implicitly&lt;/em&gt; inside Helen Custer&apos;s &lt;em&gt;Inside Windows NT&lt;/em&gt; (Microsoft Press, 1992) and a handful of internal MSDN reference monographs. A researcher reporting a finding in 1998 could not look up &quot;is this a boundary?&quot; anywhere they were authorised to read.&lt;/p&gt;

A *security boundary* provides a logical separation between the code and data of security domains with different levels of trust [@msrc-criteria]. The defining requirement is that security policy dictates what can pass through the boundary -- a guarantee, not a hint. A *security feature*, by contrast, raises the difficulty of attack but carries no vendor commitment that the separation will hold. This distinction, articulated by Mark Russinovich in 2007, is the load-bearing taxonomy of the entire MSRC triage process.
&lt;p&gt;Three failures accumulated pressure during the implicit-boundary era.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Power Users group.&lt;/strong&gt; Microsoft documented the &lt;code&gt;Power Users&lt;/code&gt; group on Windows 2000 and XP as a &quot;less-privileged-than-administrator&quot; middle tier. Microsoft Knowledge Base article KB 825069 eventually conceded that members could obtain administrator rights through multiple privilege paths (the article has since been retired).The Power Users group survived through Windows Server 2003 and was finally dropped from the default Windows Vista install. The lesson stuck: a tier presented as a separation without a policy-enforced guarantee is not a separation at all. The Russinovich convenience-vs-boundary distinction inherits the lesson. A tier presented operationally as a boundary that turned out never to have been one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The wormable RCE class of 2001-2003.&lt;/strong&gt; Code Red (July 2001) and the RPC DCOM Blaster worm (August 2003) compromised millions of internet-connected Windows hosts [@caida-code-red], [@cert-vu-568148]. Microsoft shipped MS03-026 with Critical severity for the Blaster RPC interface vulnerability [@ms-bulletin-ms03-026]. Operationally, the events made one thing legible: there was no place in the kernel architecture you could point at and say &quot;this is the network boundary that held.&quot; There was a buffer overflow, an unauthenticated RPC call, and a worm.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The 2002 Shatter class.&lt;/strong&gt; In August 2002, a researcher posting under the handle &quot;Foon&quot; (Chris Paget) disclosed to NTBugtraq that any process on the interactive desktop could drive any other process&apos;s windows via Win32 messages [@helpnetsecurity-shatter-2002]. That included &lt;code&gt;SYSTEM&lt;/code&gt;-level services with windows on the same desktop, turning every interactive service into a local privilege-escalation surface. Brett Moore generalised the class the following year in &lt;em&gt;Shattering By Example&lt;/em&gt;, walking message types like &lt;code&gt;WM_SETTEXT&lt;/code&gt;, &lt;code&gt;SB_SETTEXT&lt;/code&gt;, and &lt;code&gt;SB_GETTEXTLENGTH&lt;/code&gt; and turning a one-off bug into a systematic primitive [@exploit-db-21691]. Microsoft&apos;s initial response framed the problem as architectural-by-design rather than as a vulnerability. The community could not predict that response, because the boundary was nowhere written down.&lt;/p&gt;

timeline
    title Pre-doctrine era (NT 3.1 to Vista RTM)
    1993 : Windows NT 3.1 ships with SeAccessCheck and per-user SIDs
    1995 : Windows NT 3.51 and the SAM database stabilise
    1996 : Windows NT 4.0 ships with the Power Users group
    2000 : Windows 2000 introduces Active Directory
    2001 : Code Red worm compromises IIS hosts at internet scale
    2002 : Chris Paget discloses Shatter via NTBugtraq
    2002 : Bill Gates Trustworthy Computing memo reorders Microsoft priorities
    2003 : Brett Moore generalises Shatter in Shattering By Example
    2003 : RPC DCOM Blaster worm and MS03-026
    2006 : Russinovich joins Microsoft via Winternals acquisition
    2006 : Windows Vista RTM ships with UAC, MIC, UIPI, and Session 0 isolation
    2007 : Russinovich promoted to Technical Fellow
&lt;p&gt;The combined pressure forced Bill Gates&apos;s January 15, 2002 &lt;em&gt;Trustworthy Computing&lt;/em&gt; memo -- &lt;em&gt;&quot;Trustworthy Computing is the highest priority for all the work we are doing&quot;&lt;/em&gt; [@wired-twc-memo]. The memo did not itself contain a boundary taxonomy. It reorganised engineering priorities so that one could be written.&lt;/p&gt;
&lt;p&gt;By the November 2006 Vista launch, the mechanisms were in the box. Windows Vista shipped with User Account Control, the linked-token split, Mandatory Integrity Control, the User Interface Privilege Isolation (UIPI) shield, and Session 0 isolation [@ms-news-vista-launch]. By June 2007, those mechanisms had names. The document the next two decades of Windows vulnerability disclosure would route through was about to be written -- not by an MSRC document committee, but by a single Technical Fellow Microsoft had promoted to the title five months earlier.&lt;/p&gt;
&lt;h2&gt;3. Russinovich, June 2007, and the Birth of the Distinction&lt;/h2&gt;
&lt;p&gt;In the June 2007 issue of &lt;em&gt;TechNet Magazine&lt;/em&gt;, Mark Russinovich -- promoted to Technical Fellow that January, after joining Microsoft via the July 2006 Winternals acquisition -- published a single article that would dictate the disposition of every Windows vulnerability filed for the next nineteen years. The article was &lt;em&gt;Inside Windows Vista User Account Control&lt;/em&gt; [@russinovich-vista-uac-wayback]. Its load-bearing section, &lt;em&gt;Elevations and Security Boundaries&lt;/em&gt;, ran two paragraphs.&lt;/p&gt;

It&apos;s important to be aware that UAC elevations are conveniences and not security boundaries. A security boundary requires that security policy dictates what can pass through the boundary. User accounts are an example of a security boundary in Windows because one user can&apos;t access the data belonging to another user without having that user&apos;s permission. -- Mark Russinovich, *Inside Windows Vista User Account Control*, TechNet Magazine, June 2007
&lt;p&gt;The article was first published on TechNet on May 23, 2007 and ran in the June issue of the magazine [@russinovich-vista-uac-announce]. That sentence is the doctrinal origin point. Three architectural ideas appear in it: boundaries exist, they are different from features, and UAC sits on the feature side.&lt;/p&gt;
&lt;p&gt;Russinovich then walked the structural reason. The Vista UAC split-token model shares a great deal between the standard-user token and the elevated-administrator token [@russinovich-vista-uac-wayback]: the same SID, the same &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory, the same &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; registry hive, the same logon session, and the same DOS device object directory. Those shared resources are the reason the elevation path cannot be a &lt;em&gt;guaranteed&lt;/em&gt; separation. An attacker running at standard integrity on the same desktop can interact with the elevated process&apos;s window station, its named objects, and its user-writable files. The convenience is real -- prompting before a privileged operation is a high-friction barrier against accidental elevation. The guarantee is not.&lt;/p&gt;

flowchart TD
    User[Interactive user logs on]
    User --&amp;gt; Linked[Linked-token logon]
    Linked --&amp;gt; Standard[Standard-user token]
    Linked --&amp;gt; Elevated[Elevated administrator token]
    subgraph Shared[Shared resources between the two tokens]
        SID[Same user SID]
        Profile[Same USERPROFILE]
        HKCU[Same HKCU hive]
        Session[Same logon session]
        Desktop[Same interactive desktop]
    end
    Standard -.-&amp;gt; Shared
    Elevated -.-&amp;gt; Shared
    Shared --&amp;gt; Verdict[No guaranteed separation = feature, not boundary]
&lt;p&gt;The article identifies the &lt;em&gt;real&lt;/em&gt; boundaries Windows enforces -- the user boundary (cross-user access requires explicit permission), the kernel boundary (the syscall gate), and the process boundary (one process cannot read another&apos;s memory without &lt;code&gt;PROCESS_VM_READ&lt;/code&gt; access) -- as the lines policy &lt;em&gt;does&lt;/em&gt; enforce. UAC sits among the features that make those boundaries cheaper to defend, not among the boundaries themselves.&lt;/p&gt;

The widely-circulated press narrative is that Microsoft *initially* called UAC a security boundary and *retracted* that classification in 2009 after the Zheng and Rivera research. This framing is false. Russinovich&apos;s June 2007 article already said verbatim that UAC elevations are &quot;conveniences and not security boundaries.&quot; The position was on the record from Vista&apos;s first six months, two years before any 2009 Windows 7 beta disclosure. What Microsoft changed in 2009 was *implementation* -- the UAC slider began running at High integrity, UAC-settings changes began prompting -- not the classification. The Russinovich Windows 7 follow-up restated the original position word for word [@ms-learn-russinovich-win7].
&lt;p&gt;The historical record matters because so much downstream doctrine rests on it. In late January 2009, Long Zheng and Rafael Rivera demonstrated a Windows 7 beta UAC auto-elevation flaw via &lt;code&gt;rundll32.exe&lt;/code&gt;: Microsoft-signed binaries inside &lt;code&gt;%SystemRoot%&lt;/code&gt; auto-elevated when invoked from a process holding the user&apos;s administrator token, and &lt;code&gt;rundll32.exe&lt;/code&gt; accepted arbitrary DLL paths [@crn-uac-flaw-2009].The original &lt;code&gt;istartedsomething.com&lt;/code&gt; post and the Ars Technica contemporary coverage have since been reorganised away by both sites; the CRN contemporary report (cited here) preserves the disclosure timeline, the &lt;code&gt;rundll32.exe&lt;/code&gt; mechanism, and the Microsoft response. The historical claim is uncontested. What is contested is the framing of Microsoft&apos;s response, which primary sources show was implementation hardening, not a change in classification. Microsoft&apos;s &lt;em&gt;initial&lt;/em&gt; reply (&quot;by design; UAC is not a security boundary&quot;) was operationally consistent with the June 2007 article. The &lt;em&gt;engineering&lt;/em&gt; response that followed -- UAC slider promoted to High integrity, UAC-settings changes prompting -- was implementation hardening, not reclassification. The doctrinal position did not move. Russinovich&apos;s July 2009 follow-up, &lt;em&gt;Inside Windows 7 User Account Control&lt;/em&gt;, restated the convenience-vs-boundary argument with the same architectural reasoning [@ms-learn-russinovich-win7].&lt;/p&gt;
&lt;p&gt;Russinovich&apos;s June 2007 article gave the community three ideas: boundaries exist; they are different from features; UAC sits on the feature side. The next step was to publish the table. That took roughly five years.&lt;/p&gt;
&lt;h2&gt;4. The Document Accumulates&lt;/h2&gt;
&lt;p&gt;Between 2007 and 2026, the boundary table grew by accretion. One new entry per Windows generation. The shape of the doctrine changed three times.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 1 -- scattered prose (2007 to roughly 2010).&lt;/strong&gt; Russinovich&apos;s June 2007 article, plus the July 2009 &lt;em&gt;Inside Windows 7 User Account Control&lt;/em&gt; restatement, articulated the convenience-vs-boundary doctrine without a public enumeration. A reader of the two articles could correctly predict the disposition of a UAC bypass, and could correctly predict that user-to-user data access was a CVE-eligible boundary violation. They could not, from those articles alone, predict the disposition of a network-stack RCE, an AppContainer escape, or a guest-to-host virtual-machine break. The doctrine was consistent but it was not yet a document.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 2 -- the enumerated MSRC page (roughly 2010 to 2015).&lt;/strong&gt; The &lt;code&gt;microsoft.com/en-us/msrc/windows-security-servicing-criteria&lt;/code&gt; page appears in something close to its current form. It states the two-question triage rule. It includes the verbatim definition of a security boundary. It enumerates a list of boundaries -- process, kernel, network, session, user, AppContainer, virtual machine, web browser -- and a parallel list of security features. The doctrine moves from a single magazine article to a vendor commitment with a URL [@msrc-criteria].The first-publication date of the page is folk knowledge. Wayback Machine snapshots survive from 2017 onward at the current URL slug. No Microsoft announcement post pins the exact date the page first appeared, so the &quot;roughly 2010&quot; figure is a community estimate rather than a documented birthday.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 3 -- VTL added (2015 to 2017).&lt;/strong&gt; Windows 10 1507 (RTM July 29, 2015) shipped Virtualization-Based Security, the Secure Kernel, Isolated User Mode (IUM), and the first canonical Trustlet -- LsaIso, the Credential Guard isolated LSA process. The boundary table grew a row whose enforcement primitive is the hypervisor itself: VTL0 (the normal kernel) cannot read or modify VTL1 (the Secure Kernel and IUM) without going through documented hypercalls [@ms-learn-vbs-ci]. The strongest local boundary on the system is now classified, not orphaned.&lt;/p&gt;

A *Trustlet* is a process that runs inside Isolated User Mode (IUM) -- the user-mode portion of VTL1 -- protected by the hypervisor from the normal-kernel VTL0 [@ms-learn-vbs-ci]. The canonical example is LsaIso, the Isolated LSA process that holds the credential material Credential Guard protects. Even a kernel-mode attacker in VTL0 cannot read the memory of a Trustlet running in VTL1; the hypervisor&apos;s second-level address translation tables do not map VTL1 pages into VTL0. Cross-VTL communication routes through Virtual Secure Mode hypercalls (`HvCallVtlCall` and `HvCallVtlReturn`), which are the only documented channel.
&lt;p&gt;&lt;strong&gt;Generation 4 -- stabilised reference (2018 to 2024).&lt;/strong&gt; No new rows. The boundary list is treated as a stable reference that MSRC, researchers, and the community all cite. Three flagship community projects encode the doctrine in their names and structure during this period: hfiref0x&apos;s UACMe (more than 80 catalogued UAC bypasses, none of which receive CVE numbers) [@uacme]; Gabriel Landau&apos;s &lt;em&gt;ItsNotASecurityBoundary&lt;/em&gt; GitHub repository, whose name is an explicit homage to MSRC&apos;s admin-to-kernel policy [@landau-itsnotasb-gh]; and Alon Leviev&apos;s &lt;a href=&quot;https://paragmali.com/blog/windows-downdate-when-the-update-itself-is-the-attack/&quot; rel=&quot;noopener&quot;&gt;Windows Downdate&lt;/a&gt;, presented at Black Hat USA 2024 [@leviev-downdate-orig]. The community-side institutional memory now exists outside MSRC, augmented by Matt Miller&apos;s BlueHat IL keynotes (notably the 2019 &lt;em&gt;Trends, challenges, and shifts in software vulnerability mitigation&lt;/em&gt; talk) that carried the boundary-and-mitigations story to the security-conference audience in parallel with the MSRC page [@miller-bluehat-il-2019].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generation 5 -- Administrator Protection (2024 to 2026).&lt;/strong&gt; On November 19, 2024, David Weston announced &lt;a href=&quot;https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/&quot; rel=&quot;noopener&quot;&gt;Administrator Protection&lt;/a&gt; at Microsoft Ignite, framing it as part of the Windows Resiliency Initiative [@weston-ignite-2024]. The Microsoft Learn page carries the verbatim doctrinal statement: &lt;em&gt;&quot;Administrator protection introduces a new security boundary with support to fix any reported security bugs&quot;&lt;/em&gt; [@ms-learn-admin-protection]. This is the first new boundary entry added to the servicing-criteria table in nearly a decade.&lt;/p&gt;

The *System Managed Administrator Account* is the elevation primitive at the heart of Administrator Protection [@ms-learn-admin-protection]. Each interactive user with administrator privileges has a hidden, system-generated, profile-separated SMAA companion account provisioned in the SAM database. Elevations route through Windows Hello consent and run against the SMAA token, which has a *different* SID, a *different* profile directory, and a *different* logon session from the user&apos;s standard-user token. The token is destroyed when the elevated process ends. The shared-resources structural reason UAC could not be a boundary no longer applies, because the SMAA token does not share those resources with the user&apos;s standard token.

timeline
    title Five generations of the boundary doctrine
    section Generation 1 - Scattered prose (2007 to 2010)
        2007 : Russinovich publishes the convenience-vs-boundary distinction
        2009 : Long Zheng and Rafael Rivera force UAC implementation hardening
        2009 : Russinovich Windows 7 follow-up restates the doctrine
    section Generation 2 - Enumerated page (2010 to 2015)
        2010 : MSRC servicing-criteria page goes live with two-question rule
        2014 : hfiref0x publishes UACMe v1.0
        2014 : CVE-2014-4113 Win32k EoP becomes canonical kernel-boundary case
    section Generation 3 - VTL added (2015 to 2017)
        2015 : Windows 10 1507 ships VBS, Secure Kernel, Credential Guard
        2016 : Edge AppContainer sandbox cements the browser boundary entry
        2017 : EternalBlue and MS17-010 anchor the network-boundary case study
    section Generation 4 - Stabilised reference (2018 to 2024)
        2023 : Landau PPLFault names PPL as not a security boundary
        2024 : Landau ItsNotASecurityBoundary homages MSRC policy in repo name
        2024 : Leviev Windows Downdate at Black Hat USA 2024
    section Generation 5 - Administrator Protection (2024 to 2026)
        2024 : Ignite keynote announces Administrator Protection as new boundary
        2025 : Developer-blog detail post lands
        2025 : October non-security update KB5067036 rolls out and is reverted
        2026 : Forshaw publishes nine pre-GA bypasses via Project Zero
&lt;p&gt;The December 1, 2025 rollout revert of the October 2025 non-security update KB5067036 is an application-compatibility decision, not a doctrinal one [@ms-learn-admin-protection]. The Microsoft Learn page now reads that the feature will roll out &quot;at a later date.&quot; The boundary classification stands; the rollout schedule slipped.&lt;/p&gt;
&lt;p&gt;Five generations later, the boundary table has nine entries. The next section walks the parallel evolution that nobody outside MSRC reads first -- the not-a-boundary table -- because that is the table that decides what does &lt;em&gt;not&lt;/em&gt; get a CVE.&lt;/p&gt;
&lt;h2&gt;5. The Not-a-Boundary Table Also Accumulates&lt;/h2&gt;
&lt;p&gt;For every boundary Microsoft has added to the servicing-criteria table, there is a primitive that did not make the list. The not-a-boundary table tells a parallel story: primitives that attackers repeatedly tried to make into boundaries, and that Microsoft repeatedly classified as features. Seven entries, each tied to a load-bearing research artifact.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User Account Control (since June 2007).&lt;/strong&gt; The original not-a-boundary entry; see Section 8.1 for the full treatment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Driver Signing / Code Integrity / KMCS (since the Vista x64 kernel-mode driver signing requirement).&lt;/strong&gt; Local administrator can, by design, load drivers; see Section 8.2. The &quot;bring your own vulnerable driver&quot; (BYOVD) catalog and the &lt;a href=&quot;https://www.loldrivers.io/&quot; rel=&quot;noopener&quot;&gt;LOLDrivers project&lt;/a&gt; are the institutional memory [@loldrivers].&lt;/p&gt;

*BYOVD* is the attack pattern in which a privileged user installs a legitimately-signed driver that happens to contain an exploitable vulnerability, then exploits the driver to obtain arbitrary kernel-mode code execution. Because Driver Signing is on the security-feature side of the doctrine, a BYOVD chain that exploits a signed driver does not, on its own, receive a CVE attributed to Microsoft -- the driver vendor may receive one, but Microsoft does not classify the loadability of the driver as a boundary crossing. The Lazarus Group&apos;s use of expired-but-signed drivers and the broader [LOLDrivers catalog](https://www.loldrivers.io/) are the operational embodiment of this classification [@loldrivers].
&lt;p&gt;&lt;strong&gt;Microsoft Defender / Antimalware.&lt;/strong&gt; A heuristic detection layer cannot, by construction, be a boundary. Defender bypasses earn CVEs only when they also cross another boundary (see Section 8.3 for the Tavis Ormandy 2014 to 2017 network-boundary pattern; the flagship CVE-2017-0290 &lt;em&gt;crazy bad&lt;/em&gt; MsMpEng RCE is the canonical example [@ms-advisory-4022344]).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HVCI / Memory Integrity.&lt;/strong&gt; A feature enforced &lt;em&gt;at&lt;/em&gt; the VTL boundary, not itself a boundary; see Section 8.4.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protected Process Light (PPL).&lt;/strong&gt; Introduced in Windows 8.1 to protect anti-malware services and other specially-signed processes from administrator tampering [@ms-learn-am-ppl]. Gabriel Landau&apos;s PPLFault research preserves the verbatim MSRC position that PPL is not a security boundary; see Section 8.5 for the full Landau quotation [@landau-pplfault].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Administrator-to-kernel privilege escalation.&lt;/strong&gt; Local administrator can, by design, load drivers; see Section 8.6. Gabriel Landau named his False File Immutability research repository &lt;em&gt;ItsNotASecurityBoundary&lt;/em&gt; as an explicit homage to MSRC&apos;s policy [@landau-itsnotasb-gh]; Alon Leviev&apos;s October 2024 Downdate follow-up contains the most recent verbatim Microsoft quotation of this position (see Section 8.6) [@leviev-downdate-update].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Same-user post-authentication.&lt;/strong&gt; Once a process has executed under a user&apos;s session, it inherits that user&apos;s trust; per-process isolation within the same user is not a declared boundary. James Forshaw&apos;s June 3, 2024 &lt;em&gt;Working your way Around an ACL&lt;/em&gt; post is the doctrinal anchor (see Section 8.7 for the verbatim formulation) [@forshaw-tyranid-acl].&lt;/p&gt;
&lt;p&gt;Here are the two tables side by side.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The boundary table (nine entries)&lt;/th&gt;
&lt;th&gt;What enforces it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;NDIS/TCP-IP/SMB/RPC stack; remote callers are the lowest trust tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel&lt;/td&gt;
&lt;td&gt;SYSCALL/SYSRET transition, syscall service table, Driver Verifier, HVCI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeAccessCheck&lt;/code&gt; on &lt;code&gt;PROCESS_VM_READ&lt;/code&gt;, &lt;code&gt;PROCESS_VM_WRITE&lt;/code&gt;, &lt;code&gt;NtDuplicateObject&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session&lt;/td&gt;
&lt;td&gt;Session 0 vs Session 1+; per-session &lt;code&gt;BaseNamedObjects&lt;/code&gt; namespace isolation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Per-user SIDs in SAM, file-system DACL inheritance, per-user &lt;code&gt;HKCU&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AppContainer&lt;/td&gt;
&lt;td&gt;LowBox token + capability SID list + DENY-by-default ACLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Virtual machine (guest-to-host)&lt;/td&gt;
&lt;td&gt;Hyper-V root partition, VMBus, synthetic device model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VTL (VTL0 to VTL1)&lt;/td&gt;
&lt;td&gt;Hypervisor-enforced SLAT (Intel EPT / AMD NPT); VSL hypercalls as the only cross-VTL channel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrator Protection elevation path (2025)&lt;/td&gt;
&lt;td&gt;SMAA with separate SID, profile, logon session; Windows Hello consent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The not-a-boundary table (seven entries)&lt;/th&gt;
&lt;th&gt;Why it is a feature, not a boundary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;UAC&lt;/td&gt;
&lt;td&gt;Split token shares SID, profile, session, namespace; no policy guarantee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Driver Signing / Code Integrity / KMCS&lt;/td&gt;
&lt;td&gt;Administrators can install drivers by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Defender / Antimalware&lt;/td&gt;
&lt;td&gt;Heuristic detection cannot guarantee detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HVCI / Memory Integrity&lt;/td&gt;
&lt;td&gt;A feature enforced &lt;em&gt;at&lt;/em&gt; the VTL boundary, not itself a boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protected Process Light (PPL)&lt;/td&gt;
&lt;td&gt;Hardened against admin tampering, not policy-guaranteed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Administrator-to-kernel privilege escalation&lt;/td&gt;
&lt;td&gt;Admin loads drivers; drivers run in kernel; structural&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same-user post-authentication&lt;/td&gt;
&lt;td&gt;One user, one trust scope; per-process isolation not declared&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The not-a-boundary table is the doctrine &lt;em&gt;learning&lt;/em&gt;. Each new entry is a primitive an attacker class repeatedly tried to treat as a boundary, and Microsoft explicitly classified as a feature so the operational question -- &lt;em&gt;does this report receive a CVE?&lt;/em&gt; -- has a stable answer.&lt;/p&gt;
&lt;p&gt;Two tables. Sixteen total entries. One operational question per report. But how does Microsoft actually apply this -- and why is the application &lt;em&gt;correct&lt;/em&gt;, not a cop-out?&lt;/p&gt;
&lt;h2&gt;6. The Two-Question Triage Rule&lt;/h2&gt;
&lt;p&gt;Here is the load-bearing engineering decision of the entire document: the classification question is &lt;em&gt;decoupled&lt;/em&gt; from the severity question. Microsoft does not ask &quot;is this report important enough to fix&quot; as a single judgment call. It asks two separate questions, and both have to be answered yes.&lt;/p&gt;
&lt;p&gt;The MSRC servicing-criteria page states the rule verbatim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The criteria used by Microsoft when evaluating whether to provide a security update or guidance for a reported vulnerability involves answering two key questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Does the vulnerability violate the goal or intent of a security boundary or a security feature?&lt;/li&gt;
&lt;li&gt;Does the severity of the vulnerability meet the bar for servicing?&quot; [@msrc-criteria]&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;The second question is parameterised by a separate document, the &lt;em&gt;Microsoft Vulnerability Severity Classification for Windows&lt;/em&gt;, often called the &lt;em&gt;Windows Bug Bar&lt;/em&gt; [@msrc-bugbar]. The Bug Bar defines four severity levels -- Critical, Important, Moderate, Low -- with worked examples for each vulnerability type (remote code execution, elevation of privilege, information disclosure, denial of service, spoofing, tampering). It also pivots between server and client severity. A bug that earns Critical on a server can earn Important on a client, and the disposition can change accordingly.&lt;/p&gt;
&lt;p&gt;The first question answers the &lt;em&gt;eligible-by-doctrine&lt;/em&gt; half. A boundary crossing is in scope. A feature defeat is &lt;em&gt;also&lt;/em&gt; in scope -- Microsoft does service security features when the severity bar is met, but the path is different. The second question answers &lt;em&gt;severity-meets-bar&lt;/em&gt;. Critical and Important on the Bug Bar route to a security update via Patch Tuesday (or out-of-band when the impact warrants it). Moderate and Low route to &quot;consider for the next version or release of Windows.&quot;&lt;/p&gt;
&lt;p&gt;The doctrine has an explicit relief valve.&lt;/p&gt;

If the answer to both questions is yes, then Microsoft&apos;s intent is to address the vulnerability through a security update and/or guidance ... If the answer to either question is no, then by default the vulnerability will be considered for the next version or release of Windows but will not be addressed through a security update or guidance, though exceptions may be made. -- Microsoft Security Servicing Criteria for Windows [@msrc-criteria]
&lt;p&gt;Notice the work the &lt;em&gt;and&lt;/em&gt; is doing. Two independent gates, both required. A feature defeat with Critical impact (for example, a Defender bypass that enables ransomware deployment at scale) &lt;em&gt;can&lt;/em&gt; still ship as a Patch Tuesday item -- but it does so via the second question, with the explicit exception clause as the framing. A boundary crossing with Low severity (a process-isolation primitive bypass that requires preconditions no realistic attacker would arrange) might &lt;em&gt;not&lt;/em&gt; ship as a bulletin.&lt;/p&gt;

flowchart TD
    Report[&quot;Vulnerability report arrives at MSRC&quot;]
    Q1{&quot;Q1: Does it violate a boundary or feature?&quot;}
    Q2{&quot;Q2: Does severity meet the bar (Critical or Important)?&quot;}
    Excp{&quot;Exception applies?&quot;}
    Service[&quot;Service via security update / Patch Tuesday&quot;]
    Defer[&quot;By design / consider for next release&quot;]
    Report --&amp;gt; Q1
    Q1 -- &quot;No&quot; --&amp;gt; Excp
    Q1 -- &quot;Yes&quot; --&amp;gt; Q2
    Q2 -- &quot;Yes&quot; --&amp;gt; Service
    Q2 -- &quot;No&quot; --&amp;gt; Excp
    Excp -- &quot;Yes&quot; --&amp;gt; Service
    Excp -- &quot;No&quot; --&amp;gt; Defer
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Classification and severity are decoupled. The &lt;em&gt;and&lt;/em&gt; of the two questions is the doctrine. Every &quot;by design&quot; reply the community has ever received is generated by this exact rule, applied with the published boundary list, the published feature list, the published severity bar, and the published exception clause.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The rule, restated as runnable pseudocode, looks like this. Try the three example inputs to see the doctrine in action.&lt;/p&gt;
&lt;p&gt;{`
// The MSRC servicing-criteria triage, in pseudocode.
const BOUNDARIES = new Set([
  &quot;network&quot;, &quot;kernel&quot;, &quot;process&quot;, &quot;session&quot;, &quot;user&quot;,
  &quot;appcontainer&quot;, &quot;vm&quot;, &quot;vtl&quot;, &quot;administrator-protection&quot;,
]);
const FEATURES = new Set([
  &quot;uac&quot;, &quot;defender&quot;, &quot;hvci&quot;, &quot;driver-signing&quot;,
  &quot;ppl&quot;, &quot;admin-to-kernel&quot;, &quot;same-user&quot;,
]);&lt;/p&gt;
&lt;p&gt;function disposition(report) {
  const { primitive, severity, exception } = report;
  const isBoundary = BOUNDARIES.has(primitive);
  const isFeature  = FEATURES.has(primitive);
  const violatedSomething = isBoundary || isFeature;
  const meetsBar = (severity === &quot;Critical&quot; || severity === &quot;Important&quot;);
  if (violatedSomething &amp;amp;&amp;amp; meetsBar) return &quot;Service via security update&quot;;
  if (exception)                     return &quot;Service via security update (exception)&quot;;
  return &quot;By design / consider for next version&quot;;
}&lt;/p&gt;
&lt;p&gt;// Example 1: a fresh UAC bypass (consent.exe registry hijack)
console.log(&quot;UAC bypass    -&amp;gt;&quot;,
  disposition({ primitive: &quot;uac&quot;, severity: &quot;Important&quot; }));&lt;/p&gt;
&lt;p&gt;// Example 2: a pre-auth SMB RCE like CVE-2017-0144 EternalBlue
console.log(&quot;SMB pre-auth  -&amp;gt;&quot;,
  disposition({ primitive: &quot;network&quot;, severity: &quot;Critical&quot; }));&lt;/p&gt;
&lt;p&gt;// Example 3: a PPLFault-class bypass loading unsigned code into a PPL
console.log(&quot;PPLFault      -&amp;gt;&quot;,
  disposition({ primitive: &quot;ppl&quot;, severity: &quot;Important&quot; }));
`}&lt;/p&gt;
&lt;p&gt;Run it. The UAC bypass returns &quot;Service via security update&quot; only because UAC is on the &lt;em&gt;feature&lt;/em&gt; table -- so the first question is yes (a feature defeat) and the second question is yes (Important severity) -- and &lt;em&gt;both&lt;/em&gt; questions matter. If you change the severity to Moderate the disposition flips to &quot;by design / consider for next version.&quot; If you change the primitive to one that is not on either table, the disposition again becomes &quot;by design&quot; unless the exception clause fires.&lt;/p&gt;
&lt;p&gt;That is the entire MSRC triage rule. Nine boundary entries, seven feature entries, one severity scheme, one exception clause. Every &quot;by design&quot; reply the community has ever received is generated by this exact rule.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A single-question rule would collapse the doctrine. &quot;Is this report important enough to fix&quot; without a published classification turns every disposition into MSRC engineers&apos; personal judgment. &quot;Is this a boundary crossing&quot; without a severity gate would force Microsoft to ship a Patch Tuesday bulletin for every low-impact boundary-adjacent finding, including the ones with no realistic attack path. Decoupling lets Microsoft commit to a published taxonomy on the first question while retaining engineering judgment on the second, with the exception clause as the explicit relief valve in either direction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the rule in hand, the next three sections walk the parameters of the rule -- the nine boundary entries, the seven feature entries, and the bounty schedule that mechanically follows both -- at one consistent pedagogical depth per entry.&lt;/p&gt;
&lt;h2&gt;7. The Nine Boundaries, Walked&lt;/h2&gt;
&lt;p&gt;One subsection per boundary. Each follows the same template: the architectural primitive that enforces the boundary, the canonical CVE-eligible violation pattern, and one verified historical case study.&lt;/p&gt;
&lt;h3&gt;7.1 Network boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; The NDIS / TCP-IP / SMB / RPC / HTTP server stacks treat remote callers as the lowest trust tier. Any code that processes attacker-influenced bytes off the wire before authenticating the caller sits at this boundary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; Pre-authentication remote code execution. A remote attacker reaches &lt;code&gt;SYSTEM&lt;/code&gt; (or any local code execution) without first satisfying an authentication primitive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; EternalBlue, CVE-2017-0144, MS17-010. The SMBv1 server in Windows Vista SP2 through Windows 10 1607 accepted crafted packets that triggered a memory-corruption primitive in the kernel-mode driver, yielding pre-authentication remote code execution [@nvd-2017-0144]. NSA-developed; Shadow Brokers-leaked; weaponised within weeks by WannaCry and NotPetya. Critical severity, mandatory patch, the canonical network-boundary case in the entire taxonomy. SMBGhost (CVE-2020-0796) [@nvd-2020-0796] and PrintNightmare (CVE-2021-34527) [@nvd-2021-34527] are the supporting cases. PrintNightmare is particularly instructive because it crosses &lt;em&gt;two&lt;/em&gt; boundaries simultaneously -- remote code execution via a malicious shared printer driver (network) &lt;em&gt;and&lt;/em&gt; local privilege escalation via the same primitive on the spooler service (kernel).&lt;/p&gt;
&lt;h3&gt;7.2 Kernel boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; The user-mode-to-kernel-mode transition is enforced by the CPU&apos;s privilege rings and the SYSCALL/SYSRET instruction pair. The syscall service table is the only legal way to enter the kernel. Driver Verifier and HVCI run on top of this transition.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; User-mode code achieves kernel-mode code execution without using the legitimate syscall interface, typically by exploiting a memory-safety bug in a kernel driver that the user-mode caller can reach.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; CVE-2014-4113, the Win32k.sys &lt;code&gt;tagWND&lt;/code&gt; elevation-of-privilege bug, exploited in the wild in October 2014.The Win32k subsystem is a recurring source of kernel-boundary findings because it processes window-manager state from user mode in kernel context, an architectural choice that predates the boundary doctrine. MS14-058 / KB3000061 was the Patch Tuesday fix on October 14, 2014 [@ms-bulletin-ms14-058]. The bug allowed a local user to run arbitrary code in kernel mode by crafting calls to the kernel-mode portion of the Win32 subsystem [@nvd-2014-4113]. Important severity; canonical kernel-boundary case; the kind of finding the doctrine was built to service cleanly.&lt;/p&gt;

*`SeAccessCheck`* is the Windows kernel&apos;s reference-monitor function that decides whether a thread holding a specific access token may perform a requested access against a securable object. It takes the object&apos;s security descriptor, the requesting token, and the desired access mask; it returns granted access or `STATUS_ACCESS_DENIED`. Every cross-process memory access, every securable kernel-object open, and every registry-key access ultimately routes through this function. It is the architectural enforcement point for both the process boundary and the user boundary.
&lt;h3&gt;7.3 Process boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; &lt;code&gt;SeAccessCheck&lt;/code&gt; mediates &lt;code&gt;PROCESS_VM_READ&lt;/code&gt;, &lt;code&gt;PROCESS_VM_WRITE&lt;/code&gt;, &lt;code&gt;PROCESS_DUP_HANDLE&lt;/code&gt;, and the access mask passed to &lt;code&gt;NtOpenProcess&lt;/code&gt; [@ms-learn-process-access-rights]. A process cannot read another process&apos;s memory without holding a token that grants the requested access against the target&apos;s security descriptor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; One process reads or writes another process&apos;s address space without having been granted permission.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; Thread injection canon: &lt;code&gt;CreateRemoteThread&lt;/code&gt;, &lt;code&gt;SetWindowsHookEx&lt;/code&gt;, &lt;code&gt;NtMapViewOfSection&lt;/code&gt;. Each violation routes through a documented OS primitive that Microsoft has hardened repeatedly. The hardening culminated in the &lt;a href=&quot;https://paragmali.com/blog/protected-process-light-when-the-administrator-isnt-enough/&quot; rel=&quot;noopener&quot;&gt;Protected Process Light&lt;/a&gt; (PPL) signer-hierarchy enforcement introduced in Windows 8.1, which lets specially-signed processes refuse code injection even from administrator processes [@ms-learn-am-ppl]. PPL itself is on the feature side of the doctrine -- &lt;em&gt;the&lt;/em&gt; canonical example of how the process boundary and PPL interact is the AM-PPL extension that anti-malware vendors use to protect their services from administrator-level interference, which Landau&apos;s research has explored at length [@landau-pplfault].The access-mask argument to &lt;code&gt;NtOpenProcess&lt;/code&gt; is the load-bearing enforcement point. A thread that opens a target process with &lt;code&gt;PROCESS_VM_READ&lt;/code&gt; and then calls &lt;code&gt;ReadProcessMemory&lt;/code&gt; is exercising an &lt;em&gt;audited&lt;/em&gt; boundary crossing; a thread that obtains the target&apos;s handle through a more circuitous route (handle duplication, named-object games) still routes through &lt;code&gt;SeAccessCheck&lt;/code&gt; somewhere. The taxonomy is what gives the audit something to anchor against.&lt;/p&gt;
&lt;h3&gt;7.4 Session boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; Session 0 (system services) is isolated from interactive user sessions (Session 1, Session 2, and so on). Each session has its own &lt;code&gt;\Sessions\&amp;lt;id&amp;gt;\BaseNamedObjects&lt;/code&gt; namespace, its own window station, and its own desktop [@ms-learn-kernel-object-namespaces]. Services that previously ran in the interactive session of the first logged-in user now run in Session 0 with no GUI.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; A low-privilege interactive process sends window messages to a &lt;code&gt;SYSTEM&lt;/code&gt;-level service on the same desktop, driving the service&apos;s UI into executing attacker-controlled code paths.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; The August 2002 Shatter class, generalised by Brett Moore in &lt;em&gt;Shattering By Example&lt;/em&gt; (2003) [@exploit-db-21691]. Microsoft&apos;s architectural response shipped with Windows Vista: Session 0 isolation. Services were moved to Session 0 with no interactive desktop; user applications run in Session 1 and higher. The Microsoft Learn &lt;em&gt;Interactive Services&lt;/em&gt; page records the engineering decision verbatim: &lt;em&gt;&quot;Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code&quot;&lt;/em&gt; [@ms-learn-interactive-services].&lt;/p&gt;
&lt;h3&gt;7.5 User boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; Per-user SIDs in the SAM database (or the domain database for joined hosts), file-system DACL inheritance, per-user &lt;code&gt;HKCU&lt;/code&gt; registry hives, the user profile directory, and the access token that travels with every thread [@ms-learn-access-tokens]. A process running as one user cannot access objects owned by another user unless the DACL explicitly permits it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; One user&apos;s process reads another user&apos;s data without permission. Classic targets: &lt;code&gt;NTUSER.DAT&lt;/code&gt; of another logged-on user, the other user&apos;s &lt;code&gt;%USERPROFILE%&lt;/code&gt;, the other user&apos;s tokens via &lt;code&gt;NtOpenProcess&lt;/code&gt; or &lt;code&gt;NtOpenProcessToken&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; The user boundary is the &lt;em&gt;example&lt;/em&gt; Russinovich uses in his June 2007 article when contrasting boundaries with conveniences [@russinovich-vista-uac-wayback]. User-to-user separation is the canonical &quot;yes, this is a boundary&quot; case in the entire taxonomy; the closest &lt;em&gt;same-user&lt;/em&gt; counter-example -- Forshaw&apos;s June 2024 Recall ACL post -- explicitly notes that &lt;em&gt;user-to-user&lt;/em&gt; would be a boundary, but &lt;em&gt;same-user&lt;/em&gt; per-process isolation is not [@forshaw-tyranid-acl]. The boundary granularity matters: the same primitive class can be a boundary at one granularity and a non-boundary at a finer granularity.&lt;/p&gt;

This is the cleanest illustration of how granularity drives classification. *User to user* is a boundary -- Alice&apos;s process cannot read Bob&apos;s data without explicit permission. *Same user, process to process* is not a boundary -- Alice&apos;s text editor, Alice&apos;s browser, and Alice&apos;s media player all run with Alice&apos;s identity and any one of them can read the others&apos; resources. PPL adds a feature-class barrier within the same user, but Microsoft has explicitly classified PPL as not a boundary [@landau-pplfault]. The taxonomy is consistent: the same primitive (the access token) can guarantee separation across user identities and *not* guarantee separation between two processes that share an identity.
&lt;h3&gt;7.6 AppContainer / sandbox boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; A &lt;a href=&quot;https://paragmali.com/blog/appcontainer-and-lowbox-tokens-windowss-capability-sandbox/&quot; rel=&quot;noopener&quot;&gt;LowBox token&lt;/a&gt; with a capability SID list; default-DENY ACLs against any object that has not explicitly granted the relevant capability; restricted access to the file system, the registry, named objects, and the network stack. AppContainer is built on top of the Mandatory Integrity Control mechanism but is strictly more restrictive than a Low IL token.&lt;/p&gt;

*MIC* is the Windows mechanism that assigns each securable object and each access token an integrity level: Untrusted, Low, Medium (the default for standard users), High (the default for administrators), and System. The access-check rules state that a lower-integrity subject cannot write to a higher-integrity object, regardless of DACL permissions. Introduced in Vista alongside UIPI, MIC underpins both the AppContainer boundary and the UAC feature.
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; A LowBox or AppContainer process escapes its capability list to perform operations the container was supposed to deny.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; Edge sandbox escape canon, from the Anniversary Update (Windows 10 1607, August 2016) forward. AppContainer as a mechanism predates 1607 (it shipped in Windows 8 alongside the Modern UI app model, where it was originally named &lt;em&gt;LowBox&lt;/em&gt;) [@ms-learn-appcontainer-legacy], but the Edge sandbox is the flagship demonstration that AppContainer can serve as a browser-grade sandbox boundary. Edge sandbox escapes route through MSRC as boundary violations and earn the Microsoft Edge Bounty Program payouts [@msrc-bounty-edge].&lt;/p&gt;
&lt;h3&gt;7.7 Virtual machine (guest-to-host) boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; Hyper-V&apos;s root partition versus L1 guest partitions, the &lt;a href=&quot;https://paragmali.com/blog/hyper-v-enlightenments-vmbus-and-the-synthetic-device-model/&quot; rel=&quot;noopener&quot;&gt;VMBus&lt;/a&gt; inter-partition channel, the synthetic device model, the virtualization-service-provider (VSP) and virtualization-service-client (VSC) split. A guest VM communicates with the host only via VMBus, and only through the synthetic devices the host exposes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; A guest VM achieves code execution on the host (or in a sibling guest).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; CVE-2024-21407, a use-after-free in a Hyper-V root-partition component reachable from a guest VM (the MSRC advisory does not name the component), shipped as a Critical-severity Patch Tuesday item on March 12, 2024 [@nvd-2024-21407]. The guest-to-host class pays the highest bounty in the Microsoft Bounty Programs portfolio.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Microsoft Hyper-V Bounty Program pays $5,000 to $250,000 USD for guest-to-host escape vulnerabilities [@msrc-bounty-hyperv]. That is the highest single-finding payout in the Microsoft bounty catalogue [@msrc-bounty-root], and it maps directly to the VM boundary on the servicing-criteria table. The bounty schedule is one of the cleanest market-side confirmations available that the boundary list drives every other operational artifact: the boundary that protects the most consequential trust separation (cloud tenant from cloud tenant on shared hypervisor hardware) also pays the most.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;7.8 VTL (VTL0 to VTL1) boundary&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; Hypervisor-enforced second-level address translation (SLAT, implemented as Intel EPT or AMD NPT) separates the address spaces of VTL0 (the normal kernel and user mode) and VTL1 (the Secure Kernel and Isolated User Mode). The hypervisor mediates every cross-VTL access. The only documented cross-VTL channel is the Virtual Secure Mode hypercall pair (&lt;code&gt;HvCallVtlCall&lt;/code&gt; and &lt;code&gt;HvCallVtlReturn&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; A VTL0 attacker observes or modifies VTL1 memory or Trustlet state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; &lt;a href=&quot;https://paragmali.com/blog/the-empty-hash-credential-guard-the-lsaiso-trustlet-and-the-/&quot; rel=&quot;noopener&quot;&gt;Credential Guard&lt;/a&gt; / Isolated LSA is the canonical VTL1 success story. The LSA Trustlet (LsaIso) holds the credential material Credential Guard protects; even an &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt;-class attacker in VTL0 cannot read those credentials because the relevant pages are not mapped into the VTL0 kernel&apos;s address space at all [@ms-learn-vbs-ci]. The doctrine has a row that says so, and the bounty schedule pays Critical-class amounts under the Windows Insider Preview Bounty Program for VTL violations.&lt;/p&gt;

*Virtual Trust Levels* are the hypervisor-enforced trust tiers Hyper-V introduces inside a single guest partition [@ms-learn-vbs-ci]. VTL0 is the &quot;normal&quot; Windows world: the regular kernel, regular drivers, and regular user-mode processes. VTL1 is the secure world: the Secure Kernel and Isolated User Mode (IUM), where Trustlets like LsaIso run. The hypervisor&apos;s SLAT tables enforce the separation: VTL0 page-table entries that would let the normal kernel read VTL1 memory simply fail the SLAT check at hardware-page-fault granularity. The only cross-VTL channel is the VSL hypercall pair. The VTL boundary is the strongest local boundary on Windows.
&lt;h3&gt;7.9 Administrator Protection elevation path (2025 addition)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Primitive.&lt;/strong&gt; The System Managed Administrator Account (SMAA) sits in the SAM database with its own SID, profile, and home directory. The &lt;code&gt;appinfo.dll&lt;/code&gt; consent service authorises SMAA-scoped elevation via Windows Hello. When a user requests an elevation, &lt;code&gt;appinfo.dll&lt;/code&gt; walks the Windows Hello flow, the SMAA token is created in a fresh logon session, the elevated process runs, and the token is destroyed when the process exits [@ms-learn-admin-protection].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Violation.&lt;/strong&gt; A standard-user process obtains the SMAA&apos;s elevated token without Windows Hello consent, typically by exploiting a primitive in the elevation path that lets the attacker substitute their own controlled object for one the SMAA elevation flow expects to create.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; James Forshaw&apos;s January 2026 nine pre-GA Administrator Protection bypass series, disclosed via the Project Zero issue tracker [@pz-tracker-432313668]. The canonical illustration is the &quot;lazy DOS device directory hijack&quot; (Project Zero issue 432313668): DOS device object directories are created on demand for each logon session rather than at session creation time, and an attacker can race the SMAA elevation flow to create the directory first, with attacker-controlled permissions. Microsoft fixed all nine pre-GA -- not &quot;by design&quot;-replied. The boundary classification is operationally enforced.&lt;/p&gt;

flowchart TB
    subgraph Network[&quot;Network boundary&quot;]
        Remote[&quot;Remote / unauthenticated attacker&quot;]
    end
    subgraph Hypervisor[&quot;Hyper-V root partition&quot;]
        subgraph Guest[&quot;L1 guest VM&quot;]
            subgraph VTL0[&quot;VTL0 (normal kernel)&quot;]
                Kernel[&quot;Kernel mode&quot;]
                subgraph Session1[&quot;Session 1+ interactive&quot;]
                    subgraph User[&quot;Per-user identity&quot;]
                        ProcA[&quot;Process A&quot;]
                        ProcB[&quot;Process B&quot;]
                        subgraph AppC[&quot;AppContainer / LowBox&quot;]
                            Sandbox[&quot;Sandboxed renderer&quot;]
                        end
                    end
                end
                subgraph Session0[&quot;Session 0 services&quot;]
                    Svc[&quot;SYSTEM services&quot;]
                end
                subgraph AP[&quot;Administrator Protection elevation path&quot;]
                    SMAA[&quot;SMAA token&quot;]
                end
            end
            subgraph VTL1[&quot;VTL1 (Secure Kernel + IUM)&quot;]
                Trustlet[&quot;LsaIso Trustlet&quot;]
            end
        end
    end
    Remote -.-&amp;gt;|&quot;Network boundary&quot;| Kernel
    ProcA -.-&amp;gt;|&quot;Process boundary&quot;| ProcB
    Session1 -.-&amp;gt;|&quot;Session boundary&quot;| Session0
    Sandbox -.-&amp;gt;|&quot;AppContainer boundary&quot;| ProcA
    Kernel -.-&amp;gt;|&quot;VTL boundary&quot;| Trustlet
    ProcA -.-&amp;gt;|&quot;Administrator Protection boundary&quot;| SMAA
&lt;p&gt;Nine boundaries. Every one of them backed by a real architectural primitive, every one of them carrying a documented violation history. But the doctrine is only half a table. The other half is the table of primitives Microsoft has &lt;em&gt;explicitly&lt;/em&gt; chosen not to commit to.&lt;/p&gt;
&lt;h2&gt;8. What Is Not a Boundary&lt;/h2&gt;
&lt;p&gt;For every primitive on the boundary list, there is a primitive Microsoft has named in the same document and chosen &lt;em&gt;not&lt;/em&gt; to commit to. The seven entries, with the structural reason for each classification.&lt;/p&gt;
&lt;h3&gt;8.1 UAC&lt;/h3&gt;
&lt;p&gt;Russinovich&apos;s June 2007 sentence is the doctrinal source: &lt;em&gt;&quot;UAC elevations are conveniences and not security boundaries&quot;&lt;/em&gt; [@russinovich-vista-uac-wayback]. The structural reason is the shared-resources model -- same SID, same profile, same logon session, same DOS device object directory between the standard-user and elevated tokens. UACMe is the operational catalogue: more than 80 documented auto-elevation methods, zero CVEs [@uacme]. The reply to a UAC bypass report is &quot;by design, please refer to the servicing criteria,&quot; and that reply is operationally correct.&lt;/p&gt;
&lt;h3&gt;8.2 Driver Signing / Code Integrity / KMCS&lt;/h3&gt;
&lt;p&gt;Local administrator can, by design, install drivers. Once a driver is installed, it runs in kernel mode. Classifying admin-to-kernel as a boundary would require redesigning the Administrators group itself. The downstream operational consequence is the &lt;a href=&quot;https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/&quot; rel=&quot;noopener&quot;&gt;BYOVD attack family&lt;/a&gt;: an administrator installs a legitimately-signed driver with an exploitable vulnerability and uses the driver to obtain arbitrary kernel-mode code execution. Microsoft maintains the &lt;em&gt;Vulnerable Driver Blocklist&lt;/em&gt; as feature hardening, and the Windows Defender Application Control (WDAC) infrastructure as a tighter enforcement option, but those are features layered over a primitive Microsoft has not classified as a boundary [@leviev-downdate-update].&lt;/p&gt;
&lt;h3&gt;8.3 Microsoft Defender / Antimalware&lt;/h3&gt;
&lt;p&gt;A heuristic detection layer cannot, by construction, be a boundary. Antivirus operates by recognising patterns -- signature, behaviour, reputation -- and an adversary tuning a payload against those patterns can always find a path that the detector does not recognise.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A boundary requires that &quot;security policy dictates what can pass through.&quot; Heuristic detection cannot meet that requirement. There is no policy oracle that can decide, in finite time with finite memory, whether an arbitrary binary will exhibit malicious behaviour. The decision problem is undecidable in the general case (Rice&apos;s theorem); in practice antivirus is a probabilistic filter, not a guarantee. Microsoft&apos;s classification of Defender as a feature acknowledges this constraint. Defender will be improved, hardened, and updated -- but the doctrine does not promise that it will &lt;em&gt;catch&lt;/em&gt; any specific malware. Bypassing Defender is expected and continuous, and a Defender-bypass report on its own does not earn a CVE.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tavis Ormandy&apos;s 2014 to 2017 Defender disclosures earned CVEs not because they bypassed Defender&apos;s detection but because they crossed &lt;em&gt;other&lt;/em&gt; boundaries [@ms-advisory-4022344]. The bugs were memory-corruption primitives in the Defender parsing engine reachable from attacker-controlled inputs the engine fetched from email or web traffic. The flagship example is CVE-2017-0290, the &lt;em&gt;crazy bad&lt;/em&gt; MsMpEng RCE Microsoft addressed with out-of-band Security Advisory 4022344 on May 8, 2017 [@ms-advisory-4022344]. The network boundary crossing is what earned the CVE.This is the operational lesson for anyone reporting a Defender finding: lead with the boundary, not the feature. If your bypass is a clever signature evasion, expect a &quot;by design&quot; reply. If your bypass is a parsing-engine memory-corruption primitive that fires from attacker-controlled input arriving over the network, that is a network-boundary crossing and you have a CVE-eligible report.&lt;/p&gt;
&lt;h3&gt;8.4 HVCI / Memory Integrity&lt;/h3&gt;
&lt;p&gt;The doctrinally subtle one. &lt;a href=&quot;https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/&quot; rel=&quot;noopener&quot;&gt;HVCI&lt;/a&gt; is the kernel-mode code integrity check that lives &lt;em&gt;inside&lt;/em&gt; VTL1, running under the protection of the hypervisor. The VTL boundary is what protects HVCI from attacker tampering. HVCI itself is a &lt;em&gt;feature&lt;/em&gt; enforced &lt;em&gt;at&lt;/em&gt; the VTL boundary, not a boundary in its own right.&lt;/p&gt;
&lt;p&gt;The operational consequence: an HVCI bypass that does not also cross VTL0 to VTL1 is a feature defeat. Critical-severity HVCI bypasses may still ship as security updates through the exception clause -- but the primary disposition path is feature-hardening rather than boundary-servicing. Microsoft&apos;s &lt;em&gt;Virtualization-based protection of code integrity&lt;/em&gt; page documents the architecture in detail and is the canonical reference [@ms-learn-vbs-ci].&lt;/p&gt;
&lt;h3&gt;8.5 Protected Process Light (PPL)&lt;/h3&gt;
&lt;p&gt;Introduced in Windows 8.1 to protect anti-malware services and other specially-signed processes from administrator tampering [@ms-learn-am-ppl]. PPL uses code integrity to refuse unsigned code injection into protected processes, and refuses termination requests even from administrators.&lt;/p&gt;
&lt;p&gt;Gabriel Landau&apos;s PPLFault chain demonstrated loading unsigned code into a PPL process by racing the kernel&apos;s signature check against attacker-controlled storage during catalog load -- the False File Immutability primitive [@landau-pplfault], [@landau-ffi-elastic]. Microsoft&apos;s response was the Canary build 25941 mitigation on September 1, 2023 -- feature hardening that ships out-of-cycle when the impact warrants it, &lt;em&gt;not&lt;/em&gt; boundary-class servicing. Landau&apos;s article preserves the verbatim MSRC position.&lt;/p&gt;

The PPL mechanism was introduced in Windows 8.1, enabling specially-signed programs to run in such a way that they are protected from tampering and termination, even by administrative processes ... Microsoft does not consider PPL to be a security boundary, meaning they won&apos;t prioritize security patches for code-execution vulnerabilities discovered therein, but they have historically addressed some such vulnerabilities on a less-urgent basis. -- Gabriel Landau, Elastic Security Labs, September 2023 [@landau-pplfault]
&lt;h3&gt;8.6 Administrator-to-kernel privilege escalation&lt;/h3&gt;
&lt;p&gt;The structural impossibility argument applies cleanly here. By Saltzer-Schroeder&apos;s &lt;em&gt;complete mediation&lt;/em&gt; principle [@saltzer-schroeder-mit], a boundary requires that every access through it be mediated by policy. Administrators are policy-authorised to load drivers; drivers run in kernel mode; therefore admin-to-kernel is the &lt;em&gt;expected&lt;/em&gt; operation, not a policy violation. Reclassifying this as a boundary would mean redesigning the Administrators group itself.&lt;/p&gt;
&lt;p&gt;The Landau &lt;em&gt;ItsNotASecurityBoundary&lt;/em&gt; GitHub repository name is an explicit homage to this Microsoft policy [@landau-itsnotasb-gh]. The repository&apos;s research extends False File Immutability into kernel space: the Windows Code Integrity subsystem (&lt;code&gt;ci.dll&lt;/code&gt;) is itself susceptible to FFI, letting an attacker who controls a catalog file on attacker-controlled storage race the CI signature check and then load unsigned drivers. Microsoft fixed the specific FFI primitive but did not move the admin-to-kernel classification.&lt;/p&gt;
&lt;p&gt;Alon Leviev&apos;s Windows Downdate is the recent flagship demonstration. Microsoft assigned CVE-2024-21302 to the chain because it crossed the VTL boundary; the underlying Windows Update takeover -- the admin-to-kernel piece -- remained unpatched [@leviev-downdate-update]. The classification stood. Specific chains earn CVEs when they cross another boundary; the primitive itself does not become a boundary by accumulation of exploitation evidence.&lt;/p&gt;

While CVE-2024-21302 was patched because it crossed a defined security boundary, the Windows Update takeover which was reported to Microsoft as well, has remained unpatched, as it did not cross a defined security boundary. Gaining kernel code execution as an Administrator is not considered as crossing a security boundary (not a vulnerability). -- Alon Leviev, SafeBreach Labs, October 26, 2024 [@leviev-downdate-update]
&lt;h3&gt;8.7 Same-user post-authentication&lt;/h3&gt;
&lt;p&gt;The most recent addition to the feature table, articulated by James Forshaw in &lt;em&gt;Working your way Around an ACL&lt;/em&gt; (June 3, 2024). Once a process has executed under a user&apos;s session, it inherits the user&apos;s trust. Per-process isolation within the same user is not a declared boundary. Forshaw&apos;s verbatim formulation: &lt;em&gt;&quot;any privilege escalation (or non-security boundary &lt;em&gt;cough&lt;/em&gt;) is sufficient to leak the information&quot;&lt;/em&gt; [@forshaw-tyranid-acl].&lt;/p&gt;
&lt;p&gt;The operational stakes here are higher than they look. AI-mediated features like Windows 11 Recall continuously record sensitive user state into a same-user-readable database. If same-user is not a boundary, every non-PPL local process under the same user identity can read that database. The &quot;ACLed to SYSTEM&quot; mitigation that protects the Recall storage is operationally weak under the doctrine, because &lt;em&gt;any&lt;/em&gt; same-user privilege escalation -- including the entire UACMe catalogue, all of the same-user-post-authentication footguns, and every UI-Access trick -- is a sufficient predicate.&lt;/p&gt;

flowchart TD
    Report[&quot;Vulnerability report arrives&quot;]
    Cls{&quot;Classify primitive&quot;}
    BdyQ2{&quot;Boundary path: severity Critical or Important?&quot;}
    FtrQ2{&quot;Feature path: severity Critical or Important?&quot;}
    Excp{&quot;Exception applies?&quot;}
    SvcBdy[&quot;Boundary servicing: Patch Tuesday CVE&quot;]
    SvcFtr[&quot;Feature servicing: Patch Tuesday CVE (Q2 yes path)&quot;]
    SvcExc[&quot;Exception servicing: feature hardening, possible bulletin&quot;]
    Defer[&quot;By design / consider for next version&quot;]
    Report --&amp;gt; Cls
    Cls -- &quot;Boundary&quot; --&amp;gt; BdyQ2
    Cls -- &quot;Feature&quot; --&amp;gt; FtrQ2
    BdyQ2 -- &quot;Yes&quot; --&amp;gt; SvcBdy
    BdyQ2 -- &quot;No&quot; --&amp;gt; Excp
    FtrQ2 -- &quot;Yes&quot; --&amp;gt; SvcFtr
    FtrQ2 -- &quot;No&quot; --&amp;gt; Excp
    Excp -- &quot;Yes&quot; --&amp;gt; SvcExc
    Excp -- &quot;No&quot; --&amp;gt; Defer
&lt;p&gt;The central insight: the not-a-boundary table is &lt;em&gt;not&lt;/em&gt; a list of bugs Microsoft has not gotten around to fixing. It is a list of primitives Microsoft has &lt;em&gt;deliberately&lt;/em&gt; chosen not to commit to, because guaranteeing those primitives as boundaries would require either reorganising the architecture (admin-to-kernel) or operating against an inherent impossibility (heuristic detection cannot guarantee detection).&lt;/p&gt;
&lt;p&gt;Nine boundaries that Microsoft commits to. Seven features Microsoft hardens but does not commit to. One remaining structural artifact ties the two together: the bounty schedule.&lt;/p&gt;
&lt;h2&gt;9. The Bounty Schedule Mirrors the Boundary List&lt;/h2&gt;
&lt;p&gt;If you wanted a market-side confirmation that the boundary list is the operational anchor, you would look at the bounty schedule. The two documents are mechanically linked.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bounty program&lt;/th&gt;
&lt;th&gt;Payout range&lt;/th&gt;
&lt;th&gt;Primary boundary (or boundaries)&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Microsoft Hyper-V Bounty Program&lt;/td&gt;
&lt;td&gt;$5,000 to $250,000 USD&lt;/td&gt;
&lt;td&gt;Virtual machine (guest-to-host)&lt;/td&gt;
&lt;td&gt;[@msrc-bounty-hyperv]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Insider Preview Bounty Program&lt;/td&gt;
&lt;td&gt;$500 to $100,000 USD&lt;/td&gt;
&lt;td&gt;Kernel, network, sandbox, VBS / VTL&lt;/td&gt;
&lt;td&gt;[@msrc-bounty-wip]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Edge Bounty Program&lt;/td&gt;
&lt;td&gt;$250 to $30,000 USD&lt;/td&gt;
&lt;td&gt;AppContainer / sandbox, network&lt;/td&gt;
&lt;td&gt;[@msrc-bounty-edge]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Bounty Programs (landing)&lt;/td&gt;
&lt;td&gt;Varies by program&lt;/td&gt;
&lt;td&gt;Identity, Cloud, M365, Azure (cloud-side boundaries)&lt;/td&gt;
&lt;td&gt;[@msrc-bounty-root]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standalone UAC bypass bounty&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;(UAC is on the feature list, no bounty)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Hyper-V is the highest payout.&lt;/strong&gt; Up to $250,000 USD for a guest-to-host escape, which is the largest single-finding payout in the Microsoft bounty catalogue [@msrc-bounty-hyperv]. The program&apos;s verbatim definition of an eligible submission is a remote-code-execution vulnerability that lets an L1 guest virtual machine compromise the hypervisor, escape from the guest to the host, or escape to another L1 guest. That maps directly to the VM boundary on the servicing-criteria table. The market signal is unambiguous: the boundary whose violation matters the most pays the most.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows Insider Preview is the kernel / network / VBS catch-all.&lt;/strong&gt; Up to $100,000 USD for vulnerabilities found on the latest Canary Channel build, with the eligibility requirement that the vulnerability &quot;must be Critical or Important severity as defined in the Microsoft Vulnerability Severity Classification for Windows&quot; [@msrc-bounty-wip]. That severity requirement is the &lt;em&gt;Question 2&lt;/em&gt; gate from the two-question rule, written directly into the bounty&apos;s eligibility clause. The bounty program inherits Question 2 mechanically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Edge is the sandbox program.&lt;/strong&gt; Up to $30,000 USD for Edge-unique vulnerabilities (not reproducing on the equivalent Google Chrome channel) in the Dev, Beta, or Stable channels [@msrc-bounty-edge]. The &quot;unique to Edge&quot; requirement reflects that Chromium engine bugs upstream are Google Chrome&apos;s bounty scope; the Microsoft Edge program covers the Edge-specific shell, AppContainer integration, and Windows integration code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The absence of a UAC bounty.&lt;/strong&gt; There is no standalone UAC bypass bounty program. Not because Microsoft does not care about UAC bypasses, but because UAC is not on the boundary list -- the market signal follows the doctrine.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The bounty schedule is the most reliable cross-check available for the boundary list. Reading the bounty page is a reasonable proxy for reading the boundary list, because Microsoft only pays for findings that violate primitives the company has committed to defending. The absence of a UAC bounty, the presence of a $250,000 Hyper-V tier, and the Critical-or-Important severity gate baked into the Windows Insider Preview bounty are all consequences of the servicing-criteria classification. The classification drives the payout. The payout reveals the classification.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The mapping is &lt;em&gt;dominantly&lt;/em&gt; tight, not &lt;em&gt;strictly&lt;/em&gt; tight. The exception clause from the servicing criteria applies here too: a sufficiently impactful feature defeat may receive an out-of-band bounty under the broader Microsoft Bounty Programs umbrella [@msrc-bounty-root]. But the structural mapping is consistent enough that the bounty page is a fair proxy for the classification.&lt;/p&gt;
&lt;p&gt;You have now read the doctrine in full. Two tables, one rule, one bounty overlay. The next question is the one the doctrine itself cannot answer: where are the gaps?&lt;/p&gt;
&lt;h2&gt;10. What the Doctrine Cannot Decide&lt;/h2&gt;
&lt;p&gt;The doctrine is the most enumerated vulnerability-classification policy any major OS vendor has published. It still has gray zones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resourcing versus security.&lt;/strong&gt; Microsoft&apos;s admin-to-kernel position is at least partly a &lt;em&gt;resourcing&lt;/em&gt; decision: finite engineering capacity to harden the admin elevation path. The structural impossibility argument (admin loads drivers; drivers run in kernel) is genuine, but it does not by itself force the classification -- a sufficiently invasive architectural change (sealed-system mode; VTL Enclaves hosting the entire kernel) could in principle move the line. What &quot;guaranteed by Windows&quot; means in a model that admits BYOVD, Windows Downdate, and False File Immutability is a question reasonable researchers can disagree on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Severity-meets-bar as the second filter.&lt;/strong&gt; Two findings that cross the same boundary can receive different fates depending on Question 2. The Bug Bar [@msrc-bugbar] documents the &lt;em&gt;types&lt;/em&gt; of severity (RCE, EoP, info disclosure, DoS, spoofing, tampering) and the &lt;em&gt;pivots&lt;/em&gt; (server vs client; default-on vs default-off; user interaction required vs not), but the thresholds within each type are not exhaustively published. A researcher who knows the boundary list still cannot, from the document alone, predict severity to single-step accuracy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The &quot;exceptions may be made&quot; clause.&lt;/strong&gt; The doctrine itself admits exceptions exist. PPLFault shipped a feature-hardening mitigation in Canary build 25941 [@landau-pplfault] even though PPL is a feature; CVE-2024-21302 received a Patch Tuesday bulletin even though the underlying admin-to-kernel primitive remained on the feature side [@leviev-downdate-update]. Researchers cannot fully predict the MSRC reply from the document alone; the exception clause is structural relief, not an edge case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Boundary classification of paths, not just components.&lt;/strong&gt; Administrator Protection is the elevation &lt;em&gt;path&lt;/em&gt;, not the account [@ms-learn-admin-protection]. Admin-to-kernel via driver load is still not a boundary even when the elevation path is. The two coexist: a researcher who finds a way for a standard-user process to obtain an SMAA elevated token without consent has a CVE-eligible boundary crossing; a researcher who finds a way for an &lt;em&gt;administrator&lt;/em&gt; process to install a vulnerable driver and pivot to kernel has a feature defeat.&lt;/p&gt;

Saltzer and Schroeder&apos;s 1975 *The Protection of Information in Computer Systems* [@saltzer-schroeder-mit] articulates the *open design* principle: the security design should be public, &quot;the mechanisms should not depend on the ignorance of potential attackers.&quot; A published classification doctrine like Microsoft&apos;s satisfies open design. Their *complete mediation* principle is the other constraint at work: a boundary requires that every access through it be mediated by policy. The Microsoft doctrine lives precisely in the gap between *enumerable* (an upper bound: a published doctrine must list the boundaries it commits to) and *complete* (a lower bound: no doctrine can list every primitive that will ever matter). The &quot;exceptions may be made&quot; clause is the doctrine&apos;s explicit acknowledgment of the gap.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The doctrine does not promise that every reported finding will be serviced. It does not promise that severity thresholds are publicly enumerated to single-step accuracy. It does not promise that the boundary list will not grow or contract. It does not promise that two reports against the same primitive at the same severity will receive identical disposition. What it promises is that the &lt;em&gt;classification half&lt;/em&gt; of the triage will follow the published list, and that the &lt;em&gt;exception clause&lt;/em&gt; exists as the explicit relief valve when the published list does not fit. The promise is procedural, not absolute. That procedural promise is what makes the doctrine more legible than any comparable vendor policy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Microsoft&apos;s doctrine has gray zones -- but it has more enumerated certainty than any comparable doctrine. How does it compare to Apple&apos;s, Chromium&apos;s, Mozilla&apos;s, and the Linux kernel&apos;s?&lt;/p&gt;
&lt;h2&gt;11. How Other Vendors Classify the Same Primitives&lt;/h2&gt;
&lt;p&gt;Microsoft&apos;s document is one of five major published doctrines. Each draws the line differently.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Taxonomic structure&lt;/th&gt;
&lt;th&gt;Primary URL&lt;/th&gt;
&lt;th&gt;Example divergence from Microsoft&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;Enumerated boundary + feature tables; two-question rule&lt;/td&gt;
&lt;td&gt;[@msrc-criteria]&lt;/td&gt;
&lt;td&gt;The Microsoft baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apple (macOS / iOS)&lt;/td&gt;
&lt;td&gt;Architectural-by-section; sealed system + SIP&lt;/td&gt;
&lt;td&gt;[@apple-platform-security]&lt;/td&gt;
&lt;td&gt;SIP classifies admin-to-OS-modification as a boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chromium&lt;/td&gt;
&lt;td&gt;Design-time &lt;em&gt;Rule of 2&lt;/em&gt;; severity guidelines for triage&lt;/td&gt;
&lt;td&gt;[@chromium-rule-of-2]&lt;/td&gt;
&lt;td&gt;Design-time pre-commitment, not post-hoc classification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mozilla&lt;/td&gt;
&lt;td&gt;sec-rating (sec-critical / sec-high / sec-moderate / sec-low)&lt;/td&gt;
&lt;td&gt;[@mozilla-client-bounty]&lt;/td&gt;
&lt;td&gt;Severity-only, no primitive enumeration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;Per-subsystem implicit classification&lt;/td&gt;
&lt;td&gt;[@linux-security-bugs]&lt;/td&gt;
&lt;td&gt;No central table; maintainer-driven&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Apple&apos;s Platform Security Guide.&lt;/strong&gt; A sealed-system / Signed System Volume model with stricter user/kernel separation. macOS System Integrity Protection (SIP) restricts the root user account and limits the actions root may perform on protected parts of the OS [@apple-sip-ht204899]. Some admin-to-system-modification paths that Windows classifies as features (Driver Signing, Code Integrity, admin-to-kernel) are classified by SIP as boundaries the OS protects against modification, &lt;em&gt;including&lt;/em&gt; by the local administrator. The Apple guide is less enumerated than Microsoft&apos;s -- it organises by section rather than by table -- but it commits to architectural separations that the open-driver-loading Windows model cannot match [@apple-platform-security].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chromium&apos;s Rule of 2 plus Severity Guidelines.&lt;/strong&gt; A &lt;em&gt;design-time&lt;/em&gt; pre-commitment, fundamentally different from Microsoft&apos;s post-hoc triage. The Rule of 2 states: &lt;em&gt;&quot;When you write code to parse, evaluate, or otherwise handle untrustworthy inputs from the Internet ... Pick no more than 2 of: untrustworthy inputs; unsafe implementation language; and high privilege&quot;&lt;/em&gt; [@chromium-rule-of-2]. Code that violates the rule must be sandboxed before it ships. Site isolation (each origin in its own renderer process) is the operational boundary equivalent. The Severity Guidelines parameterise triage with a Critical (S0) / High / Medium / Low scheme [@chromium-severity-guidelines].The Chromium Rule of 2 and Microsoft&apos;s servicing criteria are not substitutes -- they live at different layers. The Rule of 2 is an &lt;em&gt;engineering&lt;/em&gt; rule that forecloses entire vulnerability classes at design time. The Microsoft doctrine is a &lt;em&gt;triage&lt;/em&gt; rule that classifies findings at disclosure time. A Chromium project can adopt both, and Microsoft Edge does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mozilla&apos;s Client Bug Bounty Program.&lt;/strong&gt; A severity-only rating: sec-critical, sec-high, sec-moderate, sec-low. The bounty page states verbatim: &lt;em&gt;&quot;Typically, the security rating given by the Bounty Committee for a bug must be rated a &apos;sec-high&apos; or &apos;sec-critical&apos; in order for it to be eligible for a bounty&quot;&lt;/em&gt; [@mozilla-client-bounty]. There is no published boundary enumeration. The Bounty Committee&apos;s judgment is the deciding factor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Linux kernel security-bugs process.&lt;/strong&gt; Per-subsystem, not per-boundary. The verbatim policy: &lt;em&gt;&quot;By definition if an issue cannot be reproduced, it is not exploitable, thus it is not a security bug&quot;&lt;/em&gt; [@linux-security-bugs]. CVE assignment runs through the kernel&apos;s CVE Numbering Authority since 2024. There is no Linux equivalent of the MSRC servicing-criteria document; classification is implicit in the maintainer&apos;s response.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s document is the most enumerated, most operationally legible vulnerability-classification doctrine published by any major OS vendor. That legibility is itself a vendor commitment, and is what makes &quot;by design&quot; a predictable answer rather than an arbitrary one. All five doctrines agree that boundaries exist. They disagree on which primitives count, how to enumerate them, and how to communicate the result. Microsoft has chosen the most-enumerated point in that gap. The next question is whether the enumeration will keep growing.&lt;/p&gt;
&lt;h2&gt;12. The 2026 Frontier&lt;/h2&gt;
&lt;p&gt;The boundary list grew by accretion for twenty years. Four pressures are pushing the next additions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloud-side boundaries.&lt;/strong&gt; Conditional Access policy enforcement (Microsoft Entra), the Primary Refresh Token (PRT), and the Microsoft 365 service boundary that Copilot operates within. These are not currently in the Windows servicing criteria -- they are governed by separate MSRC documents and per-product bounty programs [@msrc-bounty-root]. Modern Windows attack chains routinely involve both client-side (Windows) and cloud-side (Entra / Azure) primitives. A finding that crosses a &lt;em&gt;cloud-side&lt;/em&gt; boundary may or may not also cross a &lt;em&gt;client-side&lt;/em&gt; boundary, and the Windows document does not yet arbitrate.&lt;/p&gt;
&lt;p&gt;The open question is whether the Windows servicing criteria document will expand to cover cloud-side primitives, or whether a parallel &lt;em&gt;Microsoft Identity Security Servicing Criteria&lt;/em&gt; document will appear. The bounty pages function as a &lt;em&gt;derived&lt;/em&gt; boundary list today -- reading them tells a researcher which cloud-side primitives Microsoft commits to servicing -- but the unified document does not yet exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agentic / AI-mediated privilege expansion.&lt;/strong&gt; Copilot in Windows and Copilot for Microsoft 365 can take actions on behalf of a user. Prompt injection from untrusted content can cause Copilot to perform actions the user did not intend. Is that a boundary crossing?&lt;/p&gt;

A prompt-injected Copilot action operates *within* the user&apos;s identity and the user&apos;s authorisations. By the same-user-post-authentication classification, that should be a feature defeat, not a boundary crossing. But the *intent* the user expressed (summarise my email; do not exfiltrate it) is defeated by the injected prompt. The doctrine was designed to classify primitives in terms of policy-enforced separations, not in terms of user-intent-vs-attacker-intent. The MITRE ATT&amp;amp;CK framework has begun to enumerate prompt-injection-class techniques [@mitre-attack]; the Microsoft document has not yet. Whichever way Microsoft decides -- a new boundary entry, a new feature entry, or a deferral -- will be the most consequential doctrinal move since the 2025 Administrator Protection addition.
&lt;p&gt;&lt;strong&gt;Administrator Protection rollout resumption.&lt;/strong&gt; The December 2025 revert was an application-compatibility decision; the boundary classification stands [@ms-learn-admin-protection]. What would have to be true for the rollout to resume: Win32 application compatibility validated across the long tail, Visual Studio elevation flows verified, the WebView2 installer regression resolved [@ms-blogs-admin-protection-dev]. What stays the same when it does: Forshaw&apos;s nine pre-GA bypasses all fixed; the elevation path still on the boundary side.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Same-user as a possible new boundary.&lt;/strong&gt; The Recall disclosure and the broader same-user post-authentication class push on this question. The community position, articulated by Forshaw, is that same-user should not be expected to be a boundary [@forshaw-tyranid-acl]. Microsoft&apos;s response has been &lt;em&gt;feature hardening&lt;/em&gt; (Personal Data Encryption, VTL Enclave use) rather than reclassification.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If VTL Enclaves and Personal Data Encryption become a per-user attestable substrate -- a per-user equivalent of VTL1 -- then &lt;em&gt;same-user&lt;/em&gt; could become a boundary in the same way &lt;em&gt;user-to-user&lt;/em&gt; already is. The structural ingredient that VTL1 added to the user boundary (hypervisor-mediated separation that even SYSTEM cannot cross) would be added to a per-process scope within a user&apos;s identity. This is a research-track conjecture, not a Microsoft commitment; no public Microsoft statement has confirmed the direction. But the &lt;em&gt;shape&lt;/em&gt; of how same-user could become a boundary is now legible, in a way it was not before Administrator Protection demonstrated that re-using an existing boundary (user-to-user) for a new primitive (the SMAA elevation path) is a viable engineering pattern.&lt;/p&gt;
&lt;/blockquote&gt;

flowchart LR
    subgraph Existing[&quot;Existing boundaries (current doctrine)&quot;]
        Net[&quot;Network&quot;]
        Krn[&quot;Kernel&quot;]
        Prc[&quot;Process&quot;]
        Sess[&quot;Session&quot;]
        Usr[&quot;User&quot;]
        AC[&quot;AppContainer&quot;]
        VM[&quot;Virtual machine&quot;]
        VTL[&quot;VTL0 to VTL1&quot;]
        AP[&quot;Administrator Protection&quot;]
    end
    subgraph Ingredients[&quot;Structural ingredients pushing the frontier&quot;]
        PRT[&quot;Primary Refresh Token&quot;]
        CA[&quot;Conditional Access policy&quot;]
        PI[&quot;Prompt injection primitives&quot;]
        PDE[&quot;Personal Data Encryption&quot;]
        Enc[&quot;VTL Enclaves&quot;]
    end
    subgraph Candidate[&quot;Candidate future boundaries&quot;]
        Cloud[&quot;Cloud-side: PRT / Conditional Access&quot;]
        AI[&quot;AI-mediated action expansion&quot;]
        SU[&quot;Same-user per-process&quot;]
    end
    Usr --&amp;gt; PRT
    Usr --&amp;gt; CA
    PRT --&amp;gt; Cloud
    CA --&amp;gt; Cloud
    PI --&amp;gt; AI
    Sess --&amp;gt; PI
    PDE --&amp;gt; SU
    Enc --&amp;gt; SU
    VTL --&amp;gt; Enc
&lt;p&gt;None of these candidates is on the table yet. All four are being pushed by primitives -- the Primary Refresh Token, prompt injection, Administrator Protection, the Recall directory ACL -- that have already shipped. The next decade&apos;s boundary list is being negotiated now, in real research posts and MSRC replies. The question is how &lt;em&gt;you&lt;/em&gt; file a report into that negotiation.&lt;/p&gt;
&lt;h2&gt;13. How to File a Useful MSRC Report&lt;/h2&gt;
&lt;p&gt;Everything in this article has been theory until this section. Here is how the doctrine becomes a checklist you can apply to your own findings before the submit button.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read the servicing-criteria document first&lt;/strong&gt; [@msrc-criteria]. Map your finding to a boundary entry. If it does not map, expect a feature-defeat reply. If it maps cleanly, you know in advance that the disposition path goes through Question 2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lead the MSRC submission with the boundary claim in the first sentence.&lt;/strong&gt; &lt;em&gt;&quot;This issue violates the [process | kernel | session | network | user | AppContainer | VM | VTL | Administrator Protection] boundary because &lt;code&gt;&amp;lt;reason&amp;gt;&lt;/code&gt;.&quot;&lt;/em&gt; The triage engineer reading your report should never have to infer which boundary you are claiming. Name it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Include the severity-meets-bar argument in the second paragraph.&lt;/strong&gt; Critical / Important / Moderate / Low per the Bug Bar [@msrc-bugbar]. Cite the specific bug-type cell (RCE, EoP, info disclosure, DoS, spoofing, tampering) and the pivot (server vs client; default-on vs default-off; user interaction required vs not). Worked examples beat assertions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If the finding crosses a feature &lt;em&gt;and&lt;/em&gt; a boundary, lead with the boundary.&lt;/strong&gt; The feature defeat is supporting evidence, not the primary claim. A Defender bypass that also crosses the network boundary is a network-boundary report with a Defender defeat as supporting detail, not the other way around.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expect the reply to be operationally predictable.&lt;/strong&gt; If the finding is on the feature side and severity is not Critical, the reply will be &quot;by design / consider for next version.&quot; Plan publication accordingly. A 90-day Project Zero clock that lines up with a probable &quot;by design&quot; reply is not a failed disclosure -- it is a successful one, because the reply was predicted in advance [@project-zero-9030].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For bounty-eligible classes, read the program-scope page carefully.&lt;/strong&gt; Hyper-V ($5K - $250K) [@msrc-bounty-hyperv], Windows Insider Preview ($500 - $100K) [@msrc-bounty-wip], Edge ($250 - $30K) [@msrc-bounty-edge], plus the Identity / Cloud / M365 / Azure programs [@msrc-bounty-root]. The boundary-payout mapping is dominantly tight; the program-scope page tells you whether the bounty fires.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If the reply surprises you, the &quot;exceptions may be made&quot; clause is the framing&lt;/strong&gt; [@msrc-criteria]. A feature defeat that &lt;em&gt;does&lt;/em&gt; receive a bulletin does not contradict the doctrine; it invokes the exception. A boundary crossing that &lt;em&gt;does not&lt;/em&gt; receive a bulletin invokes the exception in the other direction (severity below bar). Either way, the doctrine is not broken; the exception clause is doing its job.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before you spend three weeks reverse-engineering a primitive, spend three minutes reading the relevant Microsoft Bounty Program scope page. The page tells you, in plain language, whether Microsoft considers the primitive class you are attacking to be bounty-eligible. If the bounty program does not list your primitive class -- if there is no UAC-bypass bounty, no Defender-bypass-by-detection-evasion bounty, no PPL-bypass bounty -- the boundary classification has already told you the operational answer. You can still publish the research; you just know the disposition in advance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;Subject: Boundary violation -- Hyper-V guest-to-host escape via
         root-partition heap UAF (Critical, RCE, default-on)

Section 1 -- Boundary claim
  This issue violates the Hyper-V virtual machine (guest-to-host)
  security boundary as enumerated in the Microsoft Security Servicing
  Criteria for Windows. The attack flow: a malicious L1 guest VM
  triggers a use-after-free in a Hyper-V root-partition component
  reachable via VMBus; the freed allocation is reclaimed with
  attacker-controlled data via a follow-up VMBus message; the
  resulting type confusion yields remote code execution in the host
  root-partition context with SYSTEM privileges.

Section 2 -- Severity argument
  Per the Microsoft Vulnerability Severity Classification for Windows
  bug bar, this is Critical severity:
    - Vulnerability type: Remote Code Execution
    - Server severity: Critical (server pivot: Hyper-V host is by
      definition a server role)
    - Client severity: Critical (client pivot: same primitive on
      client Hyper-V used by Windows Sandbox / WSL2)
    - Default-on: Yes (the affected root-partition component ships
      and runs by default on all Hyper-V hosts)
    - User interaction required: No
    - Attack complexity: Low

Section 3 -- Reproduction
  - Attached: minimal L1 guest exploit binary (Linux x86_64),
    deterministic on Windows Server 2025 Hyper-V build 26100.4061.
  - Attached: WinDbg crash dump showing the UAF and the controlled
    write primitive.
  - Attached: video of the SYSTEM shell on the host opened by an
    unprivileged user in the guest.

Section 4 -- Bounty eligibility
  Microsoft Hyper-V Bounty Program scope: L1 Guest Escape -- RCE on
  the host from the guest. Requested payout tier per program scope
  page.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the checklist. The doctrine is internalised. You can predict the disposition of any Windows finding from the boundary list, the severity scheme, and the exception clause. The only thing left is the closing -- the return to the researcher we opened with.&lt;/p&gt;
&lt;h2&gt;14. Frequently Asked Questions and Closing&lt;/h2&gt;
&lt;p&gt;Return to the researcher we opened with. Their &quot;UAC bypass&quot; was filed against a primitive that was never on the boundary list, and the MSRC reply was operationally correct, not a cop-out. The doctrine the reply invoked is the one this article has just walked.&lt;/p&gt;

No. UAC was never officially classified as a boundary. Mark Russinovich&apos;s June 2007 *Inside Windows Vista User Account Control* article stated verbatim that *&quot;UAC elevations are conveniences and not security boundaries&quot;* -- two years before the January 2009 Long Zheng and Rafael Rivera Windows 7 beta UAC auto-elevation disclosure [@russinovich-vista-uac-wayback]. What Microsoft changed in 2009 was the *implementation* (UAC slider promoted to High integrity; UAC-settings changes prompting), not the *classification*. Russinovich&apos;s July 2009 follow-up article restated the original position [@ms-learn-russinovich-win7].

No. &quot;By design&quot; means the doctrine explicitly chose not to service this primitive class as a boundary violation. Microsoft may still harden the feature in a future Windows release, ship out-of-band Canary build mitigations (as with PPLFault build 25941) [@landau-pplfault], or assign CVEs to specific exploitation chains that cross *other* boundaries (as with Windows Downdate&apos;s CVE-2024-21302) [@leviev-downdate-update]. The finding is interesting research. It simply does not receive a CVE under the published doctrine.

Probably not, but the Administrator Protection elevation *path* is now a boundary [@ms-learn-admin-protection], and the Landau / Leviev disclosures keep pressure on the unmoved part of the classification. The structural impossibility argument (admin loads drivers; drivers run in kernel) makes a doctrinal reclassification unlikely without a deeper architectural change. The most plausible architectural change would be the extension of VTL Enclaves and VBS Trustlets to host security-critical kernel components, such that *admin-to-VTL1* becomes the boundary even as *admin-to-VTL0-kernel* stays a feature [@ms-learn-vbs-ci].

No. Defender bypasses that do not also cross another boundary typically do not receive bulletins. Tavis Ormandy&apos;s 2014 to 2017 Defender disclosures earned CVEs because the bugs were memory-corruption primitives reachable from attacker-controlled inputs over the network -- they crossed the network boundary, not because the Defender bypass itself was a boundary crossing. The CVE-2017-0290 *crazy bad* MsMpEng RCE, addressed by Microsoft Security Advisory 4022344 (May 8, 2017), is the flagship instance [@ms-advisory-4022344]. A clever signature-evasion technique alone earns &quot;by design.&quot;

No. It has grown by accretion: Session 0 isolation (Vista, 2007); AppContainer / Edge sandbox (Windows 8 / 1607, 2012 to 2016); VBS / VTL (Windows 10 1507, 2015); Administrator Protection elevation path (2025) [@ms-learn-admin-protection]. The list is expected to keep growing. Candidate future entries include cloud-side primitives (Conditional Access, Primary Refresh Token) and possibly an AI-mediated action-expansion entry.

Not on its own. BYOVD only earns a Microsoft CVE if a second primitive (network, user, AppContainer) is also crossed, or if the *driver vendor* receives the CVE. The Microsoft *Vulnerable Driver Blocklist* is feature hardening that ships in Windows updates, but the loadability of a properly-signed driver by an administrator is not a boundary crossing under the doctrine [@leviev-downdate-update].

No. AM-PPL is a *feature*. The Microsoft Learn page documents PPL as a hardening mechanism for anti-malware services [@ms-learn-am-ppl], and Gabriel Landau&apos;s *Inside Microsoft&apos;s Plan to Kill PPLFault* preserves the verbatim MSRC position: *&quot;Microsoft does not consider PPL to be a security boundary&quot;* [@landau-pplfault]. Microsoft will still ship PPLFault-class mitigations as feature hardening (build 25941 was the canary), but PPL-bypass reports that do not also cross another boundary do not earn standard Patch Tuesday bulletins.
&lt;h3&gt;Closing&lt;/h3&gt;
&lt;p&gt;The Administrator Protection addition is the most interesting recent move because it &lt;em&gt;closes&lt;/em&gt; the elevation-path gap that the entire UAC era could not close. Microsoft added the SMAA elevation path to the boundary table while leaving the admin-to-kernel primitive on the feature side. The result is a two-tier classification: UAC bypasses still do not get CVEs, but Administrator Protection bypasses do -- and Forshaw&apos;s nine pre-GA disclosures, all of which Microsoft &lt;em&gt;fixed&lt;/em&gt; (not &quot;by design&quot;-replied) are the public-record evidence that the new classification is operationally enforced [@pz-tracker-432313668]. The 2026 frontier is cloud-side and AI-mediated. The boundary list is still growing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The doctrine of what is a boundary is the silent gatekeeper of MSRC triage. Reading it is the difference between filing a useful report and getting back &quot;by design -- UAC is not a security boundary.&quot; Every Windows security engineer should be able to recite the boundary list from memory. After this article, you can.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;windows-security-boundaries-the-document-that-decides-what-gets-a-cve&quot; keyTerms={[
  { term: &quot;Security boundary&quot;, definition: &quot;A logical separation between security domains with different levels of trust, with security policy dictating what can pass through. Boundary crossings receive CVEs under the MSRC servicing criteria when severity meets the bar.&quot; },
  { term: &quot;Security feature&quot;, definition: &quot;A mechanism that raises the difficulty of attack but does not carry a vendor guarantee that policy holds. Feature defeats may still ship as security updates via the exception clause, but they are not boundary crossings.&quot; },
  { term: &quot;Two-question rule&quot;, definition: &quot;(1) Does the vulnerability violate the goal or intent of a security boundary or a security feature? (2) Does the severity meet the bar for servicing? Both yes = service via security update. Either no = by design / next version, with exceptions.&quot; },
  { term: &quot;System Managed Administrator Account (SMAA)&quot;, definition: &quot;The Administrator Protection elevation primitive: a hidden, profile-separated user account with its own SID, profile, and logon session, used to host elevated-administrator tokens authorised via Windows Hello.&quot; },
  { term: &quot;Trustlet&quot;, definition: &quot;A process running in VTL1 (Isolated User Mode), protected by the hypervisor from VTL0 (the normal kernel). LsaIso, the Isolated LSA Trustlet that holds Credential Guard credentials, is the canonical example.&quot; },
  { term: &quot;BYOVD&quot;, definition: &quot;Bring Your Own Vulnerable Driver: an administrator installs a legitimately-signed driver containing an exploitable vulnerability and uses the driver to obtain arbitrary kernel-mode code execution. Not a Microsoft boundary crossing because admin loads drivers by design.&quot; },
  { term: &quot;Protected Process Light (PPL)&quot;, definition: &quot;A signer-hierarchy mechanism introduced in Windows 8.1 that lets specially-signed processes refuse code injection and termination even from administrators. Microsoft explicitly classifies PPL as not a security boundary.&quot; },
  { term: &quot;Mandatory Integrity Control (MIC)&quot;, definition: &quot;Each securable object and access token carries an integrity level: Untrusted / Low / Medium / High / System. Lower-integrity subjects cannot write to higher-integrity objects regardless of DACL permissions.&quot; }
]} flashcards={[
  { front: &quot;Is UAC a security boundary?&quot;, back: &quot;No. UAC has been classified as a security feature, not a boundary, since Russinovich&apos;s June 2007 TechNet article. UACMe has documented more than 80 auto-elevation bypasses and zero CVEs.&quot; },
  { front: &quot;Is admin-to-kernel a security boundary?&quot;, back: &quot;No. Administrators can load drivers by design; drivers run in kernel mode. The Landau ItsNotASecurityBoundary repo name is an explicit homage to this MSRC policy.&quot; },
  { front: &quot;Is the Administrator Protection elevation path a security boundary?&quot;, back: &quot;Yes, as of 2025. The SMAA token has a separate SID, separate profile, and separate logon session from the user&apos;s standard-user token; the user boundary applies.&quot; },
  { front: &quot;Is HVCI a security boundary?&quot;, back: &quot;No. HVCI is a feature enforced inside VTL1. The VTL boundary is on the boundary list; HVCI is a feature that lives at that boundary.&quot; },
  { front: &quot;Is PPL a security boundary?&quot;, back: &quot;No. Microsoft has stated verbatim that &apos;Microsoft does not consider PPL to be a security boundary.&apos; AM-PPL is a feature that protects anti-malware services.&quot; },
  { front: &quot;Is bypassing Defender a CVE?&quot;, back: &quot;Only if the bypass also crosses another boundary. Defender-itself bypasses are feature defeats; Tavis Ormandy&apos;s 2014 to 2017 CVEs crossed the network boundary.&quot; },
  { front: &quot;Is same-user post-authentication a security boundary?&quot;, back: &quot;No. Once a process executes under a user&apos;s session, it inherits the user&apos;s trust. Forshaw&apos;s June 2024 Recall ACL post is the doctrinal anchor.&quot; },
  { front: &quot;Is guest-to-host on Hyper-V a security boundary?&quot;, back: &quot;Yes. It pays $5,000 to $250,000 USD under the Microsoft Hyper-V Bounty Program -- the highest single-finding payout in the Microsoft bounty catalogue.&quot; }
]} questions={[
  { q: &quot;Why is decoupling Question 1 (classification) from Question 2 (severity) the load-bearing engineering decision of the entire doctrine?&quot;, a: &quot;Because a single-question rule would collapse the doctrine into opaque MSRC judgment. Decoupling lets Microsoft commit to a published taxonomy on the classification half while retaining engineering judgment on severity, with the explicit exception clause as the relief valve in either direction.&quot; },
  { q: &quot;Explain why HVCI is on the feature list even though VTL is on the boundary list.&quot;, a: &quot;HVCI is a feature enforced inside VTL1, under the protection of the hypervisor. The VTL boundary protects HVCI from VTL0 attackers, but HVCI itself does not enforce a separation between security domains. The boundary is the VTL line; HVCI is one of the features that runs at that boundary.&quot; },
  { q: &quot;How did Administrator Protection close a gap that the entire UAC era could not?&quot;, a: &quot;By creating a new elevation primitive (the SMAA token) with a separate SID, separate profile, and separate logon session, so that the existing user boundary applies. The Russinovich-2007 shared-resources structural argument that disqualified UAC from boundary status no longer applies because the SMAA token does not share those resources with the standard-user token.&quot; },
  { q: &quot;Why does the absence of a UAC-bypass bounty matter for understanding the doctrine?&quot;, a: &quot;Because the bounty schedule mirrors the boundary list mechanically. Microsoft only pays standalone bounties for findings that violate primitives the company commits to defending. The absence of a UAC bounty is structural, not oversight: there is no boundary to violate, so there is nothing to pay for.&quot; },
  { q: &quot;Predict the MSRC disposition of a Defender bypass that allows malware to evade signature detection but does not introduce any other primitive. Justify your prediction.&quot;, a: &quot;By design / consider for next version. Defender is on the feature list (heuristic detection cannot guarantee detection); a signature-evasion technique is a feature defeat with no boundary crossing; the severity gate is satisfied only by Critical / Important impact, and a pure detection evasion typically does not meet the bar. The exception clause could fire for an unusually impactful detection-evasion technique, but the default disposition is by design.&quot; }
]} /&amp;gt;&lt;/p&gt;
&lt;p&gt;The boundary list. From memory. Now.&lt;/p&gt;
</content:encoded><category>windows-security</category><category>msrc</category><category>vulnerability-disclosure</category><category>security-boundaries</category><category>cve</category><category>patch-tuesday</category><category>uac</category><category>administrator-protection</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Adminless: How Windows Finally Made Elevation a Security Boundary</title><link>https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/</link><guid isPermaLink="true">https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/</guid><description>Administrator Protection replaces UAC with a system-managed admin account created per elevation, gated by Windows Hello, and destroyed when the job is done.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Administrator Protection (informally &quot;Adminless&quot;) replaces Windows 11&apos;s split-token UAC with a separate, system-managed local user account.** The operating system creates this **System Managed Administrator Account (SMAA)** per local admin, links it to the primary admin via paired SAM attributes, and uses it to host elevated processes in a fresh logon session gated by Windows Hello. The kernel asks LSA to authenticate &quot;a new instance of the shadow administrator&quot; without any SMAA credential because the SMAA has none. The mechanism makes the elevation path a security boundary for the first time, with bulletin-grade fixes when it fails. Microsoft shipped it in KB5067036 on October 28, 2025, then reverted it on December 1, 2025 over an application-compatibility issue, not a security failure. This article walks the twenty-year argument that produced the design, the nine pre-GA bypasses Forshaw found and Microsoft fixed, and exactly where the new boundary still leaks.
&lt;h2&gt;1. Two tokens, one user, twenty years&lt;/h2&gt;
&lt;p&gt;Open an elevated console on a Windows 11 device with the registry value &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; set, and run &lt;code&gt;whoami /all&lt;/code&gt;. The user name is no longer yours. It is &lt;code&gt;ADMIN_&amp;lt;sixteen random characters&amp;gt;&lt;/code&gt; -- a local account you never created, owned by an operating-system component you never ran, in a logon session that did not exist five seconds ago and will not exist five seconds after the console closes.&lt;/p&gt;
&lt;p&gt;For twenty years, an elevated Windows command prompt reported the same user name as the unelevated one. The integrity level changed. The token changed. The user did not. That single architectural fact is the load-bearing premise of every UAC bypass ever published. The Vista User Account Control design from 2006 issued two tokens at logon for a member of the local Administrators group: a filtered standard-user token for everyday work, and a full admin token linked to it via the &lt;code&gt;TokenLinkedToken&lt;/code&gt; field [@ms-uac-how-it-works]. When the user clicked Yes on a consent prompt, the Application Information service called &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with the linked token. Same user. Same profile. Same &lt;code&gt;HKCU&lt;/code&gt;. Same logon session. Different integrity level.&lt;/p&gt;
&lt;p&gt;Four resources stayed shared between the filtered and full tokens, and four categories of attack grew out of them. Files dropped in a writable directory the elevated process trusts. Registry values planted under &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; that an elevated binary reads before it consults &lt;code&gt;HKEY_CLASSES_ROOT&lt;/code&gt;. COM elevation monikers that hand the attacker an elevated &lt;code&gt;IFileOperation&lt;/code&gt; interface. Path-resolution overrides that redirect &lt;code&gt;%SystemRoot%&lt;/code&gt; for a single auto-elevating process. The UACMe project [@uacme] catalogues 81 such methods, each one a load against the shared-resource shape of Vista&apos;s split token.&lt;/p&gt;
&lt;p&gt;Administrator Protection inverts that shape. The elevated administrator becomes a &lt;em&gt;different account&lt;/em&gt; with a different security identifier, a different profile directory, a different &lt;code&gt;NTUSER.DAT&lt;/code&gt; hive, a different authentication-ID LUID, and a different DOS device object directory under &lt;code&gt;\Sessions\0\DosDevices\&lt;/code&gt;. The operating system manages the account itself. It is created on demand the first time the policy is enabled, linked to the primary admin via paired Security Account Manager attributes, used in a fresh logon session for every elevation, and the elevated token is destroyed when the process exits [@ms-developer-blog-2025, @call4cloud-osint].&lt;/p&gt;
&lt;p&gt;The feature ships under four names -- &lt;strong&gt;Administrator Protection&lt;/strong&gt; in Microsoft Learn, &lt;strong&gt;Adminless&lt;/strong&gt; as the community shorthand this article uses, &lt;strong&gt;ShadowAdmin&lt;/strong&gt; in the &lt;code&gt;samsrv.dll&lt;/code&gt; engineering symbols, &lt;strong&gt;System Managed Administrator Account (SMAA)&lt;/strong&gt; in the Windows Developer Blog [@ms-admin-protection, @ms-developer-blog-2025, @call4cloud-osint] -- and §6 walks each in turn. The launch arc was short: announced at Ignite 2024 by David Weston on November 19, 2024 [@bleepingcomputer-2024], surfaced earlier that fall in Insider Preview build 27718 on October 2, 2024 [@ms-insider-build-27718], shipped to stable Windows in KB5067036 on October 28, 2025 [@ms-kb5067036], and disabled on December 1, 2025 over a WebView2 application-compatibility regression [@forshaw-pz-jan2026, @ms-admin-protection].&lt;/p&gt;
&lt;p&gt;This article walks what changed and what did not. By the end you will know exactly which UAC bypass families are dead, exactly which survive, exactly what the December 2025 revert was about, and exactly where the new boundary still leaks. The path runs through twenty years of design tradeoffs and seven years of binary-level fixes that never converged on a real boundary. It runs through nine Project Zero bypasses Microsoft fixed before shipping. It ends at a question Microsoft&apos;s own design documents do not yet answer: when the prompt is a credential gate instead of a click-through, what is left for the attacker to do?&lt;/p&gt;
&lt;p&gt;The first thing to understand is what UAC was trying to do, and why Microsoft said for twenty years it was not a security boundary.&lt;/p&gt;
&lt;h2&gt;2. &quot;Convenience, not boundary&quot;: UAC as Microsoft conceived it&lt;/h2&gt;
&lt;p&gt;Why did Vista ship UAC at all? For most of Windows history, every interactive logon for a member of the local Administrators group produced one full-admin token. The desktop shell ran as a full administrator. Every child process inherited those rights. The worm era of 2003 to 2005 demonstrated, repeatedly, that one process running in user context owned the whole machine. By 2006 the cost of admin-by-default had become impossible to defend [@wikipedia-uac].The pre-Vista &lt;em&gt;Limited User Account&lt;/em&gt; (LUA) was Microsoft&apos;s first attempt at a fix. The conceptual ancestor of the filtered token failed in practice because roughly half of the third-party application base broke under it, and the documented workaround -- &lt;code&gt;RUNAS.EXE&lt;/code&gt; -- was operationally hostile enough that almost no one used it.&lt;/p&gt;
&lt;p&gt;The redesign that produced UAC pivoted on a single observation. Forcing administrators to run as standard users had failed because too much software assumed admin rights. So Vista would give each admin user &lt;em&gt;two&lt;/em&gt; identities. One would be standard-user enough to run the desktop, the browser, and the day-to-day applications without privilege. The other would carry the admin rights, and the operating system would arrange for the user to opt into it on a per-task basis.&lt;/p&gt;
&lt;p&gt;Mark Russinovich&apos;s June 2007 article &lt;em&gt;Inside Windows Vista User Account Control&lt;/em&gt; in TechNet Magazine [@russinovich-2007-vista] remains the canonical reference for the design. The mechanism is two tokens at logon; the integrity-level taxonomy (Low, Medium, High, System) gating object access; file-system and registry virtualisation rerouting writes by legacy apps; and Mandatory Integrity Control enforcing the no-write-up rule at the kernel-object boundary.&lt;/p&gt;

The mechanism by which Vista UAC assigns two distinct access tokens to a single interactive logon for a member of the local Administrators group. The Local Security Authority issues both at logon: a filtered standard-user token with most privileges removed and the Administrators group marked as deny-only, and a linked full administrator token referenced from the filtered token&apos;s `TokenLinkedToken` field [@ms-uac-how-it-works].
&lt;p&gt;The disclaimer that follows the design is the single most quoted sentence Russinovich ever published about UAC. The article will lift it verbatim once, because every Administrator Protection design decision falls out of its absence:&lt;/p&gt;

It&apos;s important to be aware that UAC elevations are conveniences and not security boundaries. -- Mark Russinovich, *Inside Windows Vista User Account Control*, TechNet Magazine, June 2007 [@russinovich-2007-vista]
&lt;p&gt;This is not an accidental disclaimer. It is the canonical Microsoft classification, preserved into the Microsoft Security Servicing Criteria document [@msrc-servicing-criteria]. James Forshaw of Google Project Zero, writing in January 2026, re-states the position verbatim: &quot;due to the way it was designed, it was quickly apparent it didn&apos;t represent a hard security boundary, and Microsoft downgraded it to a security feature&quot; [@forshaw-pz-jan2026]. The classification is what determined what Microsoft would and would not pay attention to. A &quot;security boundary&quot; gets a security bulletin when an attacker crosses it. A &quot;security feature&quot; does not. A bypass of a boundary is a vulnerability. A bypass of a feature is a quality bug. For twenty years, UAC bypasses were quality bugs.&lt;/p&gt;
&lt;p&gt;The two-tokens-at-logon mechanism is the shape from which the entire bypass canon grows. The twenty years of evolution that follow run along a single timeline.&lt;/p&gt;

timeline
    title Privilege separation in Windows, NT 3.1 to Administrator Protection
    1993 : NT 3.1 ships multi-user accounts and DACLs but admin-by-default desktop culture
    2006 : Vista UAC introduces the split-token model and Mandatory Integrity Control
    2009 : Davidson publishes the first UAC bypass; Windows 7 ships auto-elevation
    2014 : hfiref0x&apos;s UACMe catalogue collects the bypass canon
    2016 : enigma0x3 publishes the registry-hijack family (eventvwr, fodhelper, sdclt)
    2019 : CVE-2019-1388 (consent.exe certificate dialog) is the lone UAC LPE bulletin
    2024 : Insider Preview build 27718 surfaces Administrator Protection; Ignite 2024 announces it
    2025 : KB5067036 ships the SMAA on stable Windows, then reverts on December 1
    2026 : Forshaw&apos;s nine pre-GA bypasses all fixed; the elevation path is now a security boundary
&lt;p&gt;To see why the entire bypass canon grew out of the split-token shape, the next section walks the mechanic at function-name granularity. It is the load-bearing pre-history of everything that comes after.&lt;/p&gt;
&lt;h2&gt;3. The Vista UAC split-token in detail&lt;/h2&gt;
&lt;p&gt;The mechanics at logon. The Local Security Authority Subsystem Service (LSASS) validates credentials. For a user in the local Administrators group, it constructs two tokens. The filtered token has its dangerous privileges removed and the Administrators SID marked deny-only; the full token retains them. The Token Manager wires the filtered token&apos;s &lt;code&gt;TokenLinkedToken&lt;/code&gt; field to a handle on the full token. LSASS hands the filtered token to &lt;code&gt;winlogon.exe&lt;/code&gt;. Winlogon launches &lt;code&gt;userinit.exe&lt;/code&gt;. Userinit launches &lt;code&gt;explorer.exe&lt;/code&gt;. The shell, holding the filtered token, becomes the parent process from which every user-initiated process inherits [@ms-uac-how-it-works].&lt;/p&gt;

The kernel structure that connects the filtered standard-user token to the linked full administrator token in Vista&apos;s split-token model. A process holding the filtered token can read the `TokenLinkedToken` field via the `GetTokenInformation` API to discover the handle of the full token, and pass that handle to `CreateProcessAsUser` to launch an elevated child. The same link is the structural premise of token-stealing attacks: any code path that can read or impersonate the linked token bypasses the consent UI entirely [@ms-uac-how-it-works, @forshaw-pz-jan2026].
&lt;p&gt;The shell shares four resources with anything launched under the full token.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The same user security identifier.&lt;/strong&gt; Both tokens carry the same primary SID. Files, registry keys, and kernel objects that grant access to the user grant identical access to both processes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory tree.&lt;/strong&gt; &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\&lt;/code&gt; is the home of both. The Documents folder, the Downloads folder, the AppData hives, and any application-specific subdirectory belong to one user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; hive.&lt;/strong&gt; Both tokens map &lt;code&gt;HKCU&lt;/code&gt; to the same &lt;code&gt;NTUSER.DAT&lt;/code&gt; file. An elevated process that reads a user setting reads the value the unelevated user wrote.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same logon-session LUID.&lt;/strong&gt; The Locally Unique Identifier that identifies an interactive logon session is the same on both tokens. The kernel uses that LUID as a key for per-logon-session caching: the DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt;, drive-letter mappings, mapped network drives, and the credential cache.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The elevation pipeline. A user clicks Yes on a UAC prompt. The mechanism beneath that click runs through a chain of named function calls.&lt;/p&gt;

sequenceDiagram
    participant User as User shell (filtered token)
    participant AppInfo as appinfo.dll (Application Information service)
    participant Consent as consent.exe (secure desktop)
    participant LSA as LSASS
    participant New as Elevated child process&lt;pre&gt;&lt;code&gt;User-&amp;gt;&amp;gt;AppInfo: ShellExecute / CreateProcess &quot;as admin&quot;
AppInfo-&amp;gt;&amp;gt;AppInfo: RAiLaunchAdminProcess RPC
AppInfo-&amp;gt;&amp;gt;AppInfo: Read manifest requestedExecutionLevel
AppInfo-&amp;gt;&amp;gt;AppInfo: Check ConsentPromptBehaviorAdmin
AppInfo-&amp;gt;&amp;gt;Consent: Launch consent.exe on Winlogon desktop
Consent-&amp;gt;&amp;gt;User: Show Yes / No prompt
User--&amp;gt;&amp;gt;Consent: Click Yes
Consent--&amp;gt;&amp;gt;AppInfo: Approved
AppInfo-&amp;gt;&amp;gt;LSA: Resolve TokenLinkedToken handle
AppInfo-&amp;gt;&amp;gt;New: CreateProcessAsUser(linked full token)
Note over New: Same SID and profile and HKCU and logon session
Note over New: Integrity level High
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The prompt runs on the &lt;em&gt;secure desktop&lt;/em&gt;, the same Winlogon-owned &lt;code&gt;Winsta0\Winlogon&lt;/code&gt; desktop where the credential-entry dialog appears at logon, not the user&apos;s interactive &lt;code&gt;Winsta0\Default&lt;/code&gt; desktop [@ms-uac-how-it-works]. User Interface Privilege Isolation (UIPI) blocks lower-integrity input from reaching higher-integrity windows; the secure-desktop switch is its first defence against synthetic-keystroke attacks against the prompt itself.The secure desktop is not invulnerable. It changes the integrity-isolation context, but a process holding the filtered token can still trigger the switch (that is the whole point of clicking Yes), and code running before the switch can in principle modify the surrounding UI state. CVE-2019-1388 in late 2019 turned out to exploit a different aspect entirely -- a UI-interaction path through the consent.exe certificate-viewer dialog -- and not the secure-desktop switch itself.&lt;/p&gt;
&lt;p&gt;Compare this to what comes next. Both tokens share four resources. Each of those resources is a category of attack waiting for a researcher to find it. The next section is the story of what happened when Microsoft tried to make UAC less annoying by silently elevating its own Microsoft-signed binaries -- and what the bypass canon did with the change.&lt;/p&gt;
&lt;h2&gt;4. Windows 7 auto-elevation and the birth of the bypass canon&lt;/h2&gt;
&lt;p&gt;A specific moment. December 2009. Leo Davidson publishes &lt;em&gt;Windows 7 UAC whitelist: Code-injection Issue / Anti-Competitive API / Security Theatre&lt;/em&gt; on pretentiousname.com [@davidson-2009]. The title is the argument. The page itself is sprawling, contentious, and on a few key technical points exactly right. Microsoft&apos;s response, in Davidson&apos;s own words: &quot;this is a non-issue, and ignored my offers to give them full details for several months.&quot; Microsoft Security Essentials eventually classified the &lt;em&gt;binary&lt;/em&gt; (not the technique) as &lt;code&gt;HackTool:Win32/Welevate.A&lt;/code&gt; and &lt;code&gt;HackTool:Win64/Welevate.A&lt;/code&gt;; in Davidson&apos;s pointed observation, &quot;recompiling the binaries in VS2010 means they are no longer detected&quot; [@davidson-2009].Davidson kept writing into his original page over the following decade. A marker buried inside the text reads &quot;As I was typing more words into this page, this appeared in my text editor at the 10,000th word!&quot; In March 2020 he removed the proof-of-concept binaries, noting &quot;I got sick of the page being marked as malware, even by Google (FFS).&quot; The prose remains the canonical first source on UAC bypasses [@davidson-2009].&lt;/p&gt;
&lt;p&gt;What Windows 7 added, in October 2009, to fix Vista&apos;s prompt-fatigue problem [@russinovich-2009-win7]:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;autoElevate=true&lt;/code&gt; manifest attribute, embedded in selected Microsoft-signed Windows binaries.&lt;/li&gt;
&lt;li&gt;An internal whitelist of Microsoft-signed binaries living under &lt;code&gt;%SystemRoot%\System32&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;COM Elevation Moniker&lt;/strong&gt; -- already shipping in Vista (&lt;code&gt;BIND_OPTS3&lt;/code&gt;, syntax &lt;code&gt;Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;&lt;/code&gt;) -- was the activation primitive. Windows 7 extended &lt;em&gt;implicit&lt;/em&gt; auto-elevation to qualifying COM servers whose registrations matched the new whitelist criteria, so callers such as &lt;code&gt;IFileOperation&lt;/code&gt;, &lt;code&gt;ICMLuaUtil&lt;/code&gt;, and &lt;code&gt;IColorDataProxy&lt;/code&gt; could be launched elevated without a consent prompt under the Win7 model [@russinovich-2009-win7, @uacme]. The dedicated registry-curation surface, the &lt;code&gt;COMAutoApprovalList&lt;/code&gt; (&lt;code&gt;HKLM\Software\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList&lt;/code&gt;) that UACMe Method 49 references verbatim, did &lt;em&gt;not&lt;/em&gt; ship in Windows 7; it was introduced seven years later in Windows 10 RS1 (build 14393, August 2016) as a Redstone-1 hardening that replaced implicit COM auto-elevation with explicit list curation [@uacme].&lt;/li&gt;
&lt;li&gt;The default consent-prompt behaviour &lt;code&gt;ConsentPromptBehaviorAdmin = 5&lt;/code&gt;: prompt for consent for non-Windows binaries [@russinovich-2009-win7].&lt;/li&gt;
&lt;/ol&gt;

The Windows 7 mechanism by which selected Microsoft-signed binaries elevate without showing the consent prompt to a user who is a member of the local Administrators group. The Application Information service consults a whitelist of signature, path, and manifest attributes; if the binary qualifies, `appinfo.dll` calls `CreateProcessAsUser` with the linked full token and no UI step at all [@russinovich-2009-win7].

A COM activation syntax introduced in Windows Vista that lets an unelevated caller request an elevated instance of a COM server class. The `IBindCtx` is augmented with a `BIND_OPTS3` structure carrying a window handle to attribute the prompt to. The bind moniker `Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;` causes the COM Service Control Manager to launch the server elevated. UACMe methods that target `IFileOperation`, `ICMLuaUtil`, and `IColorDataProxy` all descend from this mechanism [@russinovich-2009-win7, @uacme].
&lt;p&gt;Davidson&apos;s technique against the new whitelist is one paragraph of detail. Use the &lt;code&gt;IFileOperation&lt;/code&gt; COM elevation moniker, which itself auto-elevates, to write a planted &lt;code&gt;CRYPTBASE.DLL&lt;/code&gt; into &lt;code&gt;%SystemRoot%\System32\sysprep\&lt;/code&gt;. The path is a writable destination from the limited token because &lt;code&gt;IFileOperation&lt;/code&gt; runs elevated. Then launch &lt;code&gt;sysprep.exe&lt;/code&gt;, which is auto-elevated as a Microsoft-signed binary in System32. Sysprep loads &lt;code&gt;CRYPTBASE.DLL&lt;/code&gt; from its own directory before the system path. The attacker&apos;s DLL runs at High integrity in the elevated sysprep process [@davidson-2009, @uacme]. No prompt. The whitelist did the work.&lt;/p&gt;
&lt;p&gt;The bypass canon. Davidson&apos;s technique was the start, not the totality. The successors walked the same shape across families.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The DLL side-load family.&lt;/strong&gt; Sysprep was the canonical instance. Subsequent variants targeted &lt;code&gt;cliconfg.exe&lt;/code&gt;, &lt;code&gt;mcx2prov.exe&lt;/code&gt;, &lt;code&gt;migwiz.exe&lt;/code&gt;, and &lt;code&gt;setupsqm.exe&lt;/code&gt; -- each an auto-elevating Microsoft binary that loaded a DLL from a writable directory before consulting the system path. Microsoft removed the auto-elevation attribute from many of these binaries over the Windows 10 1709 cycle, but did so one binary at a time [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The registry-hijack family.&lt;/strong&gt; Matt Nelson&apos;s August 2016 disclosure of an &lt;code&gt;eventvwr.exe&lt;/code&gt; plus &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt; bypass [@enigma0x3-2016-eventvwr] established the pattern. An auto-elevating binary consults &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; before &lt;code&gt;HKEY_CLASSES_ROOT&lt;/code&gt; for a value the binary trusts to dispatch a child process. The limited user, who owns &lt;code&gt;HKCU&lt;/code&gt;, writes whatever they want into the value. The elevated binary executes the attacker&apos;s command line. March 2017 produced &lt;code&gt;sdclt.exe&lt;/code&gt; plus App Paths [@enigma0x3-2017-app-paths] and &lt;code&gt;sdclt.exe&lt;/code&gt; plus &lt;code&gt;IsolatedCommand&lt;/code&gt; [@enigma0x3-2017-sdclt]; May 2017 produced the &lt;code&gt;fodhelper.exe&lt;/code&gt; plus &lt;code&gt;ms-settings&lt;/code&gt; variant [@uacme]. All fileless. All generalising to any auto-elevating binary that walks &lt;code&gt;HKCU&lt;/code&gt; before &lt;code&gt;HKCR&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The COM-elevation-moniker abuse family.&lt;/strong&gt; UACMe&apos;s Method 1 (Davidson&apos;s original &lt;code&gt;IFileOperation&lt;/code&gt;) ages into Methods 41 (&lt;code&gt;ICMLuaUtil&lt;/code&gt;, Oddvar Moe, via &lt;code&gt;ucmCMLuaUtilShellExecMethod&lt;/code&gt;) and 43 (&lt;code&gt;IColorDataProxy&lt;/code&gt; paired with &lt;code&gt;ICMLuaUtil&lt;/code&gt;, Oddvar Moe derivative, via &lt;code&gt;ucmDccwCOMMethod&lt;/code&gt;), each one a different COM interface that auto-elevates and exposes a method useful for arbitrary file or registry write [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The environment-variable and path-poisoning family.&lt;/strong&gt; Per-process &lt;code&gt;%windir%&lt;/code&gt; or &lt;code&gt;%SystemRoot%&lt;/code&gt; redirection via registry shims and Image File Execution Options, redirecting auto-elevating binaries to load resources from attacker-controlled directories.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The Windows 7 auto-elevation whitelist &lt;em&gt;was&lt;/em&gt; the bypass. The day Microsoft shipped a class of binaries that could elevate silently based on signing and path, the entire problem of UAC bypass reduced to &quot;make one of those binaries do something the attacker wants it to do.&quot; Every UACMe method that targets a Microsoft-signed binary in &lt;code&gt;System32&lt;/code&gt; descends from this design choice. The 81-method catalogue is not a list of separate vulnerabilities; it is one architectural mistake spreading through the binary inventory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enter &lt;strong&gt;hfiref0x&apos;s UACMe&lt;/strong&gt; [@uacme]. The project has been on GitHub since 2014. It currently lists 81 named methods. Each entry pairs the method number with the author credit, the target binary, the technique class, and the &quot;Fixed in&quot; build number. The README, taken together, is the institutional memory of UAC&apos;s failure as a boundary. Forshaw&apos;s January 2026 framing is the operational summary: &quot;A good repository of known bypasses is the UACMe tool which currently lists 81 separate techniques for gaining administrator privileges&quot; [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;Microsoft chose to fix individual bypasses rather than redesign the model. The next section asks whether seven years of fixes ever caught up.&lt;/p&gt;
&lt;h2&gt;5. 2017-2024: incremental hardening, no convergence&lt;/h2&gt;
&lt;p&gt;The middle Windows 10 era was the moment Microsoft treated UAC bypasses as a quality problem and shipped fixes at quality-fix cadence, not security-bulletin cadence. The work was real, but it was always one binary or one interface at a time.&lt;/p&gt;
&lt;p&gt;The named milestones, kept short.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Windows 10 1709 (October 2017).&lt;/strong&gt; Beginning with this build, &lt;code&gt;IFileOperation&lt;/code&gt; auto-elevation for callers other than Explorer was restricted [@uacme]. The originating Davidson 2009 family of bypasses, against the sysprep + planted-CRYPTBASE shape, ceased to function for processes other than the shell itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tighter &lt;code&gt;appinfo.dll&lt;/code&gt; manifest parsing across multiple Windows 10 builds.&lt;/strong&gt; Stricter binary-signature checks. Stricter path checks. Stricter manifest checks. Each of these closed individual bypass methods; none of them closed a family.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Per-binary hardening recorded in UACMe&apos;s &quot;Fixed in&quot; column.&lt;/strong&gt; UACMe version 3.5.0 retired roughly eighty percent of the 2014-vintage catalogue as obsolete; the v3.2.x branch retains the full historical record. The project&apos;s README warns that &quot;since version 3.5.0, all previously &apos;fixed&apos; methods are considered obsolete and have been removed. If you need them, use v3.2.x branch&quot; [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE-2019-1388 (November 2019; reporter: Eduardo Braun Prado via Trend Micro&apos;s Zero Day Initiative).&lt;/strong&gt; The lone departure from the &quot;UAC bypasses get no CVE&quot; rule. A UI-interaction path through &lt;code&gt;consent.exe&lt;/code&gt;&apos;s certificate-viewer dialog: an unsigned application could trigger consent.exe to display a certificate dialog whose &quot;View Certificate&quot; link launched Internet Explorer running as &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt;, and IE&apos;s File menu opened &lt;code&gt;cmd.exe&lt;/code&gt; at the same integrity level [@nvd-cve-2019-1388]. Microsoft fixed it on the November 2019 Patch Tuesday and gave it an LPE bulletin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVE-2019-1388 was a &lt;em&gt;prompt-UI&lt;/em&gt; bug -- specifically, a crash-path that surfaced an IE process at SYSTEM integrity via the certificate viewer -- not a UAC-bypass bug in the categorical sense. The classification distinction matters: Microsoft did not change its position that UAC was not a boundary; the bulletin treated this as a separate UI defect that incidentally crossed the boundary. CISA later added the CVE to the Known Exploited Vulnerabilities Catalog [@nvd-cve-2019-1388].&lt;/p&gt;
&lt;p&gt;The accumulating evidence by 2024 was three observations.&lt;/p&gt;
&lt;p&gt;UACMe&apos;s catalogue has grown from its 2014 origins to 81 methods today [@uacme]. Each &lt;em&gt;family&lt;/em&gt; of attack survived the &lt;em&gt;individual&lt;/em&gt; fixes. As Davidson predicted in 2009, the auto-elevation whitelist was the structural problem; patching each whitelisted binary as a separate bug was a treadmill, not a convergence.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own Security Servicing Criteria continued to classify UAC as a security feature, not a boundary, throughout the period [@msrc-servicing-criteria, @forshaw-pz-jan2026]. The decision was load-bearing. Fixing the elevation pipeline at &lt;em&gt;quality&lt;/em&gt; cadence meant accepting that bypasses would appear quarterly and would not appear in the Patch Tuesday bulletins until the day Microsoft changed its mind about the classification.&lt;/p&gt;
&lt;p&gt;The third piece of evidence is what the attackers were doing while the defenders were churning the binary list. Microsoft&apos;s own number, quoted by the Windows Developer Blog from the Microsoft Digital Defense Report 2024, is &lt;em&gt;39,000 token-theft incidents per day&lt;/em&gt; [@ms-developer-blog-2025]. A token, once stolen from an elevated process, requires no further bypass: it is a bearer credential good for the lifetime of the logon session. The same logon session is the one the unelevated user and the elevated process share under the split-token model. The &quot;one logon session&quot; property of UAC&apos;s design is the structural premise that token theft depends on.&lt;/p&gt;
&lt;p&gt;There is one further thread worth naming here. Forshaw&apos;s broader 2022 Kerberos work in the user-credential-delegation space is a thread that survives the elevation-redesign question entirely. The May 2022 &lt;em&gt;Exploiting RBCD using a normal user account&lt;/em&gt; post [@forshaw-2022-rbcd] is the representative artifact. Network-credential delegation primitives -- Resource-Based Constrained Delegation, User-to-User Kerberos, S4U2Self -- operate at a layer beneath token-level elevation, and survive even a perfect SMAA design because they do not run through the elevation path at all.&lt;/p&gt;
&lt;p&gt;Piecewise fixes never converged on a boundary. The question that drove the next five years of Microsoft work was the obvious one: if the issue is the shared-resource model itself, what is the smallest plausible change that fixes it?&lt;/p&gt;
&lt;h2&gt;6. The breakthrough: the System Managed Administrator Account&lt;/h2&gt;
&lt;p&gt;The load-bearing design decision is one sentence. Stop trying to make one user account play both roles. The elevated administrator should be a different account with a different SID, a different profile, a different &lt;code&gt;HKCU&lt;/code&gt;, a different logon session, and a different DOS device object directory -- and the operating system should manage that account itself.&lt;/p&gt;
&lt;p&gt;What is striking about the design is how prosaic the underlying mechanism is. Multi-user accounts have shipped with Windows NT since version 3.1 in 1993. The architecture for running an elevated process under a separate local user has been present in NT for thirty-three years. What changed is that Microsoft finally chose to &lt;em&gt;enforce&lt;/em&gt; the multi-user model for privilege separation, by making the operating system itself create and manage the second account, link it to the primary admin via paired Security Account Manager attributes, and use it for every elevation. The sophistication is in linkage, in lifecycle, and in &lt;em&gt;removing auto-elevation&lt;/em&gt;, not in any single new primitive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The thing that changes between UAC and Administrator Protection is not the elevation &lt;em&gt;mechanism&lt;/em&gt; (a manifest, a prompt, a &lt;code&gt;CreateProcessAsUser&lt;/code&gt; call) but the elevation &lt;em&gt;classification&lt;/em&gt;. An elevation bypass used to be a quality bug. It is now a security-bulletin vulnerability. Every Administrator Protection design decision -- separate account, fresh logon session, removed auto-elevation, Hello-gated consent -- is a consequence of the classification change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The names. Microsoft Learn&apos;s term is &lt;strong&gt;Administrator Protection&lt;/strong&gt; [@ms-admin-protection]. Microsoft&apos;s announcement material at Ignite 2024 and in the Insider Preview build 27718 post uses the same &quot;Administrator Protection&quot; label [@ms-insider-build-27718]; &lt;strong&gt;Adminless&lt;/strong&gt; is the community shorthand that stuck. The internal engineering term in &lt;code&gt;samsrv.dll&lt;/code&gt; (the Security Account Manager service DLL) is &lt;strong&gt;ShadowAdmin&lt;/strong&gt; [@call4cloud-osint]. The Windows Developer Blog&apos;s canonical term for the underlying entity is the &lt;strong&gt;System Managed Administrator Account (SMAA)&lt;/strong&gt; [@ms-developer-blog-2025].&lt;/p&gt;

The hidden local user account that Windows creates per primary administrator when the `TypeOfAdminApprovalMode` policy is set to 2. The SMAA has its own random user name (typically `ADMIN_`), its own SID, its own profile directory under `C:\Users\ADMIN_\`, its own `NTUSER.DAT` and therefore its own `HKCU`, and its own membership in the local Administrators group. The operating system uses it to host elevated processes; the user never logs into it directly [@ms-developer-blog-2025, @call4cloud-osint].
&lt;p&gt;The SMAA lifecycle. Four beats. Each anchored to a verified source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Provisioning.&lt;/strong&gt; When &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; is set under &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System&lt;/code&gt; (either by Group Policy or by the Intune Settings Catalog), &lt;code&gt;samsrv.dll&lt;/code&gt;&apos;s &lt;code&gt;ShadowAdminAccount::CreateShadowAdminAccount&lt;/code&gt; runs once per existing local-administrator account. &lt;code&gt;CreateRandomShadowAdminAccountName&lt;/code&gt; produces an &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; name. &lt;code&gt;AddAccountToLocalAdministratorsGroup&lt;/code&gt; adds the new account to the Administrators group. Accounts managed by Windows LAPS (Local Administrator Password Solution) are skipped; their lifecycle is owned by a different subsystem and Microsoft did not want the SMAA mechanism to fight LAPS rotation [@call4cloud-osint].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linking.&lt;/strong&gt; Two paired SAM attributes encode the trust relationship between the two accounts. The primary admin&apos;s user record gets a &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; attribute pointing at the SMAA&apos;s SID. The SMAA&apos;s user record gets a &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt; attribute pointing back at the primary admin. These two attributes are the only structural relationship between the two accounts; everything else -- profile, HKCU, group memberships -- is independent [@call4cloud-osint].&lt;/p&gt;

Two paired SAM-database attributes that encode the trust relationship between a primary admin user and its System Managed Administrator Account. The forward link sits on the primary admin&apos;s record and points at the SMAA&apos;s SID. The back link sits on the SMAA&apos;s record and points back at the primary admin. The Application Information service uses the forward link at elevation time to resolve which SMAA to launch the elevated process under [@call4cloud-osint].

The registry value under `HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System` that selects the elevation policy. Value 0 disables UAC. Value 1 selects classic Admin Approval Mode (the Vista / Win7 / Win10 split-token behaviour). Value 2 selects Admin Approval Mode with Administrator Protection: every elevation routes through the SMAA path. The value is set by Group Policy (&quot;User Account Control: Configure type of Admin Approval Mode&quot;) or by an Intune Settings Catalog policy and requires a reboot to take effect [@ms-admin-protection, @call4cloud-osint].
&lt;p&gt;&lt;strong&gt;Per-elevation use.&lt;/strong&gt; &lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; RPC endpoint reads &lt;code&gt;TypeOfAdminApprovalMode&lt;/code&gt;. When the value is 2, it walks the forward link to find the calling user&apos;s SMAA, launches &lt;code&gt;consent.exe&lt;/code&gt; on the secure desktop in &lt;em&gt;credential&lt;/em&gt; prompt mode (not Yes/No), authenticates the primary user via Windows Hello (PIN, fingerprint, face, or password fallback), asks the kernel to ask LSA for a fresh primary token for the SMAA in a brand-new logon session, and calls &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with that token, the user&apos;s requested executable, and the SMAA&apos;s profile environment [@ms-developer-blog-2025, @ms-admin-protection, @forshaw-pz-jan2026]. The credential-less LSA logon at the heart of step three of this beat is walked in §7.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Teardown.&lt;/strong&gt; When the elevated process exits, the SMAA&apos;s token handle goes out of scope. The logon session is reaped. The elevated profile directory remains on disk at &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt; -- it has to, to preserve per-elevation user state across reboots -- but the live admin token does not. There is no persistent High-integrity process running between elevations [@ms-developer-blog-2025].&lt;/p&gt;

flowchart TD
    Start[Policy enabled: TypeOfAdminApprovalMode = 2] --&amp;gt; Provision
    Provision[samsrv.dll: CreateShadowAdminAccount per local admin] --&amp;gt; Naming
    Naming[CreateRandomShadowAdminAccountName -&amp;gt; ADMIN_random] --&amp;gt; AddGroup
    AddGroup[AddAccountToLocalAdministratorsGroup] --&amp;gt; Link
    Link[SAM linkage: ShadowAccountForwardLinkSid /&lt;br /&gt;ShadowAccountBackLinkSid] --&amp;gt; Idle[SMAA exists, no token live]
    Idle --&amp;gt;|Each elevation| RPC[appinfo.dll: RAiLaunchAdminProcess]
    RPC --&amp;gt; Prompt[consent.exe: Hello credential prompt]
    Prompt --&amp;gt; LSA[Kernel asks LSA: credential-less logon for SMAA]
    LSA --&amp;gt; Run[CreateProcessAsUser with SMAA token]
    Run --&amp;gt;|Process exits| Teardown[Token handle released;&lt;br /&gt;logon session reaped]
    Teardown --&amp;gt; Idle

Windows creates a temporary isolated admin token to get the job done. This temporary token is immediately destroyed once the task is complete, ensuring that admin privileges do not persist. -- David Weston, Microsoft Ignite 2024 keynote, November 19, 2024 [@bleepingcomputer-2024]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The single design decision behind Administrator Protection: the elevated and unelevated halves of an administrator must be different accounts. Different SID, different profile, different &lt;code&gt;HKCU&lt;/code&gt;, different logon session, different DOS device object directory. The shared-resource attacks of the UAC bypass canon cannot persist if there are no shared resources.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The mechanism is now described. The next section walks it at function-name granularity for a single elevation, end to end -- and in particular, the credential-less LSA logon at step six that does the load-bearing work of minting the SMAA token without any SMAA credential.&lt;/p&gt;
&lt;h2&gt;7. The elevation pipeline end to end&lt;/h2&gt;
&lt;p&gt;Walk a single elevation. Nine steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The caller invokes &lt;code&gt;ShellExecute&lt;/code&gt; or &lt;code&gt;CreateProcess&lt;/code&gt; with an elevation request. For the shell-launched case the user right-clicks an executable and selects &quot;Run as administrator&quot;; the same RPC endpoint serves manifest-declared &lt;code&gt;requestedExecutionLevel = &quot;requireAdministrator&quot;&lt;/code&gt; callers and &lt;code&gt;Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;&lt;/code&gt; COM moniker requests.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; RPC endpoint, hosted inside the Application Information service in &lt;code&gt;svchost.exe&lt;/code&gt;, receives the call [@ms-uac-how-it-works].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; reads &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\TypeOfAdminApprovalMode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the value is 2 (Admin Approval Mode with Administrator Protection), &lt;code&gt;appinfo&lt;/code&gt; reads the calling user&apos;s SAM record, locates the &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; attribute, and validates the corresponding &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt; on the SMAA&apos;s SAM record. The linkage check is what binds a given elevated process to a given primary user; without both attributes pointing at each other, the elevation is refused [@call4cloud-osint].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; launches &lt;code&gt;consent.exe&lt;/code&gt; on the secure desktop in &lt;em&gt;credential&lt;/em&gt; prompt mode rather than the classic Yes/No mode. The prompt asks the primary user to authenticate via Windows Hello (PIN, fingerprint, face, or password fallback), not the SMAA. The SMAA &lt;em&gt;has no human credentials&lt;/em&gt;. The Windows Developer Blog states the property explicitly [@ms-developer-blog-2025], and Forshaw&apos;s January 2026 post restates it in operational terms: &quot;The user does not need to know the credentials for the shadow administrator as there aren&apos;t any. Instead UAC can be configured to prompt for the limited user&apos;s credentials, including using biometrics if desired&quot; [@forshaw-pz-jan2026].&lt;/li&gt;
&lt;li&gt;On a positive Hello result, &lt;code&gt;appinfo.dll&lt;/code&gt; -- running as &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt; inside the Application Information service -- asks the kernel to ask LSA for a fresh primary access token for the SMAA&apos;s SID in a brand-new logon session. The LSA logon is &lt;em&gt;credential-less&lt;/em&gt;. The kernel asks LSA to authenticate &quot;a new instance of the shadow administrator,&quot; and LSA fulfils the request without any SMAA credential because the SMAA has no credential to verify. The trust architecture mirrors the way the Service Control Manager asks LSA for service-account tokens: SCM is trusted to ask for the token; LSA mints it on the strength of the &lt;em&gt;request&lt;/em&gt; rather than on the strength of any credential. In Administrator Protection, &lt;code&gt;appinfo.dll&lt;/code&gt; is the trusted requester, and its request is gated on the user-side Hello result it received in step 5. The Forshaw verbatim that anchors the mechanism is below this section [@forshaw-pz-jan2026, @ms-developer-blog-2025].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; calls &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with the SMAA token, the user&apos;s requested executable, and the SMAA&apos;s profile environment block (&lt;code&gt;USERPROFILE=C:\Users\ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;, &lt;code&gt;USERNAME=ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;, the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt; mapped as &lt;code&gt;HKCU&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The new process loads at High integrity, holding the SMAA&apos;s primary token, in a fresh logon session with a freshly minted authentication-ID LUID. The DOS device directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; does not yet exist; the kernel will create it on first reference.&lt;/li&gt;
&lt;li&gt;Subsequent &lt;code&gt;SeAccessCheck&lt;/code&gt; calls on system objects evaluate against the SMAA&apos;s local Administrators group membership and succeed. The elevated process can write to &lt;code&gt;HKLM&lt;/code&gt;, modify program files, install services, load WHQL-signed drivers (subject to App Control for Business and HVCI), and otherwise behave as a member of the Administrators group [@ms-developer-blog-2025].&lt;/li&gt;
&lt;/ol&gt;

The mechanism by which the Local Security Authority mints a primary access token for the SMAA without verifying any SMAA credential. `appinfo.dll`, running as `NT AUTHORITY\SYSTEM` inside the Application Information service, requests the logon on the SMAA&apos;s behalf after the primary user has succeeded against the Hello credential gate. LSA fulfils the request because the *requester* is trusted; the architecture mirrors the way the Service Control Manager requests service-account tokens. The &quot;credential-less&quot; label is descriptive of the SMAA side of the exchange: the SMAA never has a human credential to verify, so LSA cannot and does not ask for one [@forshaw-pz-jan2026, @ms-developer-blog-2025].
&lt;p&gt;The trust architecture is not new in Administrator Protection. The Service Control Manager has asked LSA for service-account tokens since Windows NT 3.1 in 1993; LSA accepts the request because SCM is the trusted requester, not because the service account presented a credential. Administrator Protection generalises the same pattern to elevation: &lt;code&gt;appinfo.dll&lt;/code&gt; is the trusted requester, and the SMAA is its functional analogue of a service account. What is new is the user-side gate -- the trusted requester only makes the request after a positive Hello result on the &lt;em&gt;primary user&apos;s&lt;/em&gt; credential.&lt;/p&gt;

in Administrator Protection the kernel calls into the LSA and authenticates a new instance of the shadow administrator. This results in every token returned from `TokenLinkedToken` having a unique logon session, and thus does not currently have the DOS device object directory created. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]
&lt;p&gt;The &quot;unique logon session&quot; property in Forshaw&apos;s quote is exactly the structural property the lazy-DOS-device-directory bypass exploits, and §12 walks that exploit in full. For now, the load-bearing observation is the credential-less logon itself: the SMAA token is real, the logon session is real, the integrity level is real, but no SMAA credential ever changes hands. The trust is in the requester, gated by a Hello gesture from the primary user.&lt;/p&gt;

sequenceDiagram
    participant User as User shell (primary admin filtered token)
    participant AppInfo as appinfo.dll (NT AUTHORITY\SYSTEM)
    participant SAM as samsrv.dll / SAM database
    participant Consent as consent.exe (secure desktop)
    participant Hello as Windows Hello / TPM
    participant LSA as LSASS
    participant Elev as Elevated SMAA process&lt;pre&gt;&lt;code&gt;User-&amp;gt;&amp;gt;AppInfo: ShellExecute &quot;as admin&quot;
AppInfo-&amp;gt;&amp;gt;AppInfo: RAiLaunchAdminProcess RPC
AppInfo-&amp;gt;&amp;gt;AppInfo: Read TypeOfAdminApprovalMode = 2
AppInfo-&amp;gt;&amp;gt;SAM: Resolve ShadowAccountForwardLinkSid
SAM--&amp;gt;&amp;gt;AppInfo: SMAA SID + backlink check OK
AppInfo-&amp;gt;&amp;gt;Consent: Launch consent.exe (credential mode)
Consent-&amp;gt;&amp;gt;Hello: Request Hello gesture for primary user
Hello--&amp;gt;&amp;gt;Consent: PIN / biometric / password verified
Consent--&amp;gt;&amp;gt;AppInfo: Approved
AppInfo-&amp;gt;&amp;gt;LSA: Credential-less logon for SMAA (trusted-requester pattern)
LSA--&amp;gt;&amp;gt;AppInfo: Fresh SMAA primary token and fresh LUID
AppInfo-&amp;gt;&amp;gt;Elev: CreateProcessAsUser with SMAA token and profile
Note over Elev: Different SID and USERPROFILE and HKCU and LUID
Note over Elev: Integrity level High -- DOS device dir not yet created
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A practical illustration of the shift, displayed as the diff between the pre-AP and post-AP elevated console session.&lt;/p&gt;
&lt;p&gt;{`
// Modelled output of &apos;whoami /all&apos; run from an elevated console.
// Before: TypeOfAdminApprovalMode = 1 (classic UAC).
// After:  TypeOfAdminApprovalMode = 2 (Administrator Protection).&lt;/p&gt;
&lt;p&gt;const before = {
  user: &apos;CONTOSO\\alice&apos;,
  sid: &apos;S-1-5-21-123456789-987654321-1122334455-1001&apos;,
  profile: &apos;C:\\Users\\alice&apos;,
  authId: &apos;0x3e7:0x000abcde&apos;,
  integrity: &apos;S-1-16-12288 (High)&apos;,
  groups: [&apos;BUILTIN\\Administrators (Enabled)&apos;]
};&lt;/p&gt;
&lt;p&gt;const after = {
  user: &apos;WIN11-PC\\ADMIN_9f2c7e1bdc4a8033&apos;,
  sid: &apos;S-1-5-21-123456789-987654321-1122334455-1051&apos;,
  profile: &apos;C:\\Users\\ADMIN_9f2c7e1bdc4a8033&apos;,
  authId: &apos;0x3e7:0x000abf42&apos;,
  integrity: &apos;S-1-16-12288 (High)&apos;,
  groups: [&apos;BUILTIN\\Administrators (Enabled)&apos;],
  shadowBacklink: &apos;CONTOSO\\alice&apos;
};&lt;/p&gt;
&lt;p&gt;console.log(&apos;Different user name:&apos;, before.user !== after.user);
console.log(&apos;Different SID:&apos;,       before.sid !== after.sid);
console.log(&apos;Different profile:&apos;,   before.profile !== after.profile);
console.log(&apos;Different LUID:&apos;,      before.authId !== after.authId);
console.log(&apos;Same integrity:&apos;,      before.integrity === after.integrity);
`}&lt;/p&gt;
&lt;p&gt;The pipeline is now a single chain of named function calls. The next section asks what &lt;em&gt;changed&lt;/em&gt; about the four shared-resource properties from §3, and which UAC-bypass family each fix forecloses.&lt;/p&gt;
&lt;h2&gt;8. The four shared-resources fixes, precisely&lt;/h2&gt;
&lt;p&gt;Each of the four shared resources from §3 maps to a precise Administrator Protection fix, and each fix maps to a named UAC-era attack class it forecloses.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shared resource (UAC)&lt;/th&gt;
&lt;th&gt;Administrator Protection fix&lt;/th&gt;
&lt;th&gt;UAC-era attack class foreclosed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Same SID across both tokens&lt;/td&gt;
&lt;td&gt;SMAA has its own SID; no shared user identity&lt;/td&gt;
&lt;td&gt;Same-user file and registry ACE confusion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same &lt;code&gt;%USERPROFILE%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SMAA has &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DLL side-load family (sysprep / CRYPTBASE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same &lt;code&gt;HKCU&lt;/code&gt; hive&lt;/td&gt;
&lt;td&gt;SMAA has its own &lt;code&gt;NTUSER.DAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registry-hijack family (eventvwr, fodhelper, sdclt)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same logon-session LUID&lt;/td&gt;
&lt;td&gt;SMAA gets a fresh LUID per elevation&lt;/td&gt;
&lt;td&gt;Token-theft via &lt;code&gt;TokenLinkedToken&lt;/code&gt;; logon-session DOS device hijack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Profile separation.&lt;/strong&gt; The SMAA owns its own &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory tree under &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;. Files created by elevated processes land there by default. Library folder divergence is the most visible consequence: an elevated Notepad&apos;s File &amp;gt; Save dialog opens at the SMAA&apos;s &lt;code&gt;Documents&lt;/code&gt;, not the primary user&apos;s. The primary user cannot see those files in their own Explorer without explicit cross-profile navigation. The structural property that closes is the writable-shared-directory premise of the Davidson 2009 DLL side-load family. Sysprep + CRYPTBASE was a profile-shared attack; without a shared profile, the elevated binary searches a different directory tree from the one the limited user can write to [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Registry separation.&lt;/strong&gt; The SMAA&apos;s &lt;code&gt;HKCU&lt;/code&gt; maps to the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt;, not the primary user&apos;s. When &lt;code&gt;eventvwr.exe&lt;/code&gt;, running in an SMAA process, queries &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt;, it reads the SMAA&apos;s hive, not the primary user&apos;s. The primary user has no write access to the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt;. The entire registry-hijack family -- eventvwr / mscfile [@enigma0x3-2016-eventvwr], fodhelper / ms-settings, sdclt / IsolatedCommand [@enigma0x3-2017-sdclt], sdclt / App Paths [@enigma0x3-2017-app-paths] -- forecloses on the same property: the elevated binary&apos;s &lt;code&gt;HKCU&lt;/code&gt; lookup walks a hive the attacker does not control [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logon-session separation.&lt;/strong&gt; Every SMAA elevation gets a fresh authentication-ID LUID. The Local Security Authority allocates a new logon session for each elevation; when the elevated process exits, the session is reaped. Per-logon-session kernel resource caches, including the DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; and the credential cache, do not flow across the boundary. Token handles cannot be reused. Drive-letter overrides under the limited user&apos;s logon session do not appear in the SMAA&apos;s session [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No auto-elevation.&lt;/strong&gt; The &lt;code&gt;autoElevate=true&lt;/code&gt; manifest attribute is no longer honoured by &lt;code&gt;appinfo.dll&lt;/code&gt; under &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt;. Every elevation that previously went silent now prompts. The Windows Developer Blog states the change directly: &quot;With administrator protection, all auto-elevations in Windows are removed and users need to interactively authorize every admin operation&quot; [@ms-developer-blog-2025]. Forshaw&apos;s January 2026 framing of the consequence: &quot;as auto-elevation is no longer permitted they will always show a prompt, therefore these are not considered bypasses&quot; [@forshaw-pz-jan2026]. This is the single most consequential fix in the design. The auto-elevation whitelist &lt;em&gt;was&lt;/em&gt; the bypass; removing the whitelist eliminates the class at the source, including the entire silent-elevation primitive class that Forshaw&apos;s older &lt;code&gt;RAiProcessRunOnce&lt;/code&gt; research relied on.&lt;/p&gt;

Multi-user separation is the original UNIX privilege model. The `root` user holds privilege; ordinary users do not; the boundary between them is the file-permission system enforced by the kernel. Windows NT shipped the same primitives in 1993 -- discretionary access control lists on every securable object, per-user profiles, multi-user logon sessions -- but the surrounding culture treated Administrator-as-default as the path of least resistance. The architectural sophistication in Administrator Protection is in *linkage* (the SAM forward / back attributes), *lifecycle* (provisioning on policy enable, teardown on process exit), and *enforcement* (removal of auto-elevation as a mechanism). The primitives themselves are old.
&lt;p&gt;The four fixes share a property. Each one breaks a shared resource that an attacker depends on. But there is one more piece of the redesign that has not yet been described: the prompt itself is no longer a Yes/No click-through. The next section asks what happens when the consent UI becomes a credential.&lt;/p&gt;
&lt;h2&gt;9. Windows Hello as the consent gate&lt;/h2&gt;
&lt;p&gt;The classic UAC prompt is a Yes / No on the secure desktop. Administrator Protection turns the prompt into a &lt;em&gt;credential&lt;/em&gt; prompt for the &lt;em&gt;primary user&apos;s&lt;/em&gt; Windows Hello: a PIN, a fingerprint, a face match, or a password fallback. The credential is for the primary user, not the SMAA, because the SMAA has no human credentials; the Hello verification is what &lt;em&gt;authorises&lt;/em&gt; the cross-profile elevation [@ms-admin-protection, @ms-developer-blog-2025, @forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;To talk precisely about what the gate does, name the primitive it closes. Under classic UAC, the consent prompt treated a click on the secure desktop as sufficient evidence of consent; physical presence was the entire evidence requirement. That primitive shows up in three sub-cases that the UAC literature has documented for two decades.&lt;/p&gt;

The primitive by which the legacy UAC consent dialog accepted a click on the secure desktop as sufficient evidence of consent, without verifying *who* clicked. Three operational sub-cases follow. *Unattended-session click-through* -- an attacker (or co-located third party) with brief physical access to an unlocked screen showing a UAC prompt clicks Yes on the presumption that whoever is at the keyboard is the legitimate user. *Habituated-click click-through* -- the legitimate user has clicked Yes on hundreds of UAC prompts and clicks one more without conscious attention. *Pretext click-through* -- a malicious application argues a legitimate-looking case to the user and elicits the Yes click. Administrator Protection&apos;s credential gate cost-raises all three sub-cases without fully eliminating any [@forshaw-pz-jan2026, @ms-admin-protection].
&lt;p&gt;&lt;strong&gt;Unattended-session click-through.&lt;/strong&gt; An attacker who walks up to an unlocked screen showing a UAC prompt can click Yes and elevate. The legitimate user has authenticated; the prompt assumes the person at the keyboard is the legitimate user. Post-AP, the click is not sufficient. The Hello biometric or PIN is required, and the attacker (who does not know either) cannot complete the gesture. Microsoft&apos;s Ignite 2024 framing addresses this primitive implicitly with &quot;elevation rights only when needed&quot; and &quot;interactively authorize every admin operation&quot; [@bleepingcomputer-2024].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Habituated-click click-through.&lt;/strong&gt; A user who has clicked Yes on hundreds of UAC prompts over the course of a year clicks Yes on a malicious one as reflex. The classic UAC prompt requires no attentional engagement beyond physical presence and a click. Hello&apos;s gesture (a four-digit PIN entry, a fingerprint press, a face-recognition glance) is higher-friction and harder to perform inattentively. The Windows Developer Blog frames the property as &quot;just-in-time administrator privileges, incorporating Windows Hello to enhance both security and user convenience&quot; [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pretext click-through.&lt;/strong&gt; A malicious application that argues its case to the user -- a fake installer, a re-skinned setup utility, a Trojan masquerading as a legitimate update -- can elicit a Yes click pre-AP. Post-AP, the user is also asked for a credential, which is a stronger user-side check. The user is more likely to interrogate &quot;why am I being asked for my PIN &lt;em&gt;again&lt;/em&gt;?&quot; than &quot;why is a prompt appearing?&quot; Microsoft Learn captures the intent as &quot;users are aware of potentially harmful actions before they occur, providing an extra layer of defense against threats&quot; [@ms-admin-protection].&lt;/p&gt;
&lt;p&gt;None of the three sub-cases is &lt;em&gt;fully&lt;/em&gt; eliminated. Forshaw is explicit that visible-prompt bypasses are not classified as security vulnerabilities by Microsoft&apos;s design-document position: bypasses that result in a visible prompt are not security bulletins, because the user could equivalently have launched the prompt themselves [@forshaw-pz-jan2026]. What the gate does is &lt;em&gt;cost-raise&lt;/em&gt; each sub-case. The unattended-screen attack requires a stolen PIN or coerced biometric. The habituated user must perform a gesture they cannot perform inattentively. The pretext attack must justify the second authentication, not just the first.&lt;/p&gt;
&lt;p&gt;What it does &lt;em&gt;not&lt;/em&gt; close is worth naming, because three primitives that look like they belong on the credential gate&apos;s account sheet were already closed by independent mechanisms, and the article should say so to avoid the common over-attribution mistake.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Synthetic-keystroke &lt;code&gt;SendInput&lt;/code&gt; against &lt;code&gt;consent.exe&lt;/code&gt;.&lt;/strong&gt; Already closed by UIPI in Vista 2006, and doubly closed by the secure-desktop switch to &lt;code&gt;Winsta0\Winlogon&lt;/code&gt;. Even UI Access processes -- whose purpose is to bypass UIPI for accessibility -- cannot reach into the secure desktop [@forshaw-pz-feb2026].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headless UI Automation against the prompt.&lt;/strong&gt; Same UIPI / secure-desktop boundary closes it. Redundant with respect to the credential gate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE-2019-1388-class UI-interaction paths surfaced through the prompt&apos;s own UI.&lt;/strong&gt; Closed by Microsoft&apos;s November 2019 HHCtrl patch and the cert-viewer UI redesign, prior to any Administrator Protection development [@nvd-cve-2019-1388].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The credential is hardware-rooted via &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM&lt;/a&gt; or &lt;a href=&quot;https://paragmali.com/blog/pluton-a-tpm-on-silicon-microsoft-can-patch/&quot; rel=&quot;noopener&quot;&gt;Pluton&lt;/a&gt; on capable hardware. The PIN is unsealed only under the user&apos;s gesture; the biometric flows through Enhanced Sign-in Security (ESS) on capable hardware; the credential itself never leaves the Trusted Platform Module or Pluton enclave when ESS is engaged [@ms-windows-hello-ess]. The detail of the Hello architecture itself -- FIDO2 attestation, the &lt;code&gt;ngc&lt;/code&gt; protector, the ESS isolation path through the Secure Kernel -- belongs to the &lt;a href=&quot;https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/&quot; rel=&quot;noopener&quot;&gt;Windows Hello article&lt;/a&gt; in this series, and is not re-derived here.&lt;/p&gt;
&lt;p&gt;The new risk the gate does &lt;em&gt;not&lt;/em&gt; close is the obvious one. Phishing the prompt now phishes a &lt;em&gt;real credential&lt;/em&gt;, not just consent. A malicious application that can convince the user to authenticate on its behalf gets the elevation the user would otherwise have given to a legitimate request. The credential remains hardware-rooted and is not exfiltrated to the malware, but the elevation produces a working SMAA token in the attacker&apos;s process. This is the surface §15 carries forward to open problems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The credential gate closes one specific primitive: &lt;em&gt;consent-without-identity-verification&lt;/em&gt;. It cost-raises three sub-cases (unattended-session, habituated-click, pretext click-through) without eliminating any. The structural boundary is profile separation plus fresh logon session plus auto-elevation removal; the credential gate is the fourth, defence-in-depth, property that ensures the boundary cannot be silently crossed by anyone holding only the limited user&apos;s physical access.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The prompt is a credential gate, but it remains a UI element. The next section asks how this elevation model compares to what other operating systems do.&lt;/p&gt;
&lt;h2&gt;10. Competing approaches: what other operating systems do&lt;/h2&gt;
&lt;p&gt;Three one-paragraph treatments. The article does not re-derive each system; it positions Administrator Protection against the field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux: &lt;code&gt;sudo&lt;/code&gt; plus PolKit &lt;code&gt;pkexec&lt;/code&gt; plus PAM modules.&lt;/strong&gt; The authority model on Linux is file-based. &lt;code&gt;/etc/sudoers&lt;/code&gt; (or its LDAP equivalent) is the policy table; the &lt;code&gt;sudoers&lt;/code&gt; plugin reads it and decides whether to permit a given user to run a given command [@sudo-ws-sudoers]. PolKit -- &lt;code&gt;polkitd&lt;/code&gt; and its authentication-agent helpers -- is the parallel mechanism for GUI privileged-service requests, with actions and mechanisms separated in the polkit configuration files [@polkit-docs]. Biometric integration arrives through the PAM stack: &lt;code&gt;pam_fprintd&lt;/code&gt; for fingerprint, &lt;code&gt;pam_u2f&lt;/code&gt; for FIDO2 tokens, &lt;code&gt;pam_yubico&lt;/code&gt; for Yubikeys. There is no profile separation by default; &lt;code&gt;sudo -i&lt;/code&gt; switches &lt;code&gt;HOME&lt;/code&gt; to root&apos;s home directory but does not separate per-elevation. The model is per-command authorisation, not per-account isolation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;macOS: Authorization Services plus Touch ID via &lt;code&gt;pam_tid&lt;/code&gt;.&lt;/strong&gt; GUI elevation prompts are gated by &lt;code&gt;authorizationdb&lt;/code&gt;, a property-list-format policy database whose rules name which credentials (admin password, Touch ID, system-wide entitlements) authorise which actions [@apple-auth-services]. Touch ID is verified by the Secure Enclave Processor; the credential never leaves the SEP, and Authorization Services integrates with &lt;code&gt;pam_tid&lt;/code&gt; to allow &lt;code&gt;sudo&lt;/code&gt; invocations to use the gesture [@apple-pam-tid]. There is no separate admin profile; Transparency, Consent, and Control (TCC) guards privileged resource access at the per-action level, not the per-profile level. The Mac architecture privileges hardware-rooted consent (Touch ID, Secure Enclave) over account separation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft&apos;s own &lt;code&gt;sudo.exe&lt;/code&gt; (Windows 11 24H2).&lt;/strong&gt; An inbox terminal transport that triggers the &lt;em&gt;existing&lt;/em&gt; UAC or Administrator Protection pipeline; not an alternative to either [@ms-sudo-docs]. The &lt;code&gt;forceNewWindow&lt;/code&gt; mode opens an elevated console in a new window. The &lt;code&gt;disableInput&lt;/code&gt; mode keeps the elevated console in the current window but blocks keyboard input to it from the unelevated terminal. The &lt;code&gt;normal&lt;/code&gt; (inline) mode preserves POSIX-style pipes between the unelevated and elevated processes. Microsoft Learn warns explicitly about the inline mode: &quot;Sudo for Windows can be used as a potential escalation of privilege vector when enabled in certain configurations&quot; [@ms-sudo-docs]. The mechanism is RPC between the unelevated and elevated &lt;code&gt;sudo.exe&lt;/code&gt; processes; the elevation itself still goes through &lt;code&gt;appinfo.dll&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intune Endpoint Privilege Management (EPM).&lt;/strong&gt; Cloud-policy-driven virtual-account elevation [@ms-epm-overview]. EPM performs elevation via a &lt;em&gt;virtual&lt;/em&gt; account that is not a member of the local Administrators group; the elevation rights are conferred only for the duration of the policy-permitted action. Three elevation modes are available: Automatic (no user interaction), User-confirmed (a prompt), and Elevate as Current User (the action runs as the user&apos;s elevated identity rather than the virtual account). EPM is architecturally complementary to Administrator Protection: EPM is the &lt;em&gt;enterprise policy&lt;/em&gt; story, Administrator Protection is the &lt;em&gt;per-device architecture&lt;/em&gt; story. The two can coexist on the same device.&lt;/p&gt;
&lt;p&gt;The distinguishing property of Administrator Protection in this comparison is whole-profile separation: the SMAA&apos;s own profile, the SMAA&apos;s own &lt;code&gt;HKCU&lt;/code&gt;, the SMAA&apos;s own library folders, plus a fresh logon session per elevation. Neither Linux &lt;code&gt;sudo&lt;/code&gt; nor macOS Authorization Services provides that property as a default desktop primitive. EPM provides per-elevation isolation via the virtual account but does not give the elevated process a persistent profile, which is what makes Administrator Protection&apos;s compatibility story so different from EPM&apos;s.&lt;/p&gt;
&lt;p&gt;Administrator Protection is the architecturally tightest desktop elevation model now in production. The next section asks where the boundary still leaks.&lt;/p&gt;
&lt;h2&gt;11. Theoretical limits: what Administrator Protection cannot fix&lt;/h2&gt;
&lt;p&gt;Four structural ceilings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Showing a prompt is not crossing the boundary.&lt;/strong&gt; Microsoft&apos;s design position is explicit: bypasses that result in a &lt;em&gt;visible&lt;/em&gt; elevation prompt are not security bulletins, because the user could equivalently have right-clicked &quot;Run as administrator.&quot; Forshaw&apos;s January 2026 post states the position verbatim: &quot;I expect that malware will still be able to get administrator privileges even if that&apos;s just by forcing a user to accept the elevation prompt&quot; [@forshaw-pz-jan2026]. The operational consequence is that social-engineering the consent dialog remains a structural attack surface. The prompt is a UI element. The boundary is the credential gate. The gate is only as strong as the user&apos;s resistance to whatever pretext induces them to authenticate.&lt;/p&gt;

The MSRC servicing-criteria definition of a security boundary: a logical separation between code or data of different trust levels, intended to be enforced by the operating system and accompanied by a Microsoft commitment to issue a security update when an unauthorised crossing is found. UAC under the classic split-token model is classified as a *security feature*, not a boundary; bypasses receive quality-fix attention but not security-bulletin attention. Administrator Protection is the first elevation mechanism classified as a security boundary, with bulletin-grade fixes when it fails [@msrc-servicing-criteria, @forshaw-pz-jan2026].
&lt;p&gt;&lt;strong&gt;Admin equals kernel.&lt;/strong&gt; Once code is running inside an SMAA elevated process, it has the local Administrators group; it can write to &lt;code&gt;HKLM&lt;/code&gt;; it can install services; it can load WHQL-signed drivers; it can call into kernel-mode interfaces gated by &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; and the App Control for Business policy. The MSRC servicing-criteria position that &quot;admin-to-kernel is not a security boundary&quot; continues to apply inside the SMAA [@msrc-servicing-criteria]. Administrator Protection makes the path &lt;em&gt;to&lt;/em&gt; admin into a boundary; it does not change the relationship between admin and kernel. Driver-loading controls remain the domain of WHQL signing, the Microsoft Vulnerable Driver Blocklist (default-on in Windows 11 since the 2022 update), App Control for Business policies, and Hypervisor-protected Code Integrity (HVCI) [@ms-vuln-driver-blocklist]. The &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;App Identity article&lt;/a&gt; in this series covers the App Control mechanism in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The SMAA is in the local Administrators group.&lt;/strong&gt; Discretionary access control list-based exposures of admin-only resources -- &lt;code&gt;CREATOR OWNER&lt;/code&gt; ACEs on persistent objects, world-writable DACLs on certain &lt;code&gt;\Sessions\0\DosDevices&lt;/code&gt; entries, default-permissive ACLs on a handful of legacy registry trees -- still grant the SMAA full access. The boundary is between &lt;em&gt;standard user&lt;/em&gt; and &lt;em&gt;SMAA&lt;/em&gt;, not between &lt;em&gt;SMAA&lt;/em&gt; and &lt;em&gt;SYSTEM&lt;/em&gt;. The SMAA is a high-privilege actor inside the operating system; the relationship between it and the rest of the privileged surface is unchanged.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Out of scope per Microsoft Learn.&lt;/strong&gt; Remote logon, roaming profiles, backup-admin accounts, Managed Service Accounts and group Managed Service Accounts (MSAs and gMSAs), virtual accounts for services, and domain-admin scenarios are explicitly outside the Administrator Protection model in its current form [@ms-admin-protection]. The feature is local-machine-only, interactive-admin-only. Domain administrators who log into a workstation will not see the SMAA path; service accounts under &lt;code&gt;LOCAL SERVICE&lt;/code&gt;, &lt;code&gt;NETWORK SERVICE&lt;/code&gt;, or &lt;code&gt;IIS_IUSRS&lt;/code&gt; are unaffected.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A genuine architectural ceiling on consent-prompt elevation: the prompt is a UI element; the boundary is the credential gate; the gate is only as strong as the user&apos;s resistance to social engineering. Closing the gap requires out-of-band consent (smartcard, phone push) or per-action policy without human consent in the loop (EPM&apos;s automatic mode). Neither is the default.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Four limits, four sentences. The next section walks the concrete evidence of what actually leaked in the pre-GA Insider Preview builds, and what Microsoft did about it.&lt;/p&gt;
&lt;h2&gt;12. Forshaw&apos;s nine bypasses, classified&lt;/h2&gt;
&lt;p&gt;Between October 2024, when Administrator Protection first appeared in Insider Preview build 27718, and October 2025, when KB5067036 made the feature available on stable Windows, James Forshaw of Google Project Zero audited the mechanism and found nine separate silent-bypass paths. Microsoft fixed all nine -- either in the KB5067036 ship or in subsequent security bulletins [@forshaw-pz-jan2026]. The fact pattern is the structural confirmation that Administrator Protection is now treated as a security boundary. Under the UAC classification, none of those nine would have received CVEs. Each one would have been a quality bug. The bypass canon ran for twenty years without bulletins. The fact that the first cohort of Administrator Protection bypasses produced nine bulletin-eligible fixes is exactly the change in posture the classification change implies.&lt;/p&gt;

All the issues that I reported to Microsoft have been fixed, either prior to the feature being officially released (in optional update KB5067036) or as subsequent security bulletins. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]
&lt;p&gt;Walk the nine as three classes.&lt;/p&gt;
&lt;h3&gt;The lazy DOS device directory hijack&lt;/h3&gt;
&lt;p&gt;The single most interesting vulnerability in the feature&apos;s history; Forshaw&apos;s January 26, 2026 deep analysis [@forshaw-pz-jan2026]; Project Zero issue 432313668 [@pz-issue-432313668]. The mechanism turns on a behaviour change Administrator Protection itself introduced. Every SMAA elevation gets a &lt;em&gt;fresh&lt;/em&gt; logon session, which means the per-logon-session DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; is not created at SMAA logon time. The kernel routine &lt;code&gt;SeGetTokenDeviceMap&lt;/code&gt; creates the directory &lt;em&gt;lazily&lt;/em&gt;, on the first reference. The owner of the new directory is the owner of the access token that triggered the creation [@forshaw-pz-jan2026, @theregister-2026].&lt;/p&gt;

The impersonation level (`SecurityIdentification`) at which an impersonating thread can read security information about the impersonated token -- the SID set, the privilege set -- but cannot perform privileged operations or open kernel objects as the impersonated user. The kernel allows access checks to consult an identification-level token for *reading* the security information; certain code paths inadvertently use that information for *granting* operations, which is the structural primitive Forshaw&apos;s lazy DOS device directory exploit depends on [@forshaw-pz-jan2026].
&lt;p&gt;The &lt;code&gt;SECURITY_IMPERSONATION_LEVEL&lt;/code&gt; enumeration in &lt;code&gt;winnt.h&lt;/code&gt; defines four levels in ascending order: &lt;code&gt;SecurityAnonymous&lt;/code&gt; (value 0), &lt;code&gt;SecurityIdentification&lt;/code&gt; (1), &lt;code&gt;SecurityImpersonation&lt;/code&gt; (2), &lt;code&gt;SecurityDelegation&lt;/code&gt; (3). &lt;code&gt;SecurityIdentification&lt;/code&gt; is the second-lowest -- it sits one above &lt;code&gt;SecurityAnonymous&lt;/code&gt; -- and is the level Windows uses when it wants to ask the kernel &quot;what would this token be allowed to do?&quot; without actually doing the operation. The trap is when a code path that runs &lt;em&gt;as the caller&lt;/em&gt; uses an identification-level impersonation to read a token property -- here, the linked-token field -- and the resulting object inherits the caller&apos;s owner SID rather than the impersonated token&apos;s.&lt;/p&gt;
&lt;p&gt;The exploit chain. An attacker running as the primary user (filtered token, Medium integrity) starts an elevation. Before the SMAA process touches its DOS device directory, the attacker impersonates the SMAA&apos;s &lt;code&gt;TokenLinkedToken&lt;/code&gt; at identification level and triggers a code path that walks the directory. The kernel creates &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;&lt;/code&gt; lazily; in the affected code path, the owner of the new directory becomes the attacker&apos;s primary token&apos;s owner SID rather than the SMAA&apos;s.&lt;/p&gt;
&lt;p&gt;The attacker plants a &lt;code&gt;C:&lt;/code&gt; symbolic link inside the directory pointing at an attacker-controlled location. When the elevated SMAA process loads its DLLs, the resolution walks &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;\C:&lt;/code&gt; first; the symlink redirects the load to the attacker&apos;s directory; the attacker&apos;s DLL runs in the High-integrity SMAA process [@forshaw-pz-jan2026].&lt;/p&gt;

sequenceDiagram
    participant Att as Attacker (limited user)
    participant Kern as &quot;Kernel (SeGetTokenDeviceMap)&quot;
    participant SMAA as SMAA elevated process&lt;pre&gt;&lt;code&gt;Note over SMAA: Fresh logon session -- DOS device dir not yet created
Att-&amp;gt;&amp;gt;Att: Impersonate SMAA TokenLinkedToken at Identification level
Att-&amp;gt;&amp;gt;Kern: Reference \Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;
Kern-&amp;gt;&amp;gt;Kern: Lazy-create directory
Note over Kern: Owner SID inherited from impersonating token
Att-&amp;gt;&amp;gt;Kern: Create C: symlink under attacker control
SMAA-&amp;gt;&amp;gt;Kern: Resolve C: at first DLL load
Kern--&amp;gt;&amp;gt;SMAA: Returns attacker symlink target
SMAA-&amp;gt;&amp;gt;SMAA: Load attacker DLL at High integrity
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What makes this bypass extraordinary is that it is &lt;em&gt;caused by&lt;/em&gt; the feature&apos;s design. Pre-Administrator-Protection, the user&apos;s primary logon session was created at desktop logon and the DOS device directory existed before any elevation. Lazy directory creation never came up. The SMAA design&apos;s &quot;fresh logon session per elevation&quot; property -- the same property Forshaw&apos;s January 2026 pull-quote in §7 establishes via the credential-less LSA logon -- is exactly the precondition the lazy-creation path exploits.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s pre-GA fix has two parts. First, the manifest-parsing access check uses the SYSTEM-impersonating-the-low-user identity rather than the user&apos;s primary token. Second, the DOS device directory is materialised with the correct owner before any user-controlled code path can trigger the lazy-creation path [@forshaw-pz-jan2026]. The Register&apos;s coverage of the disclosure noted &quot;the most notable of the nine bugs he reported was a Logon Sessions flaw that relied upon five different Windows behaviors. He added that he likely only found it because he was previously familiar with the OS&apos;s &apos;weird behavior when creating the DOS device object directory&apos;&quot; [@theregister-2026].&lt;/p&gt;
&lt;h3&gt;The five UI Access bypasses&lt;/h3&gt;
&lt;p&gt;Forshaw&apos;s February 2026 post details the second class, comprising five of the nine bypasses [@forshaw-pz-feb2026]. UI Access is a token flag retrofitted in Vista to let accessibility applications cross UIPI. To qualify, an executable needs three things: a manifest declaring &lt;code&gt;uiAccess=&quot;true&quot;&lt;/code&gt;, a trusted code-signing certificate, and an installation location under an administrator-only directory (typically &lt;code&gt;%ProgramFiles%&lt;/code&gt;). The Application Information service&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; endpoint launches qualifying UI Access processes &lt;em&gt;without showing the consent prompt&lt;/em&gt;, on the theory that the three-criteria check is itself sufficient evidence of administrator approval [@forshaw-pz-feb2026].&lt;/p&gt;

The token flag (`TOKEN_UIACCESS`) that allows a process to interact with windows of higher integrity level than its own, bypassing User Interface Privilege Isolation. UI Access is meant for accessibility software (screen readers, on-screen keyboards) that needs to interact with elevated UI. To qualify, an executable must carry a `uiAccess=&quot;true&quot;` manifest, a trusted code-signing certificate, and an administrator-only installation directory; qualifying processes run without showing the consent prompt and at integrity level High [@forshaw-pz-feb2026].
&lt;p&gt;Under classic UAC, a UI Access process ran with the filtered standard-user token bumped from Medium to High integrity -- not with the full admin token. Forshaw&apos;s February 2026 post states the mechanism verbatim: &quot;the service will take a copy of the caller&apos;s access token, enable the UI Access flag and increase the integrity level... If the caller is a limited user of an UAC administrator it will set the integrity level to High&quot; [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;p&gt;Under Administrator Protection, the pre-GA design preserved that behaviour unchanged: the UI Access process inherited the limited user&apos;s primary token (not the SMAA&apos;s), bumped to High integrity. That decision was the structural flaw. A High-integrity process under the limited user can interact with the SMAA&apos;s windows whenever a High-integrity SMAA process exists on the same desktop, send messages to them, read clipboard data, and -- through &lt;code&gt;GetProcessHandleFromHwnd&lt;/code&gt; -- obtain a process handle on the SMAA process that lets the limited-user process inject code into it.&lt;/p&gt;
&lt;p&gt;The five UI Access variants exploit different sub-categories of the same structural property. The Quick Assist binary, a remote assistance application on Windows 10 and 11 that carries the uiAccess flag, is one such variant; R41N3RZUF477 published a public proof-of-concept that exploits the &lt;code&gt;BrowserExecutableFolder&lt;/code&gt; group policy to make Quick Assist load WebView2 from an attacker-controlled directory [@quickassist-bypass]. The remaining four exploit, respectively, weaknesses in the secure-application-directory check, the manifest parsing routine, COM marshalling in UI Access contexts, and message-only window handling [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s pre-GA fix is structural: UI Access processes no longer run as the limited user. They are created with a &lt;em&gt;filtered copy of the SMAA&apos;s token&lt;/em&gt; (the SMAA&apos;s SID, the SMAA&apos;s profile, but with &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; and similar removed). Profile separation is restored at the cost of a more complex token-creation path [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;h3&gt;The remaining three: implementation flaws&lt;/h3&gt;
&lt;p&gt;The third class -- three bypasses described by Forshaw only as &quot;implementation flaws and long-standing UAC issues&quot; -- is not detailed publicly [@forshaw-pz-jan2026]. The article does not invent details. Forshaw names the category and cites the framing; the engineering specifics are presumably in Microsoft Security Response Center advisories or are still under disclosure. What can be said is that two of the three appear from Forshaw&apos;s framing to be UAC-era bugs that Administrator Protection inherited rather than introduced, and one is an Administrator-Protection-specific implementation flaw.&lt;/p&gt;
&lt;p&gt;The bypass canon ran for twenty years without bulletins. The fact that all nine pre-GA Administrator Protection bypasses received fixes -- including a deep one rooted in the feature itself -- is the structural confirmation that the elevation path is now a boundary. The next section asks why Microsoft pulled the feature in December 2025.&lt;/p&gt;
&lt;h2&gt;13. The compatibility surface and the December 2025 revert&lt;/h2&gt;
&lt;p&gt;About one month after KB5067036 made Administrator Protection available, Microsoft pulled it. Forshaw, writing in January 2026, gives the canonical attribution: &quot;As of 1st December 2025 the Administrator Protection feature has been disabled by Microsoft while an application compatibility issue is dealt with. The issue is unlikely to be related to anything described in this blog post so the analysis doesn&apos;t change&quot; [@forshaw-pz-jan2026]. Microsoft Learn confirms: &quot;The feature previously listed in the October 2025 non-security update (KB5067036) has been reverted and will roll out at a later date&quot; [@ms-admin-protection, @ms-kb5067036].The November 2025 KB5067036 amendment is worth knowing. Microsoft included an unrelated fix for an AutoCAD MSI-repair UAC-prompt regression in the same cumulative; that fix shipped and was not reverted. The WebView2 installer regression is what caused the Administrator Protection revert specifically [@ms-kb5067036].&lt;/p&gt;
&lt;p&gt;The structural causes. The Windows Developer Blog (May 2025) [@ms-developer-blog-2025] enumerates the surface where applications break under the SMAA model.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Single sign-on does not cross.&lt;/strong&gt; Domain and Microsoft Entra credentials cached for the primary user&apos;s session are not available inside the SMAA&apos;s session. Any elevated process touching Microsoft Graph, Entra ID, or Kerberos-protected resources must re-authenticate. The login dialogs an elevated installer triggers are not failures of the application; they are consequences of the separated logon session.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network drives do not carry.&lt;/strong&gt; Drive-mapping in the primary user&apos;s session is not inherited by the SMAA. Installers that mount network shares to install per-machine components break. The workaround for affected installers is to use UNC paths directly rather than drive letters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Library folders diverge.&lt;/strong&gt; Files saved to &lt;code&gt;Documents&lt;/code&gt;, &lt;code&gt;Desktop&lt;/code&gt;, &lt;code&gt;Downloads&lt;/code&gt;, or &lt;code&gt;Pictures&lt;/code&gt; from an elevated app land in &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt; rather than the primary user&apos;s home. A user clicks Save in an elevated text editor and saves to &quot;Documents&quot;; from their own Explorer, the file is invisible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HKCU diverges.&lt;/strong&gt; Application settings -- theme, recent-files lists, per-user COM registrations, last-opened paths -- live in the SMAA&apos;s &lt;code&gt;HKCU&lt;/code&gt;, not the primary user&apos;s. The canonical example in Microsoft&apos;s documentation is Notepad&apos;s dark-mode theme [@ms-developer-blog-2025]: the primary user sets the theme; an elevated Notepad opens in the default theme; the two sessions never agree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebView2 installers fail.&lt;/strong&gt; The error message &quot;Microsoft Edge can&apos;t read and write to its data directory&quot; is the recognisable symptom of an installer that assumes one shared profile. The WebView2 runtime stores per-user state in &lt;code&gt;AppData\Local\Microsoft\EdgeWebView\&lt;/code&gt; under whichever profile is active at install time; if the runtime is installed under the SMAA&apos;s profile and then used by an unelevated application running as the primary user, the data-directory write fails. This is the regression that triggered the December 2025 revert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hyper-V and WSL incompatibilities.&lt;/strong&gt; Microsoft Learn explicitly tells IT administrators not to enable Administrator Protection on devices that require Hyper-V or WSL [@ms-admin-protection].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Studio.&lt;/strong&gt; Microsoft&apos;s own development environment is &quot;not supported in such a configuration&quot; when run elevated. Extensions don&apos;t carry; settings don&apos;t carry; project-dialog paths point at the SMAA&apos;s profile rather than the developer&apos;s actual workspace.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft Learn explicitly excludes Hyper-V and WSL devices from the recommended enablement set [@ms-admin-protection]. Symptoms of incorrect enablement include WSL distribution startup failures (the WSL service runs under a different account from the launching user, and the SMAA&apos;s logon-session-isolation properties interact badly with WSL&apos;s named-pipe communication) and Hyper-V Manager connection errors that are difficult to attribute to the elevation model.&lt;/p&gt;
&lt;/blockquote&gt;

I guess app compatibility is ultimately the problem here, Windows isn&apos;t designed for such a radical change. I&apos;d have also liked to have seen this as a separate configurable mode rather than replacing admin-approval completely. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]

Administrator Protection is the right architecture, and the compatibility surface is the bill of materials for twenty years of admin-as-default assumption. Application developers have written installer logic, theme-persistence code, drive-letter assumptions, and HKCU-shared state into shipping software for two decades, on the structural premise that the elevated process and the unelevated user share a profile. The December 2025 revert is the first iteration&apos;s learning round, not a structural failure. The same revert pattern accompanied the Windows Vista UAC rollout in 2006-2007, the Windows 7 auto-elevation introduction in 2009 (which itself softened the Vista prompt fatigue at the cost of the bypass canon), and the Smart App Control rollout in Windows 11 22H2. Microsoft will re-enable Administrator Protection when the WebView2 regression and a handful of installer-pattern fixes have shipped.
&lt;p&gt;The architecture survives audit. The deployment is held back by twenty years of accumulated software assumptions. The next section asks what tools defenders now have that they did not have before.&lt;/p&gt;
&lt;h2&gt;14. The audit and detection surface&lt;/h2&gt;
&lt;p&gt;Every privileged operation on a device with Administrator Protection enabled now generates an ETW (Event Tracing for Windows) event in the &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt; provider [@ms-admin-protection]. This is the first time the elevation pipeline itself is the &lt;em&gt;source&lt;/em&gt; of a stable, operationally useful audit trail.&lt;/p&gt;
&lt;p&gt;The basics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provider: &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt;, GUID &lt;code&gt;{93c05d69-51a3-485e-877f-1806a8731346}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Event ID 15031: Elevation Approved.&lt;/li&gt;
&lt;li&gt;Event ID 15032: Elevation Denied or Failed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each event carries the caller user SID, the application name and path, the elevation outcome, the SMAA used to host the elevation, and the authentication method (Hello PIN, biometric, password) [@ms-admin-protection]. The authentication method field records the &lt;em&gt;primary user&apos;s&lt;/em&gt; Hello credential, not the SMAA&apos;s; the SMAA&apos;s authentication in step 6 of §7 is the credential-less LSA logon and has no method field of its own. The Microsoft Learn-documented &lt;code&gt;logman&lt;/code&gt; invocation to capture the trace is short:&lt;/p&gt;

The Event Tracing for Windows provider that surfaces Administrator Protection elevation events. Provider GUID `{93c05d69-51a3-485e-877f-1806a8731346}`. Event ID 15031 marks an elevation that succeeded; Event ID 15032 marks an elevation that was denied or failed. Each event carries fields for the caller&apos;s SID, the application path, the elevation outcome, the SMAA used, and the authentication method [@ms-admin-protection].
&lt;p&gt;{`
// Pseudocode for a detection pipeline that reads ETW Event 15031
// (Administrator Protection elevation approved) and flags unusual
// application paths per SMAA correlation key.&lt;/p&gt;
&lt;p&gt;const allowList = new Set([
  &apos;C:\\Windows\\System32\\mmc.exe&apos;,
  &apos;C:\\Windows\\System32\\regedit.exe&apos;,
  &apos;C:\\Windows\\System32\\cmd.exe&apos;,
  &apos;C:\\Program Files\\Microsoft VS Code\\Code.exe&apos;,
]);&lt;/p&gt;
&lt;p&gt;function onEtwEvent(event) {
  if (event.provider !== &apos;Microsoft-Windows-LUA&apos;) return;
  if (event.id !== 15031) return;&lt;/p&gt;
&lt;p&gt;  const smaa = event.fields.shadowAccountName;
  const app  = event.fields.applicationPath;
  const auth = event.fields.authenticationMethod;
  const user = event.fields.callerUserSid;&lt;/p&gt;
&lt;p&gt;  if (!allowList.has(app)) {
    emit({
      severity: &apos;high&apos;,
      title: &apos;Unexpected elevation under Administrator Protection&apos;,
      smaa, app, auth, user,
      hint: &apos;Was the Hello prompt phished?&apos;
    });
  }
}
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For detection engineers, the &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; name is the highest-value correlation key on the device. It is stable per primary admin (the SMAA name is created once and persists across elevations), distinct from the limited-user SID (the SMAA has its own SID, so user-by-SID correlations and SMAA-by-name correlations are independent axes), and present in every ETW 15031 / 15032 event. A detection rule that groups elevations by SMAA name and flags unexpected application paths is the canonical &quot;someone phished a Hello prompt&quot; alert pattern.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Defenders now have the audit trail they did not have under UAC. The next section asks what residual attack surface survives the SMAA architecture, the Hello gate, and the new audit trail.&lt;/p&gt;
&lt;h2&gt;15. Open problems: what survives&lt;/h2&gt;
&lt;p&gt;Five residual attack surfaces, each acknowledged in Microsoft&apos;s own documentation, Forshaw&apos;s Project Zero posts, or the operational literature on Windows privilege escalation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The user is still the weak link.&lt;/strong&gt; Every elevation depends on a human accepting the prompt. The Hello credential gate makes that human&apos;s decision more costly to fake than the classic Yes/No, but the gate does not change the fact that a successful prompt is a successful elevation. The three sub-cases of consent-without-identity-verification from §9 -- unattended-session, habituated-click, pretext click-through -- are cost-raised, not closed. Phishing-the-prompt remains a live attack surface and Microsoft does not classify it as a vulnerability [@forshaw-pz-jan2026]. Out-of-band consent -- a phone-push approval channel, a smartcard tap, a separate hardware key tap -- would close the gap; none of these is the Administrator Protection default.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loopback authentication.&lt;/strong&gt; The structural property that Windows services authenticate to themselves over the local network stack is independent of the SMAA model. SMB to &lt;code&gt;localhost&lt;/code&gt;, Kerberos against the local machine account, NTLM challenge-response between processes on the same box -- these protocols predate UAC and are not changed by Administrator Protection. Forshaw&apos;s broader 2022 Kerberos research [@forshaw-2022-rbcd] catalogues the class. The &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless article&lt;/a&gt; in this series covers SMB signing, Extended Protection for Authentication (EPA), and channel binding mitigations that defenders should pair with Administrator Protection to close the loopback path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service-account &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt;.&lt;/strong&gt; The Potato lineage of attacks (cataloged in the &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;Access Control article&lt;/a&gt; in this series) runs in service accounts (&lt;code&gt;IIS_IUSRS&lt;/code&gt;, &lt;code&gt;LOCAL SERVICE&lt;/code&gt;, &lt;code&gt;NETWORK SERVICE&lt;/code&gt;), not in interactive admin sessions. Administrator Protection scopes itself to interactive admin elevation; the Potato class is structurally out of scope.&lt;/p&gt;

Service-account Potato attacks run inside `IIS_IUSRS`, `LOCAL SERVICE`, and `NETWORK SERVICE` rather than in interactive admin sessions. The attacker has compromised a service that holds `SeImpersonatePrivilege`, then uses one of several primitives (the SSPI / NEGOEX dance, the EFS RPC interface, a printer-spooler endpoint) to coerce a higher-privileged service into authenticating against the attacker&apos;s local socket, and impersonates the resulting token. Administrator Protection&apos;s promise is around the *interactive elevation* path -- the flow from a logged-in user clicking an installer to an elevated process running. Potato is a separate problem class with its own mitigations: removing `SeImpersonatePrivilege` from service accounts that don&apos;t need it, applying EPA, and patching the named primitives one by one.
&lt;p&gt;&lt;strong&gt;Driver loading once inside an SMAA elevation.&lt;/strong&gt; Admin equals kernel applies once a process is running inside the SMAA. Vulnerable-driver loading, kernel-mode code execution, and rootkit installation fall under the §11 &quot;admin equals kernel&quot; ceiling -- WHQL signing, the Vulnerable Driver Blocklist, App Control for Business, and HVCI remain the four-mechanism mitigation surface, with the App Identity article in this series covering the App Control mechanism. Administrator Protection does not change the relationship between admin and kernel; it changes the relationship between standard user and admin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Hello credential phishing surface.&lt;/strong&gt; The prompt now phishes a &lt;em&gt;real credential&lt;/em&gt; rather than a click-through approval. A malicious application that successfully argues its case to the user gets a Hello gesture against the primary user&apos;s PIN or biometric. The credential remains hardware-rooted; ESS-engaged biometrics never leave the TPM or Pluton enclave; the malware does not learn the PIN. But the malware does get the elevation. The Windows Hello article in this series covers FIDO2 / ESS / PIN architecture hardening. Defender-side mitigation is the ETW 15031 / 15032 detection rule set on unexpected application paths [@ms-admin-protection].&lt;/p&gt;
&lt;p&gt;The boundary is real, the audit trail is new, and the five-class residual surface is the next decade of work. The next section turns to operator-side practicalities.&lt;/p&gt;
&lt;h2&gt;16. Practical guide&lt;/h2&gt;
&lt;p&gt;Six tips, each tied to one Microsoft Learn or Windows Developer Blog primary source. Remember that, as of December 2025, Microsoft has reverted the rollout and the feature is currently disabled on stable Windows; the guidance below applies once Microsoft re-enables it. The Spoiler below contains the verbatim commands.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable.&lt;/strong&gt; Set &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; via Group Policy (&quot;User Account Control: Configure type of Admin Approval Mode&quot; -&amp;gt; &quot;Admin Approval Mode with Administrator Protection&quot;) or via the Intune Settings Catalog OMA-URI. A reboot is required for the new policy to take effect [@ms-admin-protection, @ms-kb5067036].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify.&lt;/strong&gt; Run &lt;code&gt;whoami&lt;/code&gt; in an elevated console. The profile name shows &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;. Run &lt;code&gt;whoami /priv&lt;/code&gt; to confirm the SMAA has the Administrators group enabled [@ms-admin-protection, @call4cloud-osint].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Capture.&lt;/strong&gt; Start the ETW trace with the documented &lt;code&gt;logman&lt;/code&gt; invocation; filter for Event IDs 15031 and 15032 [@ms-admin-protection]. The provider GUID is stable across builds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Do not enable&lt;/strong&gt; on devices that require Hyper-V or WSL. Re-evaluate when Microsoft re-enables the broad rollout [@ms-admin-protection, @forshaw-pz-jan2026].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For application developers&lt;/strong&gt;, follow the Windows Developer Blog (May 19, 2025) guidance [@ms-developer-blog-2025]: install per-user packages unelevated; use &lt;code&gt;%ProgramFiles%&lt;/code&gt; (and accept the elevated install path); avoid context switching during install; avoid sharing files between elevated and unelevated profiles; remove auto-elevation dependencies. The auto-elevation manifest attribute is no longer honoured under Administrator Protection, so any installer that relied on silent elevation needs to be reworked.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For IT admins&lt;/strong&gt; on already-enabled devices broken by an elevated install: disable Administrator Protection temporarily, reinstall the application unelevated, then re-enable [@ms-developer-blog-2025].&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Enable via Group Policy registry value (administrator console, persists across reboots):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# Set TypeOfAdminApprovalMode to 2 (Admin Approval Mode with Administrator Protection)
reg add &quot;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System&quot; /v TypeOfAdminApprovalMode /t REG_DWORD /d 2 /f
# Reboot required:
shutdown /r /t 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Capture the elevation event trace:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;logman start AdminProtectionTrace -p {93c05d69-51a3-485e-877f-1806a8731346} -ets
:: After some elevations:
logman stop AdminProtectionTrace -ets
:: Process the .etl with PerfView, Message Analyzer, or:
wevtutil qe Microsoft-Windows-LUA/Operational /q:&quot;*[System[(EventID=15031 or EventID=15032)]]&quot; /f:text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Verify the SMAA presence after enablement:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-LocalUser | Where-Object Name -like &apos;ADMIN_*&apos;
# After an elevation, run from the elevated console:
whoami
# Expect: WIN11-PC\ADMIN_&amp;lt;random16hex&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The single most common mistake in response to an Administrator Protection compatibility problem is to disable UAC globally by setting &lt;code&gt;EnableLUA = 0&lt;/code&gt;. This returns the device to the Windows XP single-token model, removes Mandatory Integrity Control enforcement on application processes, and effectively defeats every layer of UAC and Administrator Protection together. It is universally discouraged. The correct fix is per-application, via manifest, or per-device, via the documented Administrator Protection compatibility list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Six tips, one boundary, one operational checklist. The next section answers the most common misconceptions.&lt;/p&gt;
&lt;h2&gt;17. Frequently asked questions&lt;/h2&gt;

No. Administrator Protection runs in `appinfo.dll` inside the Application Information service, which runs in `svchost.exe` in VTL0 (the normal Windows kernel context). The SMAA itself is a normal SAM-database account, not a Virtual Secure Mode trustlet. The cross-process protections of Virtualization-Based Security apply to LSASS Credential Guard and a handful of other VTL1 services; the elevation pipeline is not one of them. The Secure Kernel article in this series treats VTL0 / VTL1 separation in detail.

Partially. Administrator Protection replaces Admin Approval Mode UAC when `TypeOfAdminApprovalMode = 2`. The credential-prompt path (the over-the-shoulder elevation that asks a standard user to enter an administrator&apos;s credentials) and classic Admin Approval Mode (`TypeOfAdminApprovalMode = 1`) coexist with Administrator Protection across different configurations [@ms-admin-protection]. On a device with Administrator Protection enabled, only the interactive admin&apos;s elevation path goes through the SMAA; the standard-user-asking-for-admin-credentials path is unchanged.

No. There is absolutely an admin token; it lives in a different account, in a different logon session, for a bounded lifetime. The marketing language describes lifetime and isolation, not nonexistence [@ms-developer-blog-2025, @bleepingcomputer-2024]. The SMAA&apos;s token persists for the lifetime of the elevated process; when the process exits, the token handle is released and the logon session is reaped. Between elevations, no SMAA token exists in memory.

No. Malware can still elevate if the user accepts the Hello prompt. The boundary Administrator Protection creates is between *silent* elevation and *consented* elevation, not between any elevation and none. Microsoft&apos;s design position is explicit: &quot;I expect that malware will still be able to get administrator privileges even if that&apos;s just by forcing a user to accept the elevation prompt&quot; [@forshaw-pz-jan2026]. The three sub-cases of consent-without-identity-verification from §9 are cost-raised, not eliminated. What changes is that the elevation must be visible. Defenders gain the ETW 15031 audit trail as a result.

No. EPM uses a virtual elevated account on a per-request basis with cloud-side policy, and the virtual account is *not* a member of the local Administrators group [@ms-epm-overview]. Administrator Protection uses a persistent local SMAA per admin user, with on-box `appinfo.dll` policy, and the SMAA *is* a member of the local Administrators group [@call4cloud-osint]. EPM is centrally policy-driven and works on standard-user devices; Administrator Protection is per-device architecture and applies only to interactive admin users. The two can coexist on the same device.

No. Per Microsoft Learn, remote logon, roaming profiles, and backup admins are out of scope [@ms-admin-protection]. A domain administrator who logs into a workstation interactively will not see the SMAA path. Microsoft has stated that domain scenarios may be added in future iterations; the current GA-target form is local-machine-only, interactive-admin-only.

No. Mimikatz inside the elevated SMAA session still has `SeDebugPrivilege` and can call `OpenProcess` on `lsass.exe` to dump LSASS unless LSA Protection (Run As Protected Process Light) and Credential Guard are also enabled. Administrator Protection protects the *elevation path*; it does not protect the *resulting privileged session*. To protect the privileged session, pair Administrator Protection with LSA Protection (`RunAsPPL=1`), Credential Guard, App Control for Business, and HVCI. The Secure Kernel article in this series covers the LSA Protection mechanism.
&lt;p&gt;The misconceptions are cleared. The next section returns to the opening hook with the new vocabulary the article has built.&lt;/p&gt;
&lt;h2&gt;18. The user-elevation companion to Credential Guard&lt;/h2&gt;
&lt;p&gt;Return to the two &lt;code&gt;whoami /all&lt;/code&gt; outputs from §1, this time with the vocabulary the article has built.&lt;/p&gt;
&lt;p&gt;The first output shows the primary user under classic UAC. One SID, one profile, one &lt;code&gt;HKCU&lt;/code&gt;, one logon-session LUID; the elevated console is the same user as the unelevated console, distinguished only by the integrity level on the token.&lt;/p&gt;
&lt;p&gt;The second output shows the same login under Administrator Protection. A different user name -- &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; -- with a different SID linked to the primary admin via &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; and &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt;. A different profile under &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;. A different &lt;code&gt;NTUSER.DAT&lt;/code&gt; mapped as &lt;code&gt;HKCU&lt;/code&gt;. A fresh authentication-ID LUID minted by LSASS through the credential-less logon path described in §7, on the strength of &lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s trusted request and a Hello gesture the primary user just performed. An ETW Event 15031 in the &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt; provider, freshly emitted, recording the elevation as approved, the application path, and the authentication method.&lt;/p&gt;
&lt;p&gt;The thesis lands. The elevation path is now itself a security boundary, with bulletin-grade fixes when it fails. Administrator Protection is the user-elevation companion to Credential Guard. Where Credential Guard isolated LSA secrets from admin-equals-kernel &lt;em&gt;inside&lt;/em&gt; the machine -- the &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Secure Kernel article&lt;/a&gt; in this series covers the VBS-rooted isolation in detail -- Administrator Protection isolates the elevation path &lt;em&gt;from&lt;/em&gt; the standard-user session. The two answer the two halves of the question the foundational Access Control article in this series left open: if admin equals kernel and tokens are bearer credentials, what is left to harden? The answer is the path that gets you there (Administrator Protection) and the data that is there once you arrive (Credential Guard).&lt;/p&gt;
&lt;p&gt;The December 2025 revert is the first iteration&apos;s learning round. The architecture is the right one. The application base catches up next. Forshaw&apos;s framing in February 2026 -- that Microsoft might have shipped this as a configurable mode rather than replacing admin approval completely -- is a reasonable critique, and the re-enablement is likely to address it. Until then, the operational reality on most stable Windows devices is the classic split-token model, with all the bypass canon it implies, and the SMAA design remains an Insider-Preview-and-policy-opted-in posture.&lt;/p&gt;
&lt;p&gt;What stays unchanged is the structural insight. The mechanism Microsoft used to make the elevation path a boundary is not novel; multi-user accounts have shipped in Windows NT since 1993. What changed is the &lt;em&gt;classification&lt;/em&gt;. Microsoft accepted, after twenty years of evidence, that the elevation pipeline needed to be a security boundary, and accepted with it the engineering cost: separate accounts, separate profiles, separate logon sessions, removal of auto-elevation, a credential gate instead of a click-through, an audit-trail ETW provider, and a willingness to ship bulletin-grade fixes for every Forshaw finding. The classification was the engineering decision. Everything else followed.&lt;/p&gt;
&lt;p&gt;This is what it took, in mechanism and in time, to make the elevation path real [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;adminless-administrator-protection-in-windows&quot; keyTerms={[
  { term: &quot;Split-token model&quot;, definition: &quot;The Vista UAC mechanism that issues two access tokens at logon for a member of the local Administrators group: a filtered standard-user token and a linked full administrator token referenced via the TokenLinkedToken field.&quot; },
  { term: &quot;System Managed Administrator Account (SMAA)&quot;, definition: &quot;The hidden local user account that Windows creates per primary administrator when TypeOfAdminApprovalMode = 2, used to host elevated processes in a fresh logon session.&quot; },
  { term: &quot;ShadowAccountForwardLinkSid / ShadowAccountBackLinkSid&quot;, definition: &quot;The paired SAM attributes that encode the trust relationship between a primary admin user and its SMAA.&quot; },
  { term: &quot;TypeOfAdminApprovalMode&quot;, definition: &quot;The registry value selecting the elevation policy: 0 disables UAC; 1 selects classic Admin Approval Mode; 2 selects Admin Approval Mode with Administrator Protection.&quot; },
  { term: &quot;Auto-elevation&quot;, definition: &quot;The Windows 7 mechanism by which selected Microsoft-signed binaries elevated without showing a consent prompt; removed under Administrator Protection.&quot; },
  { term: &quot;COM Elevation Moniker&quot;, definition: &quot;The COM activation syntax that lets an unelevated caller request an elevated instance of a COM server class; the structural primitive of many UACMe bypasses.&quot; },
  { term: &quot;Credential-less LSA logon&quot;, definition: &quot;The mechanism by which LSA mints a primary access token for the SMAA without verifying any SMAA credential, on the strength of appinfo.dll&apos;s trusted request and the primary user&apos;s Hello result.&quot; },
  { term: &quot;Consent-without-identity-verification&quot;, definition: &quot;The primitive by which the legacy UAC consent dialog accepted a click on the secure desktop as sufficient evidence of consent. Administrator Protection&apos;s credential gate cost-raises three sub-cases (unattended-session, habituated-click, pretext click-through) without eliminating any.&quot; },
  { term: &quot;UI Access flag&quot;, definition: &quot;The token flag (TOKEN_UIACCESS) that allows a process to interact with windows of higher integrity, bypassing UIPI; the basis of five of Forshaw&apos;s nine pre-GA Administrator Protection bypasses.&quot; },
  { term: &quot;ETW provider Microsoft-Windows-LUA&quot;, definition: &quot;The Event Tracing for Windows provider, GUID {93c05d69-51a3-485e-877f-1806a8731346}, that surfaces Administrator Protection elevation events. Event 15031 = approved; Event 15032 = denied/failed.&quot; },
  { term: &quot;Security boundary (MSRC servicing criteria)&quot;, definition: &quot;A logical separation between code or data of different trust levels accompanied by a Microsoft commitment to issue a security update when an unauthorised crossing is found. Administrator Protection is the first elevation mechanism to be classified as a security boundary.&quot; }
]} questions={[
  { q: &quot;What four shared resources of the Vista split-token model do the four Administrator Protection fixes attack?&quot;, a: &quot;Same SID across both tokens; same %USERPROFILE%; same HKCU hive; same logon-session LUID.&quot; },
  { q: &quot;Why is the auto-elevation whitelist &apos;the bypass&apos;, in Davidson&apos;s framing?&quot;, a: &quot;The day Microsoft shipped a class of binaries that elevated silently based on signing and path, the entire UAC-bypass problem reduced to making one of those binaries do something the attacker wanted it to do. The whitelist itself was the structural mistake.&quot; },
  { q: &quot;What does the SAM forward/back linkage do at elevation time?&quot;, a: &quot;appinfo.dll&apos;s RAiLaunchAdminProcess reads the calling user&apos;s ShadowAccountForwardLinkSid, walks to the SMAA, and validates the matching ShadowAccountBackLinkSid. Without both attributes pointing at each other, the elevation is refused.&quot; },
  { q: &quot;What is the credential-less LSA logon at step 6 of the Administrator Protection pipeline, and why is the SMAA mintable without a credential?&quot;, a: &quot;After a positive Hello result on the primary user&apos;s credential, appinfo.dll asks the kernel to ask LSA to authenticate a new instance of the shadow administrator. LSA fulfils the request because the requester (appinfo.dll as SYSTEM) is trusted -- the same trust-the-requester pattern SCM uses to obtain service-account tokens -- and the SMAA has no human credential to verify in any case.&quot; },
  { q: &quot;Which class of Forshaw&apos;s nine pre-GA bypasses is uniquely caused by Administrator Protection itself rather than inherited from UAC?&quot;, a: &quot;The lazy DOS device directory hijack. The &apos;fresh logon session per elevation&apos; design property means the per-session DOS device directory is created lazily on first reference; an identification-level impersonation of the SMAA&apos;s linked token could trick the kernel into creating it with the attacker&apos;s owner SID.&quot; },
  { q: &quot;Why did Microsoft revert Administrator Protection on December 1, 2025?&quot;, a: &quot;A WebView2 application-compatibility regression: installers that wrote per-user state into the elevated SMAA&apos;s profile broke under unelevated callers running as the primary user. Forshaw confirmed the revert was unrelated to security findings.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows</category><category>security</category><category>uac</category><category>administrator-protection</category><category>privilege-escalation</category><category>windows-hello</category><category>project-zero</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>&quot;Can This Code Do This?&quot; -- Twenty-Five Years of Attacks on the Windows Access-Control Model</title><link>https://paragmali.com/blog/windows-access-control-25-years-of-attacks/</link><guid isPermaLink="true">https://paragmali.com/blog/windows-access-control-25-years-of-attacks/</guid><description>How a single kernel function, SeAccessCheck, decides every Windows operation -- and how Mimikatz, the Potato lineage, and seventy UAC bypasses each attack one of its inputs.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><content:encoded>
Windows answers the question *can this code do this?* with one kernel function, `SeAccessCheck`, evaluated against five inputs: a security descriptor, an access token, a desired-access mask, a generic-mapping table, and any previously-granted access. The function and its inputs have not structurally changed since July 27, 1993. Every famous Windows local-privilege-escalation tool of the last twenty-five years -- Mimikatz, JuicyPotato and seven other Potatoes, the seventy AutoElevate-redirect methods catalogued in UACMe -- attacks one of those inputs. This article tells that story as one system, names the five structural limits Microsoft has publicly conceded, and explains why Adminless, NTLMless, VBS Trustlets, and Credential Guard are the four non-overlapping ways to close them.
&lt;h2&gt;1. One Question, Billions of Times a Second&lt;/h2&gt;
&lt;p&gt;Open a Windows PowerShell window and run &lt;code&gt;whoami /priv&lt;/code&gt;. Read the column on the right. &lt;code&gt;SeShutdownPrivilege&lt;/code&gt;. &lt;code&gt;SeUndockPrivilege&lt;/code&gt;. &lt;code&gt;SeIncreaseWorkingSetPrivilege&lt;/code&gt;. &lt;code&gt;SeTimeZonePrivilege&lt;/code&gt;. About twenty rows of capabilities, almost all marked &lt;em&gt;Disabled&lt;/em&gt;, on a token that lives inside &lt;code&gt;explorer.exe&lt;/code&gt;&apos;s memory and that the kernel consults billions of times a second.&lt;/p&gt;
&lt;p&gt;Now run &lt;code&gt;icacls C:\Windows\System32\drivers\etc\hosts&lt;/code&gt;. The output reads &lt;code&gt;BUILTIN\Administrators:(F)&lt;/code&gt;, &lt;code&gt;NT AUTHORITY\SYSTEM:(F)&lt;/code&gt;, &lt;code&gt;BUILTIN\Users:(R)&lt;/code&gt;. Six characters per principal, decoded by something inside the kernel called &lt;code&gt;SeAccessCheck&lt;/code&gt;, applied to a data structure called a security descriptor, against a credential called an access token, every time any process anywhere on the machine asks for read access to that single file [@ms-learn-access-control].&lt;/p&gt;
&lt;p&gt;This article is about the model behind those two outputs. A model that has not structurally changed since July 27, 1993, when Windows NT 3.1 shipped from Redmond [@en-wiki-windows-nt-3-1]. A model that every famous Windows local-privilege-escalation tool of the last twenty-five years -- Mimikatz, JuicyPotato, fodhelper.exe, the seventy methods in the open-source UACMe catalogue -- exists to attack [@github-gentilkiwi-mimikatz, @github-ohpe-juicy-potato, @github-hfiref0x-uacme].&lt;/p&gt;
&lt;p&gt;The thesis comes in three convictions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;SeAccessCheck&lt;/code&gt; is the answer.&lt;/strong&gt; Every securable Windows operation that touches a securable object resolves through one decision function with one set of inputs [@ms-learn-how-dacls-control-access].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Every famous Windows escalation tool attacks one of those inputs.&lt;/strong&gt; JuicyPotato attacks the token. Mimikatz attacks the privilege list. Fodhelper attacks the elevation flow that produces the token. HiveNightmare attacks the DACL on a single file [@nvd-cve-2021-36934]. The vocabulary scales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The model has five structural limits its keepers have publicly conceded&lt;/strong&gt; [@msrc-servicing-criteria], and Adminless, NTLMless, VBS Trustlets, and Credential Guard are the four non-overlapping ways to close them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The forecast for the next 14,000 words: ten primitives (the Security Reference Monitor, security identifiers, tokens, security descriptors, DACLs, SACLs, ACEs, privileges, Mandatory Integrity Control, User Account Control), one canonical oracle (&lt;code&gt;SeAccessCheck&lt;/code&gt;), two attack families (the Potato lineage and the UACMe bypass tradition), and four successor architectures (Adminless, NTLMless, VBS Trustlets, Credential Guard).&lt;/p&gt;
&lt;p&gt;If the model has not structurally changed since 1993, why has it taken thirty-three years and seventy bypasses to map its failure modes -- and what does each generation tell us about the next?&lt;/p&gt;
&lt;h2&gt;2. Origins: From Lampson&apos;s Matrix to Cutler&apos;s Kernel (1971-1993)&lt;/h2&gt;
&lt;p&gt;The vocabulary starts in a paper Butler Lampson presented at Princeton in 1971 and the ACM republished in &lt;em&gt;Operating Systems Review&lt;/em&gt; in January 1974. Lampson framed protection as a 2-D matrix: rows index the &lt;em&gt;subjects&lt;/em&gt; (users, processes), columns index the &lt;em&gt;objects&lt;/em&gt; (files, devices, memory pages), and the cell at the intersection holds the &lt;em&gt;operations&lt;/em&gt; the subject is permitted on the object. The matrix is a sparse, mostly-empty table the size of every-process times every-file. No real system has ever stored it that way.&lt;/p&gt;
&lt;p&gt;Two implementation strategies fall out of the formalism. Slice the matrix by row and you get &lt;em&gt;capability lists&lt;/em&gt;: each subject carries a token that names the objects it can touch. Slice by column and you get &lt;em&gt;access-control lists&lt;/em&gt;: each object carries a list of subjects allowed to touch it. Lampson worked through both in the paper. Operating systems built on the second slice came to dominate, partly because hardware in 1971 made unforgeable capabilities expensive, partly because file systems could carry an ACL at the inode without changing every program. Decades later, the gap between the two implementations would still matter; we will reach Norm Hardy&apos;s &quot;Confused Deputy&quot; in a moment.&lt;/p&gt;
&lt;p&gt;The lever that turned theory into Windows came from procurement, not academia. On December 26, 1985, the U.S. Department of Defense published &lt;code&gt;DoD 5200.28-STD&lt;/code&gt;, the &lt;em&gt;Trusted Computer System Evaluation Criteria&lt;/em&gt;, known by the colour of its cover as the Orange Book [@nist-csrc-rainbow]. The Orange Book defined four divisions of trusted-system assurance, and its C2 class -- &quot;Controlled Access Protection&quot; -- made discretionary access control plus auditing a federal procurement floor. The September 30, 1987 Neon Orange Book (NCSC-TG-003) and the July 28, 1987 Tan Book (NCSC-TG-001) elaborated DAC and audit respectively [@nist-csrc-rainbow]. After 1985, no operating system that wanted U.S. federal customers could ship without per-user ACLs and an audit log.&lt;/p&gt;
&lt;p&gt;A year before the Orange Book ossified DAC into procurement, Norm Hardy of the Tymshare / KeyKOS lineage published a three-page paper in &lt;em&gt;Operating Systems Review&lt;/em&gt; that named the structural limit of the entire ACL-shaped class: &quot;The Confused Deputy (or why capabilities might have been invented)&quot; [@wayback-cap-lore-hardy]. Hardy described a privileged compiler that wrote billing records to a system file. A user could trick the compiler into writing the user&apos;s &lt;em&gt;output&lt;/em&gt; file over the billing file, because the compiler used &lt;em&gt;its own&lt;/em&gt; authority on every write and could not distinguish &quot;authority I have&quot; from &quot;authority the caller asked me to use.&quot;&lt;/p&gt;
&lt;p&gt;The Wikipedia summary of the field is exact: &quot;Capability systems protect against the confused deputy problem, whereas access-control list-based systems do not&quot; [@en-wiki-confused-deputy]. Hold this paper. It will come back in Section 10.&lt;/p&gt;

The team that built Windows NT was not assembled in Redmond. David Cutler arrived in October 1988 from Digital Equipment Corporation [@en-wiki-cutler], where he had led VMS and the cancelled Mica successor, and brought with him a fraction of his old DEC team.&lt;p&gt;The cultural import mattered: VAX/VMS, announced October 25, 1977 alongside the VAX-11/780 (V1.0 shipped August 1978) [@en-wiki-openvms], introduced UIC-based file protection and a kernel-mode security architecture, and by the mid-1980s the VAX/VMS line had been evaluated at TCSEC Class C2 [@en-wiki-openvms], by which time the system had been hardened with per-object ACLs, audit channels, and an explicit reference monitor. That C2-hardened VMS was the cultural reference Cutler brought with him to Microsoft. G. Pascal Zachary&apos;s &lt;em&gt;Showstopper!&lt;/em&gt; tells the story of the four-year build of NT 3.1 from that team [@showstopper-zachary].&lt;/p&gt;
&lt;p&gt;The point for this article is narrower. NT 3.1&apos;s nine access-control primitives -- Security Reference Monitor, security identifier, access token, security descriptor, DACL, SACL, ACE, privileges, audit channel -- did not arrive piecemeal. They were specified together, before the first line of &lt;code&gt;SeAccessCheck&lt;/code&gt; was written, against a procurement standard the team intended to clear.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;NT 3.1 released to manufacturing on July 27, 1993 [@en-wiki-windows-nt-3-1]. NT 3.5, released to manufacturing on September 21, 1994 [@en-wiki-nt-3-5], was hardened through Service Pack 3 (June 21, 1995) and was rated by the National Security Agency in July 1995 as complying with TCSEC C2 criteria against the standalone single-user configuration [@en-wiki-nt-3-5]; NT 4.0 Service Pack 6a was evaluated at TCSEC C2 in a standalone (non-networked) configuration, consistent with NT 3.5 SP3. The combination froze the model. Once C2 evaluation was on the books, structural changes to the access-control surface would have required re-evaluation. Federal procurement obligations have kept the structural shape intact for thirty-one years, even after the Department of Defense formally retired TCSEC in favour of the Common Criteria.&lt;/p&gt;
&lt;p&gt;Cutler shipped a model that has answered &quot;can this code do this?&quot; the same way for thirty-three years. What is the actual function -- and what are its inputs?&lt;/p&gt;
&lt;h2&gt;3. The Kernel Oracle: &lt;code&gt;SeAccessCheck&lt;/code&gt; and Its Inputs&lt;/h2&gt;
&lt;p&gt;The function has one signature, one return value, and one job. Microsoft&apos;s Win32 documentation exposes a user-mode mirror called &lt;code&gt;AccessCheck&lt;/code&gt; that lets userland code ask the question without holding a handle, and a kernel routine called &lt;code&gt;SeAccessCheck&lt;/code&gt; that the kernel invokes at every securable operation [@ms-learn-access-control, @ms-learn-access-tokens]. The shape is the same in both directions:&lt;/p&gt;
&lt;p&gt;$$
\textsf{SeAccessCheck}(\textit{SD}, \textit{Token}, \textit{DesiredAccess}) \to (\textit{GrantedAccess}, \textit{Status})
$$&lt;/p&gt;
&lt;p&gt;Three inputs in (a security descriptor, an access token, a requested-access mask), two outputs out (the access mask actually granted, and a &lt;code&gt;STATUS_ACCESS_DENIED&lt;/code&gt; flavour if any). Two more hidden inputs make the kernel signature precise: a &lt;em&gt;generic mapping&lt;/em&gt; table that translates the four generic rights (&lt;code&gt;GENERIC_READ&lt;/code&gt;, &lt;code&gt;GENERIC_WRITE&lt;/code&gt;, &lt;code&gt;GENERIC_EXECUTE&lt;/code&gt;, &lt;code&gt;GENERIC_ALL&lt;/code&gt;) into object-type-specific bits, and a &lt;em&gt;previously-granted-access&lt;/em&gt; mask that the kernel carries forward when an access check happens in two phases. Together: five inputs, one decision, one log entry (the documented kernel routine carries a few additional parameters of kernel-internal bookkeeping -- a synchronization flag, an &lt;code&gt;AccessMode&lt;/code&gt; discriminator that elides the check for kernel-mode callers, and a privileges out-parameter -- which the explanatory five-input model collapses; the user-mode &lt;code&gt;AccessCheck&lt;/code&gt; mirror is closer to the model the article uses).&lt;/p&gt;

The kernel-mode component of the Windows NT executive that performs all access checks against securable objects. It owns `SeAccessCheck` and the audit log generation routines. The SRM is a *subsystem*, not a feature: every other kernel component that needs to grant or deny access calls into it.

The Windows kernel routine that decides whether a thread may perform a requested set of operations on an object. It takes a security descriptor, an access token, a desired-access mask, a per-object-type generic-mapping table, and any previously-granted access. (The documented kernel signature also carries a synchronization flag, an `AccessMode` discriminator that elides the check for kernel-mode callers, and a privileges out-parameter; the five-input model used here is an explanatory simplification that the user-mode `AccessCheck` mirror tracks more closely.) It returns the subset of the desired-access mask that the kernel grants and a status code. Every call site that opens or modifies a securable object eventually reaches this function [@ms-learn-how-dacls-control-access].
&lt;p&gt;The five inputs are not equally exotic. The desired-access mask and the generic-mapping table are bookkeeping that an object type defines once at registration time. The previously-granted-access input is the kernel handing itself a pencil for two-phase access checks, mostly invisible to userland. The two inputs the rest of the article will keep returning to are the security descriptor and the access token.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;security descriptor&lt;/em&gt; is the data structure attached to the object. It carries an owner SID, a primary-group SID, a discretionary access-control list (DACL) of allow / deny / audit entries, and a system access-control list (SACL) holding audit and integrity-label entries [@ms-learn-mic]. The DACL is what &lt;code&gt;icacls&lt;/code&gt; prints. The SACL is what writes Event Log entries when something the descriptor&apos;s writer wanted to watch happens.&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;access token&lt;/em&gt; is the data structure attached to the caller. It names the user (one SID), the user&apos;s groups (a list of SIDs), the privileges the user holds (a list of named superpowers), the integrity level the kernel will compare against the object&apos;s label, and a flag that says whether the token is a &lt;em&gt;primary&lt;/em&gt; token (one per process) or an &lt;em&gt;impersonation&lt;/em&gt; token (one per thread, used to act on a client&apos;s behalf) [@ms-learn-access-tokens].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s documentation lists the token&apos;s contents almost as bullet points: &quot;The security identifier (SID) for the user&apos;s account; SIDs for the groups of which the user is a member; A logon SID that identifies the current logon session; A list of the privileges held by either the user or the user&apos;s groups; An owner SID; The SID for the primary group; The default DACL; ... Whether the token is a primary or impersonation token; An optional list of restricting SIDs; Current impersonation levels...&quot; [@ms-learn-access-tokens].&lt;/p&gt;
&lt;p&gt;The flow inside &lt;code&gt;SeAccessCheck&lt;/code&gt; is mechanical. The kernel maps &lt;code&gt;DesiredAccess&lt;/code&gt; from generic to specific bits using the type&apos;s mapping table. It checks the integrity label of the object against the integrity level on the token (Mandatory Integrity Control runs &lt;em&gt;before&lt;/em&gt; the DACL walk, a point Section 7 expands). It walks the DACL in order, deny-first, accumulating bits granted by allow ACEs whose SID is in the token&apos;s list. It applies a &lt;em&gt;privilege bypass&lt;/em&gt; short-circuit if the caller holds &lt;code&gt;SeBackupPrivilege&lt;/code&gt;, &lt;code&gt;SeRestorePrivilege&lt;/code&gt;, &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, or one of the other privileges that grants access to whole classes of objects without consulting the DACL. It returns the accumulated &lt;code&gt;GrantedAccess&lt;/code&gt;, or &lt;code&gt;STATUS_ACCESS_DENIED&lt;/code&gt; if the requested bits were not all granted.&lt;/p&gt;

sequenceDiagram
    participant App as User-mode caller
    participant ObjMgr as Object Manager
    participant SRM as Security Reference Monitor
    participant Audit as Audit channel
    App-&amp;gt;&amp;gt;ObjMgr: OpenObject(name, DesiredAccess, ImpersonationToken)
    ObjMgr-&amp;gt;&amp;gt;ObjMgr: Resolve name (\BaseNamedObjects, \Device, \??)
    ObjMgr-&amp;gt;&amp;gt;ObjMgr: Fetch security descriptor from object header
    ObjMgr-&amp;gt;&amp;gt;SRM: SeAccessCheck(SD, Token, DesiredAccess)
    SRM-&amp;gt;&amp;gt;SRM: Map generic rights via type mapping
    SRM-&amp;gt;&amp;gt;SRM: Check mandatory integrity label
    SRM-&amp;gt;&amp;gt;SRM: Privilege-bypass short-circuit (SeBackup, SeRestore, SeDebug)
    SRM-&amp;gt;&amp;gt;SRM: Walk DACL in canonical order, deny-first
    SRM--&amp;gt;&amp;gt;ObjMgr: GrantedAccess + STATUS code
    ObjMgr-&amp;gt;&amp;gt;Audit: Emit SACL audit ACE if matched
    ObjMgr--&amp;gt;&amp;gt;App: HANDLE or STATUS_ACCESS_DENIED
&lt;p&gt;Five inputs. One function. One log entry on the way out. The thesis statement of this article is the consequence: every later section is an attack on one of those inputs. JuicyPotato attacks the token. Mimikatz attacks the privilege list. Fodhelper attacks the elevation flow that produces the token. HiveNightmare attacks the security descriptor on a single file. Conditional ACEs and Dynamic Access Control extend the matrix&apos;s &lt;em&gt;subject&lt;/em&gt; dimension by adding claims to the token. UAC tries to keep the token small by default and only inflate it on demand. Every primitive in the article maps cleanly onto one of &lt;code&gt;SeAccessCheck&lt;/code&gt;&apos;s five inputs, and every famous attack tool in the article maps cleanly onto one primitive.&lt;/p&gt;
&lt;p&gt;The function is fixed. The inputs are five. So how does the kernel actually walk a DACL -- and where does the wrong answer come from?&lt;/p&gt;
&lt;h2&gt;4. The DACL Algorithm and the SID Namespace&lt;/h2&gt;
&lt;p&gt;&quot;Walk the DACL in order.&quot; Six words that have generated hundreds of thousands of misconfigured ACLs since 1993. The Microsoft Learn page that ships the algorithm is short and exact. The system &quot;examines each ACE in sequence until... an access-denied ACE explicitly denies any of the requested access rights to one of the trustees listed in the thread&apos;s access token... one or more access-allowed ACEs for trustees listed in the thread&apos;s access token explicitly grant all the requested access rights... All ACEs have been checked and there is still at least one requested access right that has not been explicitly allowed, in which case, access is implicitly denied&quot; [@ms-learn-how-dacls-control-access].&lt;/p&gt;
&lt;p&gt;Three terminations. Deny terminates with denial. Enough allows terminates with grant. End-of-list with anything left ungranted terminates with denial. Note the asymmetry the algorithm encodes: a single deny anywhere in the DACL kills the request, but an allow has to be paired with explicit coverage of every desired bit. The default is denial.&lt;/p&gt;

The ordered list of access-control entries (ACEs) attached to a securable object&apos;s security descriptor that specifies which trustees are granted or denied which access rights. *Discretionary* means the object&apos;s owner controls the list, in contrast to a mandatory list whose entries the system enforces independent of owner intent.

A single grant, deny, audit, or mandatory-label record inside a DACL or SACL. Each ACE carries an SID identifying the trustee, a 32-bit access mask, a flags byte controlling inheritance, and a type discriminator. Windows defines four primary ACE types (`ACCESS_ALLOWED_ACE`, `ACCESS_DENIED_ACE`, `SYSTEM_AUDIT_ACE`, `SYSTEM_MANDATORY_LABEL_ACE`) plus callback variants for conditional ACEs [@ms-learn-ace-strings].
&lt;p&gt;{`
// Faithful implementation of the algorithm at
// learn.microsoft.com/en-us/windows/win32/secauthz/how-dacls-control-access-to-an-object
// Inputs: token (set of SIDs), DACL (ordered ACEs), desiredAccess mask.
// Output: granted mask + a per-ACE trace of why.&lt;/p&gt;
&lt;p&gt;function seAccessCheck(token, dacl, desiredAccess) {
  let remaining = desiredAccess;       // bits still needed
  let granted = 0;                     // bits accumulated so far
  const trace = [];&lt;/p&gt;
&lt;p&gt;  // NULL DACL grants everything; empty DACL grants nothing.
  if (dacl === null) {
    return { status: &apos;GRANTED (NULL DACL)&apos;, granted: desiredAccess, trace: [&apos;NULL DACL: full access&apos;] };
  }
  if (dacl.length === 0) {
    return { status: &apos;DENIED (empty DACL)&apos;, granted: 0, trace: [&apos;Empty DACL: no access&apos;] };
  }&lt;/p&gt;
&lt;p&gt;  for (let i = 0; i &amp;lt; dacl.length; i++) {
    const ace = dacl[i];
    const sidMatches = token.sids.includes(ace.sid);
    if (!sidMatches) {
      trace.push(`ACE ${i} (${ace.type} ${ace.sid}): SID not in token; skip`);
      continue;
    }
    if (ace.type === &apos;DENY&apos;) {
      const deniedBits = ace.mask &amp;amp; remaining;
      if (deniedBits !== 0) {
        trace.push(`ACE ${i}: DENY hits 0x${deniedBits.toString(16)} -&amp;gt; ACCESS_DENIED`);
        return { status: &apos;DENIED&apos;, granted: 0, trace };
      }
      trace.push(`ACE ${i}: DENY ${ace.sid} 0x${ace.mask.toString(16)} -- no requested bit hit; skip`);
    } else if (ace.type === &apos;ALLOW&apos;) {
      const newBits = ace.mask &amp;amp; remaining;
      granted |= newBits;
      remaining &amp;amp;= ~newBits;
      trace.push(`ACE ${i}: ALLOW grants 0x${newBits.toString(16)}, remaining 0x${remaining.toString(16)}`);
      if (remaining === 0) {
        return { status: &apos;GRANTED&apos;, granted, trace };
      }
    }
  }
  return { status: &apos;DENIED (end of DACL with bits unsatisfied)&apos;, granted: 0, trace };
}&lt;/p&gt;
&lt;p&gt;// Demo: a token with the user&apos;s SID and BUILTIN\Users; DACL with explicit deny + Everyone allow.
const token = { sids: [&apos;S-1-5-21-A-B-C-1001&apos;, &apos;S-1-5-32-545&apos;, &apos;S-1-1-0&apos;] };
const dacl = [
  { type: &apos;DENY&apos;,  sid: &apos;S-1-5-21-A-B-C-1001&apos;, mask: 0x00040000 },  // deny WRITE_DAC
  { type: &apos;ALLOW&apos;, sid: &apos;S-1-1-0&apos;,              mask: 0x00120089 }, // FILE_GENERIC_READ
  { type: &apos;ALLOW&apos;, sid: &apos;S-1-5-32-545&apos;,         mask: 0x001200A9 }, // GENERIC_READ + EXECUTE
];
console.log(seAccessCheck(token, dacl, 0x00040089));
`}&lt;/p&gt;
&lt;p&gt;The runnable above implements three subtleties the prose can flatten. First: the &lt;em&gt;NULL DACL&lt;/em&gt; versus &lt;em&gt;empty DACL&lt;/em&gt; distinction. A descriptor with no DACL at all -- a literal &lt;code&gt;NULL&lt;/code&gt; pointer where the list would be -- grants full access, on the theory that the writer expressed no policy and the kernel will not invent one. A descriptor with a DACL that exists but contains zero ACEs denies everything, because the writer expressed a policy and that policy has no allows. The single most common high-impact misconfiguration in the Windows codebase is code that meant to write the second and wrote the first, or vice versa.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Newly-written code that &quot;creates a file with no protection&quot; almost always wants an empty DACL but ends up with a NULL DACL because of how the SECURITY_DESCRIPTOR initialisation defaults work. Verify with &lt;code&gt;Get-Acl&lt;/code&gt; or &lt;code&gt;icacls&lt;/code&gt; after creation; a NULL DACL surface in &lt;code&gt;icacls&lt;/code&gt; looks like &lt;code&gt;Everyone:(F)&lt;/code&gt; and is almost always a bug, not a feature [@ms-learn-how-dacls-control-access].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Second: ACE &lt;em&gt;order&lt;/em&gt; is the caller&apos;s responsibility. The kernel walks the list in the order it finds it. The &quot;canonical&quot; order Windows expects is four-step, quoted verbatim from the Microsoft Learn reference [@ms-learn-order-of-aces]: &quot;1. All explicit ACEs are placed in a group before any inherited ACEs. 2. Within the group of explicit ACEs, access-denied ACEs are placed before access-allowed ACEs. 3. Inherited ACEs are placed in the order in which they are inherited... 4. For each level of inherited ACEs, access-denied ACEs are placed before access-allowed ACEs.&quot;&lt;/p&gt;
&lt;p&gt;The same page underlines who has to enforce the order: &quot;Functions such as &lt;code&gt;AddAccessAllowedAceEx&lt;/code&gt; and &lt;code&gt;AddAccessAllowedObjectAce&lt;/code&gt; add an ACE to the end of an ACL. It is the caller&apos;s responsibility to ensure that the ACEs are added in the proper order.&quot; If the writer of the DACL hands the kernel an out-of-order list with a deny ACE buried after a wide allow ACE, the deny will be unreachable and the descriptor will silently grant more than the writer intended.&lt;/p&gt;
&lt;p&gt;Third: there is no special case for &quot;Everyone.&quot; The well-known SID &lt;code&gt;S-1-1-0&lt;/code&gt; exists in every token of every process on the machine; an ACE against it applies to every caller. There is no extra logic that says &quot;if this is Everyone, treat it differently from any other group.&quot; James Forshaw made the point with characteristic bluntness in 2020: &quot;don&apos;t forget S-1-1-0, this is NOT A SECURITY BOUNDARY. Lah lah, I can&apos;t hear you!&quot; [@tiraniddo-sharing-logon-session]. The DACL evaluation algorithm does not know &quot;Everyone&quot; is special. It is a SID like any other.&lt;/p&gt;
&lt;p&gt;That makes the SID namespace itself worth a tour. Microsoft documents the structure as a revision number, an &lt;em&gt;identifier authority&lt;/em&gt; (a six-byte field that says which authority issued the SID), a list of sub-authorities, and a final &lt;em&gt;relative identifier&lt;/em&gt; (RID) [@ms-learn-security-identifiers]. Microsoft&apos;s own page on SIDs is precise: &quot;A security identifier (SID) is a unique value of variable length used to identify a trustee... When a SID has been used as the unique identifier for a user or group, it cannot ever be used again to identify another user or group.&quot;&lt;/p&gt;
&lt;p&gt;The well-known SIDs the kernel recognises by name include &lt;code&gt;SYSTEM&lt;/code&gt; (S-1-5-18), &lt;code&gt;LocalService&lt;/code&gt; (S-1-5-19), &lt;code&gt;NetworkService&lt;/code&gt; (S-1-5-20), &lt;code&gt;Everyone&lt;/code&gt; (S-1-1-0), &lt;code&gt;Authenticated Users&lt;/code&gt; (S-1-5-11), and the four Mandatory Integrity Control levels (S-1-16-4096 / 8192 / 12288 / 16384) [@en-wiki-mic, @ms-learn-mic]. Machine-issued SIDs encode the machine&apos;s domain identity in the sub-authorities; domain-issued SIDs encode the domain identity. RID 500 is, by convention, the local Administrator account; RID 501 is the Guest account.&lt;/p&gt;

A variable-length, never-reused identifier for a trustee (user, group, machine, service, or capability) inside the Windows security model. SIDs are encoded in canonical form `S-R-I-S1-S2-...-RID`, where R is a revision number, I is the identifier authority, the Sn are sub-authorities issued by that authority, and RID is the relative identifier. Every ACE references an SID; every token contains a list of them [@ms-learn-security-identifiers].
&lt;p&gt;James Forshaw documented in 2017 that Windows generates the per-service SID for &lt;code&gt;NT SERVICE\&amp;lt;ServiceName&amp;gt;&lt;/code&gt; deterministically: it is the SHA-1 hash of the uppercased service name, formatted into the SID&apos;s sub-authority fields. This is why Windows can refer to running services as security principals without an explicit registration step -- the kernel derives the SID on demand [@tiraniddo-trustedinstaller-blog].&lt;/p&gt;
&lt;p&gt;Two SID families this article will not derive: AppContainer &lt;em&gt;Package SIDs&lt;/em&gt; (S-1-15-2-...) and &lt;em&gt;capability SIDs&lt;/em&gt; (S-1-15-3-...). Both arrived with Windows 8 in 2012 and extend the matrix&apos;s subjects with code identity and capability tokens. The sibling &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;App Identity article&lt;/a&gt; in this series carries the canonical derivation, including the Crockford-Base32 PublisherId derivation that produces a Package SID from an MSIX package signature [@app-identity-sibling]. Section 5 of &lt;em&gt;this&lt;/em&gt; article will mention those SIDs in tokens; we will not redefine them here.&lt;/p&gt;
&lt;p&gt;The DACL is half the story. What does the &lt;em&gt;thread&lt;/em&gt; bring to the access check -- and why is the answer &quot;whoever happens to hold the handle&quot;?&lt;/p&gt;
&lt;h2&gt;5. Tokens as Bearer Credentials&lt;/h2&gt;
&lt;p&gt;A token is not a credential the way a password is. A token is a credential the way &lt;em&gt;cash&lt;/em&gt; is: whoever holds it gets the rights. This is the single most important property in the article.&lt;/p&gt;
&lt;p&gt;Microsoft splits tokens into two flavours by purpose [@ms-learn-access-tokens]. A &lt;em&gt;primary token&lt;/em&gt; hangs off a process and represents the security identity that process runs as. Every process has exactly one. An &lt;em&gt;impersonation token&lt;/em&gt; hangs off a thread and lets that thread temporarily act as someone else -- typically a network client whose request the thread is servicing. Tokens are kernel objects with handles, and like every other kernel object the kernel does not care how a process obtained the handle. If the handle resolves to a token in the kernel&apos;s table, the kernel grants the rights the token names.&lt;/p&gt;

A kernel object that names the security identity of a thread or process. It carries the user&apos;s SID, the SIDs of the user&apos;s groups, the privileges the user holds, an integrity level, an integrity-level mandatory policy, an optional list of *restricting* SIDs, a flag distinguishing primary from impersonation tokens, and the impersonation level (Anonymous / Identification / Impersonation / Delegation) [@ms-learn-access-tokens]. The kernel consults a token on every access check for the thread that holds it.

A *primary token* is owned by a process and represents the identity the process runs as; every process has exactly one primary token. An *impersonation token* is owned by a thread and represents an identity the thread is temporarily acting on behalf of -- typically a network client. The primary / impersonation distinction is a discriminator inside the token itself, set when the token is created or duplicated [@ms-learn-access-tokens].
&lt;p&gt;The impersonation flavour acquired its modern shape in Windows 2000. A token&apos;s &lt;em&gt;impersonation level&lt;/em&gt; takes one of four values, ordered from least to most privileged for the impersonator. &lt;em&gt;Anonymous&lt;/em&gt; lets the server know nothing about the client. &lt;em&gt;Identification&lt;/em&gt; lets the server learn the client&apos;s SIDs but not act as the client. &lt;em&gt;Impersonation&lt;/em&gt; lets the server perform local access checks as the client; this is the level a typical RPC server requests. &lt;em&gt;Delegation&lt;/em&gt; lets the server forward the client&apos;s identity onto another machine, useful for multi-hop scenarios but a frequent source of relay-style bugs. Almost every Potato lineage attack consumes an &lt;em&gt;Impersonation&lt;/em&gt;-level token; that is enough to call &lt;code&gt;ImpersonateLoggedOnUser&lt;/code&gt; and run as the client [@itm4n-printspoofer-blog].&lt;/p&gt;
&lt;p&gt;Microsoft documents a third token shape, the &lt;em&gt;restricted token&lt;/em&gt;, that is rare in practice but worth understanding because it is the only place in the model where an explicit deny-list lives on the token itself rather than the descriptor. A restricted token combines three knobs: a list of SIDs converted to &lt;em&gt;deny-only&lt;/em&gt; (their grants count for no allow ACE but their presence still triggers deny ACEs), a list of &lt;em&gt;restricting SIDs&lt;/em&gt; that the access check must independently permit, and a list of privileges removed from the token&apos;s privilege set [@ms-learn-restricted-tokens].&lt;/p&gt;
&lt;p&gt;The kernel runs &lt;code&gt;SeAccessCheck&lt;/code&gt; twice and grants only the intersection: &quot;When a restricted process or thread tries to access a securable object, the system performs two access checks: one using the token&apos;s enabled SIDs, and another using the list of restricting SIDs. Access is granted only if both access checks allow the requested access rights&quot; [@ms-learn-restricted-tokens]. Restricted tokens are operationally niche because the same documentation requires applications using them to &quot;run the restricted application on desktops other than the default desktop. This is necessary to prevent an attack by a restricted application, using &lt;code&gt;SendMessage&lt;/code&gt; or &lt;code&gt;PostMessage&lt;/code&gt;, to unrestricted applications on the default desktop&quot; [@ms-learn-restricted-tokens]. Few applications can spare the desktop overhead.&lt;code&gt;whoami /priv&lt;/code&gt; shows &lt;em&gt;available&lt;/em&gt; privileges, not &lt;em&gt;enabled&lt;/em&gt; privileges. The &lt;code&gt;Enabled&lt;/code&gt; column is the load-bearing one: an available-but-disabled privilege does not affect any access check until the process explicitly enables it via &lt;code&gt;AdjustTokenPrivileges&lt;/code&gt;. The discipline of leaving privileges disabled by default is a defence in depth that depends on the application not having an exploitable bug between disable and use.&lt;/p&gt;
&lt;p&gt;A token also carries flags that drive specific runtime behaviours: a &lt;em&gt;split-token&lt;/em&gt; indicator points at a &lt;em&gt;linked&lt;/em&gt; full-administrator counterpart for the UAC scenario in Section 8; an &lt;em&gt;AppContainer&lt;/em&gt; flag plus a Package SID and capability SIDs name an AppContainer-bound process. In every case, the kernel consults the token by handle and trusts the contents. The kernel does not ask how a process obtained the handle. It asks only what the token says.&lt;/p&gt;
&lt;p&gt;This is the property that organises the rest of the article.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; &lt;strong&gt;The Windows access token is a bearer credential.&lt;/strong&gt; Whichever process holds the handle gets the rights. The kernel does not ask how the handle was obtained; it asks only what the token says. This single property explains the entire Potato lineage, Mimikatz &lt;code&gt;token::elevate&lt;/code&gt;, and most of the privilege-abuse canon. Once you see it, every later attack section in the article becomes the same bug repeated against a different token-acquisition primitive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the token is a bearer credential, anyone with a way to obtain a SYSTEM token&apos;s handle is SYSTEM. Every Potato in Section 10 will be a different way to provoke a SYSTEM-token handle into the attacker&apos;s process. But the access check has another input that bypasses the DACL entirely. What is it, and which attackers know about it?&lt;/p&gt;
&lt;h2&gt;6. Privileges as a Different Dimension&lt;/h2&gt;
&lt;p&gt;Privileges are not access rights. They are pre-checked superpowers. They live on the token, they bypass the DACL for specific operations, and they are baked into the kernel for those operations alone.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s framing on Learn is exact: &quot;Privileges differ from access rights in two ways: Privileges control access to system resources and system-related tasks, whereas access rights control access to securable objects&quot; [@ms-learn-privileges]. The same page makes the operational consequence clear: &quot;Most privileges are disabled by default&quot; [@ms-learn-privileges]. A process that holds a privilege but has not enabled it (via &lt;code&gt;AdjustTokenPrivileges&lt;/code&gt;) cannot use it. The discipline is &quot;principle of least privilege at the millisecond level&quot; -- the privilege is on the token, but it does nothing until the program explicitly turns it on for the next system call.&lt;/p&gt;

A named, kernel-recognised authority on the access token that lets the holder perform a specific class of operations the DACL evaluation alone would not permit. Privileges include `SeDebugPrivilege` (read/write any process), `SeImpersonatePrivilege` (act on a client&apos;s token), `SeAssignPrimaryTokenPrivilege` (start a process under a token), `SeBackupPrivilege` (read any file regardless of DACL), `SeRestorePrivilege` (write any file regardless of DACL), `SeTcbPrivilege` (act as the operating system), and `SeLoadDriverPrivilege` (load a kernel driver). Most are disabled by default and must be enabled via `AdjustTokenPrivileges` before use [@ms-learn-privileges].
&lt;p&gt;The reason privileges deserve a section of their own is that &lt;em&gt;five of them are equivalent to &quot;I am SYSTEM&quot;&lt;/em&gt; and the other dozen are housekeeping. The five-versus-housekeeping split is the load-bearing audit decision in any Windows hardening review. Step through them.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeDebugPrivilege&lt;/code&gt; lets the holder open any process for full read and write, including processes running as SYSTEM. The privilege exists so that &lt;code&gt;Visual Studio&lt;/code&gt; and &lt;code&gt;WinDbg&lt;/code&gt; can debug code other users have started. The first move in almost every Mimikatz session is &lt;code&gt;privilege::debug&lt;/code&gt;, which enables the privilege the local administrator already has on the token [@github-gentilkiwi-mimikatz, @en-wiki-mimikatz]. Once enabled, the next Mimikatz command opens &lt;code&gt;lsass.exe&lt;/code&gt; and reads the credentials.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; lets the holder accept any token offered by a client and act as that client. The privilege is held by every Windows service account by default -- IIS, SQL Server, the Print Spooler, scheduled tasks, Docker containers, Citrix, the entire population of background services that need to handle authenticated requests. &lt;em&gt;This is the load-bearing privilege for the Potato lineage&lt;/em&gt; [@itm4n-printspoofer-blog]. Section 10 will spend twenty paragraphs on what a service account holding &lt;code&gt;SeImpersonate&lt;/code&gt; can be tricked into doing; the privilege is the entry condition.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt; lets the holder launch a new process under any primary token. Combined with &lt;code&gt;SeImpersonate&lt;/code&gt;, the pair gives an attacker the entire token-replay attack: get an impersonation handle to a SYSTEM token, then call &lt;code&gt;CreateProcessAsUser&lt;/code&gt; to run a command as SYSTEM. itm4n quotes decoder_it on the operational consequence.&lt;/p&gt;

if you have SeAssignPrimaryToken or SeImpersonate privilege, you are SYSTEM. -- decoder_it, quoted by itm4n in the PrintSpoofer disclosure [@itm4n-printspoofer-blog]
&lt;p&gt;&lt;code&gt;SeBackupPrivilege&lt;/code&gt; lets the holder read any file regardless of DACL, on the theory that backup software has to. &lt;code&gt;SeRestorePrivilege&lt;/code&gt; is the symmetric write privilege. The two together mean that a process holding both can rewrite any file on the machine, including service binaries.&lt;/p&gt;
&lt;p&gt;The 2021 &lt;em&gt;HiveNightmare&lt;/em&gt; / &lt;em&gt;SeriousSAM&lt;/em&gt; vulnerability (CVE-2021-36934) is the worked example of what happens when the model assumes nobody but the backup process has read access to a sensitive file and the assumption breaks. The NVD description is exact: &quot;An elevation of privilege vulnerability exists because of overly permissive Access Control Lists (ACLs) on multiple system files, including the Security Accounts Manager (SAM) database&quot; [@nvd-cve-2021-36934]. The DACL on the live &lt;code&gt;\Windows\System32\config\SAM&lt;/code&gt; was correct; the DACL on the &lt;em&gt;Volume Shadow Copy&lt;/em&gt; mirror was overly permissive enough that any local user could read the SAM hashes through the shadow-copy device path.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s fix required not just a patch but a manual operator step: &quot;After installing this security update, you must manually delete all shadow copies of system files, including the SAM database, to fully mitigate this vulnerability&quot; [@nvd-cve-2021-36934]. A patch alone could not erase the historical shadow copies that already had the wrong DACL.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeTcbPrivilege&lt;/code&gt; lets the holder &quot;act as the operating system&quot; -- it is the privilege that grants identity to the kernel itself. Held only by &lt;code&gt;LocalSystem&lt;/code&gt; services in well-administered environments. A non-system process that somehow acquired &lt;code&gt;SeTcb&lt;/code&gt; is, in effect, indistinguishable from the kernel.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; lets the holder load a kernel driver. By itself the privilege is harmless, because the loaded driver still has to be properly signed for HVCI / Driver Signature Enforcement to accept it. Combined with a known-vulnerable signed driver, however, the privilege becomes the entry point for &lt;em&gt;bring-your-own-vulnerable-driver&lt;/em&gt; (BYOVD) attacks: load a benign-looking but exploitable signed driver, then use its bug to execute arbitrary kernel code. Two worked examples bracket the class.&lt;/p&gt;
&lt;p&gt;The kernel-read/write half of the class is best illustrated by Micro-Star&apos;s &lt;code&gt;RTCore64.sys&lt;/code&gt; (CVE-2019-16098 [@nvd-cve-2019-16098]), the MSI Afterburner driver that &quot;allows any authenticated user to read and write to arbitrary memory, I/O ports, and MSRs&quot; [@nvd-cve-2019-16098]. In October 2022, the threat actors behind the BlackByte ransomware weaponised the primitive at scale [@sophos-blackbyte]: the dropper loaded &lt;code&gt;RTCore64.sys&lt;/code&gt;, then walked the kernel&apos;s &lt;code&gt;PspCreateProcessNotifyRoutine&lt;/code&gt; callback array and zeroed every entry, blinding every registered process-creation callback before the encryption stage ran.&lt;/p&gt;
&lt;p&gt;Sophos&apos;s October 4, 2022 disclosure named the technique exactly: &quot;We found a sophisticated technique to bypass security products by abusing a known vulnerability in the legitimate vulnerable driver RTCore64.sys. The evasion technique supports disabling a whopping list of over 1,000 drivers on which security products rely to provide protection&quot; [@sophos-blackbyte].&lt;/p&gt;
&lt;p&gt;The kernel-code-execution half of the class is GIGABYTE&apos;s &lt;code&gt;gdrv.sys&lt;/code&gt; (CVE-2018-19320 [@nvd-cve-2018-19320]). The NVD description states the primitive directly: &quot;The GDrv low-level driver in GIGABYTE APP Center v1.05.21 and earlier... exposes ring0 memcpy-like functionality that could allow a local attacker to take complete control of the affected system&quot; [@nvd-cve-2018-19320]. A signed &lt;code&gt;IOCTL&lt;/code&gt; accepts an attacker-supplied source pointer, destination pointer, and length, and copies kernel memory at ring 0 -- a write-what-where primitive that the attacker can compose with the read-anywhere primitive of &lt;code&gt;RTCore64.sys&lt;/code&gt; to mint arbitrary kernel code execution.&lt;/p&gt;
&lt;p&gt;CISA added GIGABYTE Multiple Products to the Known Exploited Vulnerabilities Catalog on October 24, 2022 with a remediation due date of November 14, 2022, citing in-the-wild exploitation [@nvd-cve-2018-19320]. The U.S. federal-civilian executive branch had two weeks to remediate; the rest of the install base did not.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s structural answer is the Microsoft-recommended driver blocklist, enabled by default on every device since the Windows 11 2022 update [@ms-learn-driver-blocklist]. The Learn page is exact about coverage: the blocklist targets drivers with &quot;known security vulnerabilities that an attacker could exploit to elevate privileges in the Windows kernel&quot;, and explicitly catches drivers whose behaviours &quot;circumvent the Windows Security Model&quot; [@ms-learn-driver-blocklist].&lt;/p&gt;
&lt;p&gt;Both &lt;code&gt;RTCore64.sys&lt;/code&gt; and &lt;code&gt;gdrv.sys&lt;/code&gt; appear on the blocklist; the ride from disclosure to default-on enforcement was four years for &lt;code&gt;RTCore64&lt;/code&gt;, four years for &lt;code&gt;gdrv&lt;/code&gt;, and the same arc applies to every member of the class. Honourable mention: &lt;code&gt;aswArPot.sys&lt;/code&gt; (CVE-2022-26522 / CVE-2022-26523 [@sentinelone-avast-avg]) shows the same pattern from a security-product driver, with SentinelLabs reporting &quot;two high severity flaws in Avast and AVG... that went undiscovered for years affecting dozens of millions of users&quot; before the silent fix [@sentinelone-avast-avg].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On a Windows machine, holding any of &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt;, &lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt;, &lt;code&gt;SeBackupPrivilege&lt;/code&gt;, or &lt;code&gt;SeRestorePrivilege&lt;/code&gt; is operationally indistinguishable from being SYSTEM. The other privileges in the standard token (the long tail of &lt;code&gt;SeShutdown&lt;/code&gt;, &lt;code&gt;SeIncreaseWorkingSet&lt;/code&gt;, &lt;code&gt;SeTimeZone&lt;/code&gt;, &lt;code&gt;SeChangeNotify&lt;/code&gt;, &lt;code&gt;SeUndock&lt;/code&gt;, &lt;code&gt;SeIncreaseQuota&lt;/code&gt;...) are housekeeping. Audit the holders of the five accordingly: any non-LocalSystem-equivalent account that holds them is a target.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The DACL is the load-bearing thing for &lt;em&gt;file&lt;/em&gt; access, but exactly &lt;em&gt;one bad DACL&lt;/em&gt; on a sensitive file ends the model. HiveNightmare proved that the cost of getting a single security descriptor wrong on a single file is the entire credential database. The general rule the lesson encodes: every primitive in Section 3&apos;s input list has at least one production example where misuse of that primitive alone dropped the security model to zero.&lt;/p&gt;
&lt;p&gt;Discretionary access control assumes the principal -- the user -- is the right unit of authorisation. By 2006, exploitable user-mode code had proven the principal was wrong. What did Microsoft do?&lt;/p&gt;
&lt;h2&gt;7. Mandatory Integrity Control: Stapling No-Write-Up onto DAC&lt;/h2&gt;
&lt;p&gt;November 2006. Vista releases to manufacturing, and for the first time in Windows history, the kernel&apos;s access check fires &lt;em&gt;before&lt;/em&gt; the DACL walk -- on something other than the user&apos;s identity. The new layer is &lt;em&gt;Mandatory Integrity Control&lt;/em&gt; (MIC), and it adds a four-level lattice to every securable object in the system.&lt;/p&gt;
&lt;p&gt;Microsoft Learn frames MIC compactly. &quot;MIC uses integrity levels and mandatory policy to evaluate access. Security principals and securable objects are assigned integrity levels that determine their levels of protection or access. For example, a principal with a low integrity level cannot write to an object with a medium integrity level, even if that object&apos;s DACL allows write access to the principal&quot; [@ms-learn-mic]. The same page enumerates the levels: &quot;Windows defines four integrity levels: low, medium, high, and system&quot; [@ms-learn-mic]. The levels are encoded as four well-known SIDs: Low (S-1-16-4096), Medium (S-1-16-8192), High (S-1-16-12288), System (S-1-16-16384) [@en-wiki-mic].&lt;/p&gt;

A Windows kernel mechanism, introduced with Vista (released to manufacturing November 8, 2006; consumer general availability January 30, 2007 [@en-wiki-windows-vista]), that adds an integrity-level check to `SeAccessCheck`. Each securable object carries an integrity label inside its SACL; each access token carries an integrity level. An access whose direction violates the configured *mandatory policy* (typically *no-write-up*) is denied at the integrity check before the DACL walk runs. MIC is the mandatory layer the Windows DAC model historically lacked [@ms-learn-mic].

A linearly-ordered tag (Low / Medium / High / System) carried on every Windows process token and every securable object. The kernel uses the relative ordering to enforce mandatory policy independent of the object&apos;s DACL. The four well-known SIDs are S-1-16-4096 (Low), S-1-16-8192 (Medium), S-1-16-12288 (High), and S-1-16-16384 (System) [@en-wiki-mic].
&lt;p&gt;The default policy is &lt;em&gt;no-write-up&lt;/em&gt;. A process at integrity level $L$ cannot modify an object at integrity level greater than $L$, regardless of what the DACL says. Microsoft&apos;s example is the load-bearing one: a process running at Low IL cannot write to a Medium-IL object even if the DACL says Everyone has full control. The integrity check fires &lt;em&gt;before&lt;/em&gt; the DACL walk; if the integrity check denies, the DACL is not consulted [@ms-learn-mic].&lt;/p&gt;
&lt;p&gt;The integrity label is stored as a &lt;code&gt;SYSTEM_MANDATORY_LABEL_ACE&lt;/code&gt; inside the SACL, not the DACL [@ms-learn-system-mandatory-label-ace]. The mask field on the label ACE encodes which directions of access the policy forbids: &lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_WRITE_UP (0x1)&lt;/code&gt;, &lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_READ_UP (0x2)&lt;/code&gt;, and &lt;code&gt;SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP (0x4)&lt;/code&gt; [@ms-learn-system-mandatory-label-ace].&lt;/p&gt;
&lt;p&gt;Storing the label in the SACL is a deliberate choice with one operational consequence: tools that copy the DACL but not the SACL silently drop the integrity label. The most common consequence is a Low-IL file getting copied to a new location and emerging with no integrity label, which defaults to Medium and unintentionally raises the object&apos;s protection. The opposite mistake -- a Medium-IL file losing its label and dropping to Low -- is the more dangerous one.&lt;/p&gt;
&lt;p&gt;The no-write-up mask is the one to memorise, because it is the policy almost every label uses. When a Low-IL caller tries to act on a Medium-IL object, the kernel denies any access whose mapped result contains write-class bits, including the standard-rights &lt;code&gt;WRITE_DAC&lt;/code&gt; (bit 18 of the 32-bit ACCESS_MASK [@ms-learn-access-mask]) and &lt;code&gt;WRITE_OWNER&lt;/code&gt; (bit 19), the type-generic &lt;code&gt;DELETE&lt;/code&gt; (bit 16), and the file-specific &lt;code&gt;FILE_WRITE_DATA&lt;/code&gt; (0x2), &lt;code&gt;FILE_APPEND_DATA&lt;/code&gt; (0x4), &lt;code&gt;FILE_WRITE_EA&lt;/code&gt; (0x10), and &lt;code&gt;FILE_WRITE_ATTRIBUTES&lt;/code&gt; (0x100) [@ms-learn-file-access-rights].&lt;/p&gt;
&lt;p&gt;The presence of &lt;code&gt;FILE_APPEND_DATA&lt;/code&gt; in that list matters operationally: a careless reader of the spec might assume that &quot;append&quot; semantics escape the no-write-up rule because they do not modify existing bytes. They do not. MIC denies both write modes, so log-only append handlers cannot be used as a write-up channel into a higher-IL object.&lt;/p&gt;
&lt;p&gt;A second rule completes the model: &lt;em&gt;process integrity inheritance&lt;/em&gt;. When a process is created, the kernel assigns it the &lt;em&gt;minimum&lt;/em&gt; of the user&apos;s integrity level and the file&apos;s integrity level [@ms-learn-mic]. A medium-IL user running a low-IL executable gets a low-IL process. This is the rule that lets Internet Explorer 7 run at Low even when launched from a Medium user session.&lt;/p&gt;
&lt;p&gt;The first MIC consumer was IE7 &lt;em&gt;Protected Mode&lt;/em&gt;, which shipped with Windows Vista RTM (released to manufacturing November 8, 2006) [@wayback-skywing-uninformed-v8a6, @en-wiki-windows-vista]. (IE7 standalone for Windows XP, released October 18, 2006 [@en-wiki-ie7], runs without Protected Mode -- the feature depends on Vista&apos;s MIC kernel layer.) Skywing&apos;s &lt;em&gt;Uninformed&lt;/em&gt; Volume 8 Article 6, &quot;Getting Out of Jail: Escaping Internet Explorer Protected Mode,&quot; is the first public reverse-engineering of the implementation.&lt;/p&gt;
&lt;p&gt;Skywing&apos;s framing remains the most-cited primer on the subject: &quot;With the introduction of Windows Vista, Microsoft has added a new form of mandatory access control to the core operating system. Internally known as &apos;integrity levels&apos;, this new addition to the security manager allows security controls to be placed on a per-process basis. This is different from the traditional model of per-user security controls used in all prior versions of Windows NT&quot; [@wayback-skywing-uninformed-v8a6]. IE7&apos;s Protected Mode pattern -- a Low-IL worker that does the dangerous parsing, paired with a Medium-IL broker that performs the system-changing operations on the worker&apos;s behalf -- became the template Windows would later generalise into AppContainer.&lt;em&gt;User Interface Privilege Isolation&lt;/em&gt; (UIPI) is the window-message gate that uses MIC at the desktop. A Low-IL window cannot send &lt;code&gt;SendMessage&lt;/code&gt; or &lt;code&gt;PostMessage&lt;/code&gt; traffic to a Medium-IL or higher window. UIPI is the reason you cannot click-jack a UAC consent prompt from a normally-running browser process: the consent prompt runs at High IL, the browser runs at Medium [@en-wiki-mic].&lt;/p&gt;
&lt;p&gt;Windows 8 generalised the MIC pattern into &lt;em&gt;AppContainer&lt;/em&gt;. An AppContainer process gets a fresh Low-IL token plus an &lt;em&gt;AppContainer&lt;/em&gt; flag, a Package SID that identifies the app, and a list of capability SIDs the app declared in its manifest. Microsoft Learn states the resulting isolation directly: &quot;Windows ensures that processes running with a low integrity level cannot obtain access to a process which is associated with an app container&quot; [@ms-learn-mic]. The Package SID and capability SID derivations are the subject of the App Identity sibling article in this series; we will not redefine them here [@app-identity-sibling].&lt;/p&gt;
&lt;p&gt;MIC fixed the integrity boundary inside the kernel. But the same year shipped a separate retrofit for a different problem: why was the consumer admin running every clicked-on &lt;code&gt;.exe&lt;/code&gt; with full administrative authority? And why did Microsoft refuse to call its answer a security boundary?&lt;/p&gt;
&lt;h2&gt;8. UAC, the Split-Token, and the Bypass Tradition&lt;/h2&gt;
&lt;p&gt;Vista&apos;s &lt;em&gt;User Account Control&lt;/em&gt; is the most famous Windows security retrofit, and the only one whose own keepers explicitly published a document declaring it not a security boundary [@msrc-servicing-criteria]. The mechanism is precise. The bypass tradition is enormous. The classification is honest.&lt;/p&gt;
&lt;p&gt;The mechanism first. Microsoft&apos;s documentation on how UAC works gives the verbatim recipe [@ms-learn-uac]: &quot;When an administrator logs on, two separate access tokens are created for the user: a standard user access token and an administrator access token. The standard user access token... contains the same user-specific information as the administrator access token, but the administrative Windows privileges and SIDs are removed... is used to display the desktop by executing the process &lt;code&gt;explorer.exe&lt;/code&gt;. &lt;code&gt;Explorer.exe&lt;/code&gt; is the parent process from which all other user-initiated processes inherit their access token. As a result, all apps run as a standard user unless a user provides consent or credentials to approve an app to use a full administrative access token.&quot;&lt;/p&gt;

A Windows mechanism, introduced with Vista (released to manufacturing November 8, 2006 [@en-wiki-windows-vista]), in which an administrative user receives two linked tokens at logon: a *filtered* Medium-IL token without administrative privileges or SIDs, used by `explorer.exe` and every process descended from it, and a *full* High-IL administrative counterpart that the kernel hands out only after the user clicks through a consent prompt or supplies credentials. The two tokens reference each other through the `LinkedToken` field. UAC is a UX-and-default-behaviour mechanism, not an enforced security boundary [@ms-learn-uac, @msrc-servicing-criteria].
&lt;p&gt;The split-token mechanism produces three elevation triggers. First, an executable can declare its required level in its manifest via the &lt;code&gt;requestedExecutionLevel&lt;/code&gt; element (&lt;code&gt;asInvoker&lt;/code&gt;, &lt;code&gt;highestAvailable&lt;/code&gt;, or &lt;code&gt;requireAdministrator&lt;/code&gt;). Second, certain Microsoft-signed binaries appear on an &lt;em&gt;AutoElevate&lt;/em&gt; whitelist that the kernel consults; processes on the whitelist transparently get the full token without prompting. Third, COM components can be marked elevatable via the &lt;em&gt;COM Elevation Moniker&lt;/em&gt;, which lets code instantiate &lt;code&gt;Elevation:Administrator!new:{guid}&lt;/code&gt; (or &lt;code&gt;Elevation:Highest!new:{guid}&lt;/code&gt;) to obtain a High-IL administrator COM caller -- not a SYSTEM caller; the moniker&apos;s supported run levels are &lt;code&gt;Administrator&lt;/code&gt; and &lt;code&gt;Highest&lt;/code&gt; [@ms-learn-com-elevation-moniker]. Method 41 (Oddvar Moe&apos;s &lt;code&gt;ICMLuaUtil&lt;/code&gt; construction) is the canonical worked example.&lt;/p&gt;
&lt;p&gt;The classification next. Microsoft&apos;s &lt;em&gt;Security Servicing Criteria for Windows&lt;/em&gt; defines a security boundary as the logical separation between security domains with different trust levels, and gives the kernel-mode / user-mode separation as the canonical example [@msrc-servicing-criteria]. The criteria document then enumerates which boundaries Microsoft commits to servicing. UAC and admin-to-kernel are not on the enumerated list.&lt;/p&gt;

A security boundary provides a logical separation between the code and data of security domains with different levels of trust... the separation between kernel mode and user mode is a classic [...] security boundary. Microsoft software depends on multiple security boundaries to isolate devices on the network, virtual machines, and applications on a device. -- Microsoft Security Servicing Criteria for Windows [@msrc-servicing-criteria]
&lt;p&gt;The &quot;outside the enumerated list&quot; classification has a concrete consequence: bypasses of UAC are not eligible for the same security-update treatment a kernel-mode-to-user-mode bypass would get. Mitigations are issued per-redirect, when an attacker&apos;s specific path becomes operationally noisy enough to warrant attention. The seventy-plus methods catalogued in UACMe are the empirical consequence.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; &lt;strong&gt;UAC was never a security boundary.&lt;/strong&gt; The seventy-plus methods catalogued in UACMe are not bugs in UAC. They are the formal consequence of UAC&apos;s classification. Once you recognise that UAC is a UX-and-default-behaviour mechanism rather than an enforced boundary, the bypass tradition is legible as a feature being used as designed and the structural arc to Adminless makes sense.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The bypass canon. Walk it generation by generation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method 1 -- Leo Davidson, 2009.&lt;/strong&gt; Davidson&apos;s &lt;em&gt;Windows 7 UAC Whitelist&lt;/em&gt; writeup is the genealogical root of the UAC bypass tradition [@pretentiousname-davidson, @github-hfiref0x-uacme]. He noticed that &lt;code&gt;sysprep.exe&lt;/code&gt; is on the AutoElevate whitelist and that, when launched from &lt;code&gt;C:\Windows\System32\sysprep\&lt;/code&gt;, it loads several DLLs from the working directory. Use the &lt;code&gt;IFileOperation&lt;/code&gt; COM interface (which the elevator treats as AutoApprove, enabling the file copy without prompting) to drop a malicious &lt;code&gt;cryptbase.dll&lt;/code&gt; into &lt;code&gt;%SystemRoot%\System32\sysprep\&lt;/code&gt;. Then trigger &lt;code&gt;sysprep.exe&lt;/code&gt; -- which is on the AutoElevate whitelist -- and the auto-elevated process loads the attacker&apos;s DLL, and the attacker has a High-IL full administrative token.&lt;/p&gt;
&lt;p&gt;Davidson&apos;s writeup quotes himself bluntly: &quot;This works against the RTM (retail) and RC1 versions of Windows 7&quot; [@pretentiousname-davidson]. UACMe Method 1 records the technique with structured metadata: &quot;Author: Leo Davidson / Type: Dll Hijack / Method: IFileOperation / Target(s): \system32\sysprep\sysprep.exe / Component(s): cryptbase.dll / Implementation: ucmStandardAutoElevation / Works from: Windows 7 (7600) / Fixed in: Windows 8.1 (9600)&quot; [@github-hfiref0x-uacme].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method 25 -- Matt Nelson (enigma0x3), August 15, 2016.&lt;/strong&gt; Seven years after Davidson, Nelson published &quot;Fileless UAC Bypass Using &lt;code&gt;eventvwr.exe&lt;/code&gt; and Registry Hijacking&quot; [@enigma0x3-eventvwr-blog]. The bypass replaces the file-system DLL hijack with a registry redirect. Nelson noticed that &lt;code&gt;eventvwr.exe&lt;/code&gt;, an AutoElevated binary, queries &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; &lt;code&gt;HKCR\mscfile\shell\open\command&lt;/code&gt; to find the command to run for the &lt;code&gt;mscfile&lt;/code&gt; ProgID. His verbatim observation: &quot;From the output, it appears that &apos;eventvwr.exe&apos;, as a high integrity process, queries both HKCU and HKCR registry hives to start mmc.exe&quot; [@enigma0x3-eventvwr-blog]. HKCU is writable by the standard user; the user writes a malicious command line under that key, runs &lt;code&gt;eventvwr.exe&lt;/code&gt;, and the auto-elevated process happily executes the user-supplied command line. The first &lt;em&gt;fileless&lt;/em&gt; UAC bypass.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method 33 -- winscripting.blog, 2017.&lt;/strong&gt; Same primitive, different target. The &lt;code&gt;fodhelper.exe&lt;/code&gt; binary is on the AutoElevate whitelist and queries &lt;code&gt;HKCU\Software\Classes\ms-settings\shell\open\command&lt;/code&gt; to launch the Settings app. UACMe records the credit precisely: &quot;Author: winscripting.blog / Type: Shell API / Method: Registry key manipulation / Target(s): \system32\fodhelper.exe / Component(s): Attacker defined / Implementation: ucmShellRegModMethod / Works from: Windows 10 TH1 (10240) / Fixed in: unfixed&quot; [@github-hfiref0x-uacme]. &lt;em&gt;Fixed in: unfixed.&lt;/em&gt; This is what &quot;outside the enumerated list&quot; looks like in practice: nine years after Method 1 and a year after Method 25 demonstrated the underlying class, the registry-redirect template was still being applied to fresh AutoElevate targets and shipping unmitigated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method 41 -- Oddvar Moe.&lt;/strong&gt; The COM elevation moniker route. UACMe records: &quot;Author: Oddvar Moe / Type: Elevated COM interface / Method: ICMLuaUtil&quot; [@github-hfiref0x-uacme]. Instantiate the &lt;code&gt;CMLuaUtil&lt;/code&gt; COM object via the elevation moniker from a Medium-IL process, get back a High-IL COM caller, and call its &lt;code&gt;ShellExec&lt;/code&gt; method to run an attacker command line at High IL. The seam is the COM moniker registry&apos;s &lt;code&gt;Elevation\Enabled&lt;/code&gt; key, which marks specific CLSIDs as elevation-capable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method 31 (sdclt), 29, 34, ...&lt;/strong&gt; The pattern repeats. Matt Nelson&apos;s &lt;code&gt;sdclt.exe&lt;/code&gt; variants exploit the backup-restore UI&apos;s registry lookups. Forshaw&apos;s &lt;code&gt;schtasks&lt;/code&gt; variant exploits the scheduled-task COM interface. The UACMe README enumerates the lot with the laconic one-liner &quot;Defeating Windows User Account Control by abusing built-in Windows AutoElevate backdoor&quot; [@github-hfiref0x-uacme]. Most of the methods reduce to the same primitive: an AutoElevated Microsoft-signed binary performs a lookup that the standard user can redirect, the standard user supplies an attacker-controlled answer, and the auto-elevated binary executes attacker-controlled work.&lt;/p&gt;

flowchart TD
    A[User Medium-IL process] --&amp;gt; B[Write attacker command line into HKCU writable seam: registry key, file system path, scheduled-task XML]
    B --&amp;gt; C[Trigger AutoElevated Microsoft-signed binary: sysprep.exe / eventvwr.exe / fodhelper.exe / sdclt.exe / etc.]
    C --&amp;gt; D[AutoElevate flag honoured by kernel]
    D --&amp;gt; E[Binary launched at High IL with full administrative token]
    E --&amp;gt; F[Binary performs lookup: HKCU registry / DLL search path / scheduled-task definition]
    F --&amp;gt; G[Lookup returns attacker-supplied content]
    G --&amp;gt; H[High-IL process executes attacker work]

Mark Russinovich&apos;s June 2007 *TechNet Magazine* cover story, &quot;Inside Windows Vista User Account Control,&quot; is the canonical practitioner walkthrough of the split-token model and is preserved on the Wayback Machine [@wayback-russinovich-uac-technet]. Russinovich opens by naming the misunderstanding: &quot;User Account Control (UAC) is an often misunderstood feature in Windows Vista... In this article I discuss the problems UAC solves and describe the architecture and implementation of its component technologies.&quot; The framing throughout the article is that UAC&apos;s purpose is to create the *expectation* that consumer software would run as a standard user, and to push the developer community to refactor away from gratuitous administrator requirements. That framing -- UAC as a UX and migration mechanism -- is consistent with the eventual MSRC servicing-criteria position: not a defended boundary, but a behaviour gate.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft&apos;s servicing-criteria position means a UAC bypass that does not also cross a serviced security boundary is not, by policy, eligible for a security update. Mitigations land when the operational footprint of a particular bypass becomes large enough to justify one. Track UAC mitigations by KB number, not by feature description; consult the UACMe README&apos;s &lt;code&gt;Fixed in:&lt;/code&gt; field as the institutional memory [@github-hfiref0x-uacme, @msrc-servicing-criteria].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;UAC bypasses redirect the elevation flow that produces a token. A different attack family takes the result and steals tokens from already-elevated SYSTEM services. Where do those attacks come from, and why are they all the same bug?&lt;/p&gt;
&lt;h2&gt;9. The Object Manager and the Lookup Surface&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;SeAccessCheck&lt;/code&gt; evaluates a security descriptor it has been handed. Who hands it the descriptor?&lt;/p&gt;
&lt;p&gt;The kernel&apos;s &lt;em&gt;Object Manager&lt;/em&gt; does, after walking a name. Every named kernel object lives somewhere in a hierarchical namespace rooted at &lt;code&gt;\&lt;/code&gt;. Devices live under &lt;code&gt;\Device&lt;/code&gt;. Synchronisation primitives live under &lt;code&gt;\BaseNamedObjects&lt;/code&gt;. Pre-resolved DLL names live under &lt;code&gt;\KnownDlls&lt;/code&gt;. Per-session subtrees live under &lt;code&gt;\Sessions&lt;/code&gt;. The DOS device prefix &lt;code&gt;\GLOBAL??&lt;/code&gt; (and its session-local sibling &lt;code&gt;\??&lt;/code&gt;) holds drive-letter symbolic links into the device tree. When a process calls &lt;code&gt;OpenObject&lt;/code&gt;, the Object Manager parses the name, walks the tree, and returns the object whose security descriptor &lt;code&gt;SeAccessCheck&lt;/code&gt; will then evaluate.&lt;/p&gt;
&lt;p&gt;The kernel performs &lt;em&gt;the lookup&lt;/em&gt; before &lt;em&gt;the access check&lt;/em&gt;. This sequencing creates a parallel attack surface that bypasses &lt;code&gt;SeAccessCheck&lt;/code&gt; entirely. If the attacker can influence the name resolution -- redirect a &lt;code&gt;\??\&lt;/code&gt; symbolic link, plant a junction in NTFS that re-targets a directory traversal, hardlink a low-privilege file at a path the kernel will trust because of the parent directory&apos;s descriptor -- then by the time &lt;code&gt;SeAccessCheck&lt;/code&gt; runs, it is being asked about a different object than the original code path intended to open.&lt;/p&gt;
&lt;p&gt;The HiveNightmare lookup path is the canonical worked example. The exploit reads the SAM database not via &lt;code&gt;\Windows\System32\config\SAM&lt;/code&gt; (which has a tight DACL) but via &lt;code&gt;\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy*\Windows\System32\config\SAM&lt;/code&gt;. That path resolves through the Object Manager&apos;s &lt;code&gt;\GLOBAL??&lt;/code&gt; symbolic link, into the device tree, into a Volume Shadow Copy mirror of the original volume, into a &lt;em&gt;copy&lt;/em&gt; of &lt;code&gt;SAM&lt;/code&gt; whose DACL was, until the August 2021 patch, readable by any authenticated local user (BUILTIN\Users) [@nvd-cve-2021-36934].&lt;/p&gt;
&lt;p&gt;The lookup-phase attack class is wider than file-system shadow copies. &lt;em&gt;Object Manager symbolic links&lt;/em&gt; and &lt;em&gt;NTFS hard links&lt;/em&gt; both produce the same primitive: the kernel resolves a name through an attacker-influenced redirect and ends up evaluating &lt;code&gt;SeAccessCheck&lt;/code&gt; against a different security descriptor than the calling code intended.&lt;/p&gt;
&lt;p&gt;CVE-2020-0668, the Service Tracing elevation-of-privilege bug Clément Labro disclosed in February 2020, is the textbook symbolic-link case [@itm4n-cve-2020-0668-blog]. The Service Tracing infrastructure under &lt;code&gt;HKLM\SOFTWARE\Microsoft\Tracing&lt;/code&gt; is user-writable, and several SYSTEM services -- &lt;code&gt;IKEEXT&lt;/code&gt;, &lt;code&gt;RasMan&lt;/code&gt;, the Update Session Orchestrator service -- consult those keys to find a tracing log path. When the log file exceeds the configured &lt;code&gt;MaxFileSize&lt;/code&gt;, the service renames it from &lt;code&gt;MODULE.LOG&lt;/code&gt; to &lt;code&gt;MODULE.OLD&lt;/code&gt;, deleting any existing &lt;code&gt;MODULE.OLD&lt;/code&gt; first.&lt;/p&gt;
&lt;p&gt;itm4n&apos;s exploit is exactly the one his blog post names: &quot;All you need to do is set the target directory as a mountpoint to the &lt;code&gt;\RPC Control&lt;/code&gt; object directory and then create two symbolic links: A symbolic link from &lt;code&gt;MODULE.LOG&lt;/code&gt; to a file you own; A symbolic link from &lt;code&gt;MODULE.OLD&lt;/code&gt; to any file on the file system&quot; [@itm4n-cve-2020-0668-blog]. The mountpoint reroutes the kernel&apos;s name resolution into an Object Manager directory the attacker controls; the two symlinks reroute the rename operation; the SYSTEM service ends up performing an arbitrary file move with kernel authority. Forshaw&apos;s &lt;code&gt;googleprojectzero/symboliclink-testing-tools&lt;/code&gt; repository [@github-projectzero-symlink-tools] provides the primitive library the exploit consumes -- &lt;code&gt;CreateSymlink&lt;/code&gt;, &lt;code&gt;CreateMountPoint&lt;/code&gt;, &lt;code&gt;BaitAndSwitch&lt;/code&gt; -- and the repository is, in effect, the institutional library every Object Manager lookup-phase attack of the past decade has linked against.&lt;/p&gt;
&lt;p&gt;The NTFS hard-link case predates the symbolic-link case by half a decade. James Forshaw&apos;s December 2015 Project Zero post, &quot;Between a Rock and a Hard Link,&quot; is the canonical primary source [@projectzero-blog-rockandhardlink]. Forshaw observes that hard links have been a feature of NTFS &quot;since it was originally designed&quot;, and that their relevance to local privilege escalation is exactly the lookup-vs-access-check sequencing this section describes: &quot;Why are hard links useful for local privilege escalation? One type of vulnerability is exploited by a file planting attack, where a privilege service tries to write to a file in a known location&quot; [@projectzero-blog-rockandhardlink].&lt;/p&gt;
&lt;p&gt;The worked example Forshaw walks is CVE-2015-4481, a Mozilla Maintenance Service hard-link primitive: any user can write a status log to &lt;code&gt;C:\ProgramData\Mozilla\logs\maintenanceservice.log&lt;/code&gt;, and during the service&apos;s pre-write &lt;code&gt;BackupOldLogs&lt;/code&gt; rename a brief window opens in which the attacker can replace the about-to-be-written log path with a hard link to an arbitrary system file. The service&apos;s subsequent write -- which it performs with its own SYSTEM authority -- ends up overwriting the system file. The DACL on the source file (the Mozilla log directory) was correct; the DACL on the destination file (the system binary) was correct; the kernel arrived at the destination by resolving a hard-link name the attacker had planted, and &lt;code&gt;SeAccessCheck&lt;/code&gt; saw only the destination DACL, not the planted-link DACL [@projectzero-blog-rockandhardlink]. Microsoft&apos;s MS15-115 mitigation tightened the kernel&apos;s hard-link semantics for sandboxed callers (the kernel&apos;s &lt;code&gt;NtSetInformationFile&lt;/code&gt; now requires &lt;code&gt;FILE_WRITE_ATTRIBUTES&lt;/code&gt; on the target handle when the caller&apos;s token has the sandboxed-token flag, matching what the user-mode &lt;code&gt;CreateHardLink&lt;/code&gt; wrapper had always opened the target with). The fix closes the sandboxed-process branch of the bug class but, as Forshaw notes, does nothing for the Maintenance Service vulnerability itself, which is exploited by a non-sandboxed local user; the structural fix is to write the log to a directory the user cannot create files in, not to enforce a hard-link mask -- a structural fix to the lookup phase, not the access-check phase.&lt;/p&gt;
&lt;p&gt;The two examples generalise the rule. The kernel resolves names &lt;em&gt;before&lt;/em&gt; checking the requesting user&apos;s authority over the destination. The DACL at &lt;code&gt;target.path&lt;/code&gt; and the DACL at &lt;code&gt;attacker.planted.path&lt;/code&gt; after a junction or hard-link redirect can be different; &lt;code&gt;SeAccessCheck&lt;/code&gt; evaluates the descriptor it arrives at, not the descriptor the original caller intended. Capability systems would resolve names through unforgeable handles instead of strings, and the redirect class would not exist by construction [@en-wiki-capability-based-security]. Windows checks the descriptor on every &lt;code&gt;OpenObject&lt;/code&gt; because the name is a forgeable string. The Object Manager namespace is therefore an attack surface whose load-bearing fix is structural rather than per-bug.The Object Manager&apos;s namespace is not documented as policy in the same way &lt;code&gt;SeAccessCheck&lt;/code&gt;&apos;s algorithm is. The de facto modern documentation is empirical: practitioners enumerate the namespace with tools that read kernel structures directly. James Forshaw&apos;s NtObjectManager PowerShell module, part of the Project Zero &lt;code&gt;sandbox-attacksurface-analysis-tools&lt;/code&gt; repository, is the dominant such tool [@github-projectzero-sandbox-attacksurface]. The repository&apos;s banner is exact: &quot;NtObjectManager: A powershell module which uses NtApiDotNet to expose the NT object manager.&quot;&lt;/p&gt;
&lt;p&gt;The James Forshaw / Project Zero corpus is the systematic reference for the Object Manager attack surface. Forshaw&apos;s &quot;Sharing a Logon Session a Little Too Much&quot; (April 2020) names a primitive PrintSpoofer would later consume: when the LSA creates a token for a new logon session, it caches the token for later retrieval. Forshaw&apos;s verbatim explanation: &quot;when LSASS creates a Token for a new Logon session it stores that Token for later retrieval. For the most part this isn&apos;t that useful, however there is one case where the session Token is repurposed, network authentication&quot; [@tiraniddo-sharing-logon-session]. The cached token plus a named-pipe path-validation bug becomes a non-DCOM SYSTEM-token primitive that no DACL touches.&lt;/p&gt;
&lt;p&gt;The lookup surface is half the attack story. The other half is the token surface, and the canonical example of the token surface is a six-year, eight-tool lineage.&lt;/p&gt;
&lt;h2&gt;10. The Potato Lineage: Eight Tools, One Bug (2016-2021)&lt;/h2&gt;
&lt;p&gt;January 16, 2016. Stephen Breen of Foxglove Security publishes &quot;Hot Potato.&quot; The disclosure post opens with a sentence the article will earn the right to repeat: &quot;Microsoft is aware of all of these issues and has been for some time (circa 2000). These are unfortunately hard to fix without breaking backward compatibility and have been [used] by attackers for over 15 years&quot; [@foxglove-hot-potato-blog]. Six years and seven tools later, that admission still describes the situation.&lt;/p&gt;
&lt;p&gt;The single underlying primitive. A low-privileged service account holding &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; (which IIS, SQL Server, the Print Spooler, scheduled tasks, Docker, Citrix, and almost every managed-service account hold by default) tricks SYSTEM into authenticating to a TCP, RPC, or named-pipe endpoint the attacker controls. The attacker&apos;s endpoint accepts the authentication, ends up with an impersonation handle to a SYSTEM token, and calls &lt;code&gt;ImpersonateLoggedOnUser&lt;/code&gt; followed by &lt;code&gt;CreateProcessAsUser&lt;/code&gt; to run arbitrary code as SYSTEM. Same primitive, eight tools, six years.&lt;/p&gt;

sequenceDiagram
    participant Attacker as Attacker (service account, SeImpersonate)
    participant Coercer as Coercion primitive (NBNS / DCOM / EFSRPC / Spooler RPC)
    participant SYSTEM as SYSTEM service
    participant Endpoint as Attacker-controlled local endpoint
    Attacker-&amp;gt;&amp;gt;Coercer: Trigger coercion (e.g. EfsRpcOpenFileRaw, BITS CoGetInstanceFromIStorage)
    Coercer-&amp;gt;&amp;gt;SYSTEM: Tell SYSTEM to authenticate
    SYSTEM-&amp;gt;&amp;gt;Endpoint: NTLM authentication to attacker endpoint
    Endpoint-&amp;gt;&amp;gt;Endpoint: Accept NTLM, build impersonation token
    Attacker-&amp;gt;&amp;gt;Attacker: ImpersonateLoggedOnUser(SYSTEM token)
    Attacker-&amp;gt;&amp;gt;Attacker: CreateProcessAsUser(SYSTEM token, &quot;cmd.exe&quot;)
    Note over Attacker: SYSTEM shell
&lt;p&gt;Walk the lineage one paragraph at a time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hot Potato (Stephen Breen / Foxglove, January 2016)&lt;/strong&gt; [@foxglove-hot-potato-blog]. The original. Hot Potato chains three Windows defaults: NBT-NS (NetBIOS name service) spoofing on the local network, the Web Proxy Auto-Discovery (WPAD) protocol&apos;s automatic proxy lookup, and Windows Update&apos;s HTTP-to-SMB NTLM relay. The exploit poisons NBT-NS so that the SYSTEM-running Windows Update service resolves &lt;code&gt;WPAD&lt;/code&gt; to the attacker&apos;s local listener; the attacker&apos;s listener serves a proxy configuration that proxies SMB through localhost; the Windows Update service authenticates to the attacker&apos;s localhost SMB endpoint as SYSTEM. Foxglove&apos;s verbatim summary: &quot;Hot Potato (aka: Potato) takes advantage of known issues in Windows to gain local privilege escalation in default configurations, namely NTLM relay (specifically HTTP-&amp;gt;SMB relay) and NBNS spoofing&quot; [@foxglove-hot-potato-blog].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rotten Potato (Stephen Breen and Chris Mallz / Foxglove, September 2016)&lt;/strong&gt; [@foxglove-rotten-potato-blog]. The successor abandons the network-protocol fragility for a DCOM activation trick that James Forshaw had published as Project Zero issue 325. The attacker calls &lt;code&gt;CoGetInstanceFromIStorage&lt;/code&gt; with the BITS CLSID &lt;code&gt;{4991d34b-80a1-4291-83b6-3328366b9097}&lt;/code&gt; and a custom marshalled &lt;code&gt;IStorage&lt;/code&gt; pointer; the COM activation runs on the local DCOM server (which runs as SYSTEM) and authenticates back to a TCP listener the attacker controls.&lt;/p&gt;
&lt;p&gt;The Foxglove blog states the three steps verbatim: &quot;1. Trick the &apos;NT AUTHORITY\SYSTEM&apos; account into authenticating via NTLM to a TCP endpoint we control. 2. Man-in-the-middle this authentication attempt (NTLM relay) to locally negotiate a security token for the &apos;NT AUTHORITY\SYSTEM&apos; account. 3. Impersonate the token... This can only be done if the attackers current account has the privilege to impersonate security tokens&quot; [@foxglove-rotten-potato-blog]. The same post credits the Project Zero work directly: &quot;this work is derived directly from James Forshaw&apos;s BlackHat talk and Google Project Zero research&quot; [@foxglove-rotten-potato-blog].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Juicy Potato (decoder_it and ohpe, 2018)&lt;/strong&gt; [@github-ohpe-juicy-potato]. A weaponised, configurable Rotten Potato. The repository README is exact about lineage and entry conditions: &quot;RottenPotatoNG and its variants leverages the privilege escalation chain based on BITS service having the MiTM listener on 127.0.0.1:6666 and when you have SeImpersonate or SeAssignPrimaryToken privileges. ... We decided to weaponize RottenPotatoNG: Say hello to Juicy Potato&quot; [@github-ohpe-juicy-potato].&lt;/p&gt;
&lt;p&gt;Juicy Potato adds a CLSID brute-list (so the attacker can cycle through DCOM activations until one works on the target Windows version), a configurable listener port, and a configurable target binary. The repo&apos;s own framing of when it works is the article&apos;s PullQuote-worthy line: &quot;If the user has SeImpersonate or SeAssignPrimaryToken privileges then you are SYSTEM&quot; [@github-ohpe-juicy-potato]. Juicy Potato was killed by a Windows 10 1809 / Server 2019 mitigation that prevented the OXID resolver from being queried on a port other than 135. The mitigation was the first time Microsoft had touched the underlying primitive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rogue Potato (Antonio Cocomazzi and Andrea Pierini, May 2020)&lt;/strong&gt; [@decoder-rogue-potato-blog]. The bypass for the loopback-OXID mitigation. Decoder&apos;s blog states the engineering problem and the fix in two sentences: &quot;Starting from Windows 10 1809 &amp;amp; Windows Server 2019, its no more possible to query the OXID resolver on a port different than 135&quot; [@decoder-rogue-potato-blog]. Rogue Potato works around the constraint by routing the OXID resolution through an attacker-controlled &lt;em&gt;remote&lt;/em&gt; OXID resolver, typically reached via &lt;code&gt;socat tcp-listen:135,fork TCP:attacker:9999&lt;/code&gt;. The remote resolver returns a string binding pointing back at the attacker&apos;s local listener; the constraint is satisfied (the OXID resolver is on port 135) but the listener it ultimately reaches is the attacker&apos;s. The lineage extends.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PrintSpoofer (Clément Labro / itm4n, May 2020)&lt;/strong&gt; [@github-itm4n-printspoofer, @itm4n-printspoofer-blog]. The same week as Rogue Potato, a different no-DCOM, no-OXID variant lands. PrintSpoofer drops DCOM entirely. It uses the Print Spooler RPC method &lt;code&gt;RpcRemoteFindFirstPrinterChangeNotificationEx&lt;/code&gt; to coerce the spooler (running as SYSTEM) to call back to a named pipe whose path the attacker controls. A path-validation bypass on the named-pipe name lets the attacker capture the SYSTEM credential the spooler offers.&lt;/p&gt;
&lt;p&gt;itm4n&apos;s repository description summarises the entry condition: &quot;From LOCAL/NETWORK SERVICE to SYSTEM by abusing SeImpersonatePrivilege on Windows 10 and Server 2016/2019&quot; [@github-itm4n-printspoofer]. The blog post opens with credit and the canonical decoder_it quote: &quot;I want to start things off with this quote from @decoder_it: &apos;if you have SeAssignPrimaryToken or SeImpersonate privilege, you are SYSTEM&apos;&quot; [@itm4n-printspoofer-blog].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RemotePotato0 (Cocomazzi and Pierini, 2021)&lt;/strong&gt; [@github-antoniococo-remotepotato0]. The first Potato to escape the local machine. A cross-session DCOM activation lets the attacker reach a token from a &lt;em&gt;different&lt;/em&gt; logged-on user; a cross-protocol RPC-to-LDAP relay then turns that user&apos;s authentication into a domain-administrator action against Active Directory.&lt;/p&gt;
&lt;p&gt;The README is candid about the shape of the response: &quot;UPDATE 21-10-2022: The main exploit scenario RPC-&amp;gt;LDAP of RemotePotato0 has been fixed... Just another &apos;Won&apos;t Fix&apos; Windows Privilege Escalation from User to Domain Admin. RemotePotato0 is an exploit that allows you to escalate your privileges from a generic User to Domain Admin... It abuses the DCOM activation service and trigger an NTLM authentication of any user currently logged on in the target machine&quot; [@github-antoniococo-remotepotato0]. &lt;em&gt;Just another &quot;Won&apos;t Fix&quot; Windows Privilege Escalation&lt;/em&gt; is the precise framing: the underlying primitive is structural, the 2022 fix addressed the specific RPC-to-LDAP path, and the construction continues to work for other relay targets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PetitPotam (Lionel Gilles / topotam77, July 2021)&lt;/strong&gt; [@github-topotam-petitpotam, @nvd-cve-2021-36942]. Not strictly a local-LPE Potato, but the source of the EFSRPC coercion primitive that local-LPE Potatoes consume. PetitPotam exploits the Encrypting File System remote-procedure-call protocol&apos;s &lt;code&gt;EfsRpcOpenFileRaw&lt;/code&gt; (and several other functions) to coerce a Windows host to authenticate to an attacker-controlled endpoint.&lt;/p&gt;
&lt;p&gt;The README is exact about the interface choices: &quot;PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions :) The tools use the LSARPC named pipe with inteface c681d488-d850-11d0-8c52-00c04fd90f7e because it&apos;s more prevalent. But it&apos;s possible to trigger with the EFSRPC named pipe and interface df1941c5-fe89-4e79-bf10-463657acf44d&quot; [@github-topotam-petitpotam]. PetitPotam&apos;s most-cited use case is cross-machine relay against Active Directory Certificate Services, but the EFSRPC coercion is also locally consumable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SharpEfsPotato (bugch3ck, 2021)&lt;/strong&gt; [@github-bugch3ck-sharpefspotato]. The local-machine variant of the PetitPotam coercion. The README is precise about lineage: &quot;Local privilege escalation from SeImpersonatePrivilege using EfsRpc. Built from SweetPotato by &lt;code&gt;@_EthicalChaos_&lt;/code&gt; and SharpSystemTriggers/SharpEfsTrigger by &lt;code&gt;@cube0x0&lt;/code&gt;&quot; [@github-bugch3ck-sharpefspotato]. SharpEfsPotato uses &lt;code&gt;EfsRpcOpenFileRaw&lt;/code&gt; against the local LSARPC pipe to coerce SYSTEM to authenticate to a local endpoint, then performs the by-now-familiar token capture and &lt;code&gt;CreateProcessAsUser&lt;/code&gt;.This article&apos;s stage-4 source verification corrected an attribution that had been carried forward from the original scope file: SharpEfsPotato&apos;s canonical repository is &lt;code&gt;bugch3ck/SharpEfsPotato&lt;/code&gt;, not the often-cited &lt;code&gt;ly4k/SharpEfsPotato&lt;/code&gt;. The latter URL returns HTTP 404. Cross-references that point at the &lt;code&gt;ly4k&lt;/code&gt; URL should be updated to point at &lt;code&gt;bugch3ck&lt;/code&gt; [@github-bugch3ck-sharpefspotato].&lt;/p&gt;
&lt;p&gt;The pattern across the lineage is that &lt;em&gt;the mitigation that did break a tool was always specific&lt;/em&gt; (the loopback-OXID restriction, the cross-session DCOM partial fix, the EFSRPC coercion partial mitigation in KB5005413), and &lt;em&gt;the mitigation that would break the family is structural&lt;/em&gt; (remove &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; from service accounts, end NTLM-to-self-as-machine relay, retire the bearer-credential property of tokens). Microsoft has shipped the first kind of fix seven times across the lineage and continues to ship them; the second kind requires architectural changes that arrive in successor articles in this series.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Author(s)&lt;/th&gt;
&lt;th&gt;Coercion vector&lt;/th&gt;
&lt;th&gt;Mitigation that broke it&lt;/th&gt;
&lt;th&gt;Mitigation that did not&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Hot Potato&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;Breen&lt;/td&gt;
&lt;td&gt;NBT-NS + WPAD + HTTP-to-SMB relay&lt;/td&gt;
&lt;td&gt;Disable WPAD; KB3146965&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotten Potato&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;Breen, Mallz&lt;/td&gt;
&lt;td&gt;DCOM &lt;code&gt;CoGetInstanceFromIStorage&lt;/code&gt; (BITS)&lt;/td&gt;
&lt;td&gt;(none specific until Juicy fix)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Juicy Potato&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;decoder_it, ohpe&lt;/td&gt;
&lt;td&gt;DCOM CLSID brute-list, configurable port&lt;/td&gt;
&lt;td&gt;Loopback-OXID restriction (1809 / 2019)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rogue Potato&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Cocomazzi, Pierini&lt;/td&gt;
&lt;td&gt;Remote OXID resolver via &lt;code&gt;socat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cross-session DCOM partial fix&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PrintSpoofer&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Labro&lt;/td&gt;
&lt;td&gt;Spooler RPC + named-pipe path bypass&lt;/td&gt;
&lt;td&gt;KB5005010 (PrintNightmare-era spooler hardening) [@nvd-cve-2021-34527]&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RemotePotato0&lt;/td&gt;
&lt;td&gt;2021&lt;/td&gt;
&lt;td&gt;Cocomazzi, Pierini&lt;/td&gt;
&lt;td&gt;Cross-session DCOM + RPC-to-LDAP relay&lt;/td&gt;
&lt;td&gt;RPC-to-LDAP relay fix (October 2022)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services; remaining relay targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PetitPotam&lt;/td&gt;
&lt;td&gt;2021&lt;/td&gt;
&lt;td&gt;Gilles&lt;/td&gt;
&lt;td&gt;EFSRPC coercion via LSARPC&lt;/td&gt;
&lt;td&gt;KB5005413 partial; ADCS hardening [@nvd-cve-2021-36942]&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services; other relay targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SharpEfsPotato&lt;/td&gt;
&lt;td&gt;2021&lt;/td&gt;
&lt;td&gt;bugch3ck&lt;/td&gt;
&lt;td&gt;Local EFSRPC coercion&lt;/td&gt;
&lt;td&gt;(none specific to local variant)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SeImpersonate&lt;/code&gt; on services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Eight tools. One privilege. Every &quot;mitigation that did not&quot; cell points at the same thing: a bearer-token model plus &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; on a service account.&lt;/p&gt;

Eight tools in six years against the same underlying primitive is not a tooling coincidence. It is the empirical signature of the bearer-credential property and the omnipresent service-account `SeImpersonate` privilege. The Hot Potato post&apos;s verbatim &quot;hard to fix without breaking backward compatibility&quot; admission [@foxglove-hot-potato-blog] is the same argument Microsoft eventually formalised in the security-servicing-criteria position: this surface is intentionally retained for compatibility, and structural changes belong in a different architecture. The article earns the bridge to the Adminless and NTLMless successors here, six years before the calendar gets there.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A service account holding &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; plus &lt;em&gt;any&lt;/em&gt; RPC interface that authenticates to attacker-controllable endpoints equals SYSTEM. Eight Potatoes in six years prove this is structural, not a tooling fad. Audit every server: any non-LocalSystem-equivalent process holding &lt;code&gt;SeImpersonate&lt;/code&gt; or &lt;code&gt;SeAssignPrimaryToken&lt;/code&gt; should be treated as a Potato target until proven otherwise. Pre-deploy per-service SIDs and Group Managed Service Accounts where possible to constrain the blast radius [@github-itm4n-printspoofer].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eight Potatoes prove the bearer-token property is unkillable by point fixes. But what does an attacker who is &lt;em&gt;already admin&lt;/em&gt; do? The answer is the most-cited offensive Windows tool of the past fifteen years.&lt;/p&gt;
&lt;h2&gt;11. Mimikatz, Conditional ACEs, and the Edges of the Model&lt;/h2&gt;
&lt;p&gt;May 2011. Benjamin Delpy releases the first version of Mimikatz [@en-wiki-mimikatz]. Wikipedia&apos;s biographical summary is precise: &quot;He released the first version of the software in May 2011 as closed source software&quot; [@en-wiki-mimikatz]. Fifteen years later, every offensive Windows engagement on Earth still reaches for it.&lt;/p&gt;
&lt;p&gt;Mimikatz contains many modules. Two of them sit directly on the access-control surface and are worth naming explicitly. The repository&apos;s own command surface lists them as &lt;code&gt;privilege::debug&lt;/code&gt; and &lt;code&gt;token::elevate&lt;/code&gt; [@github-gentilkiwi-mimikatz].&lt;/p&gt;
&lt;p&gt;&lt;code&gt;privilege::debug&lt;/code&gt; is one line of code: the command enables &lt;code&gt;SeDebugPrivilege&lt;/code&gt; on the caller&apos;s token. Any local administrator on stock Windows holds the privilege on the token by default; the command flips it from &lt;code&gt;Available&lt;/code&gt; to &lt;code&gt;Enabled&lt;/code&gt; via &lt;code&gt;AdjustTokenPrivileges&lt;/code&gt;. With &lt;code&gt;SeDebugPrivilege&lt;/code&gt; enabled, the calling process can &lt;code&gt;OpenProcess&lt;/code&gt; against any other process on the machine, including SYSTEM-level services such as &lt;code&gt;lsass.exe&lt;/code&gt;. Every Mimikatz session that wants to read process memory begins with &lt;code&gt;privilege::debug&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;token::elevate&lt;/code&gt; is three lines of code in spirit. The command opens a SYSTEM-owned process (typically &lt;code&gt;lsass.exe&lt;/code&gt;), calls &lt;code&gt;OpenProcessToken&lt;/code&gt; to retrieve a handle to the SYSTEM token, calls &lt;code&gt;DuplicateTokenEx&lt;/code&gt; to duplicate the handle for impersonation, and calls &lt;code&gt;SetThreadToken&lt;/code&gt; to attach the duplicated SYSTEM token to the calling thread. The thread is now SYSTEM. The bearer-token property in three lines of code.&lt;/p&gt;
&lt;p&gt;This article does not cover &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt;. That command is the most-cited Mimikatz capability in journalism (it reads cached credentials from &lt;code&gt;lsass.exe&lt;/code&gt;), but the credential-storage surface and the Credential Guard mitigation belong to the &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Secure Kernel sibling article&lt;/a&gt; in this series [@secure-kernel-sibling]. For the purposes of &lt;em&gt;this&lt;/em&gt; article, the lesson stops at &lt;code&gt;token::elevate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The lesson is the structural concession. With administrator rights on the local machine and &lt;code&gt;SeDebugPrivilege&lt;/code&gt; enabled, the access-control model has &lt;em&gt;no defence&lt;/em&gt; for &quot;I will pretend to be a different process,&quot; because admin equals kernel by Microsoft&apos;s own boundary definition [@msrc-servicing-criteria]. The DACL evaluation algorithm does not protect against a caller who can read and write arbitrary kernel memory. The privilege list does not protect against a caller who can rewrite the privilege check. The integrity check does not protect against a caller who can edit the integrity label. Every primitive in the model is, by construction, defenceless against an attacker who has crossed the boundary the model considers itself responsible for defending.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; With administrator rights and &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, the Windows access-control model has no defence for &quot;I will pretend to be a different process,&quot; because admin equals kernel by Microsoft&apos;s own boundary definition. Mimikatz &lt;code&gt;token::elevate&lt;/code&gt; is the canonical demonstration. The structural fix for &lt;em&gt;selected&lt;/em&gt; secrets is Credential Guard, which moves the secret out of the NT kernel&apos;s address space entirely. See the Secure Kernel sibling article for the architecture [@secure-kernel-sibling, @msrc-servicing-criteria].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The model has been extended in only one structural direction since 1993, and that direction is the &lt;em&gt;subject&lt;/em&gt; of the access matrix. &lt;em&gt;Conditional ACEs&lt;/em&gt; and &lt;em&gt;Dynamic Access Control&lt;/em&gt; (DAC) shipped together in Windows Server 2012 and Windows 8 [@ms-learn-dac]. They are the only extension of the access-matrix subject Microsoft has shipped in thirty-three years.&lt;/p&gt;
&lt;p&gt;The mechanism is twofold. First, ACEs gain an expression syntax. The SDDL ACE strings page documents &lt;code&gt;XA&lt;/code&gt;, &lt;code&gt;XD&lt;/code&gt;, &lt;code&gt;XU&lt;/code&gt;, and &lt;code&gt;ZA&lt;/code&gt; as conditional callback variants of the basic allow / deny / audit / object-allow ACE types [@ms-learn-ace-strings]. A conditional ACE carries an expression in addition to a SID and an access mask, and the kernel evaluates the expression against the token&apos;s claims at access time. The canonical example is &lt;code&gt;(XA;;FA;;;AU;(@User.Department==&quot;Finance&quot;))&lt;/code&gt; -- an allow-callback ACE that grants &lt;code&gt;FILE_ALL_ACCESS&lt;/code&gt; to Authenticated Users &lt;em&gt;if&lt;/em&gt; the token carries a &lt;code&gt;Department&lt;/code&gt; claim equal to &lt;code&gt;&quot;Finance&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Second, the token gains &lt;em&gt;claims&lt;/em&gt;. A claim is a typed key-value pair attached to the token by Active Directory at logon. Claims can be sourced from the user&apos;s AD attributes, the device&apos;s AD attributes, or resource properties on the object. Microsoft Learn states the role they play: &quot;A central access rule is an expression of authorization rules that can include one or more conditions involving user groups, user claims, device claims, and resource properties. Multiple central access rules can be combined into a central access policy&quot; [@ms-learn-dac].&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;Central Access Policy&lt;/em&gt; (CAP) is a set of &lt;em&gt;Central Access Rules&lt;/em&gt; (CARs), each of which is a conditional-ACE expression. The CAP is applied to file shares; the file-share metadata says &quot;evaluate this CAP for every access,&quot; and the CAP&apos;s expressions reference token claims. The DAC scenario guidance enumerates the deployment-side primitives -- automatic and manual file classification, central access policies for safety-net authorisation, central audit policies for compliance reporting, and Rights Management Service encryption for data-in-use protection [@ms-learn-dac-scenario].&lt;/p&gt;
&lt;p&gt;The reason DAC has not displaced classic DAC outside file-server scenarios is in the same Microsoft Learn page: &quot;Dynamic Access Control is not supported in Windows operating systems prior to Windows Server 2012 and Windows 8. When Dynamic Access Control is configured in environments with supported and non-supported versions of Windows, only the supported versions will implement the changes&quot; [@ms-learn-dac]. Heterogeneous environments fall back to classic DAC. Airgapped environments without a working AD plus AD FS plane have no claims to evaluate. Conditional ACEs are a real extension of the model&apos;s subject dimension; they are also a real bet that the AD-and-Kerberos plane is healthy enough to evaluate them on every access.AppContainer&apos;s Package SIDs (Windows 8) and conditional ACEs (Server 2012) shipped the same year. Both extend the &lt;em&gt;subject&lt;/em&gt; dimension of the access matrix -- one with code identity, one with attribute claims. Neither closes the kernel-equals-admin gap. The two extensions are coordinate, not stacked: a conditional ACE can reference a Package SID; a Package SID can be the subject of a conditional ACE [@ms-learn-dac, @app-identity-sibling].&lt;/p&gt;
&lt;p&gt;The model has been extended in two coordinate dimensions in thirty-three years. It has not been replaced. So what does the whole thing look like put together -- and what does it actually fail at?&lt;/p&gt;
&lt;h2&gt;12. The 2026 Plane: Ten Primitives, One Decision&lt;/h2&gt;
&lt;p&gt;Run a single &lt;code&gt;OpenObject&lt;/code&gt; call on a Windows 11 machine and walk the kernel&apos;s path. Every primitive the article has introduced fires for that one call.&lt;/p&gt;

flowchart LR
    A[User-mode caller] --&amp;gt;|OpenObject name, DesiredAccess, Token| B[Object Manager]
    B --&amp;gt;|Resolve name in namespace| C[Namespace lookup]
    C --&amp;gt;|Fetch security descriptor| D[Object header SD]
    D --&amp;gt; E[SeAccessCheck]
    E --&amp;gt; F[Generic-to-specific mapping]
    F --&amp;gt; G[Mandatory Integrity Control check]
    G --&amp;gt;|Pass| H[AppContainer / capability check]
    H --&amp;gt; I[Privilege bypass: SeBackup / SeRestore / SeDebug]
    I --&amp;gt; J[DACL walk in canonical order]
    J --&amp;gt; K[Conditional ACE expression evaluation]
    K --&amp;gt; L[GrantedAccess accumulated]
    L --&amp;gt; M[SACL audit ACE emit if matched]
    M --&amp;gt; N[Return HANDLE or STATUS_ACCESS_DENIED]
&lt;p&gt;The diagram is the article in one figure. Read it left to right. Every box is a primitive named in Sections 3 to 11. Every famous Windows escalation tool of the last twenty-five years targets one of those boxes:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Section introduced&lt;/th&gt;
&lt;th&gt;Year shipped&lt;/th&gt;
&lt;th&gt;Canonical primary citation&lt;/th&gt;
&lt;th&gt;Canonical attack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Security Reference Monitor&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-access-control]&lt;/td&gt;
&lt;td&gt;(Underlying surface; not directly attacked)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Security Identifier (SID)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-security-identifiers]&lt;/td&gt;
&lt;td&gt;Misused well-known SIDs (&quot;Everyone is just a SID&quot;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Access Token&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-access-tokens]&lt;/td&gt;
&lt;td&gt;The Potato lineage; Mimikatz &lt;code&gt;token::elevate&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Security Descriptor&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-how-dacls-control-access]&lt;/td&gt;
&lt;td&gt;HiveNightmare (CVE-2021-36934)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;DACL + ACE&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-how-dacls-control-access, @ms-learn-order-of-aces]&lt;/td&gt;
&lt;td&gt;NULL DACL misconfigurations; out-of-order ACEs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;SACL + audit&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-access-control]&lt;/td&gt;
&lt;td&gt;Tools that copy DACL but not SACL silently drop integrity labels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Privilege&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;[@ms-learn-privileges]&lt;/td&gt;
&lt;td&gt;Mimikatz &lt;code&gt;privilege::debug&lt;/code&gt;; &lt;code&gt;SeBackup&lt;/code&gt; abuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Mandatory Integrity Control&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2007&lt;/td&gt;
&lt;td&gt;[@ms-learn-mic]&lt;/td&gt;
&lt;td&gt;IE7 Protected Mode broker bypasses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;UAC split-token&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2007&lt;/td&gt;
&lt;td&gt;[@ms-learn-uac]&lt;/td&gt;
&lt;td&gt;UACMe: 70+ AutoElevate-redirect methods [@github-hfiref0x-uacme]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Conditional ACE / DAC&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;[@ms-learn-dac, @ms-learn-ace-strings]&lt;/td&gt;
&lt;td&gt;Falls back to classic DAC in heterogeneous environments&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Windows access-control model is one decision plane, not a feature catalogue. Every securable Windows operation resolves through &lt;code&gt;SeAccessCheck&lt;/code&gt; against five fixed inputs. Every famous escalation tool of the last twenty-five years attacks one of those inputs. Recognising the model as a single plane is the key to using its vocabulary against any specific attack.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The plane is whole. It is also full of structural holes its own keepers have publicly admitted. What are they?&lt;/p&gt;
&lt;h2&gt;13. The Five Structural Limits&lt;/h2&gt;
&lt;p&gt;Microsoft&apos;s &lt;em&gt;Security Servicing Criteria for Windows&lt;/em&gt; defines a security boundary as &quot;a logical separation between the code and data of security domains with different levels of trust... the separation between kernel mode and user mode is a classic [...] security boundary&quot; [@msrc-servicing-criteria]. The criteria document then enumerates which boundaries Microsoft commits to servicing. The kernel-mode / user-mode boundary qualifies. UAC and admin-to-kernel are not in the enumerated list. Once that admission is on the public record, the model&apos;s structural arc becomes legible. Five derived limits flow from the concession.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limit 1: Admin equals kernel.&lt;/strong&gt; Any compromise with administrator rights can rewrite the model&apos;s own enforcement code. &lt;em&gt;Consequence:&lt;/em&gt; Mimikatz, every kernel-driver-loading attack, every signed-driver bring-your-own-vulnerable-driver path. &lt;em&gt;Successor:&lt;/em&gt; VBS Trustlets, which host secrets and policy enforcement in the &lt;em&gt;Virtual Trust Level 1&lt;/em&gt; user-mode environment that the VTL0 NT kernel cannot read or modify. Detailed coverage belongs to the Secure Kernel sibling article in this series [@secure-kernel-sibling].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limit 2: Tokens are bearer credentials.&lt;/strong&gt; Whichever process holds the handle gets the rights. The kernel does not ask how the handle was obtained. &lt;em&gt;Consequence:&lt;/em&gt; the entire Potato lineage (eight tools, six years), Mimikatz &lt;code&gt;token::elevate&lt;/code&gt;, every cross-session token-theft attack. &lt;em&gt;Successor:&lt;/em&gt; Adminless / Administrator Protection, which retires the long-lived filtered/full token pair in favour of a fresh, time-limited, just-in-time elevation flow gated by Windows Hello plus a hidden, system-generated, profile-separated user account that issues an isolated admin token [@ms-learn-administrator-protection, @techcommunity-admin-protection]. The forthcoming Adminless article in this series will cover the architecture in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limit 3: &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; on every service account.&lt;/strong&gt; IIS, SQL Server, the Print Spooler, scheduled tasks, Docker, Citrix, almost every managed-service account by default. &lt;em&gt;Consequence:&lt;/em&gt; every Potato, by construction. &lt;em&gt;Partial successor today:&lt;/em&gt; per-service SIDs and Group Managed Service Accounts let administrators constrain the blast radius of a compromised service. &lt;em&gt;Structural successor:&lt;/em&gt; Adminless, which removes the privilege from the daily authentication path and demands a fresh elevation per privileged action [@ms-learn-administrator-protection, @techcommunity-admin-protection].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limit 4: NTLM relay surface.&lt;/strong&gt; As long as Windows services accept NTLM and the operating system signs NTLM challenges with the local-machine credential, the local-NTLM-to-self attack is structurally available. &lt;em&gt;Consequence:&lt;/em&gt; PetitPotam, RemotePotato0, every cross-protocol relay. &lt;em&gt;Successor:&lt;/em&gt; NTLMless, which formally retires NTLM as a default Windows authentication protocol [@techcommunity-windows-auth-evolution]. The on-ramp is the NTLM auditing channel introduced in Windows 11 24H2 and Windows Server 2025 (KB5064479, original publish date July 11, 2025), which records NTLMv1 usage in &lt;code&gt;Microsoft\Windows\NTLM\Operational&lt;/code&gt; and gives administrators a per-workload deprecation telemetry [@ms-support-ntlm-auditing]. The forthcoming NTLMless article in this series will cover the architecture in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limit 5: The DACL is local.&lt;/strong&gt; Conditional ACEs and Dynamic Access Control claims need a working AD-and-AD-FS plane to evaluate; airgapped or heterogeneous environments fall back to user / group SIDs as the only available subject. &lt;em&gt;Consequence:&lt;/em&gt; the access-matrix subject is, in practice, still &quot;user and group&quot; for most non-file-server workloads. The 2012 extension to claims and code identity is real but operationally bounded.&lt;/p&gt;
&lt;p&gt;The deepest of the five limits is the one Norm Hardy named in 1988. Hardy&apos;s framing returned in Section 2 [@en-wiki-confused-deputy] holds: capability systems close the gap structurally; ACL engineering does not.&lt;/p&gt;
&lt;p&gt;seL4 closes it with machine-checked correctness proofs and a capability-based design that makes ambient authority a category error [@en-wiki-capability-based-security]. Windows closes it, when it closes it at all, with VBS Trustlets that move &lt;em&gt;the right to perform the operation&lt;/em&gt; into a separate execution domain. The Potato lineage is the textbook confused-deputy instance: a service running with &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; is the privileged compiler; the attacker is the user holding a billing-records-shaped pointer; the service uses &lt;em&gt;its own&lt;/em&gt; authority on every authentication it accepts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Hardy&apos;s 1988 paper [@wayback-cap-lore-hardy] and the Wikipedia summary [@en-wiki-confused-deputy] both say the same thing: ACL systems are structurally vulnerable to confused-deputy attacks; capability systems are not. The gap is not asymptotic. ACL engineering does not close it. The Potato lineage is what the gap looks like in the field, repeated against eight different coercion primitives over six years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; &lt;strong&gt;The next generation of Windows defences cannot live inside the kernel, because the kernel is on the wrong side of the boundary the model draws.&lt;/strong&gt; Microsoft&apos;s own servicing criteria admit it. Adminless, NTLMless, VBS Trustlets, and Credential Guard are the four non-overlapping ways to fix it. Each successor was scoped to close a specific gap the access-control model could not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The five limits are named. The successors are shipping. What replaces what?&lt;/p&gt;
&lt;h2&gt;14. The Successors: Adminless, NTLMless, VBS Trustlets, Credential Guard&lt;/h2&gt;
&lt;p&gt;One paragraph each. This section is a forward-reference index, not a detailed walk-through.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Adminless.&lt;/strong&gt; Removes the local Administrators group from the daily authentication path. The long-lived filtered / full token pair the UAC model produces at logon is replaced with a fresh, time-limited, just-in-time elevation flow: when a user wants to perform a privileged action, the system gates the action behind &lt;a href=&quot;https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/&quot; rel=&quot;noopener&quot;&gt;Windows Hello&lt;/a&gt; plus a hidden, system-generated, profile-separated user account that issues an isolated admin token, and the resulting token is bounded in time and scope [@ms-learn-administrator-protection].&lt;/p&gt;
&lt;p&gt;The Microsoft Tech Community announcement (modified November 19, 2024) summarises the security argument: &quot;By requiring explicit authorization for every administrative task, Administrator protection protects Windows from accidental changes by users and changes by malware... Malicious software often relies on admin privileges to change device settings and execute harmful actions. Administrator protection breaks the attack kill chain&quot; [@techcommunity-admin-protection]. &lt;em&gt;Closes:&lt;/em&gt; limits #2 and #3 -- there is no long-lived bearer credential to steal, and &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; does not need to live on every service account because services run as bounded principals issued capabilities at the moment of need. Forthcoming article in this series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NTLMless.&lt;/strong&gt; Formally retires NTLM as a default Windows authentication protocol [@techcommunity-windows-auth-evolution]. The Tech Community announcement is unambiguous about direction: &quot;Reducing the use of NTLM will ultimately culminate in it being disabled in Windows 11. We are taking a data-driven approach and monitoring reductions in NTLM usage to determine when it will be safe to disable&quot; [@techcommunity-windows-auth-evolution].&lt;/p&gt;
&lt;p&gt;The transition rests on a local KDC (IAKerb) that lets Kerberos service both local and domain accounts, plus an audit channel introduced in Windows 11 24H2 and Windows Server 2025 (KB5064479, original publish date July 11, 2025) that records NTLMv1 usage in &lt;code&gt;Microsoft\Windows\NTLM\Operational&lt;/code&gt; and gives administrators per-service telemetry on which workloads still require the protocol [@ms-support-ntlm-auditing]. The local-NTLM-to-self attack class -- coerce a SYSTEM service to authenticate with the local-machine credential, accept the challenge, relay it back to a local service that trusts the credential -- ends when the local-machine NTLM credential ends. &lt;em&gt;Closes:&lt;/em&gt; limit #4. Forthcoming article in this series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VBS Trustlets and Isolated User Mode.&lt;/strong&gt; Shipped in Windows 10 1507 in 2015. &lt;em&gt;Virtualization-Based Security&lt;/em&gt; (VBS) uses the Hyper-V hypervisor to host a second user-mode environment, &lt;em&gt;Virtual Trust Level 1&lt;/em&gt; (VTL1), whose memory the NT kernel running in VTL0 cannot read or write. A &lt;em&gt;Trustlet&lt;/em&gt; is a process that runs in VTL1. &lt;em&gt;Closes:&lt;/em&gt; limit #1, for selected secrets. The ordinary NT kernel still runs the show for ordinary processes; VTL1 is a side-channel for secrets and policy decisions that the model wants to protect even from a kernel-level attacker. Detailed coverage in the Secure Kernel sibling article [@secure-kernel-sibling].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Credential Guard.&lt;/strong&gt; The canonical first Trustlet. &lt;code&gt;lsass.exe&lt;/code&gt; continues to run in VTL0 and answer authentication requests; the credential blobs &lt;code&gt;lsass.exe&lt;/code&gt; historically held are moved to a Trustlet called &lt;code&gt;LsaIso&lt;/code&gt; in VTL1. The VTL0 &lt;code&gt;lsass.exe&lt;/code&gt; retains &lt;em&gt;handles&lt;/em&gt; to the blobs but cannot read their contents; authentication happens by calling into the Trustlet. Mimikatz &lt;code&gt;sekurlsa::logonpasswords&lt;/code&gt; returns no plaintext credentials against a Credential-Guard-on system, because the plaintext does not live in VTL0 memory at all. The default-enablement timeline and the SKU-specific configuration matrix are covered in the Secure Kernel sibling article [@secure-kernel-sibling].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pluton-rooted attestation and the hardware foundation.&lt;/strong&gt; The successor architectures rest on a hardware identity chain that begins below the firmware, in Microsoft&apos;s Pluton in-die security processor. Pluton holds the keys that vouch for the boot measurements that the OS in turn uses to attest its own integrity to a remote relying party. The &lt;a href=&quot;https://paragmali.com/blog/pluton-a-tpm-on-silicon-microsoft-can-patch/&quot; rel=&quot;noopener&quot;&gt;Pluton article&lt;/a&gt; in this series covers the architecture and the Caliptra root-of-trust direction it foreshadows [@pluton-sibling]. The &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM 2.0 architecture&lt;/a&gt; that the same chain extends and the &lt;a href=&quot;https://paragmali.com/blog/secure-boot-in-windows-the-chain-from-sector-zero-to-userini/&quot; rel=&quot;noopener&quot;&gt;Secure Boot chain&lt;/a&gt; that runs before the access-control model boots are covered in their own sibling articles in this series.&lt;/p&gt;

The five limits enumerated in Section 13 and the four successor articles in this section are in one-to-one correspondence: Adminless closes #2 and #3, NTLMless closes #4, VBS Trustlets close #1, and Credential Guard is the canonical first Trustlet that demonstrates #1 closing for a specific high-value secret. Limit #5 -- the DACL is local -- is operational rather than architectural and is closed by deployment investment in AD plus AD FS rather than by a new mechanism. The correspondence is not a coincidence. Each successor was scoped to close a specific gap the access-control model could not close from inside.
&lt;p&gt;With the gaps named and the successors mapped, what does an administrator actually do today?&lt;/p&gt;
&lt;h2&gt;15. Practical Guide&lt;/h2&gt;
&lt;p&gt;Six concrete recommendations for 2026, each tied to a primary Microsoft Learn or named-expert source.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;whoami /all&lt;/code&gt; prints the SIDs in the calling thread&apos;s token, the integrity level, every privilege with its &lt;code&gt;Enabled&lt;/code&gt; / &lt;code&gt;Disabled&lt;/code&gt; / &lt;code&gt;Default Enabled&lt;/code&gt; state, and -- on AD-joined machines with claims -- the user and device claim set. It is the single most useful diagnostic command for understanding what a session can do. Read the &lt;code&gt;Enabled&lt;/code&gt; column carefully: an available-but-disabled privilege does not affect any access check until the process explicitly enables it [@ms-learn-access-tokens].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;icacls &amp;lt;path&amp;gt;&lt;/code&gt; prints the DACL on a file or directory; the mass-rights letters are &lt;code&gt;(F)&lt;/code&gt; full, &lt;code&gt;(M)&lt;/code&gt; modify, &lt;code&gt;(RX)&lt;/code&gt; read and execute, &lt;code&gt;(R)&lt;/code&gt; read, &lt;code&gt;(W)&lt;/code&gt; write, &lt;code&gt;(D)&lt;/code&gt; delete, &lt;code&gt;(GA)&lt;/code&gt; generic all, &lt;code&gt;(GR)&lt;/code&gt; generic read, &lt;code&gt;(GW)&lt;/code&gt; generic write [@ms-learn-how-dacls-control-access]. PowerShell&apos;s &lt;code&gt;Get-Acl&lt;/code&gt; returns the same descriptor as a structured object that can be filtered and audited at scale. Sysinternals &lt;code&gt;accesschk.exe&lt;/code&gt; answers the inverted query (which paths grant a given SID a given right) and is the right tool for catching descriptor misconfigurations across a large file system. Treat NULL DACL and empty DACL surfaces as the most-likely misconfiguration vectors.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On every Windows server, enumerate the principals whose tokens hold &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; or &lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt; in their &lt;em&gt;Default&lt;/em&gt; or &lt;em&gt;Available&lt;/em&gt; lists. Treat any non-LocalSystem-or-equivalent holder as a Potato target until proven otherwise. Where a service must hold the privilege (most managed-service workloads do), constrain the blast radius with per-service SIDs and Group Managed Service Accounts so that a compromise of one service does not extend to a compromise of every service that shares the host&apos;s identity [@github-itm4n-printspoofer].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The UACMe README is the institutional memory for the seventy-method bypass canon. Every method&apos;s &lt;code&gt;Fixed in:&lt;/code&gt; field cites a specific Windows version or &lt;code&gt;unfixed&lt;/code&gt;. Before declaring a binary &quot;patched,&quot; consult the README; a method with a &lt;code&gt;Fixed in: unfixed&lt;/code&gt; annotation is structurally available on every supported Windows version. The institutional position is that UAC bypasses do not, by Microsoft&apos;s own servicing-criteria policy, earn CVEs of their own, so the mitigations are issued per-redirect rather than per-feature [@github-hfiref0x-uacme, @msrc-servicing-criteria].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Windows Event ID 4688 (&quot;A new process has been created&quot;) is the most-cited detection signal for the Potato lineage and the UAC bypass tradition, because almost every member of both families ends in a &lt;code&gt;CreateProcessAsUser&lt;/code&gt; or a redirected AutoElevate launch with a command-line argument that does not match the legitimate use of the parent binary. Enable command-line auditing under &lt;em&gt;Audit Process Creation&lt;/em&gt; and forward the log; Sysmon Event ID 1 is the equivalent and richer signal in environments that deploy Sysinternals&apos; Sysmon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The access matrix is the part of the model with deliberately extensible &lt;em&gt;subjects&lt;/em&gt;. New code that lives behind an AppContainer SID gets a Low-IL token, a Package SID, and a capability list that constrain what it can touch even when the user running it is an administrator. New file shares that need attribute-based authorization should use conditional ACEs and Dynamic Access Control rather than ad-hoc group membership. Cross-link to the &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;App Identity sibling article&lt;/a&gt; for Package SID derivation [@app-identity-sibling] and to the Dynamic Access Control overview [@ms-learn-dac].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;{`
// Inputs:
//   token       -- {sids:[...], integrity:&apos;Low&apos;|&apos;Medium&apos;|&apos;High&apos;|&apos;System&apos;,
//                   appContainer:bool, capabilities:[...], claims:{...},
//                   privileges:{enabled:[...]}}
//   descriptor  -- {dacl:[...], integrityLabel:&apos;Low&apos;|...|&apos;System&apos;,
//                   policyNoWriteUp:bool}
//   desired     -- access mask (number)
// Output: {granted, status, fired:[...]}&lt;/p&gt;
&lt;p&gt;function fullAccessCheck(token, descriptor, desired) {
  const fired = [];
  const ilOrder = {Low:1, Medium:2, High:3, System:4};&lt;/p&gt;
&lt;p&gt;  // 1. MIC check fires before DACL walk.
  if (descriptor.policyNoWriteUp) {
    const writeBits = 0x00040000 | 0x00000002 | 0x00000004; // WRITE_DAC|WRITE|APPEND
    if ((desired &amp;amp; writeBits) &amp;amp;&amp;amp; ilOrder[token.integrity] &amp;lt; ilOrder[descriptor.integrityLabel]) {
      fired.push(&apos;MIC no-write-up: token IL &apos; + token.integrity + &apos; &amp;lt; object IL &apos; + descriptor.integrityLabel);
      return {granted:0, status:&apos;DENIED at integrity check&apos;, fired};
    }
  }&lt;/p&gt;
&lt;p&gt;  // 2. Privilege bypass short-circuit.
  if (token.privileges.enabled.includes(&apos;SeBackupPrivilege&apos;) &amp;amp;&amp;amp; (desired &amp;amp; 0x80000000)) {
    fired.push(&apos;SeBackupPrivilege bypass: GENERIC_READ granted&apos;);
    return {granted: desired, status:&apos;GRANTED via SeBackupPrivilege&apos;, fired};
  }&lt;/p&gt;
&lt;p&gt;  // 3. AppContainer capability check (simplified).
  if (token.appContainer &amp;amp;&amp;amp; descriptor.requiresCapability) {
    if (!token.capabilities.includes(descriptor.requiresCapability)) {
      fired.push(&apos;AppContainer capability check: missing &apos; + descriptor.requiresCapability);
      return {granted:0, status:&apos;DENIED at AppContainer check&apos;, fired};
    }
  }&lt;/p&gt;
&lt;p&gt;  // 4. DACL walk, deny-first, in canonical order.
  let remaining = desired;
  let granted = 0;
  for (const ace of (descriptor.dacl || [])) {
    if (!token.sids.includes(ace.sid)) continue;
    if (ace.condition &amp;amp;&amp;amp; !evalCondition(ace.condition, token.claims)) continue;
    if (ace.type === &apos;DENY&apos; &amp;amp;&amp;amp; (ace.mask &amp;amp; remaining) !== 0) {
      fired.push(&apos;Conditional/plain DENY: &apos; + ace.sid);
      return {granted:0, status:&apos;DENIED at DACL&apos;, fired};
    }
    if (ace.type === &apos;ALLOW&apos;) {
      const newBits = ace.mask &amp;amp; remaining;
      granted |= newBits;
      remaining &amp;amp;= ~newBits;
      fired.push(&apos;ALLOW &apos; + ace.sid + &apos;: granted 0x&apos; + newBits.toString(16));
    }
    if (remaining === 0) {
      return {granted, status:&apos;GRANTED&apos;, fired};
    }
  }
  return {granted, status: remaining === 0 ? &apos;GRANTED&apos; : &apos;DENIED end of DACL&apos;, fired};
}&lt;/p&gt;
&lt;p&gt;function evalCondition(expr, claims) {
  // Toy evaluator for &quot;(@User.Department == \&quot;Finance\&quot;)&quot;-style expressions.
  const m = expr.match(/@User\.(\w+)\s*==\s*&quot;([^&quot;]+)&quot;/);
  if (!m) return true;
  return claims[m[1]] === m[2];
}&lt;/p&gt;
&lt;p&gt;// Demo: a Medium-IL user trying to write to a System-IL object via an allow ACE.
console.log(fullAccessCheck(
  {sids:[&apos;S-1-5-21-X-Y-Z-1001&apos;], integrity:&apos;Medium&apos;, appContainer:false, capabilities:[], claims:{Department:&apos;Finance&apos;},
   privileges:{enabled:[]}},
  {dacl:[{type:&apos;ALLOW&apos;, sid:&apos;S-1-5-21-X-Y-Z-1001&apos;, mask:0xFFFFFFFF}],
   integrityLabel:&apos;System&apos;, policyNoWriteUp:true},
  0x00040000));  // WRITE_DAC
`}&lt;/p&gt;
&lt;p&gt;The simulator runs the full plane in order: MIC integrity check, privilege bypass short-circuit, AppContainer capability check, DACL walk with conditional-ACE evaluation. Reading the &lt;code&gt;fired&lt;/code&gt; log in the output tells you which primitive made the decision and why. It is the mental model the rest of the article has been building toward.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The six tips and the simulator together close the practical loop. With them, the practitioner can reason about any specific access decision the way the kernel does -- not by remembering features, but by walking the same plane.&lt;/p&gt;
&lt;p&gt;The Sysinternals &lt;code&gt;accesschk&lt;/code&gt; and &lt;code&gt;psgetsid&lt;/code&gt; utilities have long been first-line investigative tools for ACL audits. Both ship in the Sysinternals Suite today and continue to surface the same descriptors &lt;code&gt;Get-Acl&lt;/code&gt; and &lt;code&gt;icacls&lt;/code&gt; print, in the form most useful to an administrator working at scale.&lt;/p&gt;
&lt;h2&gt;16. Frequently Asked Questions&lt;/h2&gt;


No. By Microsoft&apos;s own *Security Servicing Criteria for Windows*, UAC and admin-to-kernel are not on the enumerated security-boundary list [@msrc-servicing-criteria]; bypasses are not, by policy, eligible for security servicing as boundary violations. The seventy-plus methods catalogued in UACMe are the empirical consequence of the classification, not a long string of bugs in a feature that was meant to defend against the techniques [@github-hfiref0x-uacme].


No. `Everyone` (the well-known SID `S-1-1-0`) is just a SID. ACEs that reference it are subject to the same DACL walk as any other SID; if a deny ACE for `Everyone` precedes an allow ACE for `Authenticated Users`, access is denied. The DACL evaluation algorithm does not know `Everyone` is special. Forshaw made the point with a meme-able rant in 2020: &quot;S-1-1-0 is NOT A SECURITY BOUNDARY&quot; [@tiraniddo-sharing-logon-session].


No. *Empty* DACL denies all access. *No* DACL (a NULL DACL) grants full access. Newly-written code that &quot;creates a file with no protection&quot; almost always gets this distinction wrong [@ms-learn-how-dacls-control-access]. Verify with `Get-Acl` or `icacls` after creation; an `icacls` output of `Everyone:(F)` on an object you intended to lock down is almost always a NULL DACL, not the policy you meant to write.


For DACL alone, yes. For MIC, no -- a System-IL administrator still cannot write to a process at higher integrity if MIC denies the request, because the integrity check fires before the DACL walk [@ms-learn-mic]. For AppContainer, no -- AppContainer-bound objects require the capability SID, not just an administrator SID. For VBS Trustlets, no -- secrets in VTL1 are unreachable from VTL0 even with administrator rights, which is the whole point of the architecture [@secure-kernel-sibling].


No. The list shows *available* privileges. The `Enabled` column is the one that matters for runtime decisions; available-but-disabled privileges must be enabled via `AdjustTokenPrivileges` before any privileged operation can use them. Most privileges are disabled by default precisely so that a process must explicitly opt in to using one, which lets a security-conscious application minimise the window in which a bug can abuse the privilege [@ms-learn-privileges].


No. The underlying NTLM-to-self surface is still open. SharpEfsPotato (2021) [@github-bugch3ck-sharpefspotato] is the most recent member of the lineage; new tools using fresh coercion primitives (EFSRPC, the spooler, the schedule-task COM interface, cross-session DCOM) appear every twelve to eighteen months. Microsoft&apos;s own Hot Potato post called the underlying issue &quot;hard to fix without breaking backward compatibility&quot; [@foxglove-hot-potato-blog]; the structural fix is the Adminless and NTLMless successor articles, not a point patch on any one primitive.


Partially. AppContainer is a process-level isolation mechanism with a Low-IL token plus a capability-SID list. It is also a *named principal* in the Windows access-control model -- something Chrome&apos;s sandbox is not -- which means AppContainer-bound code can be referenced by SID in a DACL or conditional ACE, and Windows can refuse access to it as a principal in its own right. The sibling App Identity article in this series covers the Package SID derivation and the relationship to Authenticode and App Control for Business [@app-identity-sibling].

&lt;h2&gt;17. Closing: Return to the Hook&lt;/h2&gt;
&lt;p&gt;Open a Windows PowerShell window again. Run &lt;code&gt;whoami /priv&lt;/code&gt;. Read the column on the right, this time with the article&apos;s vocabulary annotated above each line.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeShutdownPrivilege&lt;/code&gt; -- a privilege, in the kernel sense of a pre-checked superpower; bookkeeping rather than power.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeIncreaseWorkingSetPrivilege&lt;/code&gt; -- the same. Most of the twenty rows are housekeeping that the kernel checks at specific call sites to gate non-security-critical operations.&lt;/p&gt;
&lt;p&gt;The five rows that matter are easy to spot once you know what to look for. &lt;code&gt;SeDebugPrivilege&lt;/code&gt; -- Mimikatz starts here. &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt; -- the entire Potato lineage starts here. &lt;code&gt;SeAssignPrimaryTokenPrivilege&lt;/code&gt; -- the second half of every token-replay attack. &lt;code&gt;SeBackupPrivilege&lt;/code&gt; -- HiveNightmare&apos;s privilege class. &lt;code&gt;SeRestorePrivilege&lt;/code&gt; -- service-binary replacement. The kernel reads the same column on every securable operation, billions of times a second, and the answer to &quot;can this code do this?&quot; is built out of this list every time.&lt;/p&gt;
&lt;p&gt;Now run &lt;code&gt;icacls C:\Windows\System32\drivers\etc\hosts&lt;/code&gt; again. &lt;code&gt;BUILTIN\Administrators:(F)&lt;/code&gt; is an allow ACE granting full control to the well-known SID &lt;code&gt;S-1-5-32-544&lt;/code&gt;. &lt;code&gt;NT AUTHORITY\SYSTEM:(F)&lt;/code&gt; is an allow ACE granting full control to &lt;code&gt;S-1-5-18&lt;/code&gt;. &lt;code&gt;BUILTIN\Users:(R)&lt;/code&gt; is an allow ACE granting &lt;code&gt;FILE_GENERIC_READ&lt;/code&gt; to &lt;code&gt;S-1-5-32-545&lt;/code&gt;. The DACL is in canonical order: explicit entries before inherited entries, deny entries (none here) before allow entries within each group. &lt;code&gt;SeAccessCheck&lt;/code&gt; will walk this DACL on every read of &lt;code&gt;hosts&lt;/code&gt; from any process on the machine, and the output will be deterministic -- the same answer every time, for the same caller -- because the model that produces it is closed and finite.&lt;/p&gt;
&lt;p&gt;The article&apos;s payoff. Every later post in this series starts where this one ends. The Adminless article retires the bearer-credential property of long-lived tokens. The NTLMless article retires the local-NTLM-to-self relay surface. The Secure Kernel article hosts secrets in VTL1 outside the NT kernel&apos;s address space and tells the Credential Guard story in detail [@secure-kernel-sibling]. The Pluton article roots the hardware identity chain that the successor architectures all eventually verify against [@pluton-sibling]. The TPM article and the Secure Boot article cover the static-time and boot-time chains that run before the access-control model even loads. Each successor was scoped to close a specific gap the access-control model could not close from inside.&lt;/p&gt;
&lt;p&gt;NT 3.1 froze a model in July 1993 because federal procurement demanded it. That model has not structurally changed in thirty-three years. The accumulated attack surface against it -- twenty-five years, eight Potatoes, seventy UAC bypasses, one Mimikatz -- is the empirical proof that &quot;frozen&quot; was always going to mean &quot;attackable from below.&quot; The next generation of defences takes that lesson and stops trying to fix the model from inside. The model is not a feature catalogue. It is a decision plane with five inputs, ten primitives, and five publicly conceded structural limits, and the four successor architectures of the next decade are the four non-overlapping ways to close those limits without re-evaluating against TCSEC C2 again.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SeAccessCheck&lt;/code&gt; decides every time. The next decade decides what it decides about.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;windows-access-control-twenty-five-years&quot; keyTerms={[
  { term: &quot;SeAccessCheck&quot;, definition: &quot;The kernel routine that decides whether a thread may perform a requested set of operations on an object. Takes a security descriptor, an access token, a desired-access mask, a generic-mapping table, and previously-granted access; returns the granted access mask plus a status code.&quot; },
  { term: &quot;Security Reference Monitor (SRM)&quot;, definition: &quot;The kernel-mode component that owns SeAccessCheck and the audit log generation routines. Every other kernel component that needs to grant or deny access calls into it.&quot; },
  { term: &quot;Access Token&quot;, definition: &quot;A kernel object that names the security identity of a thread or process. Carries the user&apos;s SID, group SIDs, privileges, integrity level, primary/impersonation flag, and (for restricted tokens) a list of restricting SIDs. The kernel consults the token on every access check.&quot; },
  { term: &quot;Discretionary Access Control List (DACL)&quot;, definition: &quot;The ordered list of allow / deny ACEs attached to a securable object. The object&apos;s owner controls the contents, in contrast to a mandatory list.&quot; },
  { term: &quot;Mandatory Integrity Control (MIC)&quot;, definition: &quot;A Vista-era addition that adds an integrity-level check to SeAccessCheck. The integrity check fires before the DACL walk and enforces no-write-up by default.&quot; },
  { term: &quot;User Account Control (UAC)&quot;, definition: &quot;A Vista-era split-token mechanism in which an administrative user receives two linked tokens at logon: a filtered Medium-IL standard-user token and a full High-IL administrative counterpart. Not, by Microsoft&apos;s own servicing criteria, an enforced security boundary.&quot; },
  { term: &quot;SeImpersonatePrivilege&quot;, definition: &quot;The privilege that lets a service accept an impersonation token from a client. Held by every Windows service account by default. The load-bearing privilege for the entire Potato lineage.&quot; },
  { term: &quot;Confused Deputy&quot;, definition: &quot;Norm Hardy&apos;s 1988 framing of the structural failure mode of any ambient-authority access-control system: a privileged service can be tricked into using its own authority on the attacker&apos;s behalf because the system cannot distinguish authority the service has from authority the service is being asked to use.&quot; },
  { term: &quot;VBS Trustlet&quot;, definition: &quot;A Windows process that runs in Virtual Trust Level 1, a hardware-isolated user-mode environment whose memory the NT kernel running in VTL0 cannot read or write. The architectural answer to the admin-equals-kernel concession of the access-control model.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>access-control</category><category>privilege-escalation</category><category>security-tokens</category><category>uac</category><category>mimikatz</category><category>potato-attacks</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>