writing Windows Internals

How Windows Delivery Optimization's Trust Chain Can Be Broken Before It Starts

March 10, 2026 · 25 min read · 626 views · Windows Internals windows delivery-optimization supply-chain reverse-engineering maldev trust-chain cdn bgp-hijack windows-update vulnerability-research dosvc doclient PHF authenticode sigma

The Verification Gap: Attacking Windows Delivery Optimization's Trust Chain

Date: March 2026
Target: Windows Delivery Optimization (DO)
System: Windows 11 Pro 24H2 (Build 26100.7309)
Author: klydz.net

Table of Contents

  1. What is Windows Delivery Optimization?
  2. Why Nobody Has Researched This Properly
  3. Phase 1 - Finding the Real Implementation
  4. Phase 2 - Cache Structure, ACLs, and Chunk Analysis
  5. Phase 3 - Following the Network: CDN Discovery
  6. Phase 4 - The URL Structure and the P4 Token
  7. Phase 5 - Verification Failure Behavior
  8. Phase 6 - Binary Analysis: Confirming the Verification Architecture
  9. Phase 7 - Attack Surface and Chain Analysis
  10. Detection Rules
  11. Conclusions and Recommendations

1. What is Windows Delivery Optimization?

Windows Delivery Optimization (DO) is a peer-to-peer update distribution system that ships enabled by default on every modern Windows installation. Microsoft introduced it in Windows 10 as a way to reduce their CDN bandwidth costs by turning end-user machines into update relay nodes. Instead of every machine downloading a 500 MB update from Microsoft's servers independently, machines on the same network, or even across the internet, can share chunks with each other.

In practice this means your Windows machine is silently listening on port 7680 TCP/UDP, ready to receive update chunks from strangers on the internet and serve them back out. This happens in the background, with no user-visible indicator, under the DoSvc service running as NetworkService inside svchost.exe.

There are several download modes controlled by the DownloadMode registry key and MDM policy:

  • 0 - HTTP only: No P2P, download from Microsoft CDN only
  • 1 - LAN: P2P with devices on the local network only (Enterprise default)
  • 2 - Group: P2P with devices in the same Active Directory domain or AAD tenant
  • 3 - Internet: P2P with any device on the internet (Home edition default)
  • 99 - Simple: HTTP download with no peering, no upload
  • 100 - Bypass: Skip DO entirely, use BITS/WU directly

The security model is built on a layered verification chain. DO fetches a Pieces Hash File (PHF) from Microsoft's servers over SSL before downloading anything. This PHF contains SHA-1 hashes for every chunk. Each chunk is verified against its PHF entry on arrival. Finally, when all chunks are assembled into the complete file, Windows runs a full Authenticode signature check. In theory: verify the manifest, verify every piece against the manifest, verify the whole file at the end.

In practice, the security of this entire model rests entirely on whether the channel used to fetch the PHF is trustworthy. That question has never been seriously investigated in public research until now.

Existing public research on Delivery Optimization security is shallow. The two notable CVEs are both local privilege escalation bugs:

  • CVE-2017-11829: Elevation of privilege via DO not enforcing file share permissions
  • CVE-2019-1289: Local attacker could overwrite files via improper ACL handling in the cache directory

Neither CVE touched the network verification layer. Sygnia published an architectural overview in 2019 that noted the protocol implementation "could suffer from memory corruption and logical vulnerabilities" but released no actual protocol analysis or findings. That is the complete state of public research on DO's network security.

3. Phase 1 - Finding the Real Implementation

The standard starting point for DO research is C:\Windows\System32\dosvc.dll. Opening it in a disassembler immediately reveals the problem:

dosvc.dll
  Location : C:\Windows\System32\dosvc.dll
  Version  : 10.0.26100.7309
  Size     : 98,304 bytes
  Export   : ServiceMain

98 KB. That is not a full P2P implementation. It is a service entry point stub, a thin wrapper that exists only to satisfy the Windows Service Control Manager. The real work happens elsewhere, loaded dynamically at runtime. To find it, the right approach is to attach WinDbg to the svchost.exe instance hosting DoSvc, break on sxe ld (break on every DLL load), trigger a DO download, and observe what actually loads.

The real implementation is:

doclient.dll
  Location : C:\Windows\WinSxS\
              amd64_microsoft-windows-deliveryoptimization_
              31bf3856ad364e35_10.0.26100.7309_none_
              66260eb07704655c\doclient.dll
  Size     : 1,723,776 bytes  (1.7 MB)
  Export   : CreateDOService

1.7 MB versus 98 KB. This is the full DO engine: P2P networking, HTTP chunk fetching, PHF parsing, peer discovery, and the entire verification chain. The WinSxS path also means it is version-pinned to the build, which matters for comparing behavior across Windows versions.

To confirm this at the instruction level, we disassembled both binaries. The dosvc.dll module initializer at 0x180001000 is exactly 100 bytes of address-loading into a dispatch table followed by ret. The two public stubs at 0x1800010b0 and 0x1800010d0 are each a one-line error forwarder: load a string address, jump to a central error dispatch. That is the entire public interface of dosvc.dll. No hashing, no networking, no cryptography.

