Aug 4, 2026·7 min read·3 visits
An integer truncation in the Microsoft Malware Protection Engine's QEX parsing logic causes a heap-based buffer under-allocation followed by an out-of-bounds memory write, leading to remote code execution or denial of service with local SYSTEM privileges.
A comprehensive technical analysis of CVE-2026-45584, a high-severity heap-based buffer overflow in Microsoft Defender's QEX parsing logic. The vulnerability resides within mpengine.dll and allows unauthenticated remote code execution or denial of service when processing crafted archives designed to trigger threat remediation and QEX history logging.
The Microsoft Malware Protection Engine (mpengine.dll) serves as the core scanning component for Microsoft Defender, executing within the context of the highly privileged service MsMpEng.exe (running as NT AUTHORITY\SYSTEM). This architecture exposes a broad attack surface, as the engine automatically parses untrusted binary streams, compressed archives, and file metadata encountered across the network and filesystem.\n\nThe vulnerability, registered as CVE-2026-45584, resides within the engine's parsing logic for proprietary QEX files. QEX files are internal containers utilized by Microsoft Defender to log local scan histories and manage quarantined security items. The parsing flaw belongs to the heap-based buffer overflow class (CWE-122) and is triggered during the processing of QEX resource record lists.\n\nBecause the scanning engine performs passive evaluation of files written to disk or transferred over the network, exploitation does not require manual interaction from a logged-in user. The engine triggers automatically upon detecting threats, which initiates the cleanup, quarantine, or scan history logging phases where the vulnerable parsing logic is executed.
The vulnerability originates in the ParseQexResourceRecordList function within mpengine.dll. This routine is responsible for reading the structure of QEX resource records and converting binary logs into active memory structures. During this process, the engine extracts a 16-bit unsigned integer value representing the payload length of the resource record, which is designated as payloadLen16.\n\nTo ensure integrity, the engine performs a validation check against the input stream, confirming that the physical stream contains at least payloadLen16 bytes of data. However, the flaw emerges when calculating the memory allocation size required for the destination heap buffer. The logic adds a static metadata header overhead (such as 0x20 bytes) directly to the 16-bit payload length value.\n\nBecause payloadLen16 is a 16-bit integer, if its value is close to the upper limit of 65,535 (0xffff) — for example, 0xffee — adding the header overhead wraps the computed size past the 16-bit limit. Specifically, 0xffee + 0x20 equals 0x1000e. When this value is cast or stored back into a 16-bit variable, the upper bit is truncated, resulting in an allocation size of only 0x000e (14 bytes).\n\nConsequently, the engine allocates an under-sized heap buffer of 14 bytes. It then executes a bulk memory copy operation using the original, untruncated payload length of 0xffee bytes. This mismatch results in an out-of-bounds heap write, corrupting adjacent heap segments and causing a process crash or arbitrary code execution.
Reviewing the logic of the vulnerable function reveals the structural breakdown of the memory corruption. Below is a conceptual representation of the vulnerable disassembly sequence:\n\ncpp\n// Vulnerable parsing logic\nvoid ParseQexResourceRecordList(uint8_t* inputStream, size_t streamSize) {\n uint16_t payloadLen16 = *(uint16_t*)(inputStream + OFFSET_PAYLOAD_LEN);\n \n // Validate that the stream has enough bytes\n if (streamSize < payloadLen16 + OFFSET_PAYLOAD_LEN) {\n return;\n }\n\n // Vulnerable step: integer overflow occurs here during 16-bit addition\n uint16_t allocationSize = payloadLen16 + 0x20;\n\n // Allocates an under-sized buffer due to truncation\n uint8_t* heapBuffer = (uint8_t*)HeapAlloc(GetProcessHeap(), 0, allocationSize);\n if (heapBuffer == nullptr) {\n return;\n }\n\n // Memory copy uses the original long length, leading to overflow\n memcpy(heapBuffer, inputStream + OFFSET_PAYLOAD_DATA, payloadLen16);\n}\n\n\nIn the patched version of mpengine.dll (1.1.26040.8), the allocation size calculation is expanded to a 32-bit integer, and explicit bounds checks are implemented prior to allocation. The updated logic prevents truncation and ensures the allocation size is safe:\n\ncpp\n// Patched parsing logic\nvoid ParseQexResourceRecordList_Patched(uint8_t* inputStream, size_t streamSize) {\n uint16_t payloadLen16 = *(uint16_t*)(inputStream + OFFSET_PAYLOAD_LEN);\n \n if (streamSize < payloadLen16 + OFFSET_PAYLOAD_LEN) {\n return;\n }\n\n // Calculation performed using 32-bit integer to prevent wrap-around\n uint32_t allocationSize32 = (uint32_t)payloadLen16 + 0x20;\n\n // Explicit verification of integer overflow / limits\n if (allocationSize32 > 0xffff) {\n return; // Reject invalid structure\n }\n\n uint8_t* heapBuffer = (uint8_t*)HeapAlloc(GetProcessHeap(), 0, (uint16_t)allocationSize32);\n if (heapBuffer == nullptr) {\n return;\n }\n\n memcpy(heapBuffer, inputStream + OFFSET_PAYLOAD_DATA, payloadLen16);\n}\n\n\nThe binary execution of this vulnerability fails at offset +0xb6890b in mpengine.dll with a Write Access Violation (0xc0000005). The faulting instruction is rep movs byte ptr [rdi], byte ptr [rsi]. Because the destination pointer (rdi) points to the heap buffer of 14 bytes, copying 0xffee bytes causes the pointer to cross the boundary of the allocated block and touch an unmapped or guard page, terminating MsMpEng.exe.
Exploitation of CVE-2026-45584 depends on forcing Microsoft Defender to transition into its threat-cleanup and history-logging routines. An attacker accomplishes this by delivering a payload designed to trigger a positive threat signature while carrying an abnormal path length. This mechanism is demonstrated in the public proof-of-concept archive: vuln2_qex_longpath_eicar_single_layer.zip.\n\nThe proof-of-concept ZIP archive contains an extremely long, highly nested directory structure that terminates in a standard EICAR test string. When the real-time scanning agent evaluates this archive, the detection of the EICAR threat initiates a remediation sequence. This sequence attempts to write scanning metadata and path history into the QEX local log container.\n\nDuring the serialization of this path metadata, the engine structures the records using the full, deeply nested directory path. Because the path is structured to approach the maximum 16-bit length value (near 65,535 bytes), the generated history record triggers the integer wrapping condition in ParseQexResourceRecordList. The subsequent out-of-bounds write occurs automatically as the engine tries to log the detection.\n\nTo reproduce this crash in a diagnostic environment, a researcher can invoke the command-line scanner directly against the archive using the administrative platform interface:\n\npowershell\n$mp = Get-ChildItem \"$env:ProgramData/Microsoft/Windows Defender/Platform\" -Recurse -Filter MpCmdRun.exe | Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty FullName\n& $mp -Scan -ScanType 3 -File ./vuln2_qex_longpath_eicar_single_layer.zip\n\n\nThis execution bypasses user interface components and directly triggers the parsing logic within mpengine.dll, leading to an immediate crash of MsMpEng.exe.
The primary security consequence of CVE-2026-45584 is either Denial of Service (DoS) or arbitrary code execution. Because Microsoft Defender executes as NT AUTHORITY\SYSTEM, any successful control flow hijack within MsMpEng.exe grants the attacker local SYSTEM privileges, bypassing all operating system security controls and access restrictions.\n\nAlternatively, triggering the heap-based buffer overflow can result in a crash loop of the antivirus service. This effectively blinds the endpoint's real-time security scanning capabilities. If an attacker delivers the malformed payload periodically, the Defender service remains unavailable, enabling the unmonitored delivery and execution of secondary payloads.\n\nThe vulnerability is classified with a CVSS base score of 8.1, indicating high severity. The attack vector is Network (AV:N), as the file can be delivered via email, file share, or browser download. However, the Attack Complexity is High (AC:H) because exploitation requires triggering a specific state transition inside the scanner (such as threat classification and logging) and managing heap grooming to survive the out-of-bounds copy.
Remediation requires updating the Microsoft Malware Protection Engine to version 1.1.26040.8 or higher. Because Microsoft Defender updates its engine independently of standard operating system update cycles, endpoints connected to the internet generally receive this patch automatically within 48 hours of release.\n\nTo manually verify the installed version and force an update on enterprise hosts, administrators can run the following PowerShell command with administrative privileges:\n\npowershell\nUpdate-MpSignature\n\n\nIn addition to patching, enterprise security teams can monitor host performance and log data to detect exploitation attempts. The following XML event query can be imported into Windows Event Viewer to filter for MsMpEng.exe crashes caused specifically by this heap corruption:\n\nxml\n<QueryList>\n <Query Id=\"0\" Path=\"Application\">\n <Select Path=\"Application\">\n *[System[(EventID=1000)]] \n and \n *[EventData[Data[1]='MsMpEng.exe' and Data[2]='mpengine.dll' and Data[4]='0xc0000005' and Data[5]='0x0000000000b6890b']]\n </Select>\n </Query>\n</QueryList>\n
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Microsoft Malware Protection Engine Microsoft | < 1.1.26040.8 | 1.1.26040.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-122 / CWE-190 |
| Attack Vector | Network / Local File Parsing |
| CVSS Base Score | 8.1 |
| EPSS Score | 0.00852 (Percentile: 54.69%) |
| Impact | Remote Code Execution (RCE) / Denial of Service (DoS) |
| Exploit Status | Proof-of-Concept (PoC) Available |
| Affected Component | mpengine.dll (ParseQexResourceRecordList) |
A heap-based buffer overflow condition occurs when a buffer allocated on the heap is overwritten with more data than it can hold, leading to memory corruption, crashes, or arbitrary code execution.
CVE-2026-69258 is a high-severity property injection and unauthenticated authorization bypass vulnerability in Flowise, a drag-and-drop orchestration interface for building customized LLM workflows. In affected versions prior to 3.1.3, the unauthenticated prediction API endpoint (`POST /api/v1/prediction/:id`) processed client-controlled parameters inside an `overrideConfig` payload without authorization checks. The backend unconditionally spread this object into internal context structures, enabling unauthenticated remote attackers to overwrite critical session values, pollute execution contexts, and bypass flow restrictions.
CVE-2026-69252 represents a missing authorization check (CWE-862) in the files API route (`/api/v1/files`) of Flowise, a drag-and-drop user interface for building LLM flows. Prior to version 3.1.3, an authenticated API key or user could list, access, and delete files across arbitrary workspaces inside an organization, completely bypassing workspace logical boundaries.
A medium-severity vulnerability in Undici's retry interceptor causes body-length mismatches with the Content-Length header during HTTP 206 response resumption. Forwarding these inconsistent headers downstream leads to HTTP response desynchronization, connection hangs, or potential protocol smuggling.
CVE-2026-16729 (GHSA-v3r7-h72x-cjcm) is a medium-severity cookie attribute injection vulnerability in Undici's web-compliant cookie utility module. Due to insufficient validation of domain parameters and raw attributes in the unparsed options array, arbitrary attributes like SameSite, HttpOnly, and Secure can be injected. This allows attackers to bypass CSRF protections, strip security flags, or override intended cookie behaviors when applications pass user-controlled values to these properties.
An interpretation conflict (CWE-436) in the cache interceptor of the undici HTTP client for Node.js causes whitespace-padded Cache-Control directives to be parsed incorrectly, leading to shared cache pollution and the unauthorized disclosure of sensitive, private, or authenticated user information (CWE-524).
CVE-2026-15157 details an improper neutralization of CRLF sequences ('CRLF Injection') within undici, a widely used Node.js HTTP/1.1 client. The vulnerability is triggered when processing request bodies that exhibit a duck-typed blob-like interface. When an application accepts untrusted data and assigns it to the .type property of such an object without setting an explicit Content-Type on the request, undici appends the value directly to the outgoing headers array without validating it against control characters. This allows remote attackers to inject carriage return and line feed sequences, culminating in arbitrary header injection, HTTP response splitting, or HTTP request smuggling.