Tools

T1040

Snort 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

ComponentExampleMeaning
ActionalertWhat to do when matched — alert, drop, reject, pass, log
ProtocoltcpWhich protocol to match — tcp, udp, icmp, ip
Source IP$HOME_NETSource address or variable
Source portanySource port
Direction->Traffic direction — -> (one-way) or <> (bidirectional)
Destination IP$EXTERNAL_NETDestination address
Destination port$HTTP_PORTSDestination port
msg"MALWARE-CNC..."Alert text displayed in the alert
flowto_server,establishedMatch only established connections in the client-to-server direction
content"powershell"Pattern to match in the packet payload
nocasenocaseCase-insensitive matching
sid1000001Unique rule ID (Snort SID). User rules: 1,000,000+
rev1Rule revision number
priority1Rule 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.

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

  1. Install and run in alert-only (IDS) mode — do not enable IPS until you understand your baseline.
  2. 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).
  3. Modify rules — three approaches:
ApproachMethodWhen to Use
Enable flow constraintAdd flow:to_server,established;Alerts from non-established connections (expired sessions, retransmitted datagrams)
Add negative contentAdd 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
ThresholdAdd 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 entirelyRemove from rules file or pass -sid exclusionRule consistently fires on harmless activity and cannot be tuned further
  1. Test in staging — replay traffic through the updated ruleset and verify FP reduction.
  2. Enable IPS mode selectively — start by dropping the highest-confidence rules (critical severity, unique signatures).

Common High-FP Rule Categories

CategoryWhy It Generates FPsTuning Approach
Oversized ICMPNormal network monitoring tools send large ICMP packetsWhitelist monitoring server IPs. Exclude ICMP from known-good network segments.
DNS tunnelingCDN DNS traffic, Akamai, Fastly often has large TXT recordsExclude known CDN domains. Focus on TXT queries to unknown domains.
SQLi/XSS rulesUser-generated content (comments, profile fields) embeds SQL-like patternsWhitelist the specific URL path or parameter where user-generated content is expected.
Malware domain rulesMalvertising domains that have expired and now show benign contentUpdate 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:

QuestionWhere 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:

FeatureWhat It DoesExample Use Case
File extractionExtracts files from HTTP, SMTP, FTP streams for analysisExtract dropped executables from HTTP responses
TLS/SSL loggingLogs TLS handshake metadata without inspectionJA3 fingerprint logging, certificate issuer logging
DNS loggingFull DNS query/response loggingDGA detection, C2 domain detection
Protocol detectionIdentifies protocol even on non-standard portsDetects HTTP on port 4443, DNS on port 53535
VLAN/MPLS supportHandles VLAN and MPLS headers nativelyIDS in multi-tenant environments
Lua scriptingCustom detection logic beyond rule matchingComplex pattern matching, protocol decoders

Sources