Post

Building Argus SOC | Phase 4 Scenario 5 | Lateral Movement — When the AI Got It Wrong

Phase 4 Scenario 5 of the Argus SOC build — pivoting from a compromised Metasploitable host into the Cowrie honeypot. The detection rules fire correctly, but Claude misclassifies the alert as LOW. The first scenario where the AI triage layer — not the detection layer — was the weak link.

Building Argus SOC | Phase 4 Scenario 5 | Lateral Movement — When the AI Got It Wrong

📌 Author’s note — This post documents the Argus SOC lab at the time of publication, when the Pi 3B+ served as the MSSP edge sensor and the Pi 5 hosted the vulnerable Docker targets. The architecture was redesigned in Phase 5, which introduced a ThinkCentre M920x running Proxmox with an Active Directory lab as the client infrastructure, and moved the edge-sensor role onto the Pi 5. The detection logic, custom rules, and gap analysis described here remain valid; only the host topology has changed.

Build carried out on real hardware in a controlled home lab. Claude (Anthropic) was used as a reasoning and writing assistant — all deployments, attacks, configurations, and verifications were performed by the author.

Overview

This is the final scenario of Phase 4 and the most interesting one analytically. The previous four scenarios all followed the same broad pattern: a configuration variable or missing signature caused Suricata or Wazuh to miss the attack, and remediation came down to fixing rules. Scenario 5 breaks that pattern. The detection rules fire correctly. The pipeline routes the alert to Claude. Claude under-classifies it as LOW, the alert never reaches Telegram, and the operator is never notified.

This is the first scenario where the AI triage layer — not the detection layer — was the weak link. The remediation isn’t a Suricata signature or a HOME_NET fix; it’s a Wazuh correlation rule that escalates the alert before it reaches Claude, giving the AI the right signal to act on.


The Attack — Pivoting Through a Compromised Host

Timestamp: 2026-04-04 16:07 UTC Attack path: Kali (192.168.1.101) → Metasploitable 2 ingreslock backdoor (192.168.1.10:1524) → SSH to Pi 3B+ Cowrie honeypot (192.168.1.20:22)

This scenario simulates a realistic lateral movement chain. The attacker doesn’t directly attack the edge sensor — they compromise the client infrastructure first, then pivot through it to reach the next target. From the SOC’s perspective, the source IP of the second-stage attack is an internal host, not the original attacker.

Kill Chain

1
2
3
4
5
6
7
8
9
10
11
# Stage 1: From Kali — access compromised host via ingreslock backdoor
nc 192.168.1.10 1524

# Stage 2: From compromised Metasploitable — pivot to Pi 3B+
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@192.168.1.20

# Stage 3: Inside Cowrie fake shell — post-exploitation recon
whoami          → root
ls -la          → directory listing of /root
iduid=0(root) gid=0(root) groups=0(root)
cat /etc/passwd → full user list

Kali pivoting from Metasploitable to Cowrie Kali terminal — nc to ingreslock, then SSH from inside the compromised host to the honeypot


Detection Results — Detection Works, Triage Fails

Cowrie Honeypot — Pivot Detected ✅

Cowrie recorded the lateral movement with the correct source IP — 192.168.1.10 (Pi 5), not 192.168.1.101 (Kali):

Rule IDDescriptionLevelSource IP
100010New honeypot connection from 192.168.1.106192.168.1.10
100011Successful honeypot login from 192.168.1.1010192.168.1.10
100012Attacker command executed on honeypot6— (5 hits)

This is exactly the signal a SOC analyst would want. A server IP appearing as the source of an SSH login is the smoking gun: servers don’t normally open interactive SSH sessions to other hosts. The detection layer captured this correctly.

Wazuh — 11 Alerts Total

Rule IDDescriptionLevelCount
100012Cowrie: Attacker command executed on honeypot65
5710sshd: Attempt to login using non-existent user54
100011Cowrie: Successful honeypot login from 192.168.1.10101
100010Cowrie: New honeypot connection from 192.168.1.1061

Rule 100011 fired at level 10, passed the n8n pre-filter, and reached Claude. So far, the pipeline worked as designed.

Claude AI Triage — Classified as LOW ❌

Claude classified the level-10 Cowrie successful login as LOW severity. The alert was routed to silent logging, not Telegram. The operator was never notified.

The comparison point that makes this jump out: In Scenario 2, the same Cowrie login event — same rule ID, same level, same alert structure — coming from 192.168.1.101 (Kali) was classified MEDIUM and triggered Telegram. Coming from 192.168.1.10 (the server), the same event was classified LOW.

Claude treated the internal server source as less suspicious. In reality it’s the opposite: a server-to-server interactive SSH login is more anomalous than a workstation-to-server one, because workstations open SSH sessions all the time and servers usually don’t. The AI had the right data but lacked the topological context to interpret it correctly.

Telegram: Silent

No notification. The operator had no idea lateral movement was in progress.

Wazuh showing Cowrie alerts from Metasploitable source IP Wazuh event list — rule 100011 fires at level 10, source IP 192.168.1.10 (Pi 5), but downstream classification missed the significance

Grafana showing lateral movement detection Grafana — the honeypot login appears as a single critical alert, but no escalation, no operator notification

n8n showing alert routed as LOW n8n workflow — the alert reached Claude, was classified LOW, and routed to silent logging instead of Telegram


Root Cause — A Different Kind of Gap

The previous four scenarios all came down to detection-layer problems:

  • Scenario 1 — HOME_NET typo scoped ET SCAN rules away from real traffic
  • Scenario 3 — same HOME_NET typo, plus no signature for the UnrealIRCd backdoor
  • Scenario 4 — HTTP_PORTS only covered port 80, missed traffic on 8080

In each case, the fix was to add or correct a rule so the detection engine could see the attack.

Scenario 5 is different. The detection engine saw the attack. Cowrie logged the right source IP. Wazuh correlated the events and fired the right rule. The pipeline carried the alert to the right place. The failure happened after detection, inside the AI triage layer.

Claude’s classification depended on context it didn’t have. From the system prompt’s perspective, 192.168.1.10 was just “an internal IP” — there was nothing to tell the AI that this specific IP belonged to a server, that servers SSH’ing into other servers is anomalous, or that the broader pattern (server appearing as SSH source) was the actual indicator of compromise.

The fix isn’t a Suricata signature. It’s a Wazuh rule that recognises the anomaly before the alert reaches Claude, and escalates the severity so Claude is working from a stronger signal.

What Was and Wasn’t Detected

DetectedNot Detected
Cowrie SSH login from compromised hostThe initial ingreslock backdoor access on port 1524
Post-exploitation commands in the fake shellThe pivot chain itself — no rule correlates “host A compromised → host A now SSH’ing to host B”
Correct source IP attribution to Pi 5The operator notification — Telegram never fired
Level 10 alert reached ClaudeClaude’s prompt didn’t recognise server-IP-as-SSH-source as a strong indicator

A Wazuh rule that escalates server-originated honeypot logins addresses the most actionable of these gaps without requiring a Claude prompt rewrite.


Remediation

Custom Wazuh Correlation Rule (Hetzner)

Added to /var/ossec/etc/rules/local_rules.xml:

1
2
3
4
5
6
<rule id="100033" level="12">
  <if_sid>100011</if_sid>
  <match>192.168.1.10</match>
  <description>Cowrie: Lateral movement — honeypot login from server IP 192.168.1.10 (possible pivot from compromised host)</description>
  <mitre><id>T1021</id></mitre>
</rule>

This rule chains off Cowrie successful logins (rule 100011) and matches when the alert description contains the server IP. When matched, it escalates the alert to level 12 and explicitly maps to MITRE T1021 (Remote Services) — correctly identifying this as lateral movement rather than the generic credential access classification that triggered for Scenario 2.

A Subtle Wazuh Decoder Note

An initial attempt using <srcip>192.168.1.10</srcip> failed silently — the alert wouldn’t escalate. The Cowrie decoder doesn’t populate the standard srcip field the same way native sshd alerts do; the source IP only appears in the description text. Switching to <match> against the description string resolved this.

This is the kind of gap that’s invisible until you test the rule end-to-end. The rule looks correct on paper, doesn’t error, doesn’t log a warning — it just doesn’t fire. Lesson for the future: always verify a new Wazuh correlation rule by triggering the underlying condition and watching the manager logs in real time.


Re-Test Results — Full Pipeline Recovered

Full pipeline in ~30 seconds — Kali launches the attack, Suricata detects, Wazuh correlates, Claude classifies CRITICAL, Telegram fires.

Timestamp: 2026-04-04 20:37 UTC Same attack path: Kali → nc 192.168.1.10:1524 → ssh root@192.168.1.20

Claude AI Classification (After Remediation)

  • Severity: CRITICAL
  • MITRE: T1021 (Remote Services)
  • Confidence: 0.92
  • Action: respond_immediately
  • Summary: “A successful SSH login to the Cowrie honeypot on argus-edge-01 originated from argus-central (192.168.1.10), indicating potential lateral movement from a compromised internal host. The root account login with empty password to port 22 (honeypot) suggests an attacker has pivoted from the central server and is actively probing the network.”

The same event, from the same source IP, generated by the same Cowrie rule — but now classified correctly because the new Wazuh rule presented it to Claude as a level-12 lateral movement event mapped to T1021, rather than a level-10 generic credential access event.

Telegram: CRITICAL Alert Delivered

The operator received a CRITICAL Telegram alert within seconds, with Claude’s classification correctly identifying lateral movement and recommending immediate response.

Kali re-running the pivot Re-test — same attack, full pipeline now responds

Wazuh rule 100033 firing at level 12 Wazuh after remediation — rule 100033 fires at level 12, MITRE T1021 mapped

Grafana showing lateral movement detection Grafana — MITRE ATT&CK panel showing Remote Services classification

n8n showing alert routed as CRITICAL n8n workflow after remediation — same alert path, now routed as CRITICAL to Telegram and PagerDuty

Telegram CRITICAL alert for lateral movement Telegram — CRITICAL alert delivered, Claude correctly identifies lateral movement and recommends immediate response


Before / After

MetricBeforeAfter
Wazuh rule fired100011 (level 10)100033 (level 12)
Claude classificationLOWCRITICAL
Telegram alertNoYes
MITRE techniqueT1110.001 (Password Guessing)T1021 (Remote Services)
Recommended actionrespond_immediately
Time to operator notificationNever~5 seconds

Phase 4 Closing — Progression Across All Five Scenarios

AspectScenario 1 (Recon)Scenario 2 (Brute Force)Scenario 3 (RCE)Scenario 4 (SQLi)Scenario 5 (Lateral)
Initial detectionPartialFullZeroZeroPartial (LOW)
Root causeHOME_NET typoN/AHOME_NET + missing sigsHTTP_PORTS + missing sigsAI triage under-classification
Layer at faultDetection (Suricata)NoneDetection (Suricata + Wazuh)Detection (Suricata)Triage (Claude prompt context)
Custom rules002 Suricata + 2 Wazuh2 Suricata + 1 Wazuh1 Wazuh
After remediationET SCAN firingN/A12 CRITICAL33 alertsCRITICAL, T1021 mapped
Claude reachedNo (level 3)Yes — MEDIUMYes — CRITICALYes — MEDIUMYes — CRITICAL
TelegramNoYesYes (11 alerts)YesYes

Across the five scenarios, the detection stack started near-blind (HOME_NET miscalibration retroactively explained every Phase 0–3 gap), evolved through specific signature work (custom Suricata SIDs for UnrealIRCd, reverse shells, SQL injection), and ended with a different class of fix entirely — using Wazuh correlation to give the AI triage layer better context to work with.

That last point is the one worth holding onto. AI-augmented SOC pipelines aren’t magic detection layers. They classify what they’re shown, and the quality of the classification depends entirely on the quality of the signal they receive. Tuning the AI is real work, and most of that work happens upstream of the AI — in the detection rules, correlation logic, and severity levels that prepare each alert for triage.


Architectural Note — Guest WiFi Isolation

During Phase 4, an attempt to run attacks from the TP-Link Archer AX55 guest WiFi confirmed full client isolation — the Kali VM could not reach 192.168.1.0/24. All attack scenarios were executed from the main WiFi subnet. In a real MSSP deployment the external attacker would arrive from the internet, not a local network segment. The detection results remain valid since Suricata sees all traffic via SPAN regardless of the attacker’s network position.


Evidence Collected

Screenshots — Initial Attack (Under-Classified)

ScreenshotFilename
Kali — nc pivot + Cowrie shellphase4_scenario5_lateral-movement-kali.png
Grafana — lateral movement detectionphase4_scenario5_grafana-lateral-detection.png
Wazuh — Cowrie alerts from 192.168.1.10phase4_scenario5_wazuh-cowrie-from-metasploitable.png

Screenshots — After Remediation

ScreenshotFilename
Telegram — CRITICAL lateral movement alertphase4_scenario5_remediated-telegram-lateral-critical.png
Wazuh — rule 100033 at level 12phase4_scenario5_remediated-wazuh-rule-100033.png
Grafana — lateral movement detectedphase4_scenario5_remediated-grafana-lateral.png
Kali — re-run pivotphase4_scenario5_remediated-kali-pivot.png

Data Exports

FileDescription
scenario5_wazuh-events-export.csvDownload — Cowrie detecting pivot from Metasploitable IP, under-classified run
scenario5_remediated-wazuh-events-export.csvDownload — successful detection and CRITICAL escalation after remediation

What’s Next — Phase 5

Phase 4 closes here. Five scenarios across the kill chain, every detection gap documented honestly, every remediation tested end-to-end, every layer of the pipeline exercised — including the AI itself.

Phase 5 is the architectural pivot. Hardening across all nodes, then a full migration: the Pi 3B+ is retired from its edge-sensor role, a ThinkCentre M920x running Proxmox joins the lab as the new client infrastructure, an Active Directory domain comes online (Windows Server 2022 DC + Windows 11 domain-joined workstation), and the Pi 5 takes over as the MSSP edge sensor monitoring the new environment. Same MSSP topology, more realistic client side, ready for Phase 7’s AD-specific attack scenarios.


Part of the Argus SOC build series.

This post is licensed under CC BY 4.0 by the author.