CVE-2025-65953
Executive Summary
CVE-2025-65953 is a critical Heap-Use-After-Free (UAF) vulnerability discovered in NanoMQ, an edge messaging platform and MQTT broker. The flaw resides in the TCP transport component, specifically within the NanoNNG library's broker_tcp.c file. It is triggered by malformed MQTTv5 retain message traffic, leading to improper resource management and premature cleanup of message and pipe structures. Successful exploitation could allow an unauthenticated, remote attacker to cause a denial of service (DoS) or potentially achieve arbitrary code execution in the context of the NanoMQ process. The vulnerability affects all versions prior to 0.22.5, and a patch has been released in version 0.22.5.
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
This vulnerability is not related to a package manager (NPM, PyPI, Go, Ruby) but is a core component of the NanoMQ binary distribution. Users should verify the integrity of their NanoMQ binaries and ensure they are sourced from the official repository.
CVSS Breakdown & Threat Level
The CVSS score is currently listed as 0.0, indicating that a full vector has not been assigned by NVD. However, based on the vulnerability characteristics, a reasonable assessment would be:
- Attack Vector (AV): Network (N) – The vulnerability can be triggered remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required beyond sending malformed MQTTv5 packets.
- Privileges Required (PR): None (N) – No authentication is needed.
- User Interaction (UI): None (N) – No user action is required.
- Scope (S): Unchanged (U) – The exploit does not affect other components.
- Confidentiality (C): High (H) – Potential for memory disclosure.
- Integrity (I): High (H) – Potential for memory corruption leading to code execution.
- Availability (A): High (H) – Likely leads to a crash or DoS.
Estimated CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (Critical, 9.8)
Threat Level: Critical. The vulnerability is remotely exploitable without authentication and could lead to full system compromise.
Deep Dive & Mechanics
The vulnerability is a classic Heap-Use-After-Free (UAF) condition. In NanoMQ's TCP transport layer, when processing MQTTv5 retain messages, the broker's internal logic prematurely frees memory associated with message and pipe structures. If a subsequent operation attempts to access this freed memory, it results in a use-after-free.
Root Cause: The flaw is in src/sp/transport/mqtt/broker_tcp.c. The code does not properly track the lifecycle of message and pipe objects when handling malformed or specially crafted retain messages. Specifically, the cleanup routine may be invoked while references to the objects still exist, leading to dangling pointers.
Trigger: An attacker sends a series of malformed MQTTv5 PUBLISH packets with the retain flag set. The broker's parsing logic mishandles these packets, causing the premature deallocation.
Impact:
- Denial of Service (DoS): The most likely outcome is a crash of the NanoMQ broker.
- Arbitrary Code Execution (ACE): With careful heap manipulation, an attacker could overwrite function pointers or other critical data structures, potentially achieving remote code execution.
Vulnerable vs. Patched Code
The patch in version 0.22.5 addresses the UAF by ensuring that message and pipe structures are not freed until all references are released. The specific code changes are in src/sp/transport/mqtt/broker_tcp.c.
Vulnerable Code (Conceptual):
// Vulnerable: premature free
void cleanup_pipe(pipe_t *p) {
free(p->msg);
free(p);
}
void process_retain(pipe_t *p) {
// ... processing ...
if (malformed_condition) {
cleanup_pipe(p); // p is freed here
}
// Later, p is still used
send_message(p->msg); // UAF!
}
Patched Code (Conceptual):
// Patched: reference counting or delayed cleanup
void cleanup_pipe(pipe_t *p) {
if (--p->refcount == 0) {
free(p->msg);
free(p);
}
}
void process_retain(pipe_t *p) {
p->refcount++;
// ... processing ...
if (malformed_condition) {
// Mark for cleanup, but don't free yet
p->pending_cleanup = 1;
}
// Safe to use p->msg because refcount > 0
send_message(p->msg);
cleanup_pipe(p); // Decrement refcount
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- A vulnerable NanoMQ instance (version < 0.22.5) running on a target network.
- Ability to send raw MQTTv5 packets to the broker (typically port 1883).
Exploitation Steps:
- Reconnaissance: Scan for NanoMQ instances using Shodan or Nmap (
nmap -p 1883 --script mqtt-info <target>). - Craft Malformed Packets: Use a tool like
mqtt-spyor a custom Python script with thepaho-mqttlibrary to send malformed MQTTv5 PUBLISH packets with the retain flag set. - Trigger UAF: Send a series of these packets to the broker. The exact sequence may need to be tuned to hit the vulnerable code path.
- Achieve Code Execution (Advanced): Heap spray to control the freed memory and overwrite a function pointer. This requires detailed knowledge of the NanoMQ heap layout.
Example Python Script (Conceptual):
import socket
import struct
def send_malformed_retain(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
# MQTTv5 CONNECT packet
connect_packet = b'\x10\x0e\x00\x04MQTT\x05\x02\x00\x3c\x00\x04test'
sock.send(connect_packet)
# Malformed PUBLISH with retain flag
# This is a simplified example; actual payload needs to trigger the bug
publish_packet = b'\x3d\x0c\x00\x05topic\x00\x00\x00\x00'
sock.send(publish_packet)
sock.close()
# Usage
send_malformed_retain('192.168.1.100', 1883)
Blue Team
Detection:
- Monitor for unusual MQTT traffic, especially malformed PUBLISH packets with the retain flag.
- Use network intrusion detection systems (NIDS) to alert on anomalous MQTTv5 packets.
- Enable detailed logging on NanoMQ and monitor for crashes or memory errors.
Hunting:
- Search for logs containing "heap-use-after-free" or "segfault" in NanoMQ logs.
- Analyze network captures for MQTT packets that deviate from the protocol specification.
Mitigation:
- Immediately upgrade to NanoMQ version 0.22.5 or later.
- If upgrading is not possible, restrict network access to the MQTT broker (e.g., firewall rules, VPN).
- Implement rate limiting and input validation for MQTT connections.
Indicators of Compromise (IOCs)
- Network IOCs:
- Malformed MQTTv5 PUBLISH packets with the retain flag set.
- Repeated connection attempts from a single IP to port 1883.
- Packets with invalid MQTTv5 property lengths or topic filters.
- Host IOCs:
- NanoMQ process crash logs containing "heap-use-after-free" or "SIGSEGV".
- Unexpected memory corruption in the NanoMQ process.
- Core dumps from the NanoMQ binary.
- File IOCs:
- Modified NanoMQ binary (if attacker replaced it).
- Suspicious files in the NanoMQ data directory (e.g.,
/var/lib/nanomq/).
Detection Engineering
YARA Rule
rule CVE_2025_65953_NanoMQ_UAF {
meta:
description = "Detects NanoMQ binaries vulnerable to CVE-2025-65953"
author = "Valters IT"
date = "2025-04-10"
hash = "sha256: <hash_of_vulnerable_binary>"
strings:
$s1 = "broker_tcp.c" ascii wide nocase
$s2 = "cleanup_pipe" ascii wide nocase
$s3 = "process_retain" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2025-65953 NanoMQ Heap-Use-After-Free Exploitation Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects malformed MQTTv5 retain messages targeting NanoMQ
author: Valters IT
logsource:
category: network
product: mqtt
detection:
selection:
mqtt.packet_type: 'PUBLISH'
mqtt.retain: true
mqtt.version: 5
condition: selection
falsepositives:
- Legitimate MQTTv5 retain messages from authorized clients
level: high
Suricata Rule
alert tcp any any -> any 1883 (msg:"CVE-2025-65953 NanoMQ Heap-Use-After-Free Exploit Attempt"; flow:to_server,established; content:"|10|"; depth:1; content:"|05|"; distance:1; within:1; content:"|3d|"; distance:0; within:1; content:"|01|"; distance:0; within:1; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update NanoMQ to version 0.22.5 or later. This is the only complete fix.
- Network Segmentation: Restrict access to the MQTT broker to trusted networks only.
- Monitoring: Enable detailed logging and monitor for exploitation attempts.
Long-Term Measures:
- Implement a Web Application Firewall (WAF) or MQTT-aware IDS/IPS.
- Regularly update all software components.
- Conduct security audits of MQTT infrastructure.
Workarounds (if patching is not possible):
- Disable MQTTv5 support if not required.
- Use a reverse proxy to filter malformed packets.
- Limit the number of concurrent connections and message rates.
Valters IT
DevSecOps & Cyber Threat Intelligence