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
- What is Windows Delivery Optimization?
- Why Nobody Has Researched This Properly
- Phase 1 - Finding the Real Implementation
- Phase 2 - Cache Structure, ACLs, and Chunk Analysis
- Phase 3 - Following the Network: CDN Discovery
- Phase 4 - The URL Structure and the P4 Token
- Phase 5 - Verification Failure Behavior
- Phase 6 - Binary Analysis: Confirming the Verification Architecture
- Phase 7 - Attack Surface and Chain Analysis
- Detection Rules
- 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:
- Chunk arrives from peer or CDN
- SHA-1 hash computed, compared against PHF entry:
"Swarm %s, piece %u failed hash check" - Failure logged to ETW provider
f8ad09ba-419c-5134-1750-270f4d0fb889 - Retry scheduled after configurable delay:
"DISC: Will retry failed (hr = %x) call after %lld ms" - 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
WinVerifyTrustat0x1800b4bee. 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 at0x1800b4bee. 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-270f4d0fb889in your SIEM and alert on DO-002 patterns - In high-security environments, set
DownloadMode: 0(HTTP only, CDN-direct) orDownloadMode: 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