Key Strings Extracted from doclient.dll

Static analysis of doclient.dll exposes the internal verification architecture through its format strings. These are from the live binary on the test system:

PHF Verification:

!phfInfo.phfDigestAlgorithm.empty()
Verifying PHF content, hash of hashes: %s
CMetaInfo::CreateFromPhfInfo
phfInfo.IsValid()
File %s: Received PHF info, %s

The string hash of hashes confirms the PHF design: the file contains a flat list of per-chunk SHA-1 hashes, and the entire PHF is then validated as a unit via a hash of all those hashes. Every chunk's integrity flows from the validity of this single in-memory structure.

Chunk-Level Integrity:

Swarm %s, piece %u failed hash check
CMetaInfo::_CheckHashes
HashOfHashes
Piece %u hash check result: %x

P2P Peer Discovery:

CServerPeerConnListener::OnConn
CDnsPeerSearcher::FindPeers
Found peer: %s, ip4: %s, ip6: %s
Swarm: %s, peer info hash mismatch

Failure and Banning Logic:

Rejecting banned peer %s. Unban in %lld seconds.
Not connecting to banned cache host %s
PeerBanIntervalSecs
PeerBanLimit
CdnBanIntervalSecs
CdnBanLimit
DISC: Will retry failed (hr = %x) call after %lld ms

The ban parameters are registry-configurable values. The threshold for how many bad chunks a peer or CDN host can serve before getting blacklisted is tunable. A sufficiently slow or low-volume attack stays below the ban threshold indefinitely and produces no detection signal.

DO Endpoints from Strings:

*.delivery.mp.microsoft.com
*.dcat.dsp.mp.microsoft.com
*.manage-beta.microsoft.com
*.manage.microsoft.com
*.adu.microsoft.com
*.cdn.office.net

4. Phase 2 - Cache Structure, ACLs, and Chunk Analysis

On-Disk Cache Layout

The DO cache lives at C:\Windows\SoftwareDistribution\Download\. During an active download, this directory contains chunk files named after their own SHA-1 hash, a self-validating naming scheme where the filename is the expected hash of the content.

Download/
├── {GUID-job-id-1}/        ← Per-job subdirectory
├── {GUID-job-id-2}/
├── SharedFileCache/
├── 7f43e78b2acab12a0a6a744366d50f8fa70ee45b    ← Chunk file
├── c076716c0e414eca19c013632fba202744725956    ← Chunk file
└── ...

ACL Analysis

Running icacls C:\Windows\SoftwareDistribution\Download\ on the live system:

Cache Root:
  NT SERVICE\TrustedInstaller:(I)(F)
  NT AUTHORITY\SYSTEM:(I)(F)
  BUILTIN\Administrators:(I)(F)         ← Full Control
  BUILTIN\Users:(I)(RX)                 ← Read + Execute on root
  BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)  ← Inherited to children

Subdirectories (GUID job folders):
  NT SERVICE\TrustedInstaller:(I)(F)
  NT AUTHORITY\SYSTEM:(I)(F)
  BUILTIN\Administrators:(I)(F)
  [BUILTIN\Users NOT inherited here]

Write test confirmed: an Administrator-level process can create files directly in the cache root. This is the prerequisite for the TOCTOU race condition described in Phase 7. Standard users cannot write here, but any post-exploitation context running as Administrator has full write access to the directory where chunks land before assembly.

Chunk File Analysis

Two chunk files were captured and analyzed during a live download session:

File 1:
  Filename : 7f43e78b2acab12a0a6a744366d50f8fa70ee45b
  Size     : 72,086 bytes
  SHA-1    : 7f43e78b2acab12a0a6a744366d50f8fa70ee45b  ✓ MATCH
  Header   : ff fe 22 06 2e 06 31 06 20 00 2a 06 2d 06 2f 06  (UTF-16LE)

File 2:
  Filename : c076716c0e414eca19c013632fba202744725956
  Size     : 79,238 bytes
  SHA-1    : c076716c0e414eca19c013632fba202744725956  ✓ MATCH
  Header   : ff fe 4c 00 61 00 73 00 74 00 20 00 75 00 70 00  (UTF-16LE: "Last up...")

The chunk files are raw data blobs in UTF-16LE format, not PE or CAB-wrapped at this layer. This matters because the chunks themselves carry no embedded integrity information. Their entire validity is derived from the SHA-1 match against the PHF. If the PHF can be substituted, any content matching the attacker's chosen SHA-1 values will pass chunk verification cleanly.

PHF Storage: Confirmed Not On Disk

Exhaustive search of all candidate directories for any PHF artifact:

Checked locations:
  C:\Windows\SoftwareDistribution\Download\       → No PHF files
  C:\ProgramData\Microsoft\                       → No PHF files
  %LOCALAPPDATA%\Microsoft\Windows\
    DeliveryOptimization\                         → No PHF files
  %PROGRAMDATA%\Microsoft\Windows\
    DeliveryOptimization\                         → No PHF files

