Skip to content

Instantly share code, notes, and snippets.

@irsdl
Created June 10, 2026 21:23
Show Gist options
  • Select an option

  • Save irsdl/ad54a34d7bd16b092e0911e27135ebe1 to your computer and use it in GitHub Desktop.

Select an option

Save irsdl/ad54a34d7bd16b092e0911e27135ebe1 to your computer and use it in GitHub Desktop.
Analysis of CVE-2026-45595 MOTW Bypass by Opus 4.8

CVE-2026-45595 — Windows Mark-of-the-Web Bypass via unzoned desktop.ini

Patch-diff analysis of the June 2026 cumulative update (KB5094128)

CVE CVE-2026-45595 — Windows Mark of the Web Security Feature Bypass
Severity Important, CVSS 5.4 (not actively exploited at release)
Fixed in KB5094128 — Windows Server 2022 / 21H2, OS build 20348.5256 (released 2026-06-09)
Patched binary windows.storage.dll (11.0/10.0.20348.5256)
Source file onecoreuap\shell\windows.storage\privprof.cpp (per WIL diag strings)
Root cause Shell loaded a folder's desktop.ini without checking its security zone (MOTW)

1. Summary

Microsoft's June 2026 Patch Tuesday silently fixed a Mark-of-the-Web (MOTW) bypass. There is a public CVE entry but no technical root-cause writeup online — MSRC and ZDI only provide boilerplate. This report reconstructs the root cause by binary-diffing the pre- and post-patch windows.storage.dll.

The bug: the Windows shell processed a folder's desktop.ini and honored its directives without verifying the file's security zone. A desktop.ini delivered inside a downloaded archive (ZIP/etc.) carries Zone.Identifier = Internet (MOTW), yet when the user browsed the extracted folder the shell applied its directives as if trusted — bypassing MOTW.

The fix: windows.storage.dll now zone-gates desktop.ini via a new IsTrustedZoneFile() helper and refuses to load it when the file is in an untrusted zone (Internet/Restricted).


2. Affected vs. unaffected components

The June update (express package) stamps each component with the build it was last serviced at. Only the following were touched in June (.5256):

Binary June-serviced? MOTW-relevant change?
windows.storage.dll YES — this fix
shell32.dll no (unrelated June change)
shdocvw.dll no
wininet.dll no
iertutil.dll no
urlmon.dll ❌ (.5139 May)
zipfldr.dll ❌ (.4893 Mar)
cabview.dll ❌ (.2849)
smartscreen.exe ❌ (.5020 Apr)
explorerframe / shlwapi ❌ (.4893)

Because zipfldr/cabview/urlmon/smartscreen were not modified, this is not an archive MOTW-propagation bug nor a SmartScreen/zone-write bug.


3. Root cause (binary evidence)

3.1 New function added in the patch

// windows.storage.dll .5256 — new function, absent in .5139
char __fastcall IsTrustedZoneFile(const unsigned __int16 *path, struct IUnknown *site)
{
    unsigned int zone = -1;
    int hr = SHMapUrlToZoneEx(path, site, 0x400u, &zone);
    if (hr >= 0)
        return zone <= 2;   // 0=LocalMachine, 1=Intranet, 2=Trusted  → trusted
    return 0;               // 3=Internet (has MOTW), 4=Restricted    → NOT trusted
}

SHMapUrlToZoneEx resolves the file path to a URL security zone, which honors the NTFS Zone.Identifier alternate data stream (Mark of the Web). Only zones ≤ 2 are treated as trusted.

3.2 The new guard in CPrivateProfile::Initialize

IsTrustedZoneFile's only caller is CPrivateProfile::Initialize — the private-profile (INI) reader that backs shell desktop.ini processing (e.g. CFSFolder::_DiscoverLocalizedName). The function was rewritten (1711 → 821 bytes) to add, only when the target file is desktop.ini and gated behind feature flag Feature_1133504827:

if (file_is_desktop_ini) {
    if ( !SHWindowsPolicy(POLID_EnableShellShortcutIconRemotePath)
         && !IsTrustedZoneFile(path) ) {       // <-- ADDED in June
        reset(handle);
        return 0;                               // refuse to load/honor the desktop.ini
    }
    INIFile = CPrivateProfileCache::RetrieveINIFile(path, &cachedFile);
}

The pre-patch .5139 version contains no IsTrustedZoneFile reference and calls RetrieveINIFile/CCachedINIFile::Load on the desktop.ini unconditionally.

3.3 Supporting changes

  • IsRunningAsServiceOrSystemAccount() (new) — context exemption so the zone check doesn't break service/SYSTEM scenarios where URL-zone mapping is not meaningful.
  • CPrivateProfileCache / CCachedINIFile rewrite (shared-memory INI cache) — re-keys/validates cache entries so a cached trusted desktop.ini result cannot be reused to satisfy an untrusted lookup (cache-confusion hardening around the new gate).
  • Feature flags: new Feature_1133504827 and Feature_1318059322 act as Velocity kill-switches for the new behavior; the old Feature_Servicing_LocalizedResourceName flag was removed.

4. Attack scenario (pre-patch)

  1. Attacker crafts a folder containing a malicious desktop.ini (e.g. [.ShellClassInfo] with IconResource, LocalizedResourceName, or a CLSID/namespace directive).
  2. Folder is packed into a ZIP (or other archive) and delivered to the victim (download, email, etc.).
  3. Victim extracts the archive. Extracted files carry MOTW (Zone.Identifier, zone 3 = Internet).
  4. Victim browses into the extracted folder in Explorer.
  5. Pre-patch: the shell loads the desktop.ini and applies its directives even though it is from the Internet zone → Mark-of-the-Web bypass; the trust normally withheld from downloaded content is granted.

Impact per the CVE is integrity/availability of MOTW-dependent security features (Office Protected View, SmartScreen prompts) — i.e. those warnings can be evaded for the affected content.


5. Methodology

  1. Baseline backup — box was on 20348.5139 (May, KB5089140 = pre-patch). Backed up the MOTW binary surface (both arches) with a SHA256 manifest.
  2. Acquire patch without installing — downloaded the KB5094128 MSU from the Microsoft Update Catalog; expanded the nested cabs to the component-store forward deltas. No reboot / no change to the box.
  3. Reconstruct whole PEs — applied a two-step delta chain per binary: WinSxS reverse delta (current → RTM base) then LCU forward delta (RTM base → .5256), via msdelta.dll!ApplyDeltaB. Self-validating: ApplyDeltaB checks the embedded source hash, so a wrong base errors out.
  4. Triage — component version stamps narrowed June changes to 5 binaries; a symbol-matched function-size diff (funcs.name/size) isolated the fix to windows.storage.dll and surfaced the new IsTrustedZoneFile / IsRunningAsServiceOrSystemAccount functions and the CPrivateProfile rewrite.
  5. Confirm — decompiled the new function and CPrivateProfile::Initialize (pre vs post); verified IsTrustedZoneFile is absent pre-patch, present post-patch, and how it gates desktop.ini loading.

6. Artifacts

[redacted]


7. References

by Opus 4.8 - High thinking effort - for 12m 18s:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment