56 min read

Windows Downdate: When the Update Itself Is the Attack

How Alon Leviev turned Windows Update into a downgrade primitive, rolling fully-patched Windows 11 back to vulnerable VBS components while every signature still verified.

Permalink

1. "Up to Date" Means Less Than It Says

Imagine a Windows 11 machine that has installed every cumulative update Microsoft has released this year. Settings says You're up to date. The Authenticode signature on every system DLL validates against Microsoft's root. HVCI is on. Credential Guard is on. VBS is on with the UEFI lock engaged. Disk Cleanup is empty. The Servicing Stack reports a healthy state. And somewhere in C:\Windows\System32, a two-year-old ci.dll is happily enforcing the code-integrity policy on a kernel that thinks it is current.

This machine was the demo on the SafeBreach blog in October 2024, and it is not a misconfiguration [@safebreach-2024-oct; @thehackernews-downdate]. The version on disk is 10.0.22621.1376, a build from before May 2024, when Microsoft patched Gabriel Landau's False File Immutability race in ci.dll [@elastic-ffi; @landau-itsnotasecurityboundary-repo]. The signature on that older build is legitimately Microsoft's. The hash matches a Microsoft-issued security catalog. Windows is perfectly happy to load it.

The Driver Signature Enforcement policy, the Authenticode chain, the catalog trust path, the WinSxS component store, and the post-reboot servicing engine were all built on the same shared assumption. Windows Downdate is what happens when you stop assuming it.

The author of that demo is Alon Leviev, a researcher then at SafeBreach Labs. On August 7, 2024 he presented Windows Downdate: Downgrade Attacks Using Windows Updates at Black Hat USA, followed by a more detailed walk-through at DEF CON 32 four days later [@safebreach-2024-aug; @bh-leviev-slides].

The technique he published does one thing and does it well: it takes Administrator-level access on a fully-patched Windows machine and converts it into Microsoft-signed historical code, running in the kernel, inside the Secure Kernel, inside the hypervisor, inside Credential Guard's isolated user-mode process. The OS does not notice. EDR does not notice. sfc /scannow does not notice. Settings reports the system as patched, because in every sense Windows can express, it is.

Leviev framed his goal as a four-property objective. The attack had to be undetectable to endpoint security, invisible to the user, persistent across future updates, and irreversible by repair tooling. The rest of this article will measure each piece of the attack against those four properties, but it is worth pausing on what they imply. They do not require defeating a single Microsoft mitigation. They require defeating all of them simultaneously, and Leviev's claim is that one registry write is enough.

That sentence is the spine of the article. To understand why nobody noticed for so long, we have to start somewhere unexpected: with a TLS bug from 2014.

2. A History of Downgrade Attacks (Before Windows Knew the Name)

If you can convince a system to do something old, you can convince it to do something dangerous. Bodo Möller, Thai Duong, and Krzysztof Kotowicz figured that out first, at least in the public literature. In October 2014 their This POODLE Bites advisory described an attack on the way browsers retry failed TLS handshakes [@google-poodle-pdf; @nvd-poodle]. A man-in-the-middle could induce a connection failure, the browser would silently retry at a lower protocol version, and the server would accept SSL 3.0, where a CBC padding oracle let the attacker decrypt session cookies one byte at a time. SSL 3.0 had been broken for years, but it remained in the negotiation envelope for backwards compatibility, and the negotiation envelope was where the protocol was weakest.

POODLE established the pattern. A protocol that retains legacy modes for compatibility creates a downgrade primitive unless the protocol explicitly enforces "highest version available."

Five months later, in March 2015, Karthikeyan Bhargavan and the miTLS team at INRIA found a near-identical pattern with FREAK: a stripped-down "export-grade" RSA cipher suite from the 1990s was still negotiable, and a fast attacker could factor the 512-bit key during the handshake [2]. That same April, Möller and Adam Langley shipped RFC 7507 to standardise the first explicit in-band signal that a TLS client was deliberately falling back, so that the server could refuse [3]. Three years after that, Eric Rescorla's TLS 1.3 (RFC 8446) baked downgrade resistance directly into the ServerHello.random nonce -- a structural fix, not a hint [4]. The same period gave us SLOTH from Bhargavan and Gaétan Leurent: a transcript-collision attack on TLS, IKE, and SSH whose mitigation pushed TLS 1.3 to bind downgrade resistance into the transcript hash, making it impossible to rewrite the negotiation without breaking the integrity check [5].

The Microsoft UEFI CA 2023 rollout began in February 2024 with a phased deployment that runs through 2026, replacing the Windows Production 2011 CA in firmware databases worldwide [6]. This rollout is the firmware-layer analogue of TLS 1.3's binding: each rotation is intended to retire trust in the older signer, but the rotation only matters if the consumer enforces it.

Meanwhile, four years before POODLE, a small group of NYU and Tor researchers wrote the academic-canonical paper on what happens when an attacker controls a software update repository instead of a network. Justin Samuel, Nick Mathewson, Justin Cappos, and Roger Dingledine published Survivable Key Compromise in Software Update Systems at ACM CCS 2010. They formalised three update-specific threats nobody had named before: rollback attacks (the repository serves an older, vulnerable copy of metadata), freeze attacks (the repository serves the same copy forever, preventing a client from ever learning about patches), and replay attacks (the repository serves a stale snapshot to a victim selected by network position) [@tuf-spec; @tuf-security].

The companion specification, now stewarded by the CNCF, says it plainly: "An attacker presents files to a software update system that are older than those the client has already seen. With no way to tell it is an obsolete version that may contain vulnerabilities, the user installs the software" [7]. That is The Update Framework. Sigstore, Docker Notary, PyPI's PEP 458, and in-toto all inherit its threat model.

So by 2015 the academic and protocol communities had named the problem, given it a vocabulary, written a specification, and started shipping standards. Three years later the mobile world followed.

From protocols to operating systems

In August 2017, Android 8.0 shipped Verified Boot 2.0 (AVB), the first widely-deployed operating-system rollback defence. AVB stamps a rollback_index into each signed partition and stores per-slot maxima in TrustZone or in RPMB-backed storage; the bootloader refuses any image whose index is below the stored maximum [8]. The Android source page summarises the design goal: "AVB's key features include delegating updates for different partitions, a common footer format for signing partitions, and protection from attackers rolling back to a vulnerable version of Android" [8].

Three years after Android, Apple shipped the Signed System Volume on macOS Big Sur (November 2020). SSV seals the entire system volume into a single Merkle tree whose root is signed by Apple; on iOS and iPadOS the user cannot disable it [9]. The IETF Software Updates for Internet of Things working group standardised the same threat model in RFC 9019 (April 2021) for embedded firmware: "The firmware image is authenticated and integrity protected. Attempts to flash a maliciously modified firmware image or an image from an unknown, untrusted source must be prevented" [10].

By 2022, every major mobile platform, every IoT firmware standard, and every modern image-based update system had named rollback as a primary threat and shipped a structural fix. Then came BlackLotus.

Ctrl + scroll to zoom
A decade of downgrade-attack milestones, from network protocols (POODLE, FREAK) through update-system theory (TUF) to operating-system rollback defences (AVB, SSV) and finally the in-the-wild Windows precedent (BlackLotus).

The Windows precedent

Martin Smolar's BlackLotus UEFI Bootkit: Myth Confirmed arrived in March 2023, and it was the direct precedent Leviev would cite. BlackLotus was a UEFI bootkit that had been on sale on hacking forums since October 2022 [11]. Its key trick was to ship its own copy of a legitimately Microsoft-signed but vulnerable bootmgfw.efi -- specifically, a build still affected by CVE-2022-21894, the "Baton Drop" Secure Boot bypass that Microsoft had patched in January 2022.

Smolar wrote: "Although the vulnerability was fixed in Microsoft's January 2022 update, its exploitation is still possible as the affected, validly signed binaries have still not been added to the UEFI revocation list. BlackLotus takes advantage of this, bringing its own copies of legitimate -- but vulnerable -- binaries to the system in order to exploit the vulnerability" [11]. The NSA shipped a BlackLotus Mitigation Guide in June 2023 [12]; Microsoft began the laborious process of populating dbx, the UEFI Secure Boot revocation list, with the offending hashes [13].

The point that anchors this section: Microsoft did patch downgrade extensively at the firmware and boot-loader layer in response to BlackLotus. They updated dbx. They rolled the UEFI Production CA in February 2024 [6]. The architectural lesson -- if you have not declared which version of a signed binary is current, your signature is not enough -- had been internalised at the bottom of the stack. Whether anybody closed the same gap at the OS-component layer was a question only Leviev seems to have asked.

3. The Vista Bargain -- Component-Based Servicing and the Fourth Principal

If you sit down at a Windows 11 machine right now, open an elevated PowerShell as a local Administrator, and try to overwrite C:\Windows\System32\ntoskrnl.exe, Windows will refuse. The error is Access is denied. That is unexpected, because you are an Administrator, and on every Windows since NT 3.1 Administrators have been the highest principal on the box. The reason has a date.

