About This Project
This is my Bachelor's thesis project at Hochschule Albstadt-Sigmaringen, built to answer a question that matters in every enterprise SOC: given the same network traffic and the same attack, do Snort and Suricata see the same thing? The answer, as this lab demonstrates, is more nuanced than the common assumptions — and the differences have real consequences for how organizations design their detection architecture.
To answer that question rigorously, I designed and built a fully segmented 7-node Proxmox virtualization cluster entirely from scratch, deployed four independent detection layers simultaneously, executed three realistic attack chains from attacker to target, and analyzed the resulting telemetry across 32 custom Splunk SPL queries — producing a forensic-grade, evidence-based comparison of both engines across every attack phase.
Lab Architecture
The lab runs on a 7-node Proxmox cluster (pve-01 through pve-07) backed by a TrueNAS CE storage server with RAIDZ1 redundancy. Network segmentation is enforced by a Cisco Catalyst 2960X switch with five dedicated VLANs, two hardware SPAN sessions for passive traffic mirroring, and pfSense as the perimeter firewall and inline IPS.
The detection stack runs four independent layers simultaneously, each receiving identical traffic from the same switch:
- pfSense inline IPS: Suricata and Snort deployed in Legacy IPS mode, sitting on the perimeter and capable of actively blocking traffic
- Security Onion (IDS): Suricata running in passive detection-only mode with Zeek handling deep protocol analysis (dns, dce_rpc, kerberos, weird, http, ftp)
- Snort IDS VM (Ubuntu): Snort in passive IDS mode with sfportscan plugin enabled, receiving mirrored traffic via dedicated SPAN port
- Splunk SIEM: Universal Forwarders on every VM feeding all logs centrally; pfSense forwarding Suricata→TCP 5515, Snort→TCP 5516, syslog→UDP 5514
Endpoint telemetry was collected via Sysmon with the SwiftOnSecurity ruleset on DC01 and Client01, with PowerShell Script Block Logging enabled via GPO. This ensured that every attack step left forensic traces across multiple data sources — network, host, and firewall — enabling full kill-chain correlation in Splunk.
Attack Scenarios
Three complete attack chains were executed against the lab environment, each chosen to represent a distinct phase of the MITRE ATT&CK framework and stress-test different detection capabilities of each engine.
Scenario 1 — Network Reconnaissance (Nmap)
A structured 5-step Nmap campaign against VLAN20 targets, escalating from basic host discovery through aggressive OS fingerprinting and service version detection. This scenario was designed to reveal how each engine handles high-volume, low-and-slow scanning patterns.
- Host discovery ping sweep → TCP SYN scan → service/version scan → OS fingerprint → aggressive full scan
- 16 Splunk SPL queries built across all four detection layers
-
Key finding: all four sensors reliably detected the scan,
led by the high-confidence
ET SCAN Nmap Scripting Engine User-Agent Detectedsignature — for known reconnaissance, both engines provide solid, comparable coverage - Alert volume divergence explained by architecture: Snort produces no deduplication (raw CSV alert output), while Suricata deduplicates alerts natively (structured eve.json) — making raw count comparisons misleading without accounting for log format
Scenario 2 — Web Application Exploitation (DVWA + Metasploitable3)
A two-chain web exploitation scenario covering both manual reconnaissance-driven attacks and automated framework exploitation, targeting two different vulnerable web applications.
-
DVWA chain: Nmap service discovery →
Nikto web scan → Gobuster directory brute-force with
custom wordlist (discovered
/dvwa/) → retrieval ofconfig.inc.php.bakexposing database credentials (dvwa / p@ssw0rd) → Hydra HTTP brute-force → sqlmap full database dump extracting all 5 user password hashes (admin, gordonb, 1337, pablo, smithy) - Metasploitable3 chain: ProFTPD exploitation via CVE-2015-3306 (mod_copy arbitrary file copy) using Metasploit Framework — demonstrating known-CVE detection coverage of both engines
- Notable finding: Hydra's HTTP brute-force requests triggered CSRF detection alerts in both engines despite not being CSRF attacks — a documented false positive caused by tool-specific HTTP request patterns. This finding highlights the rule tuning requirements in real deployment and is documented as a thesis conclusion
- Attack-surface correlation: Metasploitable3 generated 2.1–4.6× more alerts than DVWA across the sensors — a clear, measurable link between a target's exposed service footprint and the resulting alert volume
- 32 total SPL queries built across 4 sensors × 2 chains × 4 detection layers
Scenario 3 — Active Directory Lateral Movement
A 10-step lateral movement chain through a Windows Active Directory environment — the most operationally realistic scenario and the one that produced the most significant detection gap findings between the two engines.
- Full kill-chain: CrackMapExec SMB enumeration → credential validation → PsExec remote execution (achieving SYSTEM on DC01) → WMIExec remote execution (achieving lab\admin on Client01)
- Forensic investigation across Sysmon (process creation, network connections), Zeek logs (dce_rpc, kerberos, weird), and pfSense filterlog
- Critical finding — detection gap: Suricata IDS (Security Onion) raised 2 alerts for "ET INFO Impacket WMIExec" and correctly identified the WMIExec lateral movement. Snort IDS raised zero alerts for the same traffic — it missed the lateral movement entirely
- Second critical finding — IPS blind spot: Both pfSense IPS engines (Suricata and Snort) generated zero alerts for the lateral movement phase. East-west SMB and WMI traffic traversing internal VLANs is structurally invisible to a perimeter-only IPS — a fundamental architectural limitation documented as a key thesis conclusion
- Zeek's dce_rpc and kerberos logs provided full protocol-level visibility where signature engines failed, reinforcing the value of behavioral protocol analysis alongside rule-based detection
Research Findings
The following table shows raw alert counts recorded by all four detection layers during Scenario 1 (Nmap Recon). The volume difference between engines is not simply a matter of sensitivity — it reflects fundamental architectural differences in how each engine handles alert aggregation and output format.
| Engine | Deployment Mode | Alert Count (Scenario 1) | Output Format |
|---|---|---|---|
| Suricata | pfSense inline IPS | 7,081 | JSON (eve.json) |
| Snort | pfSense inline IPS | 12,035 | CSV (no deduplication) |
| Suricata | Security Onion (passive) | 14,322 | JSON (eve.json) |
| Snort | Dedicated IDS VM (passive) | 7,748 | CSV (no deduplication) |
The following are the primary research conclusions drawn from all three scenarios:
ET SCAN Nmap Scripting Engine User-Agent Detected
signature. The engines differed only in detail: Snort's
sfportscan preprocessor (active on the pfSense
IPS) contributed a couple of behavioural port-scan events,
while Suricata caught the NSE user-agent signature that
Snort's inline IPS missed. Neither engine is broadly "better"
at recon — their coverage is complementary, and raw alert
counts reflect logging architecture more than detection
capability.
Conclusion
Across 48,927 alerts correlated from four sensors over three attack chains, the data tells a consistent story:
- Snort and Suricata are largely equivalent in detection logic at identical rule coverage. Their real differences are log format (Suricata's structured EVE-JSON vs. Snort's CSV) and alert volume — which challenges the common assumption that Suricata is fundamentally the stronger engine.
- Signature-based IDS/IPS are dependable for known, network-visible attacks, but structurally blind to credential-based abuse of legitimate protocols (living-off-the-land).
-
Effective detection therefore demands a
layered architecture: behavioural protocol
analysis (Zeek) and endpoint telemetry (Sysmon, Windows
Event Logs) are necessary components, not optional extras.
In this lab, the full lateral-movement kill chain could only
be reconstructed by correlating Zeek's
ntlm.log(19 cleartext-username captures) anddce_rpc.logwith Windows and Sysmon telemetry in Splunk.
SIEM Integration & Splunk Dashboard
All seven virtual machines had Splunk Universal Forwarder
deployed, feeding dedicated indexes (dc01, client01, kali,
metasploitable, dvwa, seconion, snort). pfSense log forwarding
required custom engineering: a persistent shell script using
stdbuf with a while-true loop and
pkill-based process management, persisted via the
pfSense Cron package, to ensure reliable log streaming over
TCP.
A Splunk Classic Simple XML dashboard was built grouping panels by detection mode — IPS panels on the left (Suricata in green, Snort in red) and IDS panels on the right — enabling instant side-by-side visual comparison of both engines across any given time window. 32 custom SPL queries covered all scenarios, sensors, and detection layers, including custom EXTRACT regex definitions for pfSense's BSD syslog filterlog format (TCP, UDP, and ICMP variants).
Key Highlights
- Built a fully segmented 7-node Proxmox cluster from scratch with 5 VLANs, a Cisco Catalyst enterprise switch, two hardware SPAN sessions for passive traffic mirroring, and TrueNAS CE RAIDZ1 storage
- Deployed four simultaneous, independent detection layers (pfSense IPS ×2, Security Onion IDS, Snort IDS VM) under identical network conditions — enabling direct, evidence-based engine comparison
- Executed three complete attack chains covering MITRE ATT&CK initial access, execution, credential access, discovery, lateral movement, and collection phases
- Surfaced the headline finding: credential-based lateral movement (PsExec / WMIExec) was nearly invisible to all four signature sensors — only Suricata IDS caught WMIExec, and only via low-severity INFO alerts — proving signature-based NIDS alone cannot detect living-off-the-land techniques
- Proven that perimeter IPS (both Suricata and Snort) is architecturally blind to east-west lateral movement — a finding that supports the need for internal NIDS placement in any enterprise detection strategy
- Documented a false positive pattern (Hydra triggering CSRF signatures) that reveals inherent limitations of signature-based detection without contextual rule tuning
- Built 32 custom Splunk SPL queries and a structured IPS/IDS comparison dashboard covering all scenarios, sensors, and detection layers
- Integrated Sysmon (SwiftOnSecurity config) and PowerShell Script Block Logging across the AD environment for full endpoint telemetry correlation alongside NIDS data
Challenges & Solutions
pfSense Log Forwarding Stability: Getting
Suricata and Snort logs to stream reliably from pfSense to
Splunk proved far from straightforward. The standard Splunk
Universal Forwarder approach does not work natively on
pfSense's FreeBSD environment. The solution was a custom
persistent shell script using stdbuf -oL to
disable output buffering, wrapped in a
while true loop with pkill-based
process cleanup to prevent duplicate forwarder instances — the
entire script persisted via pfSense's Cron package to survive
reboots. Suricata logs forwarded over TCP 5515, Snort over TCP
5516, and pfSense syslog over UDP 5514.
Splunk Field Extraction Conflicts: Three
pre-installed Technology Add-ons — Splunk_TA_windows,
Splunk_TA_nix, and Splunk_Security_Essentials — were silently
overriding the src field across all indexes,
producing incorrect source attribution in every SPL query.
Identifying this required methodical elimination: each TA was
removed individually and field values were re-validated. The
fix required writing custom props.conf EXTRACT
definitions for pfSense's BSD syslog filterlog format,
covering TCP, UDP, and ICMP variants with separate regex
patterns for each protocol's field layout.
HOME_NET Scope Across Four Engines: Ensuring
the attacker VLAN (VLAN10, Kali) was consistently classified
as EXTERNAL_NET — while all protected VLANs (20,
30, 40, 99) remained as HOME_NET — required
synchronized configuration across pfSense Suricata, pfSense
Snort, Security Onion's Suricata instance, and the standalone
Snort VM. A misconfiguration in any single engine would
silently invert alert directionality for that layer,
invalidating the entire comparative dataset. Each engine
required separate documentation and verification steps.
Eventtypes and Source Normalization: Building
reliable SPL queries across five completely different log
sources (Suricata eve.json, Snort CSV, pfSense filterlog,
Sysmon XML, Zeek TSV) required creating a normalization layer
via Splunk eventtypes, allowing queries to target
eventtype=suricata_alert or
eventtype=snort_alert
regardless of the underlying index or field naming
differences. Without this layer, cross-engine correlation in a
single SPL query would have been impractical.
Project Info
- Category: Bachelor Thesis
- Institution: Hochschule Albstadt-Sigmaringen
- Year: 2026
- Status: Completed