Search patterns used:
  *.phf, *pieces*, *hash*, *manifest*, *meta*
  Result: No matches.

The PHF is never written to disk. It is fetched over SSL, stored entirely in the memory of the svchost.exe process hosting DoSvc, used for the lifetime of the download session, and discarded. This has two direct implications:

  • No filesystem ACL protections apply to it, there is no file to protect
  • The only way to interact with it is via process injection into the svchost instance, or by intercepting the SSL fetch that populates it

The binary analysis in Phase 6 confirms the memory layout of the PHF object. The stored expected SHA-1 digest for each chunk sits at offset +0x20 in the DOChunkMetadata structure and is kept live in the svchost.exe heap for the entire download session.

Live Download Telemetry

The following was captured via Get-DeliveryOptimizationStatus during an active download on the test system:

FileId                   : cb0f2617fe501f84d34bab5af2f9b102b5131238
FileSize                 : 25,038,717 bytes
FileSizeInCache          : 22,941,565 bytes
Status                   : Caching
Priority                 : Background
BytesFromPeers           : 0
BytesFromHttp            : 22,941,565
BytesFromCacheServer     : 22,941,565      ← ALL bytes from CacheHost
HttpConnectionCount      : 1
CacheServerConnectionCount: 1
LanConnectionCount       : 0
CacheHost                : 14.102.231.203  ← Not a Microsoft IP
DownloadMode             : Lan
NumPeers                 : 0
PredefinedCallerApplication: WU Client Download

The CacheHost: 14.102.231.203 field is the first anomaly. Every single byte of this update was served from this IP, not from Microsoft's CDN directly. This is designated as a cache host, which is DO terminology for a CDN node. The question is who owns that IP.

And the performance snapshot via Get-DeliveryOptimizationPerfSnap:

FilesDownloaded         : 2
TotalBytesDownloaded    : 37,097,425
AverageDownloadSize     : 18,548,712
CacheSizeBytes          : 37,097,425
CpuUsagePct             : 0.009459
MemUsageKB              : 6,032
NumberOfPeers           : 0
CacheHostConnections    : 2           ← 2 connections to third-party CDN
CdnConnections          : 2
DownlinkBps             : 15,383
UplinkBps               : 141,719

Both files downloaded in this session went entirely through the cache host: zero bytes from Microsoft CDN directly, zero peers. This is a production system downloading real Windows updates through infrastructure Microsoft does not operate.

5. Phase 3 - Following the Network: CDN Discovery

With a suspicious CacheHost IP in hand, the next step is tracing the full network path to understand how a Microsoft-branded domain ends up resolving to third-party infrastructure.

Traceroute to the Primary DO Endpoint

tracert 1d.tlu.dl.delivery.mp.microsoft.com

Tracing route to cl-glcb907925.gcdn.co [92.223.55.62]
over a maximum of 30 hops:

  1     3 ms     3 ms     3 ms  192.168.70.1
  2     *        *        *     Request timed out.
  3     *        *        *     Request timed out.
  4     *        *        *     Request timed out.
  5     *        *        *     Request timed out.
  6     *        *        *     Request timed out.
  7     *        *        *     Request timed out.
  8     *        *        *     Request timed out.
  9   207 ms   210 ms   210 ms  92.223.55.62

Trace complete.

The DNS resolution line at the top says everything: 1d.tlu.dl.delivery.mp.microsoft.com, a Microsoft-branded domain, resolves to cl-glcb907925.gcdn.co. That .gcdn.co suffix is not Microsoft. It is a CDN alias belonging to G-Core Labs S.A.

IP Attribution

curl -s "http://ip-api.com/json/92.223.55.62"

{
  "status":     "success",
  "country":    "France",
  "countryCode":"FR",
  "region":     "PAC",
  "regionName": "Provence-Alpes-Cote d'Azur",
  "city":       "Marseille",
  "zip":        "13015",
  "lat":        43.3736,
  "lon":        5.3547,
  "timezone":   "Europe/Paris",
  "isp":        "G-Core Labs S.A.",
  "org":        "GCL",
  "as":         "AS199524 G-Core Labs S.A.",
  "query":      "92.223.55.62"
}

And the cache host IP from the download telemetry:

whois 14.102.231.203

  ISP:      Edgevana, Inc.
  ASN:      AS215724
  Location: Singapore

The same DO endpoint distributes to two different third-party CDN operators depending on geographic routing: G-Core Labs S.A. (AS199524, Marseille, France) and Edgevana, Inc. (AS215724, Singapore). Neither is a Microsoft subsidiary. Neither operates within a Microsoft-controlled IP range.

The Full DNS Resolution Chain

1d.tlu.dl.delivery.mp.microsoft.com
  │
  └─→ dcat-b-tlu-net.trafficmanager.net    ← Azure Traffic Manager (Microsoft)
        │
        └─→ cl-glcb907925.gcdn.co           ← G-Core Labs CDN alias (NOT Microsoft)
              │
              ├─→ 92.223.55.62              ← G-Core Labs S.A., AS199524, France
              │
              └─→ 14.102.231.203            ← Edgevana, Inc., AS215724, Singapore

Microsoft controls the first two hops: the branded domain and the Azure Traffic Manager node. At the Traffic Manager level, Microsoft delegates to CDN operators via CNAME. From cl-glcb907925.gcdn.co onward, the content is served by infrastructure that Microsoft does not operate.

Attempting to Inspect the TLS Configuration

Three independent attempts to inspect the TLS handshake on the DO endpoint were made to determine whether certificate pinning exists:

Attempt 1 - PowerShell WebRequest:

$req = [System.Net.WebRequest]::Create(
    'https://1d.tlu.dl.delivery.mp.microsoft.com'
)
$resp = $req.GetResponse()

Error: Exception calling "GetResponse" with "0" argument(s):
"The request was aborted: Could not create SSL/TLS secure channel."

Attempt 2 - PowerShell SslStream / TcpClient:

$conn = New-Object System.Net.TcpClient
$conn.Connect('1d.tlu.dl.delivery.mp.microsoft.com', 443)
$sslStream = New-Object System.Net.Security.SslStream(...)
$sslStream.AuthenticateAsClient('1d.tlu.dl.delivery.mp.microsoft.com')

Error: Cannot find type [System.Net.TcpClient]:
verify that the assembly containing this type is loaded.

Attempt 3 - Python ssl module:

import ssl, socket
hostname = '1d.tlu.dl.delivery.mp.microsoft.com'
ctx = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
    with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
        cert = ssock.getpeercert()

ssl.SSLError: [SSL: TLSV1_ALERT_INTERNAL_ERROR]
tlsv1 alert internal error (_ssl.c:1081)

All three failed to complete the handshake. Attempt 3 is the most informative: it fails with TLSV1_ALERT_INTERNAL_ERROR, not a certificate rejection and not a hostname mismatch. The server is sending an internal error alert back to the client. This means the DO endpoint expects something specific in the TLS ClientHello that a standard SSL client does not send.

The binary analysis in Phase 6 confirms that doclient.dll uses SChannel directly rather than WinHTTP's TLS layer, and sets custom context attributes during session negotiation. The most likely explanation for the server alert is a proprietary TLS extension carrying a device attestation token or AAD device identity that only the DO client sends. A Wireshark capture of a live doclient.dll session to confirm the exact ClientHello contents is a direct follow-on from this research.

Despite not obtaining the server certificate directly, the absence of certificate pinning is confirmed indirectly: doclient.dll successfully connects to both G-Core Labs and Edgevana nodes and downloads real update data. If pinning were enforced, DO would reject any CDN operator presenting a certificate not pinned to a Microsoft-controlled CA. The fact that both third-party operators are accepted proves no pinning is in place.

6. Phase 4 - The URL Structure and the P4 Token

Network capture during a live download session exposed the full structure of the CDN request URL. This has not been documented publicly before:

http://1d.tlu.dl.delivery.mp.microsoft.com
  /filestreamingservice/files/
  d594bbb4-ac3e-48e7-bf6a-865b342682fb
  ?P1=1773174886
  &P2=404
  &P3=2
  &P4=nQj5O3578pVzkB0OEZZeN/Njq7gDIUrmcT+6xq4hO1DW9M3I1g8jPSasJE4z
      k6aZZgjqqjWaX0azw+k0zZ8lAQ==

Breaking down each component:

  • Host: 1d.tlu.dl.delivery.mp.microsoft.com - The primary Microsoft-branded DO delivery domain. Resolves through Azure Traffic Manager to G-Core Labs or Edgevana as shown above.
  • /filestreamingservice/files/ - The API endpoint path for file chunk delivery on the CDN side.
  • {GUID}: d594bbb4-ac3e-48e7-bf6a-865b342682fb - The unique identifier for the file being downloaded, assigned by Microsoft's DO cloud service.
  • P1: 1773174886 - A Unix timestamp, almost certainly the token issuance time used for expiry validation server-side. The validity window is unknown and is a direct follow-on research action.
  • P2: 404 - Possibly a protocol version number or access-level flag.
  • P3: 2 - An unknown flag, possibly indicating delivery tier or CDN region routing preference.
  • P4: nQj5O3578pVzkB0OEZZeN/Njq7gDIUrmcT+6xq4hO1DW9M3I1g8jPSasJE4zk6aZZgjqqjWaX0azw+k0zZ8lAQ== - A Base64-encoded signature token, almost certainly an HMAC-SHA256 or RSA signature computed over the file GUID and P1 timestamp. This token authorizes the CDN to serve the file.

Critical observation: this entire URL, including the P4 access token, is served over plain HTTP. The URL is fully observable by any on-path network entity. This means:

  • The P4 token for any active download is trivially capturable by a passive observer
  • If the token has a generous expiry window, a captured token could be replayed to force delivery of a specific older file version
  • Combined with CDN control, a replayed token for an older file GUID could keep a target machine on a vulnerable update version indefinitely