In November 2006, Windows Vista shipped a fourth Windows security principal: NT SERVICE\TrustedInstaller. Its well-known SID is the long numeric string S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464, and its job is to be the only identity permitted to write into most of System32 [@safebreach-2024-aug; @ms-learn-servicing-stack-updates]. Administrators can take ownership of files there and grant themselves write access, but the default ACL excludes them. The change accompanied two other Vista deliverables that, taken together, became the contract that Windows servicing has obeyed for two decades.

TrustedInstaller

A Windows security principal introduced in Vista that owns most of the system files under C:\Windows\System32. Its job is to mediate component-based servicing operations: when you install a Windows Update, the work runs in TrustedInstaller's context, not the Administrator's. Direct writes to TrustedInstaller-owned files by other principals (including Administrators) are denied at the ACL.

The first deliverable was Component-Based Servicing (CBS), the replacement for the self-extracting Update.exe installers that had defined patch delivery from Windows NT 4.0 through Windows XP. CBS reshaped a Windows update from "a small executable that scribbles into your system directory" into "a manifest-driven transaction over a versioned component store." The second deliverable was WinSxS -- the side-by-side store under C:\Windows\WinSxS\ that holds every version of every CBS-managed component the system has ever installed [@safebreach-2024-aug; @ms-learn-servicing-stack-updates].

Component-Based Servicing (CBS)

The Windows servicing architecture introduced in Vista that replaced self-extracting update installers. A CBS package contains a Microsoft-signed security catalog (.cat) whose hashes cover the package's manifest files (.mum, .manifest). The manifests, transitively trusted via the signed catalog, describe which files belong to which component and how those files should be installed. CBS operations are mediated by the TrustedInstaller service.

The third deliverable was the manifest-and-catalog signing model that knit the first two together. A CBS package contains a security catalog (.cat) signed directly by Microsoft. The catalog's hashes cover the package's manifest files (.mum and .manifest); the manifests, in turn, name the package's payload files and describe their installation. The manifest files are not signed individually, but their hashes appear in the signed catalog, so they are transitively trusted [1]. The payload files are also not individually signed; their hashes appear in the manifests, which are themselves catalog-covered. The chain of custody runs catalog -> manifest -> payload, and at the root is Microsoft's signing key.

What this gives you is an elegant, declarative contract for system integrity. Microsoft signs a catalog. The catalog vouches for a manifest. The manifest vouches for a file. The file lands on disk. TrustedInstaller is the only principal allowed to write it, and TrustedInstaller has its own protected service that runs the install transactionally.

That silence is older than CBS. It traces back through the related 2005-2007 file-integrity work. Kernel Patch Protection, marketed as PatchGuard, shipped in x64 Windows Server 2003 SP1 in March 2005 and watches for tampering with running kernel structures [14]. KMCS, the Kernel-Mode Code Signing Walkthrough Microsoft published in July 2007, defined the Driver Signature Enforcement policy that kernel-mode code on x64 Vista and later had to satisfy [@kmcs-walkthrough; @msdocs-kmcs-policy].

The Microsoft Learn descendant page is more direct: "The kernel-mode driver signing policy for 64-bit versions of Windows Vista and later versions of Windows specifies that a kernel-mode driver must be signed for the driver to load" [15]. Each of these primitives bound trust to a Microsoft signature. None of them bound trust to a Microsoft-asserted version.

This was reasonable in 2007. Update.exe had been the threat: tampering with system files mid-flight, racing the installer, replacing a DLL while the system was rebooting. Vista's reply was to put the entire operation behind a principal that admins could not impersonate. The threat model said "the attacker is some Administrator-context tool that will try to overwrite system files." The reply said "only TrustedInstaller writes system files, and TrustedInstaller will only write files the catalog says are theirs." It was a complete answer to the question that had been asked.

It was an incomplete answer to a question nobody asked: which version of which file goes through that door, and is "which version" a property anyone actually checks?

Eighteen years later, the answer was: no, "which version" is not a property anyone checks at the file layer. The catalog says "this file belongs to this package." It does not say "this file is the current member of this component family."

The Vista bargain locked the door. It signed the keys. It named a single person who could turn the lock. What it did not do -- and was not designed to do -- was care whether the box behind the door was on the latest update or on the build from two years ago. That decision would land on three later generations of Windows integrity walls, and none of them caught it.

4. Generation by Generation -- The Walls That Weren't Walls of Time

Between 2007 and 2022, Microsoft built four more integrity walls on top of the Vista bargain. Each one was a generation forward. None of them added the dimension Windows Downdate needed them to add.

Generation 1: Kernel-Mode Code Signing / DSE (Vista x64, 2007)

The first wall. The kernel refused to load any driver that was not Authenticode-signed by a Microsoft-cross-signed CA [@kmcs-walkthrough; @msdocs-kmcs-policy; @msdocs-driver-signing]. DSE was enforced at driver load time by the kernel loader; non-signed drivers failed to load with an unmissable error. This was the first architectural assertion that "a Microsoft-signed binary is the unit of trust at the kernel boundary."

What it said: a kernel driver must be signed by Microsoft.

What it did not say: which Microsoft-signed driver. The catalog-trust model treats any Microsoft-signed version of a file as equally legitimate. That assumption is the one Windows Downdate exploits seventeen years later: signature validity is preserved across version rollback, because the catalog of the older version is still a Microsoft-signed catalog and the hash chain still resolves.

Generation 2: UEFI Secure Boot (Windows 8, 2012)

The second wall pushed the same idea down into firmware. The platform firmware refused to load a boot manager that was not signed by a key in the UEFI signature database (db), and refused to load any binary whose hash was in the forbidden-signature database (dbx) [@welivesecurity-blacklotus; @msft-uefi-ca-2023]. For the first time, Windows had a version-specific revocation primitive at the platform layer: dbx could enumerate specific binaries known to be unsafe.

But dbx had two problems. The first was rollout latency: BlackLotus demonstrated in 2023 that vulnerable, validly-signed bootmgfw.efi binaries were still trusted by firmware a full year after Microsoft patched them in source [11]. The second was scope: dbx covered boot-time binaries, not run-time OS components. A revocation primitive that only fires before ntoskrnl.exe loads is not a defence against rolling back ntoskrnl.exe itself.

The Microsoft UEFI CA 2023 rollout is on a multi-year phased schedule starting February 13, 2024 and running into 2026 [6]. The phased rollout exists precisely because retiring trust in older signers is slow and operationally risky -- the same shape of problem that SkuSiPolicy.p7b now faces at the OS layer.

Generation 3: VBS + HVCI + Credential Guard (Windows 10, 2015)

The third wall changed the threat model itself. Virtualization-Based Security used the Hyper-V hypervisor to create a higher-privilege isolation domain, called Virtual Trust Level 1 (VTL1), beneath the NT kernel's normal VTL0. Microsoft's own documentation states the new assumption directly: "VBS uses hardware virtualization and the Windows hypervisor to create an isolated virtual environment that becomes the root of trust of the OS that assumes the kernel can be compromised" [16].

VTL1 / Secure Kernel

Virtual Trust Level 1 is the higher-privilege half of the Hyper-V-managed split that VBS introduces. VTL0 holds the normal NT kernel and user-mode processes. VTL1 holds the Secure Kernel (securekernel.exe), the kernel-mode Code Integrity policy enforcement (skci.dll), and Isolated User Mode trustlets such as the LSA isolation process (LsaIso.exe). VTL0 cannot read VTL1 memory; transitions between the two go through a narrow set of hypercalls.

HVCI moved the kernel-mode code integrity check inside VTL1: a malicious kernel could no longer disable the check, because the check ran in a memory space the kernel could not write [17]. Credential Guard moved LSA secrets into an Isolated User Mode trustlet, LsaIso.exe, so a kernel-level attacker could not directly read NTLM hashes or Kerberos TGTs from LSASS memory [18]. The explicit, written threat model said: assume the NT kernel can be compromised, and provide a higher-privilege isolation domain for security-critical state.

That sentence is doing all the work. It says VBS is a defence against a compromised kernel, which means VBS is a defence against an attacker who has reached kernel code execution by any means. And one of the ways an attacker reaches kernel code execution -- one of the obvious ones, on a single-user Windows machine -- is to be an Administrator. The whole point of VBS was that Administrator code execution is the threat. That fact will matter again in section eight.

The unsaid assumption in 2015 was that VTL1 components -- securekernel.exe, skci.dll, LsaIso.exe, and the hypervisor binaries hvix64.exe and hvax64.exe -- were loaded from on-disk files using CBS+catalog trust, and that CBS+catalog trust was version-agnostic. Microsoft was building a higher trust boundary, but the integrity check for the binaries that lived on the other side of that boundary still ran through the Vista contract.

Generation 4: The Microsoft Vulnerable Driver Blocklist (2020 opt-in, default-on November 2022)

The fourth wall finally introduced a generic version-revocation primitive for kernel-loaded code. The Microsoft Vulnerable Driver Blocklist was the answer to a class of attacks that had emerged in the 2010s: bring-your-own-vulnerable-driver, where a malware loader installed a legitimately-signed, third-party driver with a known kernel exploit and used it as a bridge to kernel execution [19]. The blocklist's Microsoft Learn page is direct about scope: the policy targets non-Microsoft-developed drivers across the Windows software environment, and since the Windows 11 2022 update the blocklist is enabled by default for all devices [20].

