faisal-kh-alkanhal/Suricata-IDS-Lab

GitHub: faisal-kh-alkanhal/Suricata-IDS-Lab

Stars: 0 | Forks: 0

# Suricata IDS Lab A home network intrusion detection system built on Ubuntu Server 22.04, using custom Suricata rules to detect real attack patterns including port scans, brute-force attempts, and HTTP anomalies. Built as a hands-on blue team project to demonstrate network threat detection and SOC analyst skills. ## Lab Architecture ┌─────────────────────────────────────────────────┐ │ HOME LAB NETWORK │ │ │ │ [Attack Machine] ──────► [Suricata VM] │ │ Host / Kali Linux Ubuntu Server │ │ nmap, curl, hydra 22.04 LTS │ │ (generates test traffic) (monitors + alerts) │ └─────────────────────────────────────────────────┘ **Stack:** Suricata 8.0.5 · Ubuntu Server 22.04 · jq · custom detection rules ## Detection Rules | # | Rule Name | Attack Simulated | Technique | |---|-----------|-----------------|-----------| | 1 | SCAN nmap SYN Sweep | `nmap -sS` port scan | TCP SYN flag + threshold | | 2 | BRUTE FORCE SSH Login | Repeated SSH connections | Content match + rate threshold | | 3 | DNS Query Suspicious TLD | DNS lookup to `.xyz` and other domains | DNS keyword match | | 4 | HTTP Admin Panel Access | `curl /admin` endpoint probe | HTTP URI content match | ### Rule: Port Scan Detection alert tcp $EXTERNAL_NET any -> $HOME_NET any ( msg:"Nmap SYN Sweep"; flags:S; threshold:type both, track by_src, count 20, seconds 3; sid:1000001; rev:1; ) Fires when a single source sends 20+ SYN packets in 3 seconds, the signature of an nmap default scan. Threshold tuned to reduce false positives on legitimate traffic while catching automated scanners. ### Rule: SSH Brute Force alert tcp $EXTERNAL_NET any -> $HOME_NET 22 ( msg:"SSH Brute Force Attack"; flow:to_server,established; content:"SSH"; threshold:type both, track by_src, count 5, seconds 60; sid:1000002; rev:1; ) Detects repeated SSH login attempts from the same source IP. Tracks by source so distributed attacks from multiple IPs would require a separate detection approach (noted as a limitation below). ### Rule: Suspicious DNS Query alert dns any any -> any any ( msg: "DNS Query For Suspicious TLD"; dns.query; pcre:"/\.(xyz|top|biz)/i"; sid:1000003; rev:1; ) Flags outbound DNS lookups for suspicious domains, a TLD commonly associated with malware C2 infrastructure. In a real environment this would be paired with a threat intel feed. ### Rule: HTTP Admin Panel Probe alert http $EXTERNAL_NET any -> $HOME_NET any ( msg:"HTTP Admin Panel Access Attempt"; http.uri; content:"/admin"; nocase; sid:1000004; rev:1; ) Detects requests to common admin paths. Uses the `http.uri` sticky buffer for accurate URI matching rather than raw content inspection. ## Attack Simulations & Results Each rule was validated by generating matching traffic and confirming an alert fired in `fast.log`. ### Simulation Commands # Rule 1: Port scan nmap -sS # Rule 2: SSH brute force hydra -l root -P /usr/share/wordlists/rockyou.txt ssh:// # Rule 3: Suspicious DNS nslookup test.malicious.xyz # Rule 4: HTTP admin probe curl http:///admin ### Sample Alert Output (`fast.log`) 05/24/2026-15:53:04.609359 [**] [1:1000001:1] Nmap SYN Sweep [**] [Classification:(null)] [Priority: 3] {TCP} 192.168.32.131:62961 -> 192.168.32.130:106 05/24/2026-15:12:00.462001 [**] [1:1000002:1] SSH Brute Force Attack [**] [Classification(null)] [Priority: 3] {TCP} 192.168.32.131:48766 -> 192.168.32.130:22 05/24/2026-15:17:00.310172 [**] [1:1000003:1] DNS Query For Suspicious TLD [**] [Classification: (null)] [Priority: 3] {UDP} 192.168.32.131:56961 -> 192.168.32.2:53 05/24/2026-15:24:24.563944 [**] [1:1000004:1] HTTP Admin Panel Access Attempt [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.32.131:53482 -> 192.168.32.130:80 ## Alert Analysis Alerts were analysed using `jq` against the structured JSON log (`eve.json`). # Count alerts by rule name cat /var/log/suricata/eve.json \ | jq -r 'select(.event_type=="alert") | .alert.signature' \ | sort | uniq -c # Top attacking source IPs cat /var/log/suricata/eve.json \ | jq -r 'select(.event_type=="alert") | .src_ip' \ | sort | uniq -c | Rule | Alerts Fired | Notes | |------|-------------|-------| | SCAN nmap SYN Sweep | 4 | Fired on first scan run as expected | | BRUTE FORCE SSH | 4 | Multiple trigger windows during hydra run | | DNS .xyz Query | 3 | Fired on each nslookup attempt | | HTTP Admin Access | 1 | Fired on both curl requests | ## Key Findings & Limitations **What worked well:** - Threshold-based rules effectively distinguished attack traffic from noise - `http.uri` sticky buffer gave more reliable HTTP matching than raw content - `eve.json` JSON logging made post-analysis straightforward with jq **Limitations identified:** - SSH brute-force rule tracks by single source IP — a distributed attack spread across many IPs would evade it. A better approach would aggregate failed auth events at the application layer (e.g. via log correlation in a SIEM) - The `.xyz` DNS rule generates false positives for legitimate `.xyz` domains. In production this would be replaced with a dynamic threat intel feed - Running in IDS mode only, no blocking. Moving to IPS mode would require careful threshold tuning to avoid dropping legitimate traffic ## Repository Structure suricata-ids-lab/ ├── README.md ├── rules/ │ └── local.rules ├── screenshots/ │ ├── alerts-fast-log.png │ └── jq-analysis.png └── logs/ └── sample-eve.json ## Skills Demonstrated `Network Traffic Analysis` · `IDS Rule Writing` · `Threat Detection Logic` · `Log Analysis` · `Linux Administration` · `Attack Simulation` · `Blue Team / SOC`