Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 79 additions & 5 deletions src/network-services-pentesting/4840-pentesting-opc-ua.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@

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
**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 NodeId | Why 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.

```text
PORT STATE SERVICE REASON
Expand All @@ -24,7 +31,70 @@ To reveal security issues in OPC UA servers, scan it with [OpalOPC](https://opal
opalopc -vv opc.tcp://$target_ip_or_hostname:$target_port
```

### Exploiting vulnerabilities
### Discovery & Enumeration Playbook

1. **Locate all OPC UA transports**
```bash
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.
- 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.

### 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:**
```bash
# 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 `ExtensionObject`s 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](https://www.prosysopc.com/products/opc-ua-browser/) accordingly and see what you can access. This may allow anything from merely reading process values to actually operating heavy-duty industrial equipment.

Expand All @@ -33,13 +103,17 @@ To get a clue of the device you have access to, read the "ServerStatus" node val
## 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

- [https://opalopc.com/how-to-hack-opc-ua/](https://opalopc.com/how-to-hack-opc-ua/)
- [https://github.com/claroty/opcua-exploit-framework](https://github.com/claroty/opcua-exploit-framework)
- [https://certvde.com/en/advisories/VDE-2025-022/](https://certvde.com/en/advisories/VDE-2025-022/)


{{#include ../banners/hacktricks-training.md}}