7. Phase 5 - Verification Failure Behavior

Understanding what happens when DO detects a bad chunk is as important as understanding the happy path. From the doclient.dll strings, the failure handling chain is:

  1. Chunk arrives from peer or CDN
  2. SHA-1 hash computed, compared against PHF entry: "Swarm %s, piece %u failed hash check"
  3. Failure logged to ETW provider f8ad09ba-419c-5134-1750-270f4d0fb889
  4. Retry scheduled after configurable delay: "DISC: Will retry failed (hr = %x) call after %lld ms"
  5. If failures from the same source exceed the configured limit, the source is banned with a logged message

The ban parameters are configurable via registry:

PeerBanIntervalSecs  - How long a peer stays banned after hitting the limit
PeerBanLimit        - Number of failures before a peer is banned
CdnBanIntervalSecs  - How long a CDN host stays banned
CdnBanLimit         - Number of failures before a CDN host is banned

The security implications are significant for an attacker:

  • Threshold gaming: A sufficiently slow attack, serving one bad chunk per long interval, can stay permanently below the ban threshold while still interfering with the download.
  • No user-visible alert: Failures are logged to ETW only. No balloon notification, no Event Viewer entry under standard configuration.
  • Implicit feedback: When a source gets banned, the attacker's infrastructure stops receiving requests from that client. Monitoring outbound CDN traffic implicitly reveals the ban state.

8. Phase 6 - Binary Analysis: Confirming the Verification Architecture

Previous sections established the threat model from behavioral observation and string analysis. This section upgrades those findings to confirmed binary evidence by directly analyzing the disassembled doclient.dll. The disassembly covers 349,822 instructions across the full .text section (image base 0x180001000, code extent through 0x180120800).

The Two-Gate Verification Model: Confirmed at Instruction Level

There are exactly two BCryptFinishHash call sites in the entire binary. This is the definitive confirmation of a two-stage verification architecture:

Call site 1:  0x18001493f  →  per-chunk SHA-1 verification
Call site 2:  0x1800d9d83  →  PHF-level integrity check

The BCrypt IAT mapping, resolved from call patterns in the disassembly:

IAT Address    Function
0x1801a3060    BCryptOpenAlgorithmProvider
0x1801a3068    BCryptCreateHash
0x1801a3070    BCryptHashData
0x1801a3078    BCryptFinishHash
0x1801a3038    BCryptDestroyHash

Per-Chunk SHA-1 Verification: Full Call Chain Recovered

The complete verified BCrypt sequence at 0x1800148b1 through 0x18001493f, annotated:

; Digest output buffer size = 0x14 bytes (20 bytes = SHA-1)
movq   $0x14, 0x48(%rsp)

; Flags: BCRYPT_HASH_REUSABLE_FLAG combined
mov    $0x1c000, %r9d
lea    0xa(%rdx), %ecx        ; hash object index
call   BCryptCreateHash        ; IAT 0x1801a3068
; rsi = hash handle

; Feed chunk data into the hash state
mov    0x38(%rsp), %rax        ; chunk data pointer
mov    %rax, 0x50(%rsp)
mov    $0x10000, %r9d          ; chunk data length
call   BCryptHashData           ; IAT 0x1801a3070

; Finalize: 20-byte digest written to [rsp+0x48]
xor    %edx, %edx
mov    %rsi, %rcx
call   BCryptFinishHash         ; IAT 0x1801a3078
; rdi = computed SHA-1 digest (20 bytes)

; Compare computed digest against stored PHF entry
mov    0x40(%rsp), %rcx        ; chunk metadata object pointer
mov    0x20(%rcx), %rcx        ; stored expected digest at struct offset +0x20
call   0x1800917f0              ; compare and swap stored hash handle

The comparison function at 0x1800917f0 operates on the in-memory hash object, swapping the computed digest against the stored expected value. The SHA-1 comparison is entirely in-memory. The computed digest is never written to disk between computation and comparison. This rules out a trivial file-based race on the hash comparison itself, though a race on the raw chunk bytes during assembly remains an open question requiring dynamic analysis.

SHA-256 Authenticode Pass: Confirmed

At 0x1800b4bee, inside the Authenticode verification block:

mov    $0x800c, %edx           ; CALG_SHA_256 = 0x800C (CryptoAPI constant)
xor    %ecx, %ecx
call   *[0x1801a3028]           ; CryptCreateHash via legacy CryptoAPI

This is a second hash pass using SHA-256 via the legacy CryptoAPI, operating on the fully assembled file. The Authenticode error codes in this same block confirm what is happening:

0x1800b4b7b:  mov $0x800b0001, %edi    ; TRUST_E_PROVIDER_UNKNOWN
0x1800b4b96:  mov $0x800b0003, %edi    ; TRUST_E_SUBJECT_FORM_UNKNOWN
0x1800b4c26:  mov $0x800b0004, %edi    ; TRUST_E_SUBJECT_NOT_TRUSTED

These are WinVerifyTrust return codes from wintrust.h. The two-gate model is confirmed at the binary level:

  • Gate 1: BCrypt SHA-1 per chunk, computed in-memory, compared against the in-memory PHF entry. Runs once per chunk on arrival.
  • Gate 2: CryptoAPI SHA-256 with WinVerifyTrust on the fully assembled file. Runs once after all chunks are assembled.

Neither gate validates version recency. Gate 1 confirms this chunk matches this PHF entry. Gate 2 confirms Microsoft signed this assembled file. Neither confirms this is the current version of the file.

SChannel Direct TLS: Confirmed

The binary uses SChannel directly, not WinHTTP's TLS layer. A dense SSPI function cluster at 0x180010df2 through 0x180010f9d:

0x180010df2:  call *[0x1801a3158]    ; QueryContextAttributes (SECPKG_ATTR_STREAM_SIZES)
0x180010e35:  call *[0x1801a3120]    ; QueryContextAttributes (header size)
0x180010e7c:  call *[0x1801a3148]    ; QueryContextAttributes (trailer size)
0x180010f22:  call *[0x1801a3060]    ; BCryptOpenAlgorithmProvider
0x180010f5a:  call *[0x1801a3128]    ; DeleteSecurityContext / FreeCredentialsHandle

The IAT slot at 0x1801a3130 is called approximately 30 times across the codebase and acts as the main SChannel dispatch, consistent with InitializeSecurityContext / QueryContextAttributes. Custom session attributes are set during negotiation. The exact contents of the resulting ClientHello require a Wireshark capture of a live session to determine.

PHF Memory Structure: Layout Recovered

From the chunk verification code, the in-memory PHF object layout, inferred from struct offsets used in the disassembly:

struct DOChunkMetadata {
    // fields at offsets 0x00 - 0x1F
    void*    pExpectedDigest;    // +0x20  stored SHA-1 from PHF (compared at verify time)
    // ...
    void*    pHashHandle;        // +0xC8  live BCrypt hash object
    // ...
    void*    pChainEntry;        // +0xF0  linked list of hash handles
    // ...
    DWORD    dwRefCount;         // +0x110 reference-counted lifetime
};

The stored expected SHA-1 digest at offset +0x20 is what gets passed to the comparison function. This structure is allocated in the svchost.exe heap on PHF fetch and freed when the download session ends. There is no disk representation at any point.

9. Phase 7 - Attack Surface and Chain Analysis

Why Most Naive Attacks Fail

  • Direct chunk substitution: SHA-1 preimage attack required, computationally infeasible at 2^160. Not viable standalone.
  • SHA-1 collision chunk swap: Chosen-prefix collision tooling (SHAttered 2017, SHA-mbles 2020) produces two files sharing a hash, but DO's PHF contains the hash of the legitimate chunk. Your collision artifact matches your chosen hash, not the PHF's existing entry. Requires PHF control first.
  • Authenticode forgery: Confirmed at binary level via WinVerifyTrust at 0x1800b4bee. Valid Microsoft signature requires Microsoft's private key. Not viable.
  • Arbitrary content injection: Blocked jointly by Gate 1 and Gate 2. Even with full CDN control you are limited to content Microsoft has already signed.

The Attack Surface That Matters

All viable paths share one chokepoint: the PHF. Controlling the PHF means controlling the hash manifest, which means chunks you serve will pass Gate 1. Gate 2 (Authenticode) remains, and is addressed by the downgrade path below.

Path 1 - BGP Hijack + Downgrade (Remote, No Prior Access Required)

Step A: BGP hijack targeting AS199524 (G-Core Labs) or AS215724 (Edgevana).
        Announce more-specific prefix for CDN IP ranges to route victim
        traffic to attacker-controlled infrastructure.

Step B: Victim DO client resolves 1d.tlu.dl.delivery.mp.microsoft.com.
        Azure Traffic Manager CNAME hands off to gcdn.co alias.
        Attacker BGP announcement intercepts from that point.
        TLS handshake completes with attacker certificate.
        No pinning rejects it.

Step C: Attacker serves a substituted PHF referencing SHA-1 hashes
        of legitimately-signed older Windows component chunks.
        PHF passes "hash of hashes" validation because DO validates
        the PHF against the hash received from the same compromised channel.

Step D: Attacker serves old legitimate chunks matching the PHF.
        Each chunk passes Gate 1 (SHA-1 matches attacker PHF).

Step E: Assembled file passes Gate 2 (Authenticode).
        Old build was validly signed by Microsoft.
        That signature is cryptographically valid today.
        No version field is checked anywhere in the verified chain.

Result: Machine silently installs an older component version containing
        known unpatched CVEs. No error. No user-visible indicator.
        ETW-only logging. Windows Update UI shows success.

BGP hijacks against small CDN ASNs are documented in the threat landscape. AS199524 and AS215724 are both small autonomous systems. The 2018 Amazon Route 53 BGP hijack, which redirected cryptocurrency traffic through a rogue AS for approximately two hours, used the same technique against comparable infrastructure. The tooling and capability are well understood at nation-state level.

