Zero Day Initiative (ZDI) has published advisory ZDI-26-990, disclosing a critical memory corruption vulnerability in open62541, the open-source implementation of the OPC Unified Architecture (OPC UA) protocol that serves as the industrial communication backbone for a significant portion of modern ICS/OT infrastructure. Tracked as CVE-2026-126962, this is a use-after-free (UAF) flaw in the OPC UA Subscription service that enables remote code execution with a CVSS v3.1 score of 8.8 (High).
This is not a theoretical concern. open62541 is embedded in PLCs, HMIs, protocol gateways, embedded controllers, and vendor-branded industrial devices across manufacturing, energy, water treatment, and pharmaceutical production environments. It appears both as a direct library dependency in custom applications and as firmware-integrated code in commercial OT products where asset owners often have no visibility into the software bill of materials (SBOM).
The vulnerability requires authentication — a nuance that reduces but does not eliminate risk. In industrial environments, OPC UA authentication is frequently weakened by shared service accounts, default certificates, anonymous login configurations, and long-lived session tokens that persist across maintenance windows. An attacker with valid credentials — whether harvested via phishing, extracted from a compromised engineering workstation, or leveraged from a default configuration — can trigger this flaw to execute arbitrary code on the target server with the privileges of the open62541 process.
Given open62541's typical deployment context — often running with elevated privileges on embedded Linux or Windows-based industrial controllers — successful exploitation translates directly to process manipulation, lateral movement into Level 2/3 OT networks, and potential physical process disruption.
Technical Analysis
Affected Component & Root Cause
The flaw resides in open62541's Subscription service implementation, specifically in how the server manages the lifecycle of UA_Subscription objects relative to their associated UA_Session contexts.
In OPC UA, a Subscription is a long-lived, stateful communication channel. A client creates a Subscription, then attaches MonitoredItems to it for continuous data change notifications, event streams, or alarm conditions. The server must maintain tight memory management over the Subscription lifecycle — including cleanup during session termination, timeout, or explicit deletion.
The vulnerability is a use-after-free condition triggered when a Subscription is deleted or transferred while still referenced by an active session context. The root cause is a reference counting / lifecycle desynchronization defect:
- A client establishes an authenticated session and creates a Subscription (which allocates and initializes a
UA_Subscriptionobject on the heap). - Through a specific sequence of OPC UA service calls — most likely a DeleteSubscriptions or TransferSubscriptions request timed to race with another operation — the server frees the
UA_Subscriptionmemory. - Critically, a stale pointer to the freed Subscription object remains in the session's internal state (or in a pending publish request queue) without being NULLed or otherwise invalidated.
- A subsequent operation — such as a Publish request, SetPublishingMode, or session cleanup activity — dereferences the dangling pointer.
Because the freed heap memory may be reallocated for attacker-controlled data (heap spray), this UAF allows an attacker to influence execution flow. At minimum, this causes a denial of service (crash of the OPC UA server). With careful heap grooming and control over the reallocated memory contents, arbitrary code execution is achievable — as confirmed by ZDI's classification and CVSS 8.8 score.
Why CVSS 8.8 with Authentication Required?
The CVSS v3.1 vector implied by ZDI's rating is likely AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H or similar — but the "Authentication is required" note in the summary may suggest PR:L (low privileges). Even at 8.8, this score reflects:
- Network exploitable: Reachable over standard OPC UA TCP port 4840 (or vendor-configured alternates).
- High impact: Full confidentiality, integrity, and availability loss on the target system.
- No user interaction: Exploitation is server-side; no victim needs to click anything.
In OT environments, the authentication requirement is a lower barrier than it appears. Shared engineering accounts, certificates embedded in vendor firmware, and anonymous access configurations are common. Once an attacker holds any valid credential — or compromises a single HMI or engineering workstation with stored session tokens — this becomes a pre-authenticated RCE from their operational position.
Attack Chain (Defender's Perspective)
- Reconnaissance: Attacker scans for OPC UA endpoints (TCP/4840) and fingerprints open62541 via Server Hello / GetEndpoints responses (vendor strings, software version fields, supported security policies).
- Initial Access: Gains authenticated session via compromised credentials, default certificates, or an anonymous connection (if enabled).
- Trigger: Issues a crafted sequence of OPC UA service calls (CreateSubscription → DeleteSubscriptions / TransferSubscriptions → Publish / SetPublishingMode) to induce the UAF condition.
- Heap Grooming: Allocates controlled data in the freed memory region via repeated, predictable OPC UA operations (e.g., large ExtensionObject payloads, session renegotiation).
- Execution: Overwrites a function pointer, vtable entry, or critical structure in the dangling
UA_Subscriptionobject, redirecting execution when the server dereferences it. - Post-Exploitation: With code execution under the open62541 process context (often
root,SYSTEM, or a privileged service account), the attacker implants persistence, pivots to other OT assets, or manipulates process values.
Exploitation Status
- Public PoC: As of this writing, no public proof-of-concept exploit has been released. ZDI's advisory follows coordinated disclosure; technical details and PoC typically follow after a grace period unless already leaked.
- In-the-Wild Exploitation: Not confirmed in active campaigns as of publication. However, given open62541's prevalence in OT and the detailed advisory nature, weaponization by sophisticated actors (APT groups targeting industrial sectors) should be expected within weeks, not months.
- CISA KEV: Not yet listed on the CISA Known Exploited Vulnerabilities catalog. Monitor for addition — KEV listing would signal confirmed active exploitation.
- ICS-CERT: Monitor CISA ICS advisories for vendor-specific notifications, as open62541 is embedded in products from major automation vendors.
Affected Versions
Per ZDI and the open62541 project, this flaw affects open62541 versions prior to the patched release. At the time of disclosure, the vulnerability impacts the current stable branch and likely several prior versions. All organizations using open62541 should assume they are affected until verified otherwise.
Check your deployed version via:
- Application-layer:
UA_ServerConfig->applicationDescription.softwareVersion - Binary string search:
strings <binary> | grep open62541 - Package manager:
dpkg -l | grep open62541orrpm -qa | grep open62541
Detection & Response
This is a memory corruption vulnerability triggered by specific OPC UA service call sequences. Detection focuses on anomalous OPC UA traffic patterns, process crashes, and post-exploitation behaviors on the host running the open62541 server.
Sigma Rules
---
title: OPC UA open62541 Subscription Use-After-Free Exploitation Attempt
id: 8f4e2b7c-3a1d-4e6f-9b2c-5d7e9f1a3c8d
status: experimental
description: Detects suspicious OPC UA service call sequences indicative of Subscription lifecycle manipulation (UAF trigger). Focuses on rapid Create/Delete/Transfer Subscription operations followed by Publish requests, which may indicate heap grooming or exploitation attempts against CVE-2026-126962.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-990/
- https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1190
- attack.execution
logsource:
category: network_connection
product: zeek
detection:
selection:
# Zeek OPC UA analyzer or custom ICS protocol logs
opcua_service:
- 'CreateSubscriptionRequest'
- 'DeleteSubscriptionsRequest'
- 'TransferSubscriptionsRequest'
- 'PublishRequest'
- 'SetPublishingModeRequest'
# High frequency or unusual ordering from same source
id.orig_h: '*'
condition: selection
falsepositives:
- Legitimate HMI/SCADA polling behavior. Baseline normal OPC UA traffic patterns per asset before enabling alerting.
level: high
---
title: OPC UA Server Process Crash or Abnormal Termination
id: 2c7f9a1b-4d8e-6f3a-b5c7-9e1d3f5a7c9d
status: experimental
description: Detects crashes or abnormal termination of processes associated with open62541 or OPC UA server implementations. Use-after-free exploitation commonly results in segmentation faults or application crashes, which may be observed in system logs or EDR telemetry.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-990/
- https://attack.mitre.org/techniques/T1499/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.impact
- attack.t1499
logsource:
category: process_creation
product: linux
detection:
selection:
# Process names commonly associated with open62541 deployments
Image|endswith:
- 'open62541'
- 'opcua-server'
- 'ua_server'
- 'opc_ua_server'
# Followed by crash indicators in short timeframe (handled by correlation)
CommandLine|contains:
- 'segfault'
- 'core dumped'
- 'SIGSEGV'
- 'SIGABRT'
condition: selection
falsepositives:
- Development/testing environments with unstable code. Production OT servers should rarely crash; investigate all occurrences.
level: critical
---
title: Suspicious Child Process Spawned by OPC UA Server
id: 5e3a8f2c-7b4d-6e1f-9c2a-4d7e9f1b3c5a
status: experimental
description: Detects the OPC UA server process spawning unexpected child processes (e.g., shells, interpreters, or download tools), which is a strong indicator of successful remote code execution following exploitation of CVE-2026-126962.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-990/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059
- attack.command_and_control
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\opcua-server.exe'
- '\open62541.dll'
- '\ua_server.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\rundll32.exe'
- '\regsvr32.exe'
- '\curl.exe'
- '\wget.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
condition: selection_parent and selection_child
falsepositives:
- None in properly configured OT environments. OPC UA servers should not spawn interactive shells or download tools.
level: critical
KQL (Microsoft Sentinel / Defender)
This query hunts for OPC UA server crashes and suspicious child process execution. It assumes ingestion of Windows Security Events, Sysmon, or EDR data (DeviceProcessEvents) and Syslog for Linux-based OT servers.
// Hunt for open62541 exploitation indicators: process crashes and suspicious child processes
let OPCUAProcessNames = dynamic(["opcua-server.exe", "ua_server.exe", "open62541.dll", "opc_ua_server", "open62541"]);
let SuspiciousChildProcesses = dynamic(["cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe", "curl.exe", "wget.exe", "certutil.exe", "bitsadmin.exe", "bash", "sh", "python", "perl"]);
// Windows: Suspicious child processes spawned by OPC UA server
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has_any (OPCUAProcessNames)
| where FileName has_any (SuspiciousChildProcesses)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, DeviceId
| extend AlertReason = "OPC UA server spawned suspicious child process"
// Linux: Syslog for segfaults or crashes related to OPC UA
union isfuzzy=true
(
Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has_any ("segfault", "core dumped", "SIGSEGV", "SIGABRT")
| where SyslogMessage has_any (OPCUAProcessNames)
| project TimeGenerated, Computer, ProcessName, SyslogMessage, SeverityLevel
| extend AlertReason = "OPC UA server crash detected"
)
// Network: High-frequency OPC UA subscription operations from single source (proxy/firewall logs)
union isfuzzy=true
(
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where DestinationPort == 4840
| where ApplicationProtocol == "OPCUA" or Message has "OPC UA"
| summarize ServiceCallCount = count() by SourceIP, DestinationIP, bin(TimeGenerated, 5m)
| where ServiceCallCount > 100 // Threshold: baseline your environment
| extend AlertReason = "High volume of OPC UA service calls from single source"
)
| order by TimeGenerated desc
Velociraptor VQL
Use this artifact to hunt across endpoints for OPC UA server processes and their associated network connections or spawned children.
-- Hunt for open62541 exploitation indicators: processes, children, and network connections
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime,
-- Check for suspicious child processes
(SELECT Name FROM pslist(pid=Pid)) AS ChildProcesses,
-- Network connections for OPC UA port 4840
(SELECT RemoteAddr, RemotePort, State FROM netstat(pid=Pid) WHERE RemotePort = 4840 OR LocalPort = 4840) AS OPCUAConnections
FROM pslist()
WHERE Name =~ '(?i)(opcua|open62541|ua_server)'
OR CommandLine =~ '(?i)(opcua|open62541)'
OR Exe =~ '(?i)(opcua|open62541)'
-- Filter for processes with suspicious children or high connection counts
WHERE array_length(array=ChildProcesses) > 0
OR array_length(array=OPCUAConnections) > 0
ORDER BY CreateTime DESC
Remediation Script (Bash — Linux/OT Servers)
This script checks for open62541 presence, attempts package-based updates, verifies running services, and applies basic hardening if patching is delayed.
#!/bin/bash
# CVE-2026-126962: open62541 UAF Remediation & Verification Script
# Run on OT servers running open62541. Test in non-production first.
echo "=== CVE-2026-126962: open62541 UAF Remediation Script ==="
echo "Date: $(date)"
echo ""
# Check if open62541 is installed via package manager
if command -v dpkg &> /dev/null; then
PKG_MGR="dpkg"
OPEN62541_PKG=$(dpkg -l | grep -i open62541)
elif command -v rpm &> /dev/null; then
PKG_MGR="rpm"
OPEN62541_PKG=$(rpm -qa | grep -i open62541)
else
echo "[!] No supported package manager found. Manual verification required."
PKG_MGR="none"
fi
if [ "$PKG_MGR" != "none" ]; then
if [ -n "$OPEN62541_PKG" ]; then
echo "[+] open62541 package detected:"
echo "$OPEN62541_PKG"
echo ""
echo "[*] Attempting to update open62541..."
if [ "$PKG_MGR" = "dpkg" ]; then
sudo apt-get update && sudo apt-get install --only-upgrade -y libopen62541* open62541*
elif [ "$PKG_MGR" = "rpm" ]; then
sudo yum update -y open62541*
fi
echo "[+] Update attempt completed. Verify version manually."
else
echo "[-] open62541 not found via package manager. Checking for binary/library..."
fi
fi
# Check for running open62541 processes
echo ""
echo "[*] Checking for running open62541 processes..."
ps aux | grep -iE 'open62541|opcua|ua_server' | grep -v grep
# Check for listening OPC UA ports (default 4840)
echo ""
echo "[*] Checking for OPC UA listeners on port 4840..."
ss -tlnp | grep :4840 || netstat -tlnp 2>/dev/null | grep :4840
# Hardening: If patch not immediately available, restrict network access
echo ""
echo "[*] Applying temporary network-level hardening (if iptables available)..."
if command -v iptables &> /dev/null; then
# Allow only trusted HMI/SCADA IPs — CUSTOMIZE THIS LIST
TRUSTED_IPS=("10.0.0.10" "10.0.0.11" "192.168.1.100")
echo "[*] Whitelisting trusted OPC UA clients: ${TRUSTED_IPS[@]}"
for ip in "${TRUSTED_IPS[@]}"; do
sudo iptables -A INPUT -p tcp --dport 4840 -s "$ip" -j ACCEPT
done
sudo iptables -A INPUT -p tcp --dport 4840 -j DROP
echo "[+] iptables rules applied. Persistence requires saving (e.g., iptables-save)."
else
echo "[!] iptables not found. Apply network ACLs via firewall or switch configuration."
fi
# Verify version
echo ""
echo "[*] If open62541 is compiled from source, verify version in your application:"
echo " - Check UA_ServerConfig->applicationDescription.softwareVersion"
echo " - Rebuild with patched open62541 release (>= v1.4.x or vendor-supplied version)"
echo ""
echo "=== Next Steps ==="
echo "1. Confirm open62541 version is patched against CVE-2026-126962."
echo "2. Restart OPC UA services after patching."
echo "3. Review OPC UA authentication: disable anonymous access, enforce certificate validation."
echo "4. Monitor for crashes or anomalous subscription activity."
Remediation
1. Patch Immediately
The only complete remediation is to update open62541 to a version that includes the fix for CVE-2026-126962.
- Official Source: Obtain the patched release from the open62541 GitHub repository or your Linux distribution's security updates.
- Vendor Products: If open62541 is embedded in a commercial product (PLC, HMI, gateway), contact your vendor immediately for a firmware or software update. Reference ZDI-26-990 and CVE-2026-126962 explicitly.
- Rebuild from Source: If you compile open62541 into custom applications, pull the latest stable branch and rebuild all dependent binaries.
2. Verify Version & Exposure
- Inventory all assets running open62541. Use the detection queries above to identify OPC UA listeners on TCP/4840.
- Verify the open62541 version in your application. Check
UA_ServerConfig->applicationDescription.softwareVersionor inspect linked library versions (ldd,objdump, or package manager queries). - SBOM Review: If you lack an SBOM for your OT devices, treat this as a critical gap. Engage vendors to confirm whether their products embed open62541.
3. Network Segmentation & Access Control
While patching is in progress, implement compensating controls to reduce attack surface:
- Restrict OPC UA access to only authorized HMI, SCADA, and historian systems. Use firewall rules, industrial DMZs, and unidirectional gateways where appropriate.
- Disable anonymous access on all OPC UA servers. Enforce X.509 certificate-based mutual authentication or, at minimum, strong username/password policies with unique per-system credentials.
- Segment OT networks: Ensure OPC UA servers are not directly reachable from corporate IT networks or the internet. Apply IEC 62443 zones and conduits.
4. Harden OPC UA Configuration
- Review Subscription limits: Configure reasonable
maxSubscriptions,maxMonitoredItems, andmaxPublishRequeststo reduce heap grooming surface. - Enable secure transport: Use OPC UA TCP with
Basic256Sha256orAes256_Sha256_RsaPsssecurity policies. DisableNoneand deprecatedBasic128Rsa15/Basic256policies. - Certificate hygiene: Rotate default or self-signed certificates. Implement a proper PKI for OT where feasible.
- Logging: Enable verbose logging for OPC UA service calls (if performance permits) to aid forensic analysis.
5. Monitor & Hunt
- Deploy the Sigma, KQL, and VQL detections provided above.
- Baseline normal OPC UA traffic patterns per asset. Alert on deviations in service call frequency, session duration, or subscription churn.
- Monitor for open62541 server crashes. Treat every production OPC UA server crash as a potential exploitation attempt until proven otherwise.
- Subscribe to CISA ICS advisories and ZDI for updates on CVE-2026-126962 exploitation status.
6. Incident Response Preparation
- If you detect exploitation indicators (crashes, suspicious child processes, anomalous subscription sequences), isolate the affected OPC UA server from the network immediately.
- Capture memory and disk images before rebooting. Use the Velociraptor VQL artifact to triage live systems.
- Review OPC UA session logs for unauthorized access or credential abuse.
- Engage your IR retainer or CISA (if in the US) for support with OT-focused incident response.
CISA Deadlines & Vendor Coordination
As of publication, no CISA KEV deadline exists for CVE-2026-126962. However, given the CVSS 8.8 score and OT impact, treat this with emergency patch priority (72-hour SLA for critical systems). If your organization operates critical infrastructure (energy, water, healthcare), consider reporting exposure or incidents to CISA via ICS-CERT.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.