Tools
T1040Snort and Suricata
How IDS/IPS rule writing works in Snort and Suricata -- signature syntax, detection workflows, tuning rules to reduce noise, and integrating alerts into the SOC pipeline.
View on Graph
What Snort and Suricata Are and How IDS/IPS Rules Work
- Snort and Suricata are open-source Network Intrusion Detection and Prevention Systems (NIDS/NIPS).
- They inspect network traffic in real time, matching packets against a ruleset, and generate alerts when traffic matches a rule.
- Snort, originally released in 1998 by Martin Roesch and now maintained by Cisco, is the reference implementation.
- Suricata, developed by the Open Information Security Foundation (OISF), is a modern alternative with multi-threaded performance, built-in file extraction, and protocol parsing beyond simple pattern matching.
Rule Structure — The Anatomy of a Signature
Every Snort/Suricata rule follows the same structure:
[action] [protocol] [src_ip] [src_port] -> [dst_ip] [dst_port] ([rule options])
Example Rule — Detecting a PowerShell Download
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (
msg:"MALWARE-CNC Win.Trojan.PowerShell download attempt";
flow:to_server,established;
content:"powershell"; nocase;
content:"Invoke-Expression"; nocase;
content:"DownloadString"; nocase;
sid:1000001;
rev:1;
priority:1;
)
Breaking Down the Rule Components
| Component | Example | Meaning |
|---|---|---|
| Action | alert | What to do when matched — alert, drop, reject, pass, log |
| Protocol | tcp | Which protocol to match — tcp, udp, icmp, ip |
| Source IP | $HOME_NET | Source address or variable |
| Source port | any | Source port |
| Direction | -> | Traffic direction — -> (one-way) or <> (bidirectional) |
| Destination IP | $EXTERNAL_NET | Destination address |
| Destination port | $HTTP_PORTS | Destination port |
| msg | "MALWARE-CNC..." | Alert text displayed in the alert |
| flow | to_server,established | Match only established connections in the client-to-server direction |
| content | "powershell" | Pattern to match in the packet payload |
| nocase | nocase | Case-insensitive matching |
| sid | 1000001 | Unique rule ID (Snort SID). User rules: 1,000,000+ |
| rev | 1 | Rule revision number |
| priority | 1 | Rule priority (1 = highest, 4 = lowest) |
Rule Writing Patterns — Common Detection Logic
Single Content Match — Simple
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (
msg:"MALWARE-CNC Cobalt Strike beacon";
content:"|00 00 00 00 00 00 00 00|";
sid:1000002;
rev:1;
)
When to use: A unique byte sequence that is reliably present in the attack traffic (e.g., Cobalt Strike beacons) and not in legitimate traffic. Risky — high false positive potential if the sequence appears in benign payloads.
Multi-Content Match — Recommended
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (
msg:"MALWARE-CNC Metasploit staging payload";
content:"Meterpreter"; nocase;
content:"Stage"; nocase;
distance:1; within:10;
sid:1000003;
rev:1;
)
When to use: The recommended approach — match multiple strings within a proximity window, useful for Metasploit staging traffic. Reduces false positives significantly.
PCRE (Perl-Compatible Regular Expression)
alert tcp $HOME_NET any -> $EXTERNAL_NET 443 (
msg:"MALWARE-CNC Suspicious HTTPS beacon";
pcre:"/(?:Meterpreter|Beacon|Sliver|Covenant)/";
sid:1000004;
rev:1;
)
When to use: Regular expression matching for complex patterns. Performance impact — avoid PCRE with expensive lookaheads/lookbehinds in high-traffic environments.
Flowbit — Stateful Detection
alert tcp $EXTERNAL_NET any -> $HOME_NET 80 (
msg:"WEB-ATTACKS SQL injection attempt";
content:"UNION SELECT"; nocase;
flowbits:set,sqli_attempt;
flowbits:noalert;
sid:1000005;
rev:1;
)
alert tcp $HOME_NET any -> $EXTERNAL_NET any (
msg:"WEB-ATTACKS SQL injection with data exfiltration";
flowbits:isset,sqli_attempt;
content:"200 OK";
flowbits:unset,sqli_attempt;
sid:1000006;
rev:1;
)
When to use: Stateful detection across multiple packets. First rule “sets” a bit if SQLi is attempted; second rule alerts only if the attack also results in a successful response.
Tuning Rules — Reducing False Positives
A fresh Snort/Suricata installation with Emerging Threats rules will generate thousands of alerts per day. Tuning is not optional.
Tuning Workflow
- Install and run in alert-only (IDS) mode — do not enable IPS until you understand your baseline.
- Generate a baseline — collect alerts for 1-2 weeks during normal operations. Tag each alert as TP (True Positive: actual security event), FP (False Positive: noise), or TN (True Negative: benign activity that matched a poorly-written rule).
- Modify rules — three approaches:
| Approach | Method | When to Use |
|---|---|---|
Enable flow constraint | Add flow:to_server,established; | Alerts from non-established connections (expired sessions, retransmitted datagrams) |
| Add negative content | Add content:!"known_good"; | Alert fires on content that includes a known-good pattern. E.g., block the alert if the User-Agent is Mozilla/5.0 |
| Threshold | Add threshold:type both, track by_src, count 5, seconds 60; | Single false alerts are not actionable, but 5 alerts from the same source in 60 seconds is interesting |
| Disable the rule entirely | Remove from rules file or pass -sid exclusion | Rule consistently fires on harmless activity and cannot be tuned further |
- Test in staging — replay traffic through the updated ruleset and verify FP reduction.
- Enable IPS mode selectively — start by dropping the highest-confidence rules (critical severity, unique signatures).
Common High-FP Rule Categories
| Category | Why It Generates FPs | Tuning Approach |
|---|---|---|
| Oversized ICMP | Normal network monitoring tools send large ICMP packets | Whitelist monitoring server IPs. Exclude ICMP from known-good network segments. |
| DNS tunneling | CDN DNS traffic, Akamai, Fastly often has large TXT records | Exclude known CDN domains. Focus on TXT queries to unknown domains. |
| SQLi/XSS rules | User-generated content (comments, profile fields) embeds SQL-like patterns | Whitelist the specific URL path or parameter where user-generated content is expected. |
| Malware domain rules | Malvertising domains that have expired and now show benign content | Update rule set regularly. Run in alert-only until domain reputation is confirmed. |
Detection Workflow — Alert Triage
When an alert fires, here is the standard triage:
| Question | Where to Look |
|---|---|
| Does the alert match known-good traffic? | Check source/destination IP against asset inventory in Splunk or your SIEM. Is this an authorized security scanner? A known CDN? |
| What is the packet content? | Extract the matching packet from the PCAP. Review the payload that triggered the rule. |
| Is this a one-time event or a pattern? | Check the event count for this SID over the last 24 hours. If it fires once from a unique IP, it may be noise. If it fires 1000 times from one IP, it is significant. |
| Does the target host show any behavioral indicators? | Correlate with EDR — is the target host showing process creation, network connections, or file writes consistent with compromise? |
| What is the rule’s severity and priority? | Rules with priority:1 should always be investigated. Priority 4 rules can be noise-checked first. |
Suricata-Specific Features
Suricata has features Snort does not — useful for modern detection:
| Feature | What It Does | Example Use Case |
|---|---|---|
| File extraction | Extracts files from HTTP, SMTP, FTP streams for analysis | Extract dropped executables from HTTP responses |
| TLS/SSL logging | Logs TLS handshake metadata without inspection | JA3 fingerprint logging, certificate issuer logging |
| DNS logging | Full DNS query/response logging | DGA detection, C2 domain detection |
| Protocol detection | Identifies protocol even on non-standard ports | Detects HTTP on port 4443, DNS on port 53535 |
| VLAN/MPLS support | Handles VLAN and MPLS headers natively | IDS in multi-tenant environments |
| Lua scripting | Custom detection logic beyond rule matching | Complex pattern matching, protocol decoders |
Related
- Wireshark — detection and response for T1040 techniques
- Zeek (formerly Bro) — detection and response for T1040 techniques
- Network Security Basics — detection and response for T1040, T1046 techniques