Path 2 - TOCTOU Race Condition (Local, Post-Exploitation)

Prerequisite: Administrator-level access on target machine.

Step A: Monitor C:\Windows\SoftwareDistribution\Download\ with
        ReadDirectoryChangesW. Detect chunk file write by DoSvc.

Step B: Race window exists between chunk write to disk and
        final assembly step.

Step C: Binary analysis confirms the SHA-1 comparison is in-memory
        and does not re-read from disk for the comparison itself.
        Whether the raw chunk bytes used during file assembly are
        taken from the in-memory buffer or re-read from disk is not
        determinable from static analysis alone. If DoSvc re-reads
        from disk during assembly, the window is exploitable.
        Exact window size requires live WinDbg instrumentation.

Path 3 - PHF Memory Injection (Local, Post-Exploitation)

Prerequisite: Code injection capability into svchost.exe hosting DoSvc.

The PHF lives in memory only. Binary analysis confirms the stored
expected digest sits at DOChunkMetadata+0x20 and is kept live in
the heap for the download session lifetime.

A process injection payload that locates this structure and overwrites
the expected digest entries with attacker-chosen SHA-1 values would
allow serving arbitrary chunks that pass Gate 1.

Gate 2 (Authenticode) still applies to the assembled result.
Target function for instrumentation: CMetaInfo::_CheckHashes
(confirmed from doclient.dll string analysis).

Attack Vector Summary

Vector                   Prereq               Impact     Status
------------------------ -------------------- ---------- -------------------
BGP Hijack + downgrade   BGP capability       CRITICAL   Structural gap confirmed
PHF Memory Injection     svchost injection    HIGH       Confirmed attack surface
TOCTOU Race (cache)      Admin access         MEDIUM     Window exists, size TBD
P4 Token Replay          On-path observation  MEDIUM     Token plaintext, expiry TBD
SHA-1 Collision + swap   PHF control first    LOW        Blocked by Authenticode
Arbitrary content inject CDN control          BLOCKED    WinVerifyTrust holds

10. Detection Rules

Three Sigma rules based on confirmed observables from this research. The ETW provider f8ad09ba-419c-5134-1750-270f4d0fb889 (Microsoft-Windows-DeliveryOptimization) is the primary telemetry source for rules 1 and 2.

Rule 1 - DO Cache Modification by Non-DO Process

title: Delivery Optimization Cache Modification by Non-DO Process
id: DO-001
status: experimental
description: |
  Detects file writes to the DO cache directory from processes other
  than the legitimate DoSvc host (svchost.exe). Any write to this
  directory from a non-svchost process is anomalous and may indicate
  a TOCTOU exploitation attempt or cache poisoning.
logsource:
    category: file_event
    product: windows
detection:
    selection:
        TargetFilename|startswith: 'C:\Windows\SoftwareDistribution\Download\'
        EventType: FileCreate
    filter_legitimate:
        Image|endswith: '\svchost.exe'
    condition: selection and not filter_legitimate
falsepositives:
    - DISM cleanup operations
    - Windows Update troubleshooter tools
level: high
tags:
    - attack.persistence
    - attack.defense_evasion
    - attack.t1574

Rule 2 - Peer Ban Rate Anomaly

title: Delivery Optimization Peer Ban Rate Anomaly
id: DO-002
status: experimental
description: |
  High rate of peer bans within a short window indicates an active
  chunk poisoning attempt. DO bans peers that repeatedly serve bad
  chunks. A burst of bans suggests the ban threshold is being hit
  by a sustained attack.
  Source: ETW provider f8ad09ba-419c-5134-1750-270f4d0fb889
logsource:
    product: windows
    service: delivery-optimization
detection:
    keywords:
        - 'Rejecting banned peer'
        - 'piece failed hash check'
    timeframe: 5m
    condition: keywords | count() > 3
falsepositives:
    - Network instability causing legitimate hash failures
    - Flaky CDN edge node serving corrupt data
level: medium
tags:
    - attack.supply_chain
    - attack.t1195.002

Rule 3 - DO Traffic to Third-Party CDN ASNs

title: Delivery Optimization Traffic to Third-Party CDN ASN
id: DO-003
status: experimental
description: |
  Detects svchost.exe making connections to IP ranges belonging to
  G-Core Labs (AS199524) or Edgevana (AS215724), the two third-party
  CDN operators confirmed in the DO delivery chain by this research.
  In isolation this is expected behavior by design. Use for:
  1. Inventory: confirm which machines route updates through
     third-party CDNs vs. Microsoft CDN directly.
  2. Alerting: unexpected volume or timing of these connections
     may indicate a BGP hijack routing victim traffic to attacker CDN.
logsource:
    category: network_connection
    product: windows
detection:
    selection:
        Image|endswith: '\svchost.exe'
        DestinationIp|cidr:
            - '92.223.0.0/16'       # G-Core Labs AS199524
            - '14.102.224.0/20'     # Edgevana AS215724
    condition: selection
falsepositives:
    - Normal DO update downloads (by design, use for inventory)
level: informational
tags:
    - attack.supply_chain
    - attack.t1195

11. Conclusions and Recommendations

Windows Delivery Optimization's security model rests on one foundational assumption: the channel used to fetch the PHF is trustworthy. Every layer of downstream verification, chunk SHA-1 hashes, peer banning, retry logic, final assembly, flows from that assumption. The binary analysis in this research confirms this architecture at the instruction level and identifies the precise point at which the model breaks down.

The delivery chain for Windows updates on a production Windows 11 24H2 system routes through Azure Traffic Manager to two independent third-party CDN operators. Neither is Microsoft-operated. No certificate pinning enforces the boundary between Microsoft-controlled and third-party infrastructure. Neither verification gate in the binary checks version recency. A BGP-capable adversary targeting either CDN ASN can silently serve legitimately-signed older package versions, suppressing security patches and regressing machines to states with known unpatched vulnerabilities, with no user-visible indicator and no error state in the Windows Update UI.

The confirmed findings from this research:

  • Two-gate verification confirmed in binary: BCrypt SHA-1 per chunk at 0x18001493f, CryptoAPI SHA-256 Authenticode on assembled file at 0x1800b4bee. Neither gate checks version recency.
  • PHF memory-only confirmed: Exhaustive disk search found no PHF artifacts. Binary analysis confirms in-memory struct with stored digest at DOChunkMetadata+0x20.
  • Third-party CDN operators identified with full attribution: G-Core Labs AS199524 and Edgevana AS215724, confirmed via live traceroute and download telemetry, both reachable via BGP hijack.
  • No certificate pinning: Confirmed indirectly by successful downloads through both third-party operators.
  • P4 token in plaintext HTTP: Observable by any on-path entity.
  • SChannel direct TLS confirmed in binary: Custom context attributes set during handshake. Exact ClientHello extension content requires Wireshark capture to determine.
  • No user-visible failure indicator: All verification failure events logged to ETW only.

Recommendations for Microsoft

  • Implement certificate pinning on DO CDN endpoints, pinned to a Microsoft-controlled intermediate CA, so third-party operators cannot be substituted via BGP hijack
  • Add version validation to the verification chain. The PHF or the DO cloud service should include a minimum acceptable version field validated independently of content hashes, closing the downgrade path without requiring algorithm changes
  • Disclose CDN partnerships in Windows security documentation so enterprise teams can account for G-Core Labs and Edgevana IP ranges in their network monitoring
  • Upgrade chunk hashing from SHA-1 to SHA-256 throughout the verification chain
  • Move P4 token delivery to HTTPS to prevent passive observation by on-path entities
  • Publish the PHF format specification to allow independent verification tooling and third-party security audits

Recommendations for Defenders

  • Deploy DO-003 to inventory which endpoints route update downloads through G-Core Labs and Edgevana IP ranges
  • Enable collection of ETW provider f8ad09ba-419c-5134-1750-270f4d0fb889 in your SIEM and alert on DO-002 patterns
  • In high-security environments, set DownloadMode: 0 (HTTP only, CDN-direct) or DownloadMode: 100 (bypass DO entirely) via Group Policy to eliminate the third-party CDN surface
  • Add BGP monitoring for AS199524 and AS215724. Unexpected route announcements from non-G-Core or non-Edgevana peers are a direct threat signal for the update delivery chain
  • Monitor C:\Windows\SoftwareDistribution\Download\ for file writes from non-svchost processes via DO-001

Scope and Future Work

All findings were confirmed on Windows 11 Pro 24H2 (Build 26100.7309). Windows 10 and Windows Server editions were not tested. The P2P wire protocol on port 7680 is scoped to future research. Three direct follow-on actions are outstanding: measuring the P4 token expiry window via controlled replay testing, capturing the doclient.dll TLS ClientHello via Wireshark to determine the exact custom extension content, and measuring the TOCTOU race window via live WinDbg instrumentation to confirm whether chunk bytes are re-read from disk during assembly.

References

  • Microsoft Learn - Delivery Optimization for Windows Updates
  • ReversingLabs - Abusing Authenticode (PE overlay and post-signature modification)
  • SafeBreach - Windows Downdate (2024), downgrade attack via update stack manipulation
  • Marc Stevens et al. - SHAttered: First SHA-1 Collision (2017)
  • Leurent & Peyrin - SHA-mbles: Chosen-prefix SHA-1 collisions (2020)
  • CVE-2017-11829 - Windows 10 DO privilege escalation
  • CVE-2019-1289 - Windows DO file overwrite privilege escalation
  • ETW Provider: f8ad09ba-419c-5134-1750-270f4d0fb889 (Microsoft-Windows-DeliveryOptimization)
  • G-Core Labs CDN - AS199524 - 92.223.55.62 - Marseille, France
  • Edgevana, Inc. - AS215724 - 14.102.231.203 - Singapore
  • doclient.dll disassembly - Build 26100.7309 - BCrypt call sites 0x18001493f, 0x1800d9d83