CVE-2024-25075
Executive Summary
CVE-2024-25075 is a denial-of-service (DoS) vulnerability in Softing uaToolkit Embedded, a library for building OPC UA (Unified Architecture) clients and servers. The flaw resides in the subscription handling logic. When a client creates a subscription with an extremely low MaxNotificationPerPublish parameter, the server mishandles the publish response, leading to uncontrolled memory consumption. An attacker can repeatedly trigger this condition to exhaust the device's memory, causing a complete denial of service. This vulnerability is particularly critical in industrial control system (ICS) and IoT environments where device availability is paramount. No public exploit code or proof-of-concept is currently available, but the attack vector is straightforward and requires no authentication.
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
CVSS Breakdown & Threat Level
- CVSS Score: 7.5 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Attack Vector (AV): Network – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low – No special conditions or complex steps are required.
- Privileges Required (PR): None – No authentication is needed to trigger the vulnerability.
- User Interaction (UI): None – The victim does not need to perform any action.
- Scope (S): Unchanged – The exploit does not affect other components.
- Confidentiality (C): None – No data is exposed.
- Integrity (I): None – No data is modified.
- Availability (A): High – The vulnerability directly causes a denial of service, making the device unavailable.
Threat Level: High. The vulnerability is easy to exploit remotely without authentication, and the impact is a complete loss of availability for critical industrial devices.
Deep Dive & Mechanics
The vulnerability is rooted in the OPC UA subscription management logic within the uaToolkit Embedded library. In OPC UA, a subscription allows a client to receive notifications (e.g., data changes, events) from the server. The MaxNotificationPerPublish parameter limits the number of notifications sent in a single publish response.
When a client creates a subscription with a very low MaxNotificationPerPublish value (e.g., 1), the server must break down the notification queue into many small publish responses. The flaw occurs in the memory management of these responses. Instead of properly releasing memory after each publish, the server accumulates state for each pending notification, leading to unbounded memory growth. Specifically, the server fails to correctly handle the case where the number of notifications exceeds the MaxNotificationPerPublish limit, causing it to retain references to unsent notifications indefinitely.
An attacker can exploit this by:
- Establishing an OPC UA connection to the target device.
- Creating a subscription with
MaxNotificationPerPublishset to a very low value (e.g., 1). - Triggering a large number of data changes or events (e.g., by writing to monitored items).
- The server will attempt to send these notifications in many small publish responses, but due to the memory leak, each cycle consumes additional memory.
- Repeating this process will eventually exhaust all available memory, causing the device to crash or become unresponsive.
The vulnerability is present in all versions of uaToolkit Embedded before 1.41.1. The fix in version 1.41.1 corrects the memory management logic to properly release resources when MaxNotificationPerPublish is low.
Vulnerable vs. Patched Code
The vulnerable code is in the subscription handling module, specifically in the function that processes publish requests and manages the notification queue. The exact code is not publicly available, but the patch description indicates a fix in the memory deallocation logic.
Vulnerable Code (Conceptual):
// Vulnerable: Memory is not freed when MaxNotificationPerPublish is low
void process_publish_request(Subscription *sub, PublishResponse *resp) {
int max_notifications = sub->max_notifications_per_publish;
int sent = 0;
while (sent < max_notifications && !queue_empty(sub->notification_queue)) {
Notification *notif = queue_pop(sub->notification_queue);
// ... add notification to response ...
sent++;
// Memory leak: notif is not freed if queue is not empty after loop
}
// If queue still has items, they are retained but not freed
}
Patched Code (Conceptual):
// Patched: Memory is properly freed after each publish response
void process_publish_request(Subscription *sub, PublishResponse *resp) {
int max_notifications = sub->max_notifications_per_publish;
int sent = 0;
while (sent < max_notifications && !queue_empty(sub->notification_queue)) {
Notification *notif = queue_pop(sub->notification_queue);
// ... add notification to response ...
sent++;
free(notif); // Memory is freed after use
}
// Remaining notifications are properly managed
}
The key difference is the addition of free(notif) after processing each notification, preventing the memory leak.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- An OPC UA client library (e.g., open62541, python-opcua).
- Network access to the target device running uaToolkit Embedded < 1.41.1.
Exploitation Steps:
- Connect to the target: Establish an OPC UA session.
- Create a subscription with low MaxNotificationPerPublish:
from opcua import Client client = Client("opc.tcp://target:4840") client.connect() sub = client.create_subscription(1, handler) # MaxNotificationPerPublish = 1 - Trigger notifications: Write to a monitored item or create many data changes.
node = client.get_node("ns=2;i=1") for i in range(10000): node.set_value(i) - Repeat: Continuously create new subscriptions and trigger notifications to accelerate memory exhaustion.
- Observe DoS: The target device will eventually become unresponsive or crash.
Automated Exploit (Conceptual):
import socket
import struct
def exploit(target_ip, target_port=4840):
# Simplified OPC UA binary protocol exploit
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((target_ip, target_port))
# Craft malicious subscription request with low MaxNotificationPerPublish
# ... (binary payload construction)
sock.send(payload)
sock.close()
if __name__ == "__main__":
exploit("192.168.1.100")
Blue Team (Defensive)
Detection:
- Monitor for rapid creation of OPC UA subscriptions with abnormally low
MaxNotificationPerPublishvalues. - Track memory usage on OPC UA devices; sudden spikes indicate an attack.
- Use network monitoring to detect repeated OPC UA publish requests.
Mitigation:
- Immediately upgrade to uaToolkit Embedded 1.41.1 or later.
- Implement network segmentation to restrict OPC UA traffic to trusted hosts.
- Deploy an OPC UA firewall or application-layer gateway to filter malicious subscription parameters.
- Set resource limits on the device (e.g., maximum number of subscriptions, memory quotas).
Indicators of Compromise (IOCs)
Network IOCs:
- OPC UA
CreateSubscriptionrequests withMaxNotificationPerPublishset to 1 or very low values. - High volume of OPC UA
Publishrequests from a single client. - Unusually small OPC UA
PublishResponsepackets (indicating low notification counts).
- OPC UA
System IOCs:
- Rapidly increasing memory usage on the OPC UA server device.
- Device logs showing out-of-memory errors or crashes.
- OPC UA server process consuming excessive memory.
File IOCs:
- Core dump files from the OPC UA server process.
- Log entries with "memory allocation failed" or similar errors.
Detection Engineering
YARA Rule
rule CVE_2024_25075_OPC_UA_DoS {
meta:
description = "Detects OPC UA binary packets with low MaxNotificationPerPublish"
author = "Valters IT"
date = "2024-01-01"
cve = "CVE-2024-25075"
strings:
$opcua_header = { 4F 50 43 55 } // "OPCU" in ASCII
$low_notif = { 01 00 00 00 } // MaxNotificationPerPublish = 1 (little-endian)
condition:
$opcua_header at 0 and $low_notif in (0..100)
}
Sigma Rule
title: OPC UA Subscription with Low MaxNotificationPerPublish
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects OPC UA CreateSubscription requests with MaxNotificationPerPublish set to 1
author: Valters IT
date: 2024/01/01
logsource:
category: network
product: zeek
service: opcua
detection:
selection:
opcua.subscription.max_notifications_per_publish: 1
condition: selection
falsepositives:
- Legitimate low-latency monitoring applications
level: high
Suricata Rule
alert tcp any any -> any 4840 (msg:"CVE-2024-25075 OPC UA DoS - Low MaxNotificationPerPublish"; flow:to_server,established; content:"|4F 50 43 55|"; depth:4; content:"|01 00 00 00|"; within:100; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Patch: Upgrade to Softing uaToolkit Embedded version 1.41.1 or later. This is the only definitive fix.
- Workaround: If patching is not immediately possible, restrict network access to OPC UA endpoints using firewall rules. Only allow trusted IP addresses.
- Monitoring: Enable detailed logging for OPC UA subscriptions and monitor for anomalous subscription creation patterns.
Long-Term Measures:
- Implement an OPC UA application-layer firewall that validates subscription parameters (e.g., reject
MaxNotificationPerPublishvalues below a threshold). - Use resource limits (e.g., maximum memory per subscription) in the OPC UA server configuration.
- Conduct regular security audits of OPC UA implementations.
- Subscribe to vendor security advisories for Softing products.
Valters IT
Securing Industrial Networks, One CVE at a Time.