← Back to Feed CACHED · 2026-07-22 20:48:27 · CACHE_KEY CVE-2026-50458
CVE-2026-50458 · CWE-362 · Disclosed 2026-07-14

Use after free in Microsoft Brokering File System

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A cleanup routine in the Win32 App Isolation broker frees its own linked-list head and then keeps walking it

The bug lives in bfs.sys, the Brokering File System mini-filter Microsoft introduced to back Win32 App Isolation (AppSilo containers). During BfsCloseStorage, the driver deallocates the head of the DirectoryBlockList on the first loop iteration and then continues to dereference the freed chunk on subsequent iterations — a textbook use-after-free with a race window. A local, authenticated caller who can obtain a handle with the right AppSilo-flavored token and issue the vulnerable IOCTL against a PolicyEntry whose StorageObject holds multiple DirectoryBlockList entries can groom the pool and land arbitrary kernel writes → SYSTEM. Affected surface is every currently-supported Windows 10, Windows 11, and Windows Server SKU that ships bfs.sys (introduced roughly two years before disclosure, so 22H2 forward on the client side and Server 2022/2025 on the server side).

Microsoft's HIGH / 7.8 is defensible but a touch generous. The AV:L/PR:L/UI:N/C:H/I:H/A:H math correctly captures the *impact* — full kernel-mode compromise — but the practical exploitability is 'Less Likely' by Microsoft's own assessment: a narrow deallocation-to-reuse race, dependent on AppSilo token possession, with no public PoC and an EPSS of 0.18%. Real-world posture: this is a second-stage tool in a post-phish/post-malware chain, not a wormable primitive. We hold it at HIGH because the *target population is 100% of the Windows fleet* and kernel LPEs are the standard rung in every commodity intrusion — but we tick the reassessed score down to 7.0 to reflect the race-window friction.

"Kernel UAF in bfs.sys hands SYSTEM to any local low-priv process — race is fiddly but the target ships on every modern Windows host."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Land unprivileged code execution on the host

The attacker needs any low-integrity execution context on the target Windows machine — a malicious document macro, a browser sandbox escape, a phishing payload, a stolen VDI session, or an insider account. AV:L/PR:L means no network reachability is enough; the attacker must be *on the box* as at least a standard user.
Conditions required:
  • Local execution as any authenticated user
  • Ability to open handles and issue IOCTLs
Where this breaks in practice:
  • Requires prior initial access — EDR, AppLocker/WDAC, MOTW, and SmartScreen all sit in front of this step
  • Cloud-only workloads with no interactive users remove most delivery vectors
Detection/coverage: EDR telemetry on process creation, LOLBAS abuse, and script interpreters covers the initial-access step; no signature specific to CVE-2026-50458 yet
STEP 02

Acquire an AppSilo-capable token

The vulnerable IOCTL path is only reachable when the calling process impersonates a token with Win32 App Isolation attributes. Public research (HT3Labs on the earlier bfs.sys UAF family) shows this is typically obtained by spawning or hijacking a process launched under an AppSilo manifest, or by borrowing a token via NtImpersonateThread from an already-isolated app instance (Edge WebView, MSIX-packaged apps, some Store apps).
Conditions required:
  • Presence of at least one AppSilo/AppContainer parent on the host
  • SeImpersonatePrivilege *not* required — token duplication via handle inheritance suffices
Where this breaks in practice:
  • Hosts with no Store/AppSilo apps installed have very little AppSilo token surface at rest
  • Server SKUs typically don't run isolated Win32 apps
Detection/coverage: Sysmon Event ID 4688 with unusual parent-child pairings; Microsoft Defender for Endpoint's 'suspicious token manipulation' alerts
STEP 03

Populate the PolicyTable and DirectoryBlockList

The attacker calls the AppSilo storage-registration APIs to create at least one PolicyEntry whose StorageObject carries multiple DirectoryBlockList nodes. This is the setup that makes the loop iterate more than once, which is what causes the freed head to be dereferenced on iteration 2+.
Conditions required:
  • Ability to invoke AppSilo storage registration ioctls
  • Kernel pool grooming primitives (standard on modern Windows via NtCreateSection, NtAllocateVirtualMemory)
Where this breaks in practice:
  • Race window is small — many attempts required, easy for EDR to notice loop patterns
  • KVA Shadow, HVCI, and Kernel CFG raise the exploitation bar for the pool spray step
Detection/coverage: ETW Microsoft-Windows-Kernel-File provider will log unusual ioctl bursts against bfs.sys if verbose auditing is on
STEP 04

Trigger BfsCloseStorage and win the race

Attacker issues the close-storage ioctl. Between the free of the list head and the next iteration's dereference, a parallel thread must reclaim the freed pool chunk with attacker-controlled data (typical Pipe Attribute or NamedPipe spray). Winning the race converts the UAF into a controlled kernel write.
Conditions required:
  • Multi-core CPU (trivially met)
  • Reliable pool-spray primitive
Where this breaks in practice:
  • Race windows on modern Windows kernels are unreliable — most PoCs need thousands of attempts
  • Kernel telemetry from EDR sensors flag crash loops when the race is lost
Detection/coverage: System crashes / bugchecks (BAD_POOL_HEADER, KERNEL_MODE_HEAP_CORRUPTION) from failed exploit attempts — CIRT should treat repeated bugchecks on one host as a strong indicator
STEP 05

Elevate to SYSTEM and persist

With a controlled kernel write, the attacker overwrites the current process token with a copy of PID 4's (System) token — the standard token-stealing primitive — yielding NT AUTHORITY\SYSTEM. From there: disable EDR (fltmc unload), dump LSASS, install driver-level persistence, or move laterally with the machine account.
Conditions required:
  • Successful step 4
Where this breaks in practice:
  • HVCI blocks arbitrary kernel driver load
  • Credential Guard prevents LSASS secret theft even after SYSTEM
Detection/coverage: Any credible EDR flags token-swap-to-SYSTEM as CRITICAL — this is well-covered ground
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed exploitation as of 2026-07-23. Microsoft marks this 'Exploitation Less Likely'. Not on CISA KEV.
Public PoCNone specific to CVE-2026-50458. The *sibling* bug CVE-2025-29970 (same driver, same class, disclosed by HT3Labs) has a public technical writeup that maps closely to this bug's primitive.
EPSS0.00184 (0.18%) — bottom-quartile, consistent with a local-only kernel UAF with no PoC
KEV statusNot listed
CVSSCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H → 7.8 HIGH. Local, low-priv, no UI, full CIA — the classic LPE-to-SYSTEM shape
CWECWE-362 (race condition) chained with CWE-416 (use-after-free)
Affected versionsWindows 10 22H2, Windows 11 22H2/23H2/24H2, Windows Server 2022, Windows Server 2025 — every SKU carrying bfs.sys
Fixed byJuly 2026 Patch Tuesday cumulative updates (KB numbers vary by SKU — see MSRC advisory). No standalone hotfix.
Internet exposureNot applicable — local vector. Shodan/Censys/GreyNoise scan data irrelevant; every Windows host in the fleet is affected regardless of network posture
Disclosure2026-07-14 via MSRC; researcher credit not published in the advisory (bfs.sys UAF class has been tracked by HT3Labs, Angelboy@DEVCORE, and Filip Dragović)
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.0/10)

The single decisive factor is role ubiquity crossed with kernel-mode blast radius: bfs.sys ships on every supported Windows client and server, and a successful chain yields SYSTEM — the canonical LPE outcome that unlocks the rest of every commodity intrusion playbook. Race-condition friction and 'Exploitation Less Likely' pull the reassessed score down inside the HIGH bucket but cannot break the floor: an authenticated local kernel UAF affecting 100% of the Windows fleet stays HIGH until a PoC drops or telemetry says otherwise.

HIGH on affected-version scope and patch availability
HIGH on absence of current in-the-wild exploitation
MEDIUM on real-world exploit reliability — race windows are unpredictable

Why this verdict

  • Ubiquity multiplier: bfs.sys is present on every modern Windows SKU — the affected population is effectively the entire Windows install base, not a niche product
  • Role multiplier: on workstations the chain ends at local SYSTEM (host-scoped blast radius); on domain-joined servers with cached admin tickets, on jump hosts, on Tier-0 admin workstations, and on RDS/AVD session hosts the same SYSTEM primitive is the launchpad for Kerberoasting, LSASS dumping (where Credential Guard is off), and lateral movement — chain succeeds and blast radius reaches domain-scale. Floor is HIGH.
  • Friction — race window: UAF requires winning a deallocation-to-reuse race against pool sprays; historically this class of Windows kernel race takes hundreds to thousands of attempts, producing bugchecks that any competent EDR treats as an incident
  • Friction — prior compromise required: AV:L/PR:L means the attacker is *already on the box* as a user; this is a second-stage weapon, not an initial-access vector — that's what keeps the score at 7.0 instead of the vendor's 7.8
  • Friction — no PoC, no ITW: EPSS 0.18%, Microsoft 'Exploitation Less Likely', KEV clean. Real weaponization pressure is currently low

Why not higher?

Not CRITICAL because there is no unauthenticated network vector, no PoC, no observed exploitation, and the race-window reliability is genuinely poor. Kernel LPEs in the Microsoft catalog only cross into CRITICAL when a working exploit is public or in ransomware toolkits (Nokoyawa's PPL bypass, Lace Tempest's CLFS chain) — this one is neither.

Why not lower?

Not MEDIUM because bfs.sys is on every Windows host in your fleet and the payoff is SYSTEM. Downgrading a ubiquitous kernel UAF to MEDIUM based purely on 'no PoC yet' is how organizations end up patching in the 365-day backlog window and then getting mugged when the exploit lands in Cobalt Strike's BOF library six weeks later.

05 · Compensating Control

What to do — in priority order.

  1. Enable HVCI and Memory Integrity fleet-wide — Hypervisor-protected Code Integrity substantially raises the cost of turning a kernel UAF into arbitrary kernel execution. Push via Intune / GPO under Device Guard. Deploy within 30 days per the noisgate mitigation SLA for HIGH.
  2. Enforce Credential Guard on all workstations and Tier-1/Tier-0 servers — Even if the attacker reaches SYSTEM via this UAF, Credential Guard denies them cached Kerberos TGTs and NTLM hashes from LSASS — that cuts off the domain-lateral leg of the chain. Deploy within 30 days.
  3. Set your EDR to alert on unexpected bugchecks — Failed race exploits crash the box with BAD_POOL_HEADER / KERNEL_MODE_HEAP_CORRUPTION. Two+ bugchecks on one endpoint inside 24h should page the SOC. Tune this rule this week while the patch rolls.
  4. Restrict AppSilo/MSIX app installation via WDAC — The token acquisition step requires an AppSilo-capable parent process. On server SKUs with no legitimate need for isolated Win32 apps, block MSIX/AppSilo package registration outright. Within 30 days.
  5. Deploy the July 2026 cumulative update ring — Ring-0 → Ring-1 → Ring-2 → fleet. Kernel patches historically ship clean; there is no known regression on the July 2026 CU set. Complete fleet rollout within 180 days per the noisgate remediation SLA for HIGH.
What doesn't work
  • Perimeter firewalls / IPS rules — the vector is local; no packet traverses the wire
  • Least-privilege user accounts — PR:L; a standard user token is already sufficient, removing local admin does nothing
  • Application allowlisting alone (AppLocker) — helps against step 1 initial-access, does not stop the kernel primitive if the attacker uses a signed LOLBIN to load their staging code
  • Disabling SMB / RDP — unrelated attack surface; bfs.sys ioctls are local kernel calls
06 · Verification

Crowdsourced verification payload.

Run on the target Windows host in an elevated PowerShell session (Run as Administrator). The script checks the version of bfs.sys against the July 2026 Patch Tuesday fixed build. Invoke as: powershell.exe -ExecutionPolicy Bypass -File .\Check-CVE-2026-50458.ps1. Requires local admin to read the driver metadata reliably.

noisgate-verify.ps1
POWERSHELLREAD-ONLYSAFE
#requires -RunAsAdministrator
# Check-CVE-2026-50458.ps1
# noisgate verification for Microsoft Brokering File System UAF (CVE-2026-50458)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

$ErrorActionPreference = 'Stop'
$driver = Join-Path $env:SystemRoot 'System32\drivers\bfs.sys'

if (-not (Test-Path $driver)) {
    Write-Output 'PATCHED (bfs.sys not present on this SKU — not affected)'
    exit 0
}

try {
    $info = (Get-Item $driver).VersionInfo
    $ver  = [Version]$info.FileVersion.Split(' ')[0]
    Write-Output "bfs.sys version: $ver"

    # July 2026 Patch Tuesday fixed build floors (verify against MSRC advisory for your SKU):
    #   Windows 11 24H2 : 10.0.26100.4500 or later
    #   Windows 11 23H2 : 10.0.22631.4900 or later
    #   Windows 10 22H2 : 10.0.19041.5300 or later
    #   Server 2025     : 10.0.26100.4500 or later
    #   Server 2022     : 10.0.20348.3200 or later
    $build    = $ver.Build
    $revision = $ver.Revision

    $fixed = switch ($build) {
        26100 { 4500 }
        22631 { 4900 }
        22621 { 4900 }
        19041 { 5300 }
        20348 { 3200 }
        default { $null }
    }

    if ($null -eq $fixed) {
        Write-Output "UNKNOWN (unrecognized build $build — check MSRC advisory manually)"
        exit 2
    }

    if ($revision -ge $fixed) {
        Write-Output "PATCHED (revision $revision >= fixed floor $fixed for build $build)"
        exit 0
    } else {
        Write-Output "VULNERABLE (revision $revision < fixed floor $fixed for build $build) — apply July 2026 cumulative update"
        exit 1
    }
} catch {
    Write-Output "UNKNOWN (error reading bfs.sys: $_)"
    exit 2
}
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: pull your July 2026 Patch Tuesday deployment status report and identify every Windows host that has not yet taken the CU — that IS the vulnerable set for CVE-2026-50458. Kick off the EDR bugcheck-alerting rule and the HVCI/Credential Guard enforcement rollout inside the noisgate mitigation SLA of 30 days for a HIGH verdict. Complete full fleet deployment of the July 2026 cumulative update inside the noisgate remediation SLA of 180 days, prioritizing Tier-0 admin workstations, jump hosts, RDS/AVD session hosts, and any endpoint with cached privileged credentials in the first 30 days. If a working PoC appears publicly or GreyNoise/MDE telemetry starts showing bugchecks tied to bfs.sys, collapse the timeline to 'patch immediately, within hours' and treat as if KEV-listed.

Sources

  1. MSRC advisory — CVE-2026-50458
  2. MSRC advisory — sibling CVE-2026-49162 (same driver)
  3. GBHackers — bfs.sys UAF technical writeup (CVE-2025-29970 predecessor)
  4. Cybersecurity News — Brokering File System LPE analysis
  5. SentinelOne vulnerability database — related bfs.sys CVE
  6. Rapid7 vuln DB — CVE-2026-58526 (same UAF class)
  7. CISA Known Exploited Vulnerabilities catalog
  8. FIRST EPSS model
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.