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…
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .claude/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .agents/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .cursor/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .gemini/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .github/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "detecting-dnp3-protocol-anomalies" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/detecting-dnp3-protocol-anomalies into .opencode/skills/detecting-dnp3-protocol-anomalies/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "detecting-dnp3-protocol-anomalies", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
detecting-dnp3-protocol-anomalies
GitHub stars
34k
Token cost
~3.6k tokens
SKILL.md length
251 words
Files
4 (incl. scripts, references)
Skills in repo
644
Repo updated
First seen
Licence
Apache-2.0
At a glance
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…
Securing energy-sector
SKILL.md covers When to Use, Prerequisites, Workflow and Key Concepts, plus 1 more section
Runs Python scripts from its folder
Other OT/ICS networks
What it does
Detecting Dnp3 Protocol Anomalies is an agent skill from mukul975/Anthropic-Cybersecurity-Skills. 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-based IDS for industrial control traffic.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including scripts and reference files (for example `references/api-reference.md` and `scripts/agent.py`).
It sits in Data & Analytics, covering Anomaly detection and Machine learning. The repository describes itself as: 817 structured cybersecurity skills for AI agents · Mapped to 6 frameworks: MITRE ATT&CK, NIST CSF 2.0, MITRE ATLAS, D3FEND, NIST AI RMF & MITRE F3 (Fight Fraud) · agentskills.io…. The licence is Apache-2.0.
Building an anomaly-based IDS for industrial control traffic
Example prompts
“/detecting-dnp3-protocol-anomalies”
Requirements
Python 3
What it can do on your machine
Read from SKILL.md and the folder at commit 54a7988. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
Ships 1 file in scripts/ (Python), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
Network
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
Detecting Dnp3 Protocol Anomalies loads about 3.6k tokens when it runs, and up to ~4k if it reads all its reference files. Until then it costs about 118 tokens; SKILL.md has 251 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~118
When it runs· the whole SKILL.md, loaded when a task matches
~3.6k
With references· SKILL.md plus every file in references/, read only if the agent opens them
~4k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check passed
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
Download SKILL.mdSave it as .claude/skills/detecting-dnp3-protocol-anomalies/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
detecting-dnp3-protocol-anomalies
description
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-based IDS for industrial control traffic.
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
python
#!/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
# DNP3 Data Link Layer: start(2) + length(1) + control(1) + dest(2) + source(2) + crc(2)
start_bytes = struct.unpack(">H", payload[0:2])[0]
if start_bytes != 0x0564:
return None
length = payload[2]
control = payload[3]
dest_addr = struct.unpack("<H", payload[4:6])[0]
source_addr = struct.unpack("<H", payload[6:8])[0]
direction = "Master->Outstation" if (control & 0x80) else "Outstation->Master"
result = {
"length": length,
"control": control,
"direction": direction,
"dest_addr": dest_addr,
"source_addr": source_addr,
"is_master": bool(control & 0x80),
}
# Parse transport and application layer (after CRC bytes)
if len(payload) >= 12:
transport_header = payload[10]
if len(payload) >= 13:
app_control = payload[11]
func_code = payload[12]
result["function_code"] = func_code
result["function_name"] = DNP3_FUNCTIONS.get(
func_code, f"Unknown (0x{func_code:02x})"
)
return result
def analyze_packet(self, pkt):
"""Analyze a packet for DNP3 anomalies."""
self.packet_count += 1
if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
return
tcp = pkt[TCP]
if tcp.dport != 20000 and tcp.sport != 20000:
return
payload = bytes(tcp.payload)
if not payload:
return
dnp3 = self.parse_dnp3_header(payload)
if not dnp3:
return
self.dnp3_count += 1
src_ip = pkt[IP].src
dst_ip = pkt[IP].dst
session_key = f"{src_ip}->{dst_ip}"
session = self.sessions[session_key]
session["packet_count"] += 1
func_code = dnp3.get("function_code")
if func_code is not None:
session["function_codes"][func_code] += 1
# Detection 1: Unauthorized DNP3 master
if dnp3.get("is_master") and self.authorized_masters:
if src_ip not in self.authorized_masters:
self.alerts.append({
"severity": "CRITICAL",
"type": "UNAUTHORIZED_DNP3_MASTER",
"src": src_ip, "dst": dst_ip,
"function": dnp3.get("function_name"),
"description": f"Unauthorized DNP3 master {src_ip} communicating with outstation {dst_ip}",
"mitre": "T0869 - Standard Application Layer Protocol",
})
# Detection 2: Cold/Warm restart command
if func_code in (0x0D, 0x0E):
session["restarts"] += 1
restart_type = "Cold" if func_code == 0x0D else "Warm"
self.alerts.append({
"severity": "CRITICAL",
"type": "DNP3_RESTART_COMMAND",
"src": src_ip, "dst": dst_ip,
"function": f"{restart_type} Restart",
"description": f"{restart_type} restart command sent to outstation {dst_ip} (addr {dnp3['dest_addr']})",
"mitre": "T0816 - Device Restart/Shutdown",
})
# Detection 3: File operations (potential firmware update)
if func_code in (0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E):
session["file_operations"] += 1
self.alerts.append({
"severity": "CRITICAL",
"type": "DNP3_FILE_OPERATION",
"src": src_ip, "dst": dst_ip,
"function": dnp3.get("function_name"),
"description": f"File operation on outstation {dst_ip} - potential firmware update or PIPEDREAM indicator",
"mitre": "T0839 - Module Firmware",
})
# Detection 4: Control commands (Select/Operate)
if func_code in (0x03, 0x04, 0x05, 0x06):
session["control_commands"] += 1
if session_key in self.baseline_functions:
if func_code not in self.baseline_functions[session_key]:
self.alerts.append({
"severity": "HIGH",
"type": "UNEXPECTED_CONTROL_COMMAND",
"src": src_ip, "dst": dst_ip,
"function": dnp3.get("function_name"),
"description": f"Control command {dnp3.get('function_name')} not in baseline for {session_key}",
"mitre": "T0855 - Unauthorized Command Message",
})
# Detection 5: Anomalous function code for this pair
if session_key in self.baseline_functions:
if func_code not in self.baseline_functions[session_key]:
if func_code not in (0x00, 0x81, 0x82): # Exclude common response codes
self.alerts.append({
"severity": "MEDIUM",
"type": "ANOMALOUS_FUNCTION_CODE",
"src": src_ip, "dst": dst_ip,
"function": dnp3.get("function_name"),
"description": f"Function code 0x{func_code:02x} not in baseline",
"mitre": "T0855 - Unauthorized Command Message",
})
def generate_report(self):
"""Generate DNP3 anomaly detection report."""
print(f"\n{'='*70}")
print("DNP3 PROTOCOL ANOMALY DETECTION REPORT")
print(f"{'='*70}")
print(f"Analysis Time: {datetime.now().isoformat()}")
print(f"Total Packets: {self.packet_count}")
print(f"DNP3 Packets: {self.dnp3_count}")
print(f"Alerts: {len(self.alerts)}")
print(f"\n--- DNP3 SESSION SUMMARY ---")
for key, session in self.sessions.items():
print(f"\n {key}")
print(f" Packets: {session['packet_count']}")
funcs = [DNP3_FUNCTIONS.get(f, f"0x{f:02x}") for f in session["function_codes"]]
print(f" Functions: {', '.join(funcs)}")
print(f" Control Commands: {session['control_commands']}")
print(f" File Operations: {session['file_operations']}")
print(f" Restart Commands: {session['restarts']}")
if self.alerts:
print(f"\n--- ALERTS ---")
for alert in self.alerts:
print(f"\n [{alert['severity']}] {alert['type']}")
print(f" {alert['src']} -> {alert['dst']}")
print(f" Function: {alert['function']}")
print(f" Detail: {alert['description']}")
print(f" MITRE ICS: {alert.get('mitre', 'N/A')}")
if __name__ == "__main__":
detector = DNP3AnomalyDetector(
baseline_file=sys.argv[2] if len(sys.argv) > 2 else None
)
if len(sys.argv) >= 2:
print(f"[*] Analyzing: {sys.argv[1]}")
packets = rdpcap(sys.argv[1])
for pkt in packets:
detector.analyze_packet(pkt)
detector.generate_report()
else:
print("Usage: python dnp3_detector.py <capture.pcap> [baseline.json]")
Key Concepts
Term
Definition
DNP3
Distributed Network Protocol version 3, the predominant SCADA protocol in the energy sector for communication between masters and outstations
Outstation
DNP3 slave device (typically an RTU or IED) that responds to master station polls and commands
Select-Before-Operate
DNP3 safety mechanism requiring a Select command before an Operate, preventing accidental control actions
Cold Restart (FC 0x0D)
DNP3 command that fully restarts an outstation, resetting all configuration -- a high-risk denial-of-service operation
Detecting Dnp3 Protocol Anomalies next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Detecting Dnp3 Protocol Anomalies compared with similar skills
Skill
Stars
Used in
Tokens
Auto-check
Licence
Repo updated
Detecting Dnp3 Protocol Anomalies this skillmukul975/Anthropic-Cybersecurity-Skills
Build a new time-series analytics use case on top of the deployed Time Series Analytics microservice — bring it up with Docker Compose (from a repo clone, or by fetching the compose files from…
Guides time series machine learning with the aeon toolkit: classification, regression, clustering, forecasting, anomaly detection, segmentation and similarity search.
Forecasts any univariate time series zero-shot with Google's TimesFM model, returning point forecasts and calibrated prediction intervals without training.
Walks through reverse engineering Go-compiled malware in Ghidra: parsing buildinfo and pclntab, recovering stripped function names and extracting dependencies.
Detects DNS tunneling, ICMP exfiltration and HTTP-based covert channels in packet captures and DNS logs when hunting for hidden command-and-control traffic.
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…. Detecting Dnp3 Protocol Anomalies is an agent skill from mukul975/Anthropic-Cybersecurity-Skills. 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.
When should I use Detecting Dnp3 Protocol Anomalies?
Detecting Dnp3 Protocol Anomalies fits situations like: securing energy-sector; other OT/ICS networks; investigating suspicious DNP3 master/outstation activity; building an anomaly-based IDS for industrial control traffic.
How do I install Detecting Dnp3 Protocol Anomalies in Claude Code?
Run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a claude-code`. Or copy the skill folder (skills/detecting-dnp3-protocol-anomalies in mukul975/Anthropic-Cybersecurity-Skills) into .claude/skills/detecting-dnp3-protocol-anomalies in your project. Claude Code loads it when a task matches its description.
How do I install Detecting Dnp3 Protocol Anomalies in Codex?
Run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a codex`. Or copy the skill folder (skills/detecting-dnp3-protocol-anomalies in mukul975/Anthropic-Cybersecurity-Skills) into .agents/skills/detecting-dnp3-protocol-anomalies in your project. Codex loads it when a task matches its description.
Can I use Detecting Dnp3 Protocol Anomalies in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill detecting-dnp3-protocol-anomalies -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/detecting-dnp3-protocol-anomalies, .gemini/skills/detecting-dnp3-protocol-anomalies, .github/skills/detecting-dnp3-protocol-anomalies and .opencode/skills/detecting-dnp3-protocol-anomalies in your project.
What does Detecting Dnp3 Protocol Anomalies need to run?
Going by SKILL.md and its folder, Detecting Dnp3 Protocol Anomalies needs Python for the scripts in its folder. Our summary lists: Python 3.
Does Detecting Dnp3 Protocol Anomalies access the network?
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Is Detecting Dnp3 Protocol Anomalies safe to install?
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
What licence does Detecting Dnp3 Protocol Anomalies use?
Detecting Dnp3 Protocol Anomalies is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does Detecting Dnp3 Protocol Anomalies use?
About 3.6k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 418 tokens, read only when the agent opens those files.
What are the alternatives to Detecting Dnp3 Protocol Anomalies?
Skills that share tags, products or a category with Detecting Dnp3 Protocol Anomalies: Time Series Analytics User (open-edge-platform/edge-ai-libraries, 171 stars), Aeon Time Series Machine Learning (davila7/claude-code-templates, 33k stars), Automl Skill (LeoYeAI/openclaw-master-skills, 2.2k stars) and Scikit Learn (zLanqing/codex-claude-academic-skills, 4.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains Detecting Dnp3 Protocol Anomalies?
mukul975 (a GitHub user) maintains it in mukul975/Anthropic-Cybersecurity-Skills, which has 34,116 GitHub stars. The repository holds 644 skills in this directory. The repository was last updated on August 31, 2026.