Skip to content

Purple Team

André Henrique edited this page Jun 8, 2026 · 1 revision

Purple Team - OT Detection & Analysis

Purple team modules in IXF generate detection artifacts, analyze captured traffic, and produce IDS/IPS rules for OT/ICS environments. They bridge the gap between offensive assessment and defensive monitoring.


Table of Contents


Modbus PCAP Analyzer

Analyzes captured Modbus/TCP traffic for unauthorized write operations, reconnaissance patterns, and anomalous function code usage.

Path: assessment/detection/modbus_pcap_analyzer

Capture traffic first

# On the network segment hosting the PLC (Linux/Mac)
tcpdump -i eth0 -w /tmp/modbus_capture.pcap 'tcp port 502'

# Windows with Wireshark CLI
tshark -i "Ethernet" -w C:\tmp\modbus_capture.pcap -f "tcp port 502"

# Or use IXF passive MiTM capture
ixf > use assessment/lateral/modbus_mitm_inline
ixf (ModbusMiTM) > set TARGET 192.168.1.10
ixf (ModbusMiTM) > set simulate false
ixf (ModbusMiTM) > run   # Logs all Modbus frames - no injection

Analyze the capture

ixf > use assessment/detection/modbus_pcap_analyzer
ixf (ModbusPCAP) > set PCAP_FILE /tmp/modbus_capture.pcap
ixf (ModbusPCAP) > set OUTPUT_JSON /tmp/analysis.json
ixf (ModbusPCAP) > run

[*] Analyzing Modbus PCAP: /tmp/modbus_capture.pcap
[+] Parsed 847 Modbus transactions

Summary:
  Total transactions:       847
  Unique source IPs:        3
  Write operations:         12
  DANGEROUS operations:     4  <- FC5/6/15/16
  Recon operations:         2  <- FC43/FC17

[!] ALERT: 4 DANGEROUS Modbus write operations detected

Source       Destination  FC   Name                   Reg   Flag
10.0.1.100   10.0.1.10   16   Write Multiple Regs    100   [DANGEROUS]
10.0.1.100   10.0.1.10   5    Write Single Coil      1     [DANGEROUS]
10.0.1.200   10.0.1.10   43   Read Device ID         -     [RECON]
10.0.1.200   10.0.1.10   17   Report Server ID       -     [RECON]

[+] JSON report saved: /tmp/analysis.json

JSON output structure

{
  "summary": {
    "total_transactions": 847,
    "unique_src_ips": ["10.0.1.100", "10.0.1.50", "10.0.1.200"],
    "write_ops": 12,
    "dangerous_ops": 4,
    "recon_ops": 2
  },
  "dangerous_transactions": [
    {
      "src": "10.0.1.100", "dst": "10.0.1.10",
      "fc": 16, "fc_name": "Write Multiple Regs",
      "register": 100, "flag": "DANGEROUS"
    }
  ]
}

Suricata OT Rules Generator

Generates Suricata IDS rules for OT/ICS protocol anomaly detection, including CVE-based signatures for known ICS malware.

Path: assessment/detection/suricata_ot_rules_generator

Generate rules

ixf > use assessment/detection/suricata_ot_rules_generator
ixf (SuricataOT) > set OUTPUT_FILE /tmp/ics_rules.rules
ixf (SuricataOT) > set PROTOCOLS modbus,dnp3,bacnet,enip
ixf (SuricataOT) > set INCLUDE_CVE_RULES true
ixf (SuricataOT) > run

[*] Generating Suricata OT/ICS rules
[+] Modbus rules:    18 (write ops, function code abuse, broadcast)
[+] DNP3 rules:       9 (unsolicited response, unauthorized control)
[+] BACnet rules:    11 (who-is flood, foreign device abuse)
[+] EtherNet/IP:     8 (identity object abuse, forward open flood)
[+] CVE-based rules: 14 (TRITON, FrostyGoop, INCONTROLLER signatures)
[+] Total rules:     60

[+] Rules written to: /tmp/ics_rules.rules
[*] Test against capture: suricata -r /tmp/modbus_capture.pcap -S /tmp/ics_rules.rules -l /tmp/suricata_logs/

Example generated rule

# Modbus Write Multiple Registers (FC16) - unauthorized write
alert tcp any any -> any 502 (
  msg:"ICS/OT Modbus FC16 Write Multiple Registers - Potential Unauthorized Write";
  content:"|00 00|"; depth:2; offset:2;
  byte_test:1,=,16,7;
  flow:established,to_server;
  classtype:attempted-admin;
  sid:9100016; rev:1;
)

