4840 - Pentesting OPC UA

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Basic Information

OPC UA, standing for Open Platform Communications Unified Access, is a crucial open-source protocol used in various industries like Manufacturing, Energy, Aerospace, and Defence for data exchange and equipment control. It uniquely enables different vendors’ equipment to communicate, especially with PLCs.

Its configuration allows for strong security measures, but often, for compatibility with older devices, these are lessened, exposing systems to risks. Additionally, finding OPC UA services can be tricky since network scanners might not detect them if they’re on nonstandard ports.

Default port: 4840 (binary opc.tcp). Many vendors expose separate discovery endpoints (/discovery), HTTPS bindings (4843/443), or vendor-specific listener ports such as 49320 (KepServerEX), 62541 (OPC Foundation reference stack) and 48050 (UaGateway). Expect multiple endpoints per host, each advertising transport profile, security policy and user-token support.

Built-in NodeIdWhy it matters
i=2253 (0:Server)Holds ServerArray, vendor/product strings and namespace URIs.
i=2256 (ServerStatus)Reveals uptime, current state, and optionally build info.
i=2267 (ServerDiagnosticsSummary)Shows session counts, aborted requests, etc. Great for fingerprinting brute-force attempts.
i=85 (ObjectsFolder)Entry point to walk exposed device tags, methods and alarms.
PORT     STATE SERVICE REASON
4840/tcp open  unknown syn-ack

Pentesting OPC UA

To reveal security issues in OPC UA servers, scan it with OpalOPC.

opalopc -vv opc.tcp://$target_ip_or_hostname:$target_port

Discovery & Enumeration Playbook

  1. Locate all OPC UA transports

    nmap -sV -Pn -n --open -p 4840,4843,49320,48050,53530,62541 $TARGET
    

    Repeat on UDP group addresses if the environment uses LDS-ME multicast discovery.

  2. Fingerprint endpoints

    • Invoke FindServers/GetEndpoints over each transport to capture SecurityPolicyUri, SecurityMode, UserTokenType, application URI and product strings.
    • Enumerate namespaces so you can resolve vendor-specific NodeIds; abuse namespace collisions to coax clients into loading attacker-controlled schemas.
  3. Walk the address space

    • Start at ObjectsFolder (i=85) and recursively Browse/Read to find writable process variables, Method nodes and historian/log nodes.
    • Query ServerStatus.BuildInfo to understand firmware provenance, and ServerCapabilities.OperationLimits to gauge how easy it is to exhaust server resources.
    • If anonymous access is allowed, immediately test Call on maintenance methods (e.g., ns=2;s=Reset, ns=2;s=StartMotor). Many vendors forget to bind role permissions to custom methods.
  4. Session abuse

    • Reuse or clone AuthenticationToken values from other sessions (captured via MITM or diagnostics exposure) to hijack existing subscriptions.
    • Force the server into SessionDiagnostics flooding by creating dozens of inactive sessions; some stacks crash once the MaxSessionCount limit is exceeded.

Automated assessment with OpalOPC

  • The scanner can run interactively or headless, which is handy for CI/CD style OT baselines. Pipe its machine-readable findings into your reporting pipeline to highlight anonymous logins, weak policies, certificate validation errors and writable variables in minutes.
  • Combine OpalOPC output with manual browsing: feed the discovered endpoint list back into your custom tooling, then selectively weaponize high-impact nodes (e.g., MotorControl/StartStop, RecipeManager/Upload).

Attacking legacy security policies (Basic128Rsa15)

  • Bleichenbacher-style oracle: Systems that still allow the deprecated Basic128Rsa15 policy (often toggled via build flags such as CMPOPCUASTACK_ALLOW_SHA1_BASED_SECURITY) leak padding validation differences. Exploit this by flooding CreateSession / OpenSecureChannel handshakes with crafted PKCS#1 v1.5 blobs to recover the server certificate’s private key, then impersonate the server or decrypt traffic.
  • Authentication bypass: OPC Foundation’s .NET Standard stack prior to 1.5.374.158 (CVE-2024-42512) and dependent products let unauthenticated attackers force that legacy policy and subsequently skip application-level authentication. Once you own the key material you can present arbitrary UserIdentityTokens, replay signed ActivateSession requests, and operate the plant as a trusted engineering workstation.
  • Operational workflow:
    1. Enumerate policies with GetEndpoints and note any Basic128Rsa15 entries.
    2. Negotiate that policy explicitly (SecurityPolicyUri in CreateSession), then run your oracle loop until the recovered key validates.
    3. Abuse the key to forge a high-privilege session, switch roles, or silently downgrade other clients by acting as a rogue reverse proxy.
  • CODESYS Runtime Toolkit (<3.5.21.0) re-enabled Basic128Rsa15 whenever integrators compile with CMPOPCUASTACK_ALLOW_SHA1_BASED_SECURITY. Flip that flag, re-run the oracle workflow above, and you can leak the runtime’s private key to impersonate trusted engineering workstations until patch level 3.5.21.0 or later is deployed.
  • OPC Foundation simultaneously published CVE-2024-42513 for HTTPS bindings. Even if your target claims TLS, make sure it is not silently falling back to Basic128Rsa15 for the binary transport behind the proxy.

