A security guard who checks your badge twice but looks away between scans — long enough to swap it for an all-access pass
CVE-2025-13032 is a double-fetch (TOCTOU) race condition in the aswSnx.sys kernel driver that implements the sandbox and DeepScreen features in Avast and AVG Antivirus for Windows versions below 25.3. The driver reads a _UNICODE_STRING length field from user-mode memory twice — once to allocate a kernel pool buffer via ExAllocatePoolWithTag, and once to copy data with memmove. A multi-threaded attacker flips the length between reads, causing the kernel to allocate a small buffer but copy a large payload, producing a controlled paged-pool overflow. The SAFA Team research demonstrates turning this primitive into arbitrary kernel read/write via IORing RegBuffers corruption, culminating in SYSTEM-level token theft. Avast/AVG version 25.2.9898.0 and earlier are confirmed affected across four distinct double-fetch variants in IOCTL handler 0x82AC0204. The fix shipped in 25.3.9983.922 on April 9, 2025, though Gen Digital delayed CVE publication until November 11, 2025 — over seven months — describing the update only as *stability and performance fixes*.
The vendor scored this CVSS 9.9 CRITICAL with vector AV:N/AC:L/PR:L/UI:N/S:C — noisgate disputes two components. First, AV:N is incorrect: the exploit fires IOCTL calls to a local kernel driver handle, not a network service. Even in the sandbox-escape threat model (malware arrives over the network, gets sandboxed, exploits the driver), the vulnerable interface is a local IOCTL — CVSS measures how the attacker reaches the *vulnerable component*, not how the payload arrives on the system. Correct vector is AV:L. Second, AC:L is incorrect: the exploit requires winning a multi-threaded race against the kernel, performing Low Fragmentation Heap spray for pool grooming, corrupting an IORing object with precise alignment, leaking ExpPoolQuotaCookie, and repairing the ProcessBilled pointer to avoid BSOD — this is textbook AC:H. A corrected base of AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H yields ~8.1, and real-world friction (no public PoC, 0.248% EPSS, no KEV, consumer-dominated install base) pulls the practical risk further down. The vendor's 9.9 will needlessly panic enterprise teams that may not even run this product.
5 steps from start to impact.
Gain local code execution on target host
- Target host runs Avast/AVG < 25.3 on Windows
- Attacker has local code execution as any user
- Requires prior compromise or successful social engineering
- Avast/AVG's own real-time scanning may detect and block the initial payload
- Enterprise environments with application allow-listing block unsigned binaries
Register process in Avast sandbox configuration
0x82AC0204 is restricted to sandboxed processes. The attacker bypasses this gate by calling IOCTL 0x82AC0054 — which is accessible with read-only permissions — to register their process in the sandbox configuration via snx_lconfig.xml. This silently adds the attacker's process to the sandbox roster, granting access to the restricted IOCTL attack surface without any privilege escalation. No public tooling exists for this step; the attacker must reverse-engineer the CfgInput structure.- Successful code execution from step 1
- Ability to open a handle to the aswSnx.sys device object
- Requires reverse engineering of the CfgInput structure (Flags, ScanHandle, Name fields)
- No public PoC or tooling available — custom development required
%ProgramData%\Avast Software\Avast\snx_lconfig.xml can detect unauthorized sandbox registrations. Unusual device handle access to aswSnx may be logged by advanced EDR.Race the kernel's double fetch on IOCTL 0x82AC0204
_UNICODE_STRING input, and another continuously toggling the Length field between a small value (e.g., 0x100) and a large value (e.g., 0x1000). When the kernel reads the small length for allocation but the large length for the copy, the race is won. This may require thousands of iterations and each failed attempt risks a kernel crash (BSOD), making noisy, destructive failures likely during development and deployment of the exploit.- Process registered in sandbox (step 2)
- Valid handle to IOCTL 0x82AC0204
- Narrow race window — timing depends on CPU scheduling, core count, and system load
- Failed race attempts cause BSOD, destroying attacker persistence and alerting defenders
- Requires precise multi-threaded synchronisation — no public PoC simplifies this
Overflow paged pool into adjacent IORing object
RegBuffers array of a carefully positioned _IORING_OBJECT in the kernel paged pool. The attacker pre-sprays the pool with IORing allocations sized to land adjacent to the overflow buffer. Corrupting RegBuffers[0] to point to a fake _IOP_MC_BUFFER_ENTRY in userland grants an arbitrary kernel read/write primitive via IoRingReadFile (write) and IoRingWriteFile (read) operations. The attacker must also leak and repair the ProcessBilled cookie (EPROCESS ^ ChunkAddress ^ ExpPoolQuotaCookie) to prevent BSOD during pool chunk deallocation.- Race won successfully (step 3)
- Pool spray achieves correct IORing object adjacency
- LFH randomization makes pool placement probabilistic — multiple attempts may be needed
- IORing exploitation technique requires Windows 11 or recent Windows 10 builds with IORing support
- ProcessBilled repair requires leaking ExpPoolQuotaCookie from an uncorrupted adjacent chunk
Token theft — escalate to SYSTEM
EPROCESS doubly-linked list starting from a leaked pointer (obtained via the IORing MDL trick), locates the SYSTEM process's Token value, and overwrites their own process's Token field. This elevates the attacker to SYSTEM without calling any audited privilege APIs or creating new processes. The attacker then spawns a SYSTEM command shell or injects into a privileged service process.- Stable arbitrary kernel R/W from step 4
- Kernel ASLR and pointer obfuscation require the initial info leak to succeed first
- Must increment ReferenceCount on userland fake buffer entry to prevent kernel cleanup crash
The supporting signals.
| In-the-wild exploitation | Not observed. No reports from threat intelligence vendors, CISA, or incident response firms as of September 2026. The SAFA Team disclosure was purely research-driven with no evidence of malicious use. |
|---|---|
| PoC availability | No public exploit code. SAFA Team published a detailed 2-part technical writeup (Part 1, Part 2) with pseudocode and annotated screenshots, but withheld working exploit code. No repos found on GitHub or ExploitDB. |
| EPSS score | 0.00248 (0.248%) — very low predicted probability of exploitation in the next 30 days, consistent with the absence of public tooling and the high skill bar for kernel race-condition exploitation. |
| KEV status | Not listed. CISA Known Exploited Vulnerabilities catalog does not include CVE-2025-13032 as of September 2026. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H (9.9) — vendor-assigned. noisgate disputes AV:N (should be AV:L, local IOCTL) and AC:L (should be AC:H, multi-threaded kernel race). Corrected base score ≈ 8.1. |
| Affected versions | Avast/AVG Antivirus for Windows < 25.3 — confirmed vulnerable on 25.2.9898.0 and earlier. Gen Digital's shared codebase across Avast, AVG, Avira, and Norton means other brands *may* share the aswSnx.sys driver, though only Avast/AVG are named in the advisory. |
| Fixed version | 25.3.9983.922 — released April 9, 2025 via auto-update. Gen Digital described the patch only as *stability and performance fixes* with no security advisory. CVE not published until November 11, 2025 (~7 months post-patch). |
| Scanning / exposure | Desktop endpoint product — no internet-facing attack surface. Shodan/GreyNoise/Censys/FOFA not applicable (no listening port or web interface). Avast/AVG holds ~8% AV market share per industry reports, predominantly consumer and SMB. ~1,022 enterprises use AVG per 6sense. |
| Disclosure timeline | Researcher submitted to Gen Digital ~March 2025 → patch shipped April 9, 2025 (12 days) → CVE published November 11, 2025 → SAFA Team Part 1 published December 1, 2025 → Part 2 published September 18, 2026. |
| Researcher / org | SAFA Team (safateam.com). The same driver aswSnx.sys has a documented history of similar flaws: CVE-2015-8620 (heap overflow, EDB-42182), CVE-2023-5760 (TOCTOU/OOB write, fixed in 23.9). This is the third major kernel vuln in this component. |
Sources.
- SAFA Team — Entering and Breaking the Avast Sandbox (Part 1)
- SAFA Team — Entering and Breaking the Avast Sandbox (Part 2)
- Heise Online — Avast and AVG: Critical Security Vulnerability Quietly Patched
- GitHub Advisory Database — GHSA-hf76-wr32-wv5w
- CyberPress — Avast Antivirus Sandbox Vulnerabilities
- SentinelOne Vulnerability Database — CVE-2025-13032
- NVD — CVE-2025-13032
Why this verdict
- CVSS vector misscored (−1.8 points): The vendor's
AV:Nis incorrect — the exploit sends IOCTL requests to a local kernel driver, not a network service. Correcting toAV:Land adjustingAC:LtoAC:H(multi-threaded race, heap spray, IORing corruption, cookie repair) drops the base from 9.9 to ~8.1. This is the largest single adjustment. - No weaponisation path exists today (−0.3 points): Zero public PoC code, EPSS at 0.248% (bottom quartile), not on CISA KEV, and no in-the-wild exploitation reported in the 17+ months since the patch shipped. Building this exploit from the writeup requires deep Windows kernel internals expertise — IORing pool grooming, ProcessBilled cookie derivation, and MDL-based info leaks.
- Consumer-dominated installed base (−0.3 points): Avast/AVG holds ~8% AV market share, skewed heavily toward individual users and SMBs. Enterprise security teams running CrowdStrike, SentinelOne, Carbon Black, or Microsoft Defender for Endpoint are entirely unaffected. The realistic enterprise population exposed to this CVE is a fraction of the overall install base.
- Prior compromise required: The attacker needs local code execution *before* this vulnerability becomes relevant. CVE-2025-13032 is a post-initial-access privilege escalation tool, not a first-stage breach vector. The attacker is already inside — the AV itself (or another security control) had to fail first.
- Role multiplier:
aswSnx.sysis a kernel-mode security agent running at ring 0, which triggers the noisgate HIGH floor. On any host where Avast/AVG is installed, successful exploitation yields SYSTEM — disabling the AV entirely, enabling tamper-proof persistence, and exposing cached credentials. The blast radius is host-level (not fleet or domain), but a compromised AV agent on an AD-joined workstation or member server gives the attacker a clean pivot for lateral movement with no security tooling watching. Avast/AVG is not typically deployed on domain controllers, identity providers, or backup servers in enterprise environments, so the worst-case high-value-role outcome (domain takeover via DC compromise) is not applicable. The floor holds at HIGH.
Why not higher?
The vendor's CRITICAL 9.9 assumes network reachability (AV:N) and low complexity (AC:L) — both are demonstrably wrong. The actual attack requires local code execution as a prerequisite, a difficult multi-threaded race condition against the kernel, advanced heap grooming with LFH randomisation, IORing-specific exploitation techniques available only on recent Windows builds, and ProcessBilled cookie repair to avoid crashing the host. No public exploit exists, EPSS is bottom-quartile, there is no KEV listing, and the product's enterprise footprint is small. The blast radius is single-host SYSTEM — there is no direct path from this vulnerability alone to domain-wide or fleet-wide compromise.
Why not lower?
The vulnerability lives in a ring-0 kernel driver that is part of the host's primary security stack. Successful exploitation completely subverts the AV defence and grants SYSTEM — the highest local privilege on Windows. The SAFA Team research proves the full chain end-to-end from standard user to SYSTEM, and the aswSnx.sys driver has a track record of similar bugs (CVE-2015-8620, CVE-2023-5760), confirming the attack surface is well-mapped by researchers. A MEDIUM rating would undercount the impact on the hosts that *do* run this product and would ignore the kernel-mode agent floor rule.
aswSnx.sys attack surface. Complete migration within 180 days per the noisgate HIGH remediation SLA.- Network firewalls / IPS — The exploit is entirely local (IOCTL calls to a kernel driver). No network traffic is generated during exploitation; perimeter controls are completely irrelevant.
- Disabling the Avast sandbox in the UI — The
aswSnx.sysdriver may still load at boot and accept IOCTL requests even when the sandbox feature is toggled off in the user interface. Only a full upgrade or uninstall removes the attack surface. - Running a second AV alongside Avast — Adding Defender or another AV does not prevent IOCTL access to
aswSnx.sysand does not block the exploit chain. Dual-AV configurations increase total kernel attack surface rather than reducing it.
Crowdsourced verification payload.
Run on each target Windows host as any user (no admin required for the basic version check). Execute: powershell -ExecutionPolicy Bypass -File Check-CVE-2025-13032.ps1. Exits 0 (PATCHED), 1 (VULNERABLE), or 2 (UNKNOWN — product not detected).
<#
.SYNOPSIS
CVE-2025-13032 checker - Avast/AVG aswSnx.sys double-fetch LPE
.DESCRIPTION
Detects whether the installed Avast or AVG Antivirus is vulnerable
to CVE-2025-13032. Outputs VULNERABLE, PATCHED, or UNKNOWN.
#>
$ErrorActionPreference = 'SilentlyContinue'
$exitCode = 2
$result = 'UNKNOWN'
# --- Locate the driver binary ---
$driverPaths = @(
"$env:SystemRoot\System32\drivers\aswSnx.sys",
"$env:ProgramFiles\Avast Software\Avast\aswSnx.sys",
"$env:ProgramFiles\AVG\Antivirus\aswSnx.sys"
)
$driverFound = $null
foreach ($p in $driverPaths) {
if (Test-Path -LiteralPath $p) { $driverFound = $p; break }
}
# --- Fallback: check registry for product version ---
$regPaths = @(
'HKLM:\SOFTWARE\Avast Software\Avast',
'HKLM:\SOFTWARE\AVG\Antivirus'
)
$productVersion = $null
$productName = $null
if (-not $driverFound) {
foreach ($rp in $regPaths) {
if (Test-Path $rp) {
$props = Get-ItemProperty -Path $rp -ErrorAction SilentlyContinue
if ($props.ProgramVersion) {
$productVersion = $props.ProgramVersion
$productName = if ($rp -match 'AVG') {'AVG Antivirus'} else {'Avast Antivirus'}
break
}
}
}
}
# --- Not installed ---
if (-not $driverFound -and -not $productVersion) {
Write-Host '[*] Neither Avast nor AVG Antivirus detected on this host.'
Write-Host 'UNKNOWN'
exit 2
}
# --- Determine version ---
$checkVersion = $null
if ($driverFound) {
$fi = (Get-Item -LiteralPath $driverFound).VersionInfo
$checkVersion = $fi.FileVersion
Write-Host "[*] Driver found : $driverFound"
Write-Host "[*] Driver version: $checkVersion"
} elseif ($productVersion) {
$checkVersion = $productVersion
Write-Host "[*] Product found : $productName"
Write-Host "[*] Product version: $checkVersion"
}
if (-not $checkVersion) {
Write-Host '[!] Could not determine version.'
Write-Host 'UNKNOWN'
exit 2
}
# --- Compare against fixed version 25.3.9983.922 ---
$vClean = ($checkVersion -replace '[^0-9.]','').TrimEnd('.')
try {
$installed = [Version]$vClean
$fixed = [Version]'25.3.9983.922'
if ($installed -lt $fixed) {
Write-Host "[!] Version $vClean is BELOW fixed version 25.3.9983.922"
$result = 'VULNERABLE'
$exitCode = 1
} else {
Write-Host "[+] Version $vClean is AT or ABOVE fixed version 25.3.9983.922"
$result = 'PATCHED'
$exitCode = 0
}
} catch {
Write-Host "[!] Version parse error for '$vClean' - manual review needed."
$result = 'UNKNOWN'
$exitCode = 2
}
Write-Host ''
Write-Host $result
exit $exitCode