#!/usr/bin/env bash
# Lab 20.6a - OT detection: Zeek + Suricata on a Modbus pcap
#
# Workflow:
#   1. Generate a synthetic Modbus pcap by probing conpot (tcpdump)
#   2. Parse with Zeek to build a modbus.log baseline
#   3. Run Suricata over the pcap with the write-detection rule
#   4. Confirm alerts appear in fast.log for write frames
#
# Run inside ch20-tools container:
#   bash /scripts/lab20_6a_detect.sh
#
# The pcap is also written to /output/modbus_lab.pcap so you can open it
# in Wireshark on the host for Lab 20.3.

set -euo pipefail

CONPOT_IP="${MODBUS_HOST:-172.30.20.10}"
CONPOT_PORT="${MODBUS_PORT:-502}"
PCAP="/output/modbus_lab.pcap"
RULES="/rules/modbus-write.rules"
ZEEK_OUT="/output/zeek_$(date +%s)"
SURICATA_OUT="/output/suricata_$(date +%s)"

echo "[*] === Lab 20.6a: Zeek/Suricata Modbus detection ==="
echo "[*] Target: ${CONPOT_IP}:${CONPOT_PORT}"

# ── Step 1: capture traffic while probing conpot ─────────────────────────
echo ""
echo "[*] Step 1: Capturing Modbus traffic to ${PCAP} ..."
echo "    (runs probe script while tcpdump captures for 15 seconds)"

# tcpdump in background, then probe, then wait
tcpdump -i any -w "${PCAP}" "host ${CONPOT_IP} and port ${CONPOT_PORT}" 2>/dev/null &
TCPDUMP_PID=$!
sleep 2

python3 /scripts/lab20_5_probe.py 2>&1 | sed 's/^/  [probe] /'
sleep 3
kill "${TCPDUMP_PID}" 2>/dev/null || true
echo "[+] Capture saved: ${PCAP}"

# ── Step 2: tshark sanity check ──────────────────────────────────────────
echo ""
echo "[*] Step 2: tshark - function code inventory"
echo "    Command: tshark -r ${PCAP} -Y modbus -T fields -e modbus.func_code | sort | uniq -c"
tshark -r "${PCAP}" -Y modbus -T fields -e modbus.func_code 2>/dev/null \
  | sort | uniq -c \
  | awk '{printf "    FC %s: %s frame(s)\n", $2, $1}' || echo "  (no modbus frames decoded - check dissector)"

# ── Step 3: Zeek passive parse ────────────────────────────────────────────
echo ""
echo "[*] Step 3: Zeek passive parse"
mkdir -p "${ZEEK_OUT}"
if command -v zeek &>/dev/null; then
    zeek -r "${PCAP}" modbus 2>/dev/null -C -b -d "${ZEEK_OUT}" || \
        zeek -r "${PCAP}" -C 2>/dev/null
    echo "[+] Zeek logs written to ${ZEEK_OUT}/"
    if [ -f "${ZEEK_OUT}/modbus.log" ]; then
        echo "    modbus.log (first 5 entries):"
        head -5 "${ZEEK_OUT}/modbus.log" | sed 's/^/    /'
    else
        echo "    (modbus.log not generated - Zeek Modbus policy script may not be loaded)"
        echo "    Try: zeek -r ${PCAP} -C protocols/modbus"
    fi
else
    echo "  [SKIP] zeek not found in PATH - install: apt-get install zeek"
fi

# ── Step 4: Suricata alert on writes ──────────────────────────────────────
echo ""
echo "[*] Step 4: Suricata write-detection rule"
mkdir -p "${SURICATA_OUT}"
if command -v suricata &>/dev/null; then
    suricata -r "${PCAP}" -S "${RULES}" -l "${SURICATA_OUT}" \
        --set default-log-dir="${SURICATA_OUT}" 2>/dev/null || true
    if [ -f "${SURICATA_OUT}/fast.log" ]; then
        echo "[+] Alerts in fast.log:"
        cat "${SURICATA_OUT}/fast.log" | sed 's/^/    /'
    else
        echo "  fast.log not found - check ${SURICATA_OUT}/ for other output"
    fi
else
    echo "  [SKIP] suricata not found - install: apt-get install suricata"
fi

echo ""
echo "[*] === Detection summary ==="
echo "    - FC 03/01 (reads): reconnaissance - no alert expected"
echo "    - FC 06   (write):  Impair Process Control - ALERT expected"
echo "    Pcap available for Wireshark at: ${PCAP} (host-mapped via ./output/)"
echo ""
echo "[!] Safety: this script only probes the lab conpot container."
echo "    Never run against production OT or systems you do not own."