2024-2025 exploit watchlist

  • open62541 fuzz_binary_decode (CVE-2024-53429): SecureChannel chunks that declare oversized ExtensionObject bodies make the decoder dereference freed memory, so a pre-auth attacker can repeatedly crash UA servers that embed open62541 ≤1.4.6. Reuse the Claroty corpus (opcua_message_boofuzz_db) or craft your own Boofuzz harness to spam mutated OpenSecureChannel requests until the watchdog kills the process, then re-enumerate because many integrators fall back to anonymous mode after the reboot.
  • Softing OPC UA C++ SDK / edgeConnector / edgeAggregator (CVE-2025-7390): The TLS client-auth pipeline accepts any certificate that replays a trusted Common Name, so you can mint a throwaway cert, copy the CN from a plant engineer, and log in with arbitrary UserNameIdentityToken or IssuedIdentityToken data. Pair this with a downgrade to Basic128Rsa15 to strip integrity checks and persistently impersonate operators until trustlists are rebuilt.

Crafting OPC UA clients for exploitation

  • Custom clients: Drop-in libraries (python-opcua/asyncua, node-opcua, open62541) let you drive exploit logic yourself. Always enforce your target namespace index to avoid accidental cross-namespace writes when vendors reorder namespaces after firmware updates.
  • Node abuse checklist:
    • HistoryRead on production tags to snapshot proprietary recipes.
    • TranslateBrowsePathsToNodeIds to resolve human-readable asset names into NodeIds that can be fed to gadgets like Claroty’s framework.
    • Call + Method nodes to trigger maintenance tasks (firmware upload, calibration, device reboots).
    • RegisterNodes mis-use to pin frequently accessed nodes and then starve legitimate clients by never releasing the handles.
  • Session hardening tests: Attempt to bind dozens of subscriptions with extremely low publishing intervals (below 50 ms) plus oversized monitored-item queues. Many stacks miscalculate RevisedPublishingInterval and crash due to scheduler overflows.

Fuzzing & exploit development tooling

Claroty Team82 released an open-source opcua-exploit-framework that packages years of Pwn2Own-grade research into reusable modules:

  • Modes: sanity (lightweight reads/browses), attacks (e.g., thread pool starvation, file upload DoS), corpus (replay fuzzing payloads), server (rogue OPC UA server to backdoor clients).
  • Usage pattern:
    # Run a DoS attack against a Prosys Simulation Server endpoint
    python3 main.py prosys 10.10.10.10 53530 /OPCUA/SimulationServer thread_pool_wait_starvation
    
    # Replay an entire Boofuzz corpus against open62541
    python3 main.py open62541 192.168.1.50 4840 / opcua_message_boofuzz_db input_corpus_minimized/opcua.db
    
  • Rogue server scenario: The bundled asyncua-based server lets you target client software by serving malicious address spaces (for example, responses with oversized ExtensionObjects to trigger parsing bugs in UA Expert clones).
  • Target coverage: Built-in profiles map to Kepware, Ignition, Unified Automation, Softing SIS, Triangle Microworks, Node-OPCUA, Python OPC UA, Milo, open62541, etc., so you can quickly swap between stacks without rewriting payloads.
  • Integration tips: Chain its output with your own fuzzers—spray the corpus payloads first, then have OpalOPC re-verify whether the crash resurrected insecure defaults (anonymous login, setpoint write access, etc.).

Exploiting authentication bypasses

If authentication bypass vulnerabilities are found, you can configure an OPC UA client accordingly and see what you can access. This may allow anything from merely reading process values to actually operating heavy-duty industrial equipment.

To get a clue of the device you have access to, read the “ServerStatus” node values in the address space and google for a usage manual.

Shodan

  • port:4840
  • port:62541 "OPC UA"
  • ssl:"urn:opcua"
  • product:"opc ua"

Combine the search with vendor strings ("Ignition OPC UA", "KepServerEX") or certificates ("CN=UaServerCert") to prioritize high-value assets before starting intrusive testing.

References

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks