Skip to content
Skillpedia
Misc35k · #5660

detecting-dnp3-protocol-anomalies

Lets your agent detect unusual activity in industrial control systems (SCADA/ICS). It monitors commands and traffic to identify threats.

What it does

This AI agent monitors SCADA system communications using the DNP3 protocol. It looks for suspicious activities like unauthorized commands, firmware update attempts, or deviations from normal traffic to help secure industrial networks.

When to use it

  • ✓When monitoring energy systems that use DNP3.
  • ✓When investigating suspicious commands sent over DNP3.
  • ✓When building intrusion detection systems for industrial networks.

Example of what to ask your AI

“Check for unauthorized control commands in DNP3 traffic.”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/detecting-dnp3-protocol-anomalies/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/detecting-dnp3-protocol-anomalies/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

It analyzes DNP3 data packets for unusual or forbidden patterns. It uses machine learning to compare current traffic against a record of what is considered normal.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies

Or download just the file:

curl -L https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/main/skills/detecting-dnp3-protocol-anomalies/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Detecting DNP3 Protocol Anomalies

When to Use

  • When monitoring SCADA systems in the energy sector where DNP3 is the primary protocol
  • When building detection rules for DNP3-based attacks against RTUs and substations
  • When investigating suspected unauthorized control commands sent via DNP3
  • When deploying IDS with DNP3 deep packet inspection at utility substations
  • When responding to alerts from OT monitoring platforms about DNP3 traffic anomalies

Do not use for non-DNP3 protocol monitoring (see detecting-modbus-command-injection-attacks for Modbus), for DNP3 Secure Authentication configuration (separate implementation), or for protocol-agnostic network anomaly detection.

Prerequisites

  • Network TAP/SPAN on DNP3 communication segments (TCP port 20000 or serial)
  • Baseline of normal DNP3 traffic patterns (masters, outstations, poll intervals, function codes)
  • Suricata or Zeek with DNP3 protocol parser enabled
  • Understanding of DNP3 function codes and object groups used in the environment
  • DNP3 communication topology map (master-to-outstation relationships)

Workflow

Step 1: Analyze DNP3 Traffic for Anomalies

#!/usr/bin/env python3
"""DNP3 Protocol Anomaly Detector.

Monitors DNP3 communications for unauthorized control commands,
protocol violations, and deviations from established baselines.
Supports both TCP and serial DNP3 deployments.
"""

import struct
import sys
import json
from collections import defaultdict
from datetime import datetime
from typing import Dict, List, Optional, Set

try:
    from scapy.all import rdpcap, IP, TCP
except ImportError:
    print("Install scapy: pip install scapy")
    sys.exit(1)


# DNP3 Function Codes
DNP3_FUNCTIONS = {
    0x00: "Confirm", 0x01: "Read", 0x02: "Write",
    0x03: "Select", 0x04: "Operate", 0x05: "Direct Operate",
    0x06: "Direct Operate No Ack", 0x07: "Immediate Freeze",
    0x08: "Immediate Freeze No Ack", 0x09: "Freeze and Clear",
    0x0A: "Freeze and Clear No Ack", 0x0B: "Freeze at Time",
    0x0C: "Freeze at Time No Ack", 0x0D: "Cold Restart",
    0x0E: "Warm Restart", 0x0F: "Initialize Data",
    0x10: "Initialize Application", 0x11: "Start Application",
    0x12: "Stop Application", 0x13: "Save Configuration",
    0x14: "Enable Unsolicited", 0x15: "Disable Unsolicited",
    0x16: "Assign Class", 0x17: "Delay Measurement",
    0x18: "Record Current Time", 0x19: "Open File",
    0x1A: "Close File", 0x1B: "Delete File",
    0x1C: "Get File Info", 0x1D: "Authenticate File",
    0x1E: "Abort File", 0x81: "Response", 0x82: "Unsolicited Response",
}

# High-risk function codes that should trigger alerts
DNP3_CRITICAL_FUNCTIONS = {
    0x02,  # Write
    0x03, 0x04, 0x05, 0x06,  # Select/Operate/Direct Operate
    0x0D,  # Cold Restart
    0x0E,  # Warm Restart
    0x0F,  # Initialize Data
    0x10,  # Initialize Application
    0x12,  # Stop Application
    0x19, 0x1A, 0x1B,  # File operations (firmware update)
}


class DNP3AnomalyDetector:
    """Detects anomalies in DNP3 protocol communications."""

    def __init__(self, baseline_file: Optional[str] = None):
        self.alerts = []
        self.sessions = defaultdict(lambda: {
            "packet_count": 0,
            "function_codes": defaultdict(int),
            "control_commands": 0,
            "file_operations": 0,
            "restarts": 0,
        })
        self.packet_count = 0
        self.dnp3_count = 0

        self.authorized_masters: Set[str] = set()
        self.authorized_pairs: Dict[str, Set[str]] = defaultdict(set)
        self.baseline_functions: Dict[str, Set[int]] = defaultdict(set)

        if baseline_file:
            self.load_baseline(baseline_file)

    def load_baseline(self, filepath: str):
        """Load DNP3 communication baseline."""
        with open(filepath, "r") as f:
            baseline = json.load(f)

        for entry in baseline.get("authorized_communications", []):
            master = entry["master_ip"]
            outstation = entry["outstation_ip"]
            self.authorized_masters.add(master)
            self.authorized_pairs[master].add(outstation)
            self.baseline_functions[f"{master}->{outstation}"] = set(
                entry.get("expected_function_codes", [0x00, 0x01])
            )

    def parse_dnp3_header(self, payload: bytes) -> Optional[dict]:
        """Parse DNP3 data link layer and transport/application headers."""
        if len(payload) < 10:
            return None


…
FAQ

What is DNP3?

DNP3 is a set of rules (protocol) used by equipment in industrial control systems, such as those found in energy grids.

What are anomalies?

Anomalies are deviations from normal or expected behavior. In this case, they are strange activities in DNP3 traffic.

What are SCADA systems?

SCADA stands for Supervisory Control and Data Acquisition. These are systems used to monitor and control industrial processes remotely.

Details

Original description by the author

Detect anomalies in DNP3 communications used in SCADA/ICS systems by monitoring unauthorized control commands, firmware update attempts, protocol violations, and deviations from baseline traffic using deep packet inspection and machine learning approaches. Use when securing energy-sector or other OT/ICS networks, investigating suspicious DNP3 master/outstation activity, or building an anomaly-base

repo: mukul975/Anthropic-Cybersecurity-Skills

Popularity

GitHub stars
35k
Ranking position
#5660
License
Apache-2.0
Updated
8/31/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills