// HACKER NEWS — CYBERSECURITY
CVE-2025-13032: Entering and Breaking the Avast Antivirus Sandbox Part 2
This post is the second and final part of our Avast Antivirus research, detailing the full exploitation of CVE-2025-13032 on an up-to-date Windows 11 system. Starting from the double-fetch vulnerability introduced in Part 1, we walk through how the controlled paged pool overflow was turned into an arbitrary kernel read/write primitive by corrupting the RegBuffers array of the IORing object. The post covers the heap spray strategy, the kernel address leak via MDL introspection, the repairs needed to avoid a blue screen on teardown, and the final privilege escalation to SYSTEM via token theft.
This blogpost is the second and final part of our Avast research and will focus on the exploitation of CVE-2025-13032, a double-fetch vulnerability we discovered in Avast’s kernel driver.
This post recaps the bug and walks through how we exploited it on an up-to-date Windows 11 system at the time of the finding.
Feel free to read the first part if you missed it → https://www.safateam.com/intelligence-hub/research/technical-articles/cve-2025-13032-entering-and-breaking-the-avast-antivirus-sandbox-part-1
Note: In the latest version the windows kernel and drivers are using user-mode accessors (https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/user-mode-accessors) to verify each kernel access to user-mode memory and ensure at each access that user-buffers are in fact reside in userspace. This mitigation will prevent the use of the exploitation technique that is described in this writeup, see additional details at https://www.youtube.com/watch?v=ry4SNYe2f68
The bug we want to exploit is a double fetch issue that leads to a kernel pool overflow.
The snippet of code presented below is supposed to capture a `_UNICODE_STRING` structure supplied by the user, but the `Length` field of the user input is fetched multiple times which results in the double fetch issue.
The first fetch is done to allocate a buffer where the string will be copied and a second fetch is done to perform a memcpy based on the retrieved value resulting in a pool overflow if the user changes it between those actions.
To exploit the double fetch, a second thread runs in a tight loop, continuously toggling the `Length` field of the shared `_UNICODE_STRING` between a small safe value and a large malicious value (e.g. `0x1000`, larger than the allocated buffer). The main thread calls the vulnerable IOCTL in a loop. When the timing aligns — the kernel reads `Length` as small for the `ExAllocatePoolWithTag` call, then reads it as large for the `memmove` — more bytes are copied than were allocated, producing the pool overflow. The race window is narrow but can be won reliably within a modest number of iterations.
Our goal is to exploit this pool overflow to gain an arbitrary kernel read/write primitive and achieve a local privilege escalation. The bug gives us good exploitation conditions: the overflow targets `PAGED_POOL`, both the allocation size and the overflow size are controlled, and so is the content.