Read that sentence again, slowly. Non-Microsoft-developed drivers. The blocklist is the right mechanism -- a Microsoft-signed list of hashes of known-vulnerable signed binaries that the kernel refuses to load -- but it is pointed at the wrong inventory. First-party Microsoft binaries, including the very VBS components VBS depends on, are out of scope. The same Microsoft team that built the only generic version-revocation primitive Windows ships chose, by policy, not to apply it to themselves.

Ctrl + scroll to zoom
Each generation of Windows file-integrity protection added a property the previous one lacked, but only the Driver Block List added a version-revocation primitive -- and it was scoped to third-party kernel code.

By 2022, Microsoft had built every primitive a Downdate defence would have used. A Microsoft-signed hash-revocation list (the Driver Blocklist). A firmware-rooted enforcement chain (Secure Boot + dbx). A hypervisor-isolated integrity check (HVCI inside VTL1). What had not been built was a first-party hash-revocation list -- one that named the historical versions of ci.dll, ntoskrnl.exe, securekernel.exe, hvix64.exe, and LsaIso.exe and refused to load them.

Recall the thesis from §1: every Microsoft mitigation since 2015 implicitly assumes the OS being protected is the current one. The mechanism for declaring it -- hash revocation -- had existed since 2012, but it was always pointed at somebody else's code. The Driver Blocklist proves Microsoft can ship a first-party hash-revocation list. It just had not been pointed inward.

So Microsoft had built every primitive it needed by 2022: a hash-revocation list, a firmware-rooted enforcement chain, a hypervisor-isolated integrity check. Why, in 2024, is a fully-patched Windows 11 machine still capable of loading a 2022 ci.dll?

5. The Breakthrough -- Where the Integrity Boundary Moves

Leviev started with a simple specification. He wanted a downgrade that satisfied four properties [1]:

  • Undetectable by endpoint security tooling.
  • Invisible in winver, Settings, and the system's own self-reported state.
  • Persistent across future Windows Update installations.
  • Irreversible by sfc /scannow, DISM /Online /Cleanup-Image /RestoreHealth, and other repair tooling.

The "undetectable" requirement disqualified almost every obvious approach. Disabling Authenticode checking is detectable. Replacing the catalog signing root is detectable. Booting into Safe Mode and overwriting files is detectable. Loading a vulnerable driver is detectable. Whatever the attack ended up looking like, it had to run through the legitimate Windows Update path, because that path is the one EDR is least suspicious of.

Reading Leviev's August 2024 SafeBreach write-up is a study in patient state-machine reverse engineering. He had to discover the architecture of CBS, where TrustedInstaller fits into it, how pending.xml action lists are written, where the integrity boundary of each phase lies, and which registry values are TrustedInstaller-protected versus which are merely Administrator-protected. Most of the answer turned out to be hidden in plain sight.

The Windows Update state machine

A Windows Update flows through a small state machine, and Leviev's contribution is to draw it precisely.

A client process in Administrator context calls into the Windows Update Agent COM interfaces. Those interfaces transfer the update folder -- a Microsoft-signed package containing a .cat, several .mum and .manifest files, and the new payload binaries -- to a TrustedInstaller-context server (TrustedInstaller.exe). The server verifies the catalog signature, walks the manifests, and constructs an action list. The action list is the work order that explains exactly which files will be renamed, hardlinked, deleted, or written, and which registry values will be set, when the system reboots. Microsoft stores it in a file called pending.xml under a TrustedInstaller-only directory (C:\Windows\WinSxS\pending.xml) [@safebreach-2024-aug; @ms-learn-servicing-stack-updates].

On reboot, before the user logs in, a small program named poqexec.exe reads pending.xml and applies it. POQ stands for "Primitive Operations Queue." The program is the post-reboot transactional engine that performs work the running OS could not safely do while it was running (such as overwriting ntoskrnl.exe).

poqexec.exe

The post-reboot primitive-operations-queue executor. Reads the action list (pending.xml) at next boot, before normal services start, and applies its verbs -- hardlinks, file moves, registry writes -- to complete the previous boot's pending update operations. poqexec.exe has no notion of "current version" versus "older version"; it executes whatever action list its configuration points it at.

So far, nothing is wrong. The catalog is signed. The manifests are catalog-covered. The action list lives in a TrustedInstaller-only directory. The executor that consumes it is part of the Windows servicing stack. The chain of custody runs from Microsoft's signing key through to the on-disk binaries the executor produces.

The action list integrity model -- and where it breaks

The catch is this. The pointer to pending.xml is not in a TrustedInstaller-only registry key. It is in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Configuration\PoqexecCmdline. The DACL on that value allows Administrator write. There is a parallel value, HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PendingXmlIdentifier, that carries a nonce binding the action list to the boot-session identity; that value is also Administrator-writable [@safebreach-2024-aug; @splunk-downdate-detection].

Action list / pending.xml

The XML work order that describes the file and registry operations a Windows Update will apply at next boot. It uses a small set of POQ verbs (HardlinkFile, MoveFile, CreateFile, SetFileInformation, DeleteFile, CreateDirectory, CreateKey, SetKeyValue, SetKeySecurity, DeleteKeyValue, DeleteKey). The default copy lives in a TrustedInstaller-only directory. Which copy poqexec.exe parses on next boot is determined by an Administrator-writable registry value, PoqexecCmdline.

The Administrator who initiates an update can choose which action list poqexec.exe parses. The integrity check on the update folder happened at the start of the transaction, in a different phase, with TrustedInstaller doing the parsing. Once the action list has been produced, the chain of custody depends on Windows believing that pending.xml came from a Microsoft-signed package. The mechanism by which Windows believes that is a registry value that an Administrator can rewrite.

Differential update files are not individually signed -- their hashes appear in the catalog-covered manifest, so they inherit catalog trust by reference. This is a perfectly sensible design if you also assert that the manifest you are using is the manifest for the latest update, which Windows does not.

That is the architectural error, and it has a name. The integrity boundary moves between phases of the update. The update folder is verified pre-action-list-creation. The action list is verified by being in a TrustedInstaller directory. But the pointer to the action list is in admin-writable territory. The same identity (Administrator) that can legitimately initiate an update can choose which action list poqexec.exe parses, and poqexec.exe was never built to ask "is this list the one I made?"

Ctrl + scroll to zoom
The legitimate Windows Update flow (top) and the Windows Downdate variant (bottom), diverging at the registry pivot. The crafted action list lives in attacker-writable storage; PoqexecCmdline points poqexec.exe at it instead of the TrustedInstaller-protected copy.

Once you can choose which action list poqexec.exe parses, and poqexec.exe was never built to ask "is this list the one I made?", the consequences write themselves. The crafted pending.xml can issue any verb the executor supports. It can hardlink an older ci.dll over the current one. It can hardlink an older ntoskrnl.exe over the current one. It can hardlink an older securekernel.exe over the current one. The hashes of those older files appear in the Microsoft-signed catalogs of their original packages, which are still on disk in WinSxS. Every signature the kernel loader and the Secure Kernel will ever check resolves to a Microsoft key.

The bug is structural: the integrity boundary moves between phases of the update. The catalog signature verifies one phase; the directory ACL verifies the next; the registry pointer crosses the boundary in the wrong direction. The fix has to declare a new boundary that does not move.

6. The Downdate Attack End-to-End

What does python windows_downdate.py --config-xml downgrade.xml actually do on the wire? The tool's GitHub repository, SafeBreach-Labs/WindowsDowndate, ships a documented schema and eight example chains, from a generic ItsNotASecurityBoundary-Patch-Downgrade to a fully-formed VBS-UEFI-Locks-Bypass [21]. Read alongside Leviev's blog, the procedure is, in machine terms, embarrassingly small. Eight steps.

6.1 The attack sequence

  1. Parse the config XML. Each <UpdateFile source="..." destination="..."/> element names one file to downgrade. If the source file does not exist locally, the tool retrieves the base version from the WinSxS component store [21].
  2. Build a crafted pending.xml. For each target, emit a <HardlinkFile> verb that creates a hardlink from the older file's location to the current file's location, plus the other POQ verbs needed to set ACLs, register the new file with the component store, and update the on-disk manifest hash where needed.
  3. Deposit pending.xml in an attacker-writable directory. The Administrator does not need TrustedInstaller-write privilege to do this; the tool stores the crafted action list outside the TrustedInstaller-only directories.
  4. Compute a matching PendingXmlIdentifier nonce. This is the value that poqexec.exe cross-checks against the action list at parse time.
  5. Write the two registry values. PoqexecCmdline is set to point at the attacker's pending.xml. PendingXmlIdentifier is set to the nonce computed in step 4.
  6. Trigger a reboot. This can be a graceful shutdown /r /t 0 or any reboot-causing event.
  7. At next boot, poqexec.exe reads PoqexecCmdline and parses the attacker pending.xml. It applies the verbs in order. The current ci.dll is replaced (via hardlink) with 10.0.22621.1376. The current ntoskrnl.exe is replaced with whichever version the operator chose. The current securekernel.exe is replaced. The current hvix64.exe is replaced. The current LsaIso.exe is replaced.
  8. Persistence and irreversibility. Two further verbs replace poqexec.exe with a patched copy that NOPs future updates, and replace sfc.exe with a patched copy that does not flag the downgraded files. Leviev's claim in the SafeBreach blog is that poqexec.exe and sfc.exe are not Authenticode-signed in the affected builds, so substituting modified versions does not require a code-signing bypass [1].
