<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: auditing-opc-ua-security
description: >-
  Audit OPC UA server security configurations including certificate management, authentication
  modes, encryption policies, session management, and access control to prevent unauthorized
  data access and control operations in ICS environments.
domain: cybersecurity
subdomain: ot-ics-security
tags:
  - opc-ua
  - ics
  - scada
  - certificate
  - encryption
  - authentication
  - industrial-protocol
version: "1.0"
author: defconxt
license: AGPL-3.0
compatibility: Designed for Claude Code, GitHub Copilot, OpenAI Codex, Cursor, Gemini CLI, and any agentskills.io-compatible agent.
metadata:
  mitre-attack: ["T0846", "T0855"]
  nist-csf: ["PR.AC-1", "PR.DS-2", "DE.CM-1"]
  iec-62443: ["SR 1.1", "SR 4.1", "SR 4.3"]
  uuid: a1b2c3d4-1007-4000-a007-000000000007
---

# Auditing OPC UA Security

## Overview

OPC UA is the modern industrial interoperability standard, replacing DCOM-based OPC Classic.
While OPC UA supports strong security (X.509 certificates, TLS, fine-grained access control),
misconfigurations are common — anonymous access enabled, None security policy allowed,
self-signed certificates accepted, and overly broad user permissions. Pipedream/INCONTROLLER
demonstrated OPC UA abuse for ICS attacks.

Mode: `[MODE: ARCHITECT]` for configuration review; `[MODE: RED]` for security testing.

## Prerequisites

| Requirement | Details |
|---|---|
| OPC UA client tools (`opcua-commander`, `UaExpert`, Python `asyncua`) | Required |
| Network access to OPC UA servers (TCP/4840 default) | Required |
| Certificate management knowledge (X.509, PKI) | Required |
| Understanding of OPC UA security model (policies, modes, tokens) | Required |

## Key Concepts

### OPC UA Security Model

```yaml
Security Policies:
  None:               # No encryption, no signing (⚠️ INSECURE)
  Basic128Rsa15:      # Deprecated — weak crypto
  Basic256:           # Deprecated — SHA-1
  Basic256Sha256:     # Minimum acceptable
  Aes128_Sha256_RsaOaep:  # Recommended
  Aes256_Sha256_RsaPss:   # Strongest

Message Security Modes:
  None:               # No protection (⚠️ INSECURE)
  Sign:               # Integrity only
  SignAndEncrypt:      # Integrity + confidentiality (REQUIRED)

User Token Types:
  Anonymous:          # No authentication (⚠️ INSECURE)
  UserName:           # Username/password (encrypt in transit)
  Certificate:        # X.509 client certificate (RECOMMENDED)
  IssuedToken:        # Kerberos/SAML token
```

### Endpoint Discovery and Audit

```python
# Discover OPC UA server endpoints and security configuration
import asyncio
from asyncua import Client

async def audit_endpoints(url: str) -> None:
    """Audit OPC UA server security configuration."""
    client = Client(url)
    endpoints = await client.connect_and_get_server_endpoints()
    for ep in endpoints:
        print(f"Endpoint: {ep.EndpointUrl}")
        print(f"  Security Policy: {ep.SecurityPolicyUri.split('#')[-1]}")
        print(f"  Security Mode: {ep.SecurityMode}")
        print(f"  User Tokens: {[t.TokenType for t in ep.UserIdentityTokens]}")
        # Flag insecure configurations
        if "None" in ep.SecurityPolicyUri:
            print("  ⚠️  FINDING: None security policy enabled")
        if ep.SecurityMode == 1:  # MessageSecurityMode.None_
            print("  ⚠️  FINDING: No message security")

asyncio.run(audit_endpoints("opc.tcp://10.0.0.1:4840"))
```

### Certificate Validation

```bash
# Extract server certificate
openssl s_client -connect 10.0.0.1:4840 2>/dev/null | \
  openssl x509 -noout -text

# Check certificate properties
openssl x509 -in server_cert.der -inform DER -noout \
  -subject -issuer -dates -serial

# Verify certificate chain
openssl verify -CAfile ca_cert.pem server_cert.pem

# Check for self-signed certificates (common in ICS)
openssl x509 -in server_cert.pem -noout -issuer -subject | \
  awk -F= '{print $NF}' | sort -u | wc -l
# Output 1 = self-signed
```

### Network Monitoring

```bash
# Capture OPC UA traffic
tshark -i eth1 -f "tcp port 4840" -w opcua_capture.pcap

# Filter OPC UA sessions
tshark -r opcua_capture.pcap -Y "opcua"

# Detect anonymous connections
tshark -r opcua_capture.pcap \
  -Y "opcua.security.tokentype == 0" \
  -T fields -e ip.src -e ip.dst

# Suricata rule for None security policy
cat << 'EOF'
alert tcp any any -> $ICS_NET 4840 ( \
  msg:"OPC-UA - None Security Policy Negotiation"; \
  flow:established,to_server; \
  content:"http://opcfoundation.org/UA/SecurityPolicy#None"; \
  sid:4005001; rev:1;)
EOF
```

## Workflow

### Step 1: Enumerate OPC UA Servers

```bash
# Discover OPC UA services on OT network
nmap -sV -p 4840,4843,48400-48410 10.0.0.0/24 --open
```

### Step 2: Audit Security Configuration

```python
# Run endpoint audit against each discovered server
# Check: security policies, modes, user tokens, certificates
```

### Step 3: Report and Remediate

```yaml
# Finding template
finding: OPC-UA-001
severity: High
description: Anonymous access enabled on OPC UA server
location: opc.tcp://10.0.0.5:4840
remediation: Disable Anonymous token type in server configuration
```

## Verification

- [ ] All OPC UA servers discovered and inventoried
- [ ] None security policy disabled on all servers
- [ ] SignAndEncrypt mode enforced for all endpoints
- [ ] Anonymous authentication disabled
- [ ] X.509 certificates from trusted CA (not self-signed in production)
- [ ] Certificate expiration monitoring active
- [ ] Access control lists restrict node-level permissions
- [ ] Audit logging enabled on OPC UA servers

## Detection Opportunities

- None security policy negotiation → insecure client or attacker downgrade
- Anonymous token authentication → unauthorized access attempt
- Certificate validation failures → MitM or rogue client
- Browse operations across all namespaces → reconnaissance activity
- Write operations from read-only clients → access control violation

```yaml
title: Auditing Opc Ua Security Detection
id: 977d6374-7358-444c-b611-21c5e604983d
status: experimental
description: Detects suspicious activity related to auditing opc ua security techniques in ot ics security context
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    CommandLine: "*auditing*opc*"
  condition: selection
level: medium
tags:
  - attack.t0846
  - attack.t0855
  - attack.lateral_movement
falsepositives:
  - Industrial control system maintenance by authorized engineering staff
```

## References

- OPC Foundation: OPC UA Security Model (Part 2)
- IEC 62443-4-2: Component Security Requirements
- Pipedream/INCONTROLLER Technical Analysis (Dragos, Mandiant)
- NIST SP 800-82 Rev 3 §5.5.4: OPC UA Security