Load into Suricata

# Test against PCAP
suricata -r /tmp/modbus_capture.pcap -S /tmp/ics_rules.rules -l /tmp/suricata_logs/

# Live interface
suricata -i eth0 -S /tmp/ics_rules.rules -l /var/log/suricata/

Modbus Zeek Rule Generator

Generates Zeek/Bro scripts for Modbus/TCP traffic analysis and behavioral alerting.

Path: assessment/detection/modbus_zeek_rule_generator

Generate scripts

ixf > use assessment/detection/modbus_zeek_rule_generator
ixf (ModbusZeek) > set OUTPUT_DIR /tmp/zeek_scripts
ixf (ModbusZeek) > set ALERT_WRITE_OPS true
ixf (ModbusZeek) > set ALERT_BROADCAST true
ixf (ModbusZeek) > set BASELINE_WINDOW 3600
ixf (ModbusZeek) > run

[*] Generating Zeek Modbus analysis scripts
[+] modbus-write-monitor.zeek     Alert on FC5/6/15/16 write operations
[+] modbus-broadcast-detect.zeek  Detect broadcast unit_id=255 recon
[+] modbus-function-log.zeek      Full function code audit log
[+] modbus-anomaly-detect.zeek    Statistical baseline deviation (window: 3600s)

[+] Scripts saved to: /tmp/zeek_scripts/
[*] Run: zeek -i eth0 /tmp/zeek_scripts/
[*] Replay: zeek -r /tmp/modbus_capture.pcap /tmp/zeek_scripts/

Example script: write monitor

# modbus-write-monitor.zeek
# Generated by IXF Modbus Zeek Rule Generator

event modbus_write_registers(c: connection, headers: ModbusHeaders,
                              start_address: count, registers: ModbusRegisters)
{
    local msg = fmt("Modbus FC16 Write: src=%s dst=%s start=%d count=%d",
                    c$id$orig_h, c$id$resp_h,
                    start_address, |registers|);
    NOTICE([$note=Modbus::WriteOperation, $msg=msg,
            $conn=c, $identifier=cat(c$id$orig_h)]);
}

Combined Workflow

A typical purple team engagement for an OT assessment:

Step 1 - Capture baseline traffic

# 1 hour of normal operations
tcpdump -i eth0 -w /tmp/baseline.pcap 'tcp port 502' &
sleep 3600
kill %1

Step 2 - Run offensive module in simulate mode

ixf > use exploits/protocols/modbus_write_multiple_registers
ixf (ModbusWriteMultiple) > set TARGET 192.168.1.10
ixf (ModbusWriteMultiple) > set simulate true
ixf (ModbusWriteMultiple) > run
# Note the FC and register values used

Step 3 - Generate detection rules based on the attack pattern

ixf > use assessment/detection/suricata_ot_rules_generator
ixf (SuricataOT) > set OUTPUT_FILE /tmp/ics_detection.rules
ixf (SuricataOT) > set PROTOCOLS modbus
ixf (SuricataOT) > run

Step 4 - Validate rules against baseline (should be clean)

suricata -r /tmp/baseline.pcap -S /tmp/ics_detection.rules -l /tmp/baseline_results/
# Expected: 0 alerts for normal traffic

Step 5 - Capture attack traffic (authorized lab only) and validate detection

# Capture while running live module in lab
tcpdump -i eth0 -w /tmp/attack_session.pcap 'tcp port 502'
# ... run module live against Conpot ...
suricata -r /tmp/attack_session.pcap -S /tmp/ics_detection.rules -l /tmp/attack_results/
# Expected: alerts fire on FC16 writes

Step 6 - Analyze with PCAP analyzer

ixf > use assessment/detection/modbus_pcap_analyzer
ixf (ModbusPCAP) > set PCAP_FILE /tmp/attack_session.pcap
ixf (ModbusPCAP) > run
# Compare dangerous ops to attack scenario

Module Reference

Module Path Direction Output
modbus_pcap_analyzer assessment/detection/ Blue JSON report
suricata_ot_rules_generator assessment/detection/ Blue .rules file
modbus_zeek_rule_generator assessment/detection/ Blue .zeek scripts
conpot_integration assessment/detection/ Both Honeypot detection / lab target

Author: Andre Henrique (@mrhenrike) | Uniao Geek | https://uniaogeek.com.br/

Clone this wiki locally