The full set of POQ XML verbs that poqexec.exe understands, taken from Leviev's documentation: HardlinkFile, MoveFile, CreateFile, SetFileInformation, DeleteFile, CreateDirectory, CreateKey, SetKeyValue, SetKeySecurity, DeleteKeyValue, and DeleteKey. The verb that does most of the work in a Downdate is HardlinkFile, because it lets the attacker replace a file in System32 without ever calling WriteFile against a TrustedInstaller-owned path.
Ctrl + scroll to zoom
The Windows Downdate attack sequence end-to-end: from the operator's config XML through the registry pivots, the reboot, and the next-boot execution of the crafted action list by poqexec.exe.

6.2 What got downgraded

Each Downdate target is a different layer of the threat model.

Afd.sys is the Ancillary Function Driver -- a kernel-mode networking driver. In the Black Hat USA demo, Leviev paired the Downdate of Afd.sys with CVE-2023-21768 to demonstrate Administrator-to-kernel code execution on a fully patched Windows 11 system [21].

ntoskrnl.exe is the NT kernel image itself. Downgrade to a build with a public elevation-of-privilege chain and the resulting kernel is still Microsoft-signed but is also still vulnerable.

securekernel.exe is the VTL1 Secure Kernel. It is the keystone of VBS: the Secure Kernel is what HVCI and Credential Guard rely on for isolation. Replace it with an older build that contains a kernel-side bug, and every protection that runs in VTL1 is now running on top of compromised infrastructure.

hvix64.exe and hvax64.exe are the Intel and AMD Hyper-V hypervisor binaries. Downgrade the hypervisor and the entire VBS trust root has moved beneath you.

LsaIso.exe is the Credential Guard Isolated User Mode trustlet [18]. It holds the LSA secrets that Credential Guard protects. An older LsaIso.exe is, by Microsoft's own threat model, a known-bad binary running inside the security-feature-of-record.

ci.dll is the keystone of the October 2024 follow-up. The kernel-mode Code Integrity module enforces DSE: it is the gate that asks "is this driver signed?" Roll it back to 10.0.22621.1376 and Gabriel Landau's False File Immutability bypass works again on a fully-patched Windows 11.

6.3 Bypassing VBS UEFI locks without physical access

Microsoft's "VBS UEFI lock" feature, intended to be the strongest configuration of VBS, copies the VBS configuration registry settings into a UEFI non-volatile, boot-services-only variable called VbsPolicy [17]. Once set, the lock survives reboots, reinstalls, and most ordinary attacks against the registry, because the firmware re-applies it on every boot. Before Windows Downdate, the canonical advice for the highest-security configuration was: turn on VBS with the UEFI lock. The lock was the moat.

Leviev's framing of what he showed was direct: "to my knowledge, this is the first time VBS's UEFI locks have been bypassed without physical access" [1].

"To my knowledge, this is the first time VBS's UEFI locks have been bypassed without physical access." -- Alon Leviev, SafeBreach Labs, August 2024 [1]

The mechanism is the cleanest possible illustration of the architectural error. The UEFI lock pins configuration (VbsPolicy). It does not pin implementation (securekernel.exe, hvix64.exe, LsaIso.exe, ci.dll). Downgrade the implementation and the configuration is still happy. From Windows's point of view, VBS is on, the lock is engaged, the configuration variable is in firmware, everything checks out. The components doing the actual work are simply not the ones the configuration was checked against. Nobody asked it to check.

6.4 ItsNotASecurityBoundary, revived

On May 14, 2024, Microsoft shipped KB5037771 for Windows 11 22H2 and 23H2 [22]. The preview build had landed on April 23, 2024 as KB5036980. The fix closed a False File Immutability TOCTOU on ci.dll that Gabriel Landau of Elastic Security Labs had disclosed in February [23]. Landau's exploit, which he titled ItsNotASecurityBoundary, used the FFI race to swap an Authenticode catalog mid-verification, getting an unsigned driver loaded with Microsoft's blessing.

False File Immutability (FFI)

A bug class identified by Gabriel Landau (Elastic Security Labs) in 2024. Windows treats files mapped as SEC_IMAGE as immutable while a view exists, but the kernel does not always honor that immutability across separate reads of the same file. A verifier that reads the file, then re-reads it after a working-set flush, can be served different bytes the second time. On Authenticode catalogs, this becomes a TOCTOU race that lets the attacker swap the catalog between the verifier's read and the loader's load.

The October 26, 2024 SafeBreach follow-up [24], titled An Update on Windows Downdate, combined the two. It used Windows Downdate to roll ci.dll back to the pre-May build (10.0.22621.1376) and re-enabled the FFI bypass on a fully patched Windows 11 23H2 machine [25]. The Hacker News confirmed the chain: "The DSE bypass is achieved by making use of the downgrade tool to replace the 'ci.dll' library with an older version (10.0.22621.1376) to undo the patch put in place by Microsoft" [25]. The name of Landau's exploit became, in retrospect, the most pointed commentary on Microsoft's servicing policy that anyone has written.

"ItsNotASecurityBoundary's name is an homage to MSRC's policy that 'Administrator-to-kernel is not a security boundary.'" -- Gabriel Landau, Elastic Security Labs [22]

6.5 What Microsoft shipped, and when

Microsoft's response unfolded over roughly eleven months. Here is the cadence, anchored to the canonical KB and CVE pages.

DateEventSource
Aug 7, 2024CVE-2024-21302 and CVE-2024-38202 published; Black Hat USA 2024 talk[@nvd-cve-2024-21302; @nvd-cve-2024-38202; @safebreach-2024-aug]
Aug 11, 2024DEF CON 32 talk[1]
Aug 13, 2024KB5042562: opt-in SkuSiPolicy.p7b revocation policy with optional UEFI lock, plus default-enabled boot-session CI policy on Win10 1507+[26]
Oct 8, 2024KB5044284: substantive code fix for CVE-2024-38202 in Windows 11 24H2 (OS Build 26100.2033); per-SKU equivalents on the same date[@kb5044284; @nvd-cve-2024-38202]
Oct 26, 2024SafeBreach follow-up "An Update on Windows Downdate" -- ItsNotASecurityBoundary revival via ci.dll downgrade[@safebreach-2024-oct; @thehackernews-downdate]
Jul 8-10, 2025CVE-2024-21302 mitigations completed across Windows 10 1507, 1607, 1809, Windows Server 2016, and Windows Server 2018[27]

KB5042562 is the more interesting of the two artifacts. It introduces two mechanisms.

The first is an opt-in SkuSiPolicy.p7b policy: an administrator copies the Microsoft-signed .p7b file from %windir%\System32\SecureBootUpdates\ to the EFI System Partition's \EFI\Microsoft\Boot\ directory; on boot, Windows reads the policy and refuses to load any binary whose version is listed as revoked [26].

The second is a default-enabled boot-session CI policy that ships to every Windows 10 1507+ device and, per the KB, "will be loaded during boot and the enforcement of this policy will prevent rollback of VBS system files during that boot session" [26]. On Windows 11 24H2 and Server 2022/23H2, DRTM (Dynamic Root of Trust for Measurement) binds the VBS-protected encryption keys to the policy version, so a downgraded boot does not unseal the keys.

SkuSiPolicy.p7b

A Microsoft-signed Code Integrity policy file shipped in KB5042562 that lists revoked versions of VBS system files (securekernel.exe, hvix64.exe/hvax64.exe, LsaIso.exe, ci.dll, and others). When deployed to the EFI System Partition with the optional UEFI lock, it survives reformats and binds version-revocation enforcement to a Microsoft signature in firmware-stored state.

DRTM (Dynamic Root of Trust for Measurement)

A trusted-launch mechanism, available on Windows 11 24H2 and Server 2022/23H2, that uses CPU SMI / SKINIT instructions to establish a measured execution environment after the OS has begun booting. In KB5042562's context, DRTM binds Virtual Secure Mode's protected encryption keys to the version of the active CI policy, so a rolled-back boot session cannot unseal the keys.

JavaScript The shape of a Windows Downdate config XML (illustrative; does not perform a downgrade)
// Simulate the construction of the WindowsDowndate config XML for a ci.dll downgrade.
// This shows the structure the tool consumes, not the action list it emits.
// Nothing here writes to a real system or runs a real attack.

const configEntries = [
{
  source: "C:\\Windows\\WinSxS\\amd64_microsoft-windows-codeintegrity_31bf3856ad364e35_10.0.22621.1376_none\\ci.dll",
  destination: "C:\\Windows\\System32\\ci.dll",
  component: "Code Integrity (kernel DSE enforcement)",
  targetVersion: "10.0.22621.1376",
  rationale: "Pre-May-2024 build, before the FFI/ItsNotASecurityBoundary fix"
}
];

function buildConfigXml(entries) {
const lines = ['<?xml version="1.0"?>', '<UpdateConfig>'];
for (const e of entries) {
  lines.push(
    '  <UpdateFile source="' + e.source + '"',
    '              destination="' + e.destination + '" />'
  );
}
lines.push('</UpdateConfig>');
return lines.join('\n');
}

const xml = buildConfigXml(configEntries);
console.log(xml);

// What the tool would emit into the crafted pending.xml on next boot:
console.log('\nResulting POQ verb (illustrative):');
console.log('  <HardlinkFile source="' + configEntries[0].source + '"');
console.log('                destination="' + configEntries[0].destination + '" />');

Press Run to execute.

The mitigation does not patch the primitive. It patches the components Leviev demonstrated against, one at a time, with a Microsoft-signed list of historical hashes. That choice is deliberate, and the next two sections are about why.

7. Competing Approaches -- How Other Platforms Closed the Gap

Android made the opposite design decision in 2017. Apple did so in 2020. The TLS working group did so in 2018. The IETF SUIT working group did so in 2021. By the time Leviev presented at Black Hat USA 2024, every major adjacent platform had treated rollback as a primary threat and shipped a structural fix. Windows was the outlier.

Android Verified Boot 2.0: per-partition rollback indices

AVB stamps a 64-bit rollback_index into the signed footer of each partition. On each successful boot of a partition image, the bootloader updates a per-slot stored maximum in TrustZone or in eMMC Replay Protected Memory Block storage. On the next boot, the bootloader refuses any image whose rollback_index is below the stored maximum [@aosp-avb; @avb-readme].

The check happens in firmware, before the kernel loads. There is no opt-in. There is no enterprise toggle. There is no operational risk warning about the lock being irreversible. The rollback index is a structural part of the trust architecture, not a policy file that ships through the same update channel that an attacker would compromise.

Apple Sealed System Volume: a Merkle seal over the OS

Apple's Signed System Volume (Big Sur, November 2020) takes the Android approach and pushes it further. SSV computes a SHA-256 hash of every file in the system volume, builds a Merkle tree over those hashes, and signs the root with an Apple key [9].

The Apple Platform Security guide describes it precisely: "SSV features a kernel mechanism that verifies the integrity of the system content at runtime and rejects any data -- code and noncode -- without a valid cryptographic signature from Apple" and "Each SSV SHA-256 hash is stored in the main file-system metadata tree, which is itself hashed. Because each node of the tree recursively verifies the integrity of the hashes of its children -- similar to a binary hash (Merkle) tree -- the root node's hash value, called a seal, encompasses every byte of data in the SSV" [9]. On iOS and iPadOS, "Users aren't allowed to turn off the protection of a signed system volume" [9]. The check is structural and mandatory.

IETF SUIT: rollback in the IoT firmware threat model

RFC 9019 standardised the firmware-update threat model the IoT industry now treats as canonical. The document does not mince words: "The firmware image is authenticated and integrity protected. Attempts to flash a maliciously modified firmware image or an image from an unknown, untrusted source must be prevented" [10]. The Update Framework's CCS 2010 paper and its present-day specification share the same vocabulary: "Rollback attacks. An attacker presents files to a software update system that are older than those the client has already seen. With no way to tell it is an obsolete version that may contain vulnerabilities, the user installs the software" [7]. TUF, now a CNCF graduated project, is the academic-canonical reference [28].

TLS 1.3: rollback baked into the protocol

The protocol world's answer is in RFC 8446 section 4.1.3 [4]. A TLS 1.3 server that detects a downgrade attempt -- a client that supports TLS 1.3 but is being routed through a man-in-the-middle that strips it back to TLS 1.2 -- writes a specific magic constant into the last 8 bytes of ServerHello.random. A genuine TLS 1.3 client, completing the handshake, checks those bytes and aborts the connection if the magic is present. The integrity check is bound into the transcript hash, so a network attacker cannot rewrite it without breaking the handshake. The mitigation is part of the protocol, not a guideline operators can apply.

Ctrl + scroll to zoom
Where each platform stores its version-monotonicity state. Windows is the only major modern platform whose rollback defence (SkuSiPolicy.p7b) is shipped through the same update channel as the components it protects -- with an opt-in UEFI lock as the only structural anchor.

The differences between these designs are not cosmetic. They are decisions about where the rollback state lives and who is authorised to write it. Read the table below row by row and the contrast is uncomfortable.

DimensionWindows SkuSiPolicy.p7bAndroid AVB 2.0Apple SSVIETF SUITTUFTLS 1.3
InitiationOpt-in (strong) / default-enabled (boot-session)MandatoryMandatoryAdopter-definedAdopter-definedMandatory
Protected unitPer-component hash listPer-partition signed imageWhole system volumePer-firmware imagePer-package metadataPer-handshake nonce
Version-state storageEFI System Partition + optional UEFI lockTEE / RPMB rollback indexSecure Enclave / signed rootDevice-side specSnapshot + timestamp rolesIn-protocol
Hardware-root bindingOptional via UEFI lock; DRTM on Win11 24H2+TrustZone / RPMBApple silicon / T2Spec abstractSpec abstractNone required
Coverage gapsFirst-party components not in the policy still loadSlots not covered by AVBNone on iOS/iPadOS; SSV must remain on macOSAdopter-definedOut-of-spec metadata rolesNone within scope

Every other major platform's modern update architecture treats rollback as a primary threat baked into the trust architecture. Windows treats it as a privilege-boundary question -- and the answer it picked, "Administrator-to-kernel is not a security boundary," excludes the most common attacker.

If Apple, Google, and the IETF have all figured out the answer, why hasn't Microsoft?

8. Theoretical Limits -- "Admin-to-Kernel Is Not a Boundary"

Microsoft's answer is that they have no need to.

8.1 The Microsoft position

The Windows Security Servicing Criteria is the public document where Microsoft enumerates which Windows interfaces it treats as security boundaries [29]. The document defines the concept: a security boundary provides a logical separation between the code and data of security domains with different levels of trust, with kernel-mode versus user-mode as the canonical example.

It then asks the servicing test: "Does the vulnerability violate the goal or intent of a security boundary or a security feature?" [29]. If the answer is yes, Microsoft commits to ship a security update. If the answer is no, the issue can still be fixed -- in a quality update, in a refactor, in a future feature -- but it does not get a CVE and the standardised servicing cadence does not apply.

The boundaries Microsoft enumerates in that document include network boundaries (machine-to-machine), kernel-mode-to-user-mode separation, hypervisor-to-VM separation, and several others. Administrator-to-kernel is not on the list. By the document's own logic, an Administrator who reaches kernel code execution has not crossed a boundary, because the document does not declare a boundary there for them to cross. That is the policy position Landau's exploit title was named after.

The two CVEs that were assigned are the boundary-crossing parts of the chain.

CVE-2024-21302 is the Secure Kernel Mode Elevation of Privilege (VTL0-to-VTL1) -- a downgrade-induced compromise of securekernel.exe does cross a defined boundary, because the kernel-to-Secure-Kernel separation is on the list [27]. CVE-2024-38202 is the basic-user-to-Administrator elevation via the restore-point flow -- a basic user induced into authorising a system restore can be parked into a state that triggers a downgrade, which crosses the user-to-admin boundary [30]. Both CVEs were assigned and patched from August 7, 2024 onward; CVE-2024-38202 received its substantive code fix on October 8, 2024 [@kb5044284; @nvd-cve-2024-38202].

Leviev quoted Microsoft's framing of this distinction in his October 2024 follow-up:

"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, summarising the Microsoft position, October 2024 [24]

8.2 The internal tension

That position has an obvious problem. The VBS documentation says VBS assumes the kernel can be compromised [16]. The Secure Kernel exists because the NT kernel is, in the threat model VBS publishes, untrusted. If the kernel is the attacker, then anyone who can compromise the kernel is the attacker VBS is designed to mitigate. On a single-user Windows machine, the obvious path to kernel compromise is to be an Administrator and load a vulnerable signed driver, or to be an Administrator and exploit a kernel race, or to be an Administrator and downgrade ci.dll.

Leviev makes the point directly in the same blog post: "the reason VBS was created is because the kernel is assumed compromised, and there was a need for a secure place to implement security features" [1]. If the kernel is assumed compromised in VBS's threat model, then the Administrator who can compromise the kernel is precisely the attacker VBS was built to mitigate -- which makes Microsoft's servicing-criteria position and VBS's threat model load-bearing on opposite sides of the same boundary.

This is the article's most argumentative sentence: the position is not a security decision (the primitive is not a vulnerability) but a resourcing decision (we will not CVE the primitive, but we will harden it). The per-component SkuSiPolicy.p7b rollout, the default-enabled boot-session CI policy, DRTM on Win11 24H2+, and the multi-quarter cleanup across Windows 10 1507 through Windows Server 2018 are exactly what one would expect from an organisation patching a class one component at a time, while declining to declare the class.

8.3 What a hardened position would look like

The fixes are not conceptually hard. Microsoft could:

  1. Sign poqexec.exe and sfc.exe with HVCI-enforced integrity. That removes the persistence and irreversibility steps of the chain.
  2. Move PoqexecCmdline under a TrustedInstaller-only DACL with a UEFI-bound mirror. That removes the registry pivot.
  3. Introduce a monotonic update-generation counter in the TPM, bound to a transcript hash of the cumulative-update history, consulted by the boot manager and the Secure Kernel. That is the architectural fix -- the version of the answer Apple and Android shipped.

The current SkuSiPolicy.p7b mechanism is the first step on the third path. It is per-component and opt-in for the strong variant, but the conceptual shape is right: a Microsoft-signed list of historical hashes, consulted by the kernel loader, with a UEFI-bound anchor for the strong configuration [26]. The work is real, and it is well-executed within the constraints Microsoft has set itself. The question is whether the constraints will give. Whether the policy will eventually cover every Microsoft-shipped binary with a known EoP. Whether the strong variant will become the default. Whether Administrator-to-kernel will be declared a security boundary in the published criteria.

These are not conceptually hard. They are organisationally hard, because they require Microsoft to ship a new security boundary, declared as such, after declining to do so for nearly two decades.

9. Open Problems -- What the August 2024 Cadence Left Open

If you are reading this in 2026, the parts of Windows Downdate that Microsoft chose to call vulnerabilities have been patched. The parts they chose not to call vulnerabilities are exactly as exploitable today as they were on August 7, 2024.

The general primitive remains. The Administrator-context modification of PoqexecCmdline is, by Microsoft's stated policy, intentionally unpatched [24]. Every cumulative update Microsoft ships will continue to flow through the same servicing-stack path that Leviev hijacked, because that path is the path everything else depends on. The fix has to come from somewhere else.

Components not yet in the revocation policy

SkuSiPolicy.p7b covers the VBS-protected components Leviev demonstrated against -- securekernel.exe, hvix64.exe, hvax64.exe, LsaIso.exe, ci.dll, and others. It does not cover every Microsoft-shipped DLL or driver with a public EoP history [26]. Each Microsoft binary outside the policy that has a known kernel-relevant vulnerability is, in principle, a Downdate target. The inventory is open. Microsoft does not publish "the set of historical hashes of ntoskrnl.exe that we consider unsafe to load" -- and the absence of that list is the absence of the version-monotonicity boundary at scale.

Hot Patching as a parallel servicing surface

Hot Patching is the Windows servicing variant that applies code-level updates to running processes without a reboot. It reached general availability on Windows Server 2022 Datacenter: Azure Edition in February 2022 (Server Core) and July 2023 (Desktop Experience), and on Windows 11 Enterprise 24H2 in April 2025 via Microsoft Autopatch and Intune [@msdocs-hotpatch-server; @msdocs-hotpatch-win11].

Its threat model is forward-delta application: how do we apply a code patch to a running binary safely? It does not consider rollback prevention as a separate concern. Whether the hot-patch path admits its own rollback primitive -- whether you can roll back a hot patch, restoring the older code into the running process, by abusing the hot-patch infrastructure the same way Downdate abuses CBS -- is an open question that nobody has publicly answered.

WinRE as adjacent surface

Leviev's Black Hat USA 2025 talk, with Netanel Ben Simon of Microsoft's MORSE team, did not extend Downdate. It went sideways. BitUnlocker: Leveraging Windows Recovery to Extract BitLocker Secrets targeted the Windows Recovery Environment, demonstrating four CVEs that together permit a physical-access attacker to extract BitLocker keys from the WinRE servicing surface [@itnews-bitunlocker; @infocondb-defcon33-bitunlocker]. The bugs were patched in the July 2025 Patch Tuesday cumulative updates.

Alon Leviev now works on the Microsoft Offensive Research and Security Engineering (MORSE) team alongside Netanel Ben Simon. Leviev's institutional follow-up to Downdate is therefore happening from inside Microsoft -- a notable signal about how seriously Microsoft is taking the surface even as it declines to declare the boundary [31].

Two revocation policies, one product

The Microsoft Vulnerable Driver Blocklist (for third-party kernel code) and SkuSiPolicy.p7b (for first-party VBS system files) are two separate revocation policies that ship on different cadences, in different formats, and through different update channels. The Driver Blocklist updates quarterly and via monthly cumulative updates [20]; SkuSiPolicy.p7b is shipped as part of major mitigation rollouts and is opt-in for the strong variant [26]. Whether Microsoft unifies them -- whether the eventual answer is one unified hash-revocation policy covering all kernel-loaded code, Microsoft-shipped or not -- is an open architectural question.

Linux desktop coverage

The image-based Linux distributions (Fedora Silverblue, Ubuntu Core, openSUSE MicroOS) have all moved toward AVB-style or SSV-style architectures. Classical dpkg- and rpm-based distributions have not. Apt's package authentication is signature-based and largely version-aware via the Release file's Date and Valid-Until headers, but the security guarantees rely on a trusted repository and a TUF-style snapshot role that most distributions do not yet ship. The Windows lesson generalises: any update mechanism that can write into a higher-privilege domain has to enforce version monotonicity in the same domain that performs the write.

There is one open problem the rest depend on. Will Microsoft declare a version-monotonicity security boundary? The answer to that question -- whether by a future revision of the Windows Security Servicing Criteria, by a default-on Mandatory flag, by an exhaustive first-party Driver Block List equivalent, or by something nobody has prototyped yet -- is the substantive resolution of the story. The August 2024 patches were not it.

10. A Practical Guide for Defenders, Detection Engineers, and System Designers

Three audiences, three concrete tracks.

10.1 Defenders

If you operate Windows 10 or 11 endpoints, the first thing to do is apply the cumulative updates that contain the substantive code fix for CVE-2024-38202. On Windows 11 24H2, that is KB5044284 (October 8, 2024, OS Build 26100.2033) [32]. On older SKUs, the equivalent updates landed on the same date or in the multi-quarter sweep that completed July 8-10, 2025 across Windows 10 1507, 1607, 1809, Server 2016, and Server 2018 [27]. Apply them in your normal patch ring with no special handling.

The second thing to do is keep HVCI / memory integrity enabled so the default-enabled boot-session CI policy and the Vulnerable Driver Blocklist both fire [@msdocs-driver-blocklist; @msdocs-vbs-hvci]. On Windows 11 22H2 and later, both are on by default. On older SKUs, they are not, and the gap is meaningful.

The third thing -- the one that requires care -- is to consider deploying SkuSiPolicy.p7b with the optional UEFI lock where your operational risk tolerance allows.

Finally: the VBS "Mandatory" flag (HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Mandatory) is the only configuration Leviev has not bypassed [24]. Set it where boot reliability is acceptable and you have rehearsed the recovery procedure (SecConfig.efi to delete the lock, the flag set, the lock re-enabled). Inventory the count of Administrator accounts on each machine -- the Downdate primitive's blast radius is bounded by the number of identities that can write PoqexecCmdline. Every reduction in that count is a direct reduction in the attack surface.

10.2 Detection engineers

The detection signature is the registry pivot. Authenticode-based file-integrity tooling will not catch Windows Downdate, because the downgraded files are legitimately Microsoft-signed [1]. The Splunk Security Content windows_downdate_registry_activity analytic is the canonical reference detection [33]. The logic is:

  • Consume Sysmon EventIDs 12, 13, and 14 (Registry creation, set-value, and rename).
  • Match TargetObject against *PoqexecCmdline or *COMPONENTS\PendingXmlIdentifier.
  • Suppress writes whose calling ProcessPath is under *:\Windows\WinSxS\* (the legitimate-update path).
  • Map to MITRE ATT&CK T1112 (Modify Registry, Defense Impairment) and T1689 (Downgrade Attack, Persistence/Exploitation/Installation).

The Splunk detection is disabled by default in Splunk Enterprise Security. Operators must enable it explicitly [33]. The point of attack on the EDR side is the registry pivot, not the file substitution -- the substitution looks like a normal update because, by every check Windows performs, it is one.

JavaScript The shape of a registry-pivot detection (illustrative; logic only)
// Demonstrates the decision logic of the windows_downdate_registry_activity detection.
// Not a real Sysmon parser -- the inputs would be Event 12/13/14 records in production.

function isLegitimateUpdatePath(processPath) {
// Legitimate Windows Update operations run under WinSxS.
return processPath.toLowerCase().includes('\\windows\\winsxs\\');
}

function classifyRegistryWrite(event) {
const sensitiveValues = [
  'PoqexecCmdline',
  'COMPONENTS\\PendingXmlIdentifier'
];

const matchesSensitive = sensitiveValues.some(v =>
  event.TargetObject.endsWith(v)
);

if (!matchesSensitive) return 'ignore';
if (isLegitimateUpdatePath(event.ProcessPath)) return 'allow';
return 'alert';
}

const sample = [
{ TargetObject: 'HKLM\\...\\PoqexecCmdline', ProcessPath: 'C:\\Windows\\WinSxS\\amd64_x\\TrustedInstaller.exe' },
{ TargetObject: 'HKLM\\...\\PoqexecCmdline', ProcessPath: 'C:\\Users\\alice\\Desktop\\windows_downdate.exe' },
{ TargetObject: 'HKLM\\...\\COMPONENTS\\PendingXmlIdentifier', ProcessPath: 'C:\\tools\\suspicious.exe' }
];

for (const ev of sample) {
console.log(classifyRegistryWrite(ev), '<-', ev.ProcessPath);
}

Press Run to execute.

A more aggressive detection variant

The Splunk detection only watches the two registry pivots. A more aggressive variant also watches for unexpected pending.xml files appearing outside C:\Windows\WinSxS\ and for file integrity changes against expected hashes of poqexec.exe and sfc.exe. The trade-off is false positives: enterprise patch tooling and configuration-management agents touch the servicing path more often than you would expect, and an aggressive variant requires tuning before it is fleet-ready.

10.3 System designers

If you are building a new operating system in 2026, you do not have an excuse. The architectural takeaway from Windows Downdate is general: any update mechanism that can write into a higher-privilege domain must enforce version monotonicity in the same domain that performs the write. If the update is processed by a TrustedInstaller-context service, version monotonicity has to be enforced by TrustedInstaller (or by something even further from the attacker -- the boot manager, the firmware, the TPM). If the version-state pointer lives in a registry value an Administrator can rewrite, the boundary moves and the design is broken.

Concrete reference patterns are available:

  • TPM-stored generation counters. Bind the counter to a transcript hash of the cumulative-update history; the boot manager and Secure Kernel refuse to load components older than the stored counter [28]. This is the Apple SSV / Android AVB pattern translated into Windows-shaped trust roots.
  • Monotonic catalog versions. Sign the per-component catalog with an explicit <min-version> field; the kernel loader refuses to load any catalog whose <min-version> is below the loader's stored maximum. This is the TUF snapshot-role pattern [28].
  • In-protocol monotonicity at the update edge. Use the IETF SUIT envelope format and the seq-num field defined in RFC 9019 [10]. The receiver tracks the highest sequence number it has seen and refuses lower ones at the spec level, not the policy level.

The reference designs exist. TUF [28], IETF SUIT [10], and AOSP AVB [8] are open. Pick one. Adapt it. Ship it. The hard part is not the engineering. The hard part is the institutional commitment to declaring a security boundary you did not declare last year.

If you are building a new OS in 2026, you do not have an excuse.

11. Misconceptions, Corrections, and What Comes Next

Windows Downdate spawned a press cycle that got several things wrong. Here is what is actually true.

Windows Downdate frequently asked questions

Was Windows Downdate fixed in November 2024 Patch Tuesday?

No. The substantive code fix for CVE-2024-38202 (the basic-user-induced restore-point variant) shipped on October 8, 2024 as KB5044284 for Windows 11 24H2 and OS Build 26100.2033, with per-SKU equivalents on the same date [@kb5044284; @nvd-cve-2024-38202]. The earlier mitigation guidance, KB5042562 (the opt-in SkuSiPolicy.p7b policy and the default-enabled boot-session CI policy), shipped on August 13, 2024 [26]. There is no November 2024 anchor. The multi-quarter cleanup across older SKUs completed July 8-10, 2025 [27].

Did Windows Downdate bypass Secure Boot?

No. Secure Boot bypass via downgrade is BlackLotus (CVE-2022-21894, "Baton Drop"), which used a vulnerable Microsoft-signed bootmgfw.efi that was not in the UEFI dbx revocation list [11]. Windows Downdate bypasses VBS UEFI locks and downgrades the VBS-protected components (securekernel.exe, hvix64.exe, LsaIso.exe, ci.dll) along with the NT kernel itself [1]. The two attacks operate at different layers: BlackLotus at the firmware/boot manager, Downdate at the OS component layer. The mechanism shape is similar; the targets are distinct.

Was Leviev's Black Hat USA 2025 follow-up called ItsNotASecurityBoundary?

No. ItsNotASecurityBoundary is Gabriel Landau's (Elastic Security Labs) exploit name for a False File Immutability TOCTOU on ci.dll, disclosed in early 2024 and patched in May 14, 2024 (KB5037771) with a preview build on April 23, 2024 (KB5036980) [@landau-itsnotasecurityboundary-repo; @elastic-ffi]. Leviev's October 26, 2024 SafeBreach follow-up revived Landau's exploit by using Windows Downdate to roll ci.dll back to the pre-May build [24]. Leviev's actual Black Hat USA 2025 talk, with Netanel Ben Simon, was BitUnlocker, on Windows Recovery Environment attacks -- patched in July 2025 Patch Tuesday [@itnews-bitunlocker; @infocondb-defcon33-bitunlocker].

Did Microsoft initially mark CVE-2024-21302 and CVE-2024-38202 as 'out of scope'?

No. Microsoft assigned and patched both CVEs from disclosure day (August 7, 2024) onward [@nvd-cve-2024-21302; @nvd-cve-2024-38202]. The position that Microsoft has taken is narrower: the underlying primitive (the Administrator-context modification of PoqexecCmdline that the Downdate technique relies on) has remained unpatched because it does not cross a defined security boundary in the published Windows Security Servicing Criteria [@safebreach-2024-oct; @msft-servicing-criteria]. The two assigned CVEs are the boundary-crossing parts of the chain. The unassigned primitive is the part that runs on each side of the boundary that nobody declared.

Is Authenticode broken?

No. Authenticode does what it says: it verifies that a binary was signed by a specific certificate (and that the certificate chains to a trusted root). The older ci.dll that Windows Downdate installs is legitimately signed by Microsoft. Authenticode never claimed to assert "and is the current version" -- it is a signature check, not a staleness check [@safebreach-2024-aug; @msdocs-driver-signing]. The mistake is in the design above Authenticode that treats signature validity as equivalent to current-version-validity, not in Authenticode itself.

Why isn't poqexec.exe signed?

Per Leviev's claim in the August 2024 SafeBreach blog, poqexec.exe is not Authenticode-signed in the affected Windows builds, and neither is sfc.exe [1]. The persistence step of Windows Downdate exploits this directly: replacing poqexec.exe with a patched copy that NOPs future updates does not require a code-signing bypass. The hardening suggested in section 8 -- sign both binaries, enforce HVCI on them -- removes the persistence and irreversibility steps, but signing alone is not sufficient: the PoqexecCmdline registry pivot survives signing, because the pivot points the legitimately signed poqexec.exe at an attacker-chosen action list.

Does Microsoft Defender or Defender for Endpoint catch this?

EDR coverage focuses on the known indicators: registry writes to PoqexecCmdline and PendingXmlIdentifier by processes that are not under C:\Windows\WinSxS\, and unexpected pending.xml files outside the TrustedInstaller-only directories [33]. The downgrade itself, once executed, is by design indistinguishable from a legitimate update at the file-signature layer. Whether a given EDR product has shipped a detection for the registry pivot is product-specific; the Splunk Security Content analytic referenced above is the cleanest published reference signature [33]. Microsoft Defender for Endpoint operators should verify with their account team that an equivalent detection is enabled in their tenant.

Microsoft built a security boundary in 2007 that depended on the assumption that updates only move forward. We now know they do not. The work of declaring the new boundary -- one component, one SKU, one cumulative update at a time -- is what Microsoft is doing right now. Whether the boundary will eventually be declared in the Windows Security Servicing Criteria, rather than implemented quietly as a per-component policy, is the question whose answer we will know in 2027.

For now, the lesson is portable. The shape of Windows Downdate generalises: every signed-update system needs a version-monotonicity primitive co-located with the trust root that enforces signatures. The reason it took until 2024 to demonstrate this on Windows is not that the bug was deep. It is that nobody, in eighteen years of Windows servicing engineering, had been asked to declare the boundary the bug crossed. Once Leviev asked the question, the answer wrote itself.

Study guide

Key terms

TrustedInstaller
A Windows security principal introduced in Vista that owns most system files. ACLs deny direct write to other principals, including Administrators.
Component-Based Servicing (CBS)
The Vista-era Windows servicing architecture that replaced self-extracting installers with manifest-and-catalog-driven transactions over a versioned component store (WinSxS).
poqexec.exe
The post-reboot Primitive Operations Queue executor. Reads pending.xml at next boot and applies its verbs (HardlinkFile, MoveFile, ...).
PoqexecCmdline
The Administrator-writable registry value that tells poqexec.exe which pending.xml to parse on next boot. The Windows Downdate primitive.
SkuSiPolicy.p7b
A Microsoft-signed Code Integrity policy that revokes specific versions of VBS system files. Shipped in KB5042562, August 2024.
VBS UEFI lock
A configuration mode for Virtualization-Based Security that pins the VBS configuration into a UEFI non-volatile variable. Pins configuration, not implementation.
DRTM
Dynamic Root of Trust for Measurement. On Win11 24H2+, binds Virtual Secure Mode protected keys to the active CI policy version.
False File Immutability (FFI)
Gabriel Landau's bug class. Windows treats SEC_IMAGE-mapped files as immutable, but the kernel does not consistently honor that immutability across separate reads -- enabling TOCTOU on catalogs.

Comprehension questions

  1. Why does Leviev's attack succeed even though every binary Windows loads is legitimately Microsoft-signed?

    Because Authenticode and the CBS catalog-trust model assert signature validity, not version currency. A 2022 ci.dll is signed by the same Microsoft key as a 2024 ci.dll.

  2. Which registry value is the pivot at the heart of Windows Downdate, and what is its ACL?

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Configuration\PoqexecCmdline. The DACL allows Administrator write, breaking the TrustedInstaller-only chain of custody for the action list pointer.

  3. What does the VBS UEFI lock pin, and what does it not pin?

    It pins VBS configuration (the VbsPolicy UEFI variable). It does not pin VBS implementation (securekernel.exe, hvix64.exe, LsaIso.exe, ci.dll). Downgrading the implementation while leaving the configuration alone is the attack.

  4. How is the rollback-defence story different on Android and Apple platforms?

    Android AVB stores per-partition rollback indices in TrustZone or RPMB. Apple SSV signs a Merkle tree over the whole system volume. Both are structural and mandatory. Windows SkuSiPolicy.p7b is shipped via the same update channel as the components it protects, with an opt-in UEFI lock for the strong variant.

  5. Why does Microsoft consider the underlying Downdate primitive (modifying PoqexecCmdline) not a security vulnerability?

    Because the Windows Security Servicing Criteria does not enumerate Administrator-to-kernel as a security boundary. Per Microsoft's published policy, gaining kernel code execution as an Administrator does not violate the goal or intent of any declared boundary, so the primitive falls outside the servicing-CVE process.

References

  1. Alon Leviev (2024). Downgrade Attacks Using Windows Updates. https://www.safebreach.com/blog/downgrade-attacks-using-windows-updates/
  2. Microsoft (2024). KB5042562: Guidance for Blocking Rollback of VBS Security Updates. https://support.microsoft.com/en-us/topic/guidance-for-blocking-rollback-of-virtualization-based-security-vbs-related-security-updates-b2e7ebf4-f64d-4884-a390-38d63171b8d3
  3. Microsoft (2024). KB5044284: October 8, 2024 Update for Windows 11 24H2 (OS Build 26100.2033). https://support.microsoft.com/help/5044284
  4. Alon Leviev (2024). An Update on Windows Downdate. https://www.safebreach.com/blog/update-on-windows-downdate-downgrade-attacks/
  5. Microsoft Security Response Center (2024). Windows Security Servicing Criteria. https://www.microsoft.com/en-us/msrc/windows-security-servicing-criteria
  6. Ravie Lakshmanan (2024). Researchers Uncover OS Downgrade Vulnerability Targeting Microsoft Windows Kernel. https://thehackernews.com/2024/10/researchers-uncover-os-downgrade.html
  7. Gabriel Landau (2024). False File Immutability. https://www.elastic.co/security-labs/false-file-immutability
  8. Gabriel Landau (2024). gabriellandau/ItsNotASecurityBoundary. https://github.com/gabriellandau/ItsNotASecurityBoundary
  9. Alon Leviev (2024). Windows Downdate: Downgrade Attacks Using Windows Updates (Black Hat USA 2024, revised slides). https://i.blackhat.com/BH-US-24/Presentations/REVISED_US24-Leviev-Windows-Downdate-Downgrade-Attacks-Using-Windows-Updates-Wednesday.pdf
  10. Bodo Moeller, Thai Duong, & Krzysztof Kotowicz (2014). This POODLE Bites: Exploiting the SSL 3.0 Fallback. https://www.openssl.org/~bodo/ssl-poodle.pdf
  11. (2014). CVE-2014-3566. https://nvd.nist.gov/vuln/detail/CVE-2014-3566
  12. Karthikeyan Bhargavan & miTLS team (2015). The FREAK Attack. https://freakattack.com/
  13. Bodo Moeller & Adam Langley (2015). RFC 7507: TLS Fallback Signaling Cipher Suite Value (SCSV). https://datatracker.ietf.org/doc/html/rfc7507
  14. Eric Rescorla (2018). RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3. https://datatracker.ietf.org/doc/html/rfc8446
  15. Karthikeyan Bhargavan & Gaetan Leurent (2016). Transcript Collision Attacks: Breaking Authentication in TLS, IKE and SSH. https://www.ndss-symposium.org/wp-content/uploads/2017/09/transcript-collision-attacks-breaking-authentication-tls-ike-ssh.pdf
  16. Microsoft (2024). Updating Microsoft Secure Boot Keys. https://techcommunity.microsoft.com/blog/windows-itpro-blog/updating-microsoft-secure-boot-keys/4055324
  17. (2010). The Update Framework Specification. https://theupdateframework.io/specification/latest/
  18. (2010). TUF Security. https://theupdateframework.io/docs/security/
  19. Android Open Source Project (2017). Android Verified Boot 2.0. https://source.android.com/docs/security/features/verifiedboot/avb
  20. Apple Platform Security (2020). Signed System Volume Security. https://support.apple.com/guide/security/signed-system-volume-security-secd698747c9/web
  21. Brendan Moran, Hannes Tschofenig, David Brown, & Milosch Meriac (2021). RFC 9019: A Firmware Update Architecture for Internet of Things. https://datatracker.ietf.org/doc/html/rfc9019
  22. Martin Smolar (2023). BlackLotus UEFI Bootkit: Myth Confirmed. https://www.welivesecurity.com/2023/03/01/blacklotus-uefi-bootkit-myth-confirmed/
  23. National Security Agency (2023). BlackLotus Mitigation Guide. https://media.defense.gov/2023/Jun/22/2003245723/-1/-1/0/CSI_BLACKLOTUS_MITIGATION_GUIDE.PDF
  24. UEFI Forum (2024). UEFI Revocation List File. https://uefi.org/revocationlistfile
  25. Microsoft (2025). Servicing Stack Updates. https://learn.microsoft.com/en-us/windows/deployment/update/servicing-stack-updates
  26. Microsoft Security Response Center (2008). Microsoft Security Advisory 932596: Update to Improve Kernel Patch Protection. https://learn.microsoft.com/en-us/security-updates/securityadvisories/2007/932596
  27. Microsoft (2007). Kernel-Mode Code Signing Walkthrough. https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/KMCS_Walkthrough.doc
  28. Microsoft (2025). Kernel-Mode Code Signing Policy (Windows Vista and Later). https://learn.microsoft.com/en-us/windows-hardware/drivers/install/kernel-mode-code-signing-policy--windows-vista-and-later-
  29. Microsoft (2025). Driver Signing. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/driver-signing
  30. Microsoft (2025). Virtualization-Based Security (VBS). https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-vbs
  31. Microsoft (2025). Enable Virtualization-Based Protection of Code Integrity. https://learn.microsoft.com/en-us/windows/security/hardware-security/enable-virtualization-based-protection-of-code-integrity
  32. Microsoft (2025). Credential Guard Overview. https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/
  33. Microsoft Security (2021). Improve Kernel Security with the New Microsoft Vulnerable and Malicious Driver Reporting Center. https://www.microsoft.com/security/blog/2021/12/08/improve-kernel-security-with-the-new-microsoft-vulnerable-and-malicious-driver-reporting-center/
  34. Microsoft (2025). Microsoft Recommended Driver Block Rules. https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules
  35. Splunk Threat Research Team (2024). Windows Downdate Registry Activity. https://research.splunk.com/endpoint/d984fca1-ba3a-4f89-aa58-800e235fdf53/
  36. Alon Leviev (2024). SafeBreach-Labs/WindowsDowndate. https://github.com/SafeBreach-Labs/WindowsDowndate
  37. (2024). CVE-2024-21302. https://nvd.nist.gov/vuln/detail/CVE-2024-21302
  38. (2024). CVE-2024-38202. https://nvd.nist.gov/vuln/detail/CVE-2024-38202
  39. Android Open Source Project (2024). Android Verified Boot 2.0 README (libavb). https://android.googlesource.com/platform/external/avb/+/refs/heads/master/README.md
  40. Microsoft (2025). Hotpatch for Windows Server. https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch
  41. Microsoft (2025). Hotpatch Updates for Windows 11 (Microsoft Autopatch). https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates
  42. Juha Saarinen (2025). BitUnlocker: Full Volume Encryption Bypass Found by Microsoft Researchers. https://www.itnews.com.au/news/bitunlocker-full-volume-encryption-bypass-found-by-microsoft-researchers-619577
  43. (2025). BitUnlocker: Leveraging Windows Recovery to Extract BitLocker Secrets (DEF CON 33). https://infocondb.org/con/def-con/def-con-33/bitunlocker-leveraging-windows-recovery-to-extract-bitlocker-secrets
  44. garatc (2025). garatc/BitUnlocker. https://github.com/garatc/BitUnlocker