What You'll Learn
- Dissect a Suricata rule into its two main components: the header and the options section
- Identify action, protocol, source/destination IPs, ports, and direction in the rule header
- Understand key rule options: content, pcre, sid, msg, classtype, flow, and reference keywords
- Analyze 5 real Suricata rules from the Operation Wire Tap ruleset and explain what each detects
- Correlate rules with alerts that fired in EveBox to validate detection accuracy
Lab Overview
| Detail | Value |
|---|---|
| Lab Profile | lab-suricata |
| Containers | Suricata, EveBox |
| Estimated Time | 55–65 minutes |
| Difficulty | Intermediate |
| Browser Access | EveBox (Web UI) |
| Pre-Loaded Data | 49 alert groups, 47 unique signatures — same Operation Wire Tap scenario |
| Deliverable | A Rule Analysis Worksheet with 5 fully dissected rules and matching alert evidence |
Why Read Rules, Not Just Alerts? Alerts tell you WHAT happened. Rules tell you WHY the alert fired and HOW the detection works. A SOC analyst who can read rules can determine whether an alert is trustworthy, whether the rule is too broad (causing false positives), and what specific payload or pattern triggered the detection. This is the difference between alert responder and detection engineer.
The Scenario
Your team lead reviewed your triage sheet from Lab 3.1 and noticed several alerts you classified as "uncertain." She asks you to examine the actual Suricata rules behind those alerts to determine exactly what patterns they match. By understanding the rule logic, you will gain confidence in your classifications and learn to identify rules that may need tuning.
Part 1: Suricata Rule Anatomy
The Two-Part Structure
Every Suricata rule has exactly two parts:
action protocol src_ip src_port -> dst_ip dst_port (options;)
├─── HEADER ──────────────────────┤ ├─ OPTIONS ─┤
The Header
| Field | Purpose | Example Values |
|---|---|---|
| action | What to do when the rule matches | alert, drop, pass, reject |
| protocol | Network protocol to inspect | tcp, udp, icmp, http, dns, tls |
| src_ip | Source IP or network | $HOME_NET, $EXTERNAL_NET, any, 10.0.0.0/8 |
| src_port | Source port(s) | any, 1024:, [80,443] |
| direction | Traffic flow direction | -> (one-way), <> (bidirectional) |
| dst_ip | Destination IP or network | $HOME_NET, $HTTP_SERVERS |
| dst_port | Destination port(s) | 80, 443, $HTTP_PORTS |
The Options Section
Options are enclosed in parentheses and separated by semicolons. Key options include:
| Option | Purpose | Example |
|---|---|---|
| msg | Human-readable alert description | msg:"ET SCAN Nmap SYN Scan"; |
| content | Byte or string pattern to match | content:"UNION SELECT"; |
| nocase | Make content match case-insensitive | content:"select"; nocase; |
| pcre | Perl-compatible regex match | pcre:"/union.*select/i"; |
| flow | Required connection state | flow:established,to_server; |
| sid | Unique rule identifier | sid:2024897; |
| rev | Rule revision number | rev:3; |
| classtype | Alert classification | classtype:web-application-attack; |
| reference | External info links | reference:cve,2021-44228; |
| threshold | Rate-based firing control | threshold:type limit,track by_src,count 1,seconds 60; |
Part 2: Rule 1 — SQL Injection Detection
The Rule
alert http $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (
msg:"ET WEB_SERVER SQL Injection UNION SELECT attempt";
flow:established,to_server;
content:"UNION"; nocase;
content:"SELECT"; nocase;
pcre:"/UNION\s+(ALL\s+)?SELECT/Ui";
classtype:web-application-attack;
sid:2006446;
rev:12;
)
Analysis Questions
Work through each element of this rule:
- Header: What protocol does this rule inspect? What direction?
- Flow: Why does the rule require
established,to_server? - Content matches: There are two
contentkeywords — why both "UNION" and "SELECT" separately? - PCRE: What does the regex
/UNION\s+(ALL\s+)?SELECT/Uimatch that the content keywords alone might miss? - Classtype: What does
web-application-attacktell the analyst about severity?
Correlate with EveBox
Open EveBox and find alerts matching this SID. Click into the alert details and compare the actual payload against the rule logic:
- Does the payload contain "UNION SELECT"?
- What database was being targeted?
- Does the pcre match enhance detection beyond the simple content match?
Part 3: Rule 2 — DNS Tunneling Detection
The Rule
alert dns $HOME_NET any -> any any (
msg:"ET TROJAN DNS Tunneling Attempt — Unusually Long Query";
flow:established,to_server;
dns.query; content:"."; offset:50;
threshold:type both,track by_src,count 5,seconds 60;
classtype:trojan-activity;
sid:2027863;
rev:4;
)
Analysis Questions
- Protocol: This rule uses
dnsnotudp— why is the application-layer protocol more appropriate? - dns.query: What is this sticky buffer and why is it used instead of raw
content? - offset:50: The content match for "." starts at byte 50. What does this mean in plain English?
- threshold: The rule requires 5 matches in 60 seconds from the same source. Why not fire on every single long query?
- classtype: Why is DNS tunneling classified as
trojan-activityrather thanpolicy-violation?
Correlate with EveBox
Find DNS-related alerts in EveBox. Examine the DNS query fields:
- How long are the DNS queries that triggered this rule?
- What domain patterns do you see (random-looking subdomains)?
- Does the threshold explain why you see fewer alert groups than individual queries?
Part 4: Rule 3 — C2 Beacon Detection
The Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET any (
msg:"ET MALWARE Generic C2 Beacon — Periodic Callback";
flow:established,to_server;
dsize:64<>128;
content:"|00 00|"; depth:4;
flowbits:set,c2.beacon;
threshold:type both,track by_src,count 3,seconds 300;
classtype:command-and-control;
sid:2034501;
rev:2;
)
Analysis Questions
- dsize: The rule requires packet data size between 64 and 128 bytes. Why is this range significant for C2 beacons?
- content with depth:
content:"|00 00|"; depth:4;matches null bytes in the first 4 bytes. What does pipe notation (|00 00|) represent? - flowbits: What does
flowbits:set,c2.beacon;do? How can other rules reference this? - threshold: 3 matches in 300 seconds — how does this catch beaconing behavior?
- classtype: Why is
command-and-controltypically the highest-priority classtype?
Correlate with EveBox
Find C2-related alerts and compare:
- What is the timing interval between beacon events?
- Does the packet size fall within the 64–128 byte range?
- Is the destination IP the same across all beacon alerts?
Part 5: Rule 4 — Web Shell Detection
The Rule
alert http $HTTP_SERVERS any -> $EXTERNAL_NET any (
msg:"ET WEB_SERVER Web Shell Response — Command Output Detected";
flow:established,to_client;
content:"200"; http_stat_code;
content:"uid="; content:"gid=";
pcre:"/uid=\d+\(\w+\)\s+gid=\d+\(\w+\)/";
classtype:web-application-attack;
sid:2019284;
rev:7;
)
Analysis Questions
- Direction: This rule fires on traffic FROM the server TO the external network (
to_client). Why inspect responses, not requests? - http_stat_code: The rule checks for HTTP 200. Why is a successful response important for web shell detection?
- Content chain: The rule looks for "uid=" and "gid=" in the response. What Linux command produces this output?
- PCRE: The regex matches the exact format of
idcommand output. Why is precision important here? - Combined logic: How do the HTTP 200 + uid/gid output + server-to-external direction together confirm a web shell?
Part 6: Rule 5 — Lateral Movement via SMB
The Rule
alert tcp $HOME_NET any -> $HOME_NET 445 (
msg:"ET SCAN Internal SMB Sweep — Possible Lateral Movement";
flow:to_server;
content:"|ff|SMB";
threshold:type both,track by_src,count 10,seconds 30;
classtype:attempted-recon;
sid:2024291;
rev:5;
)
Analysis Questions
- Source AND destination are
$HOME_NET: What does internal-to-internal traffic on port 445 suggest? - content
|ff|SMB: This matches the SMB protocol header. Why use hex byte|ff|instead of the ASCII character? - threshold: 10 connections in 30 seconds. Why is this threshold appropriate for detecting lateral movement vs. normal file sharing?
- classtype: Why
attempted-reconrather thanattempted-admin? - Tuning: How might this rule cause false positives in an environment with legitimate file servers?
Correlate with EveBox
Find SMB-related alerts and determine:
- How many internal IPs were targeted?
- Is the source IP the same one that received the web shell?
- Does the timeline align with post-exploitation activity?
Build Your Rule Analysis Worksheet
For each of the 5 rules, complete this template:
RULE ANALYSIS WORKSHEET
════════════════════════
Analyst: [your name]
Date: [today's date]
RULE 1: [SID] — [msg]
Header: action=[x] proto=[x] src=[x] dst=[x]
Key Options: [list most important options]
What It Detects: [plain English explanation]
EveBox Match: [did alerts fire? how many?]
Accuracy Assessment: [is this rule precise or overly broad?]
[... repeat for Rules 2–5 ...]
Deliverable Checklist
Before completing the lab, ensure you have:
- Rule 1 analysis — SQL injection rule fully dissected with EveBox correlation
- Rule 2 analysis — DNS tunneling rule with threshold and sticky buffer explanation
- Rule 3 analysis — C2 beacon rule with dsize, flowbits, and timing analysis
- Rule 4 analysis — Web shell response rule with direction and content chain explanation
- Rule 5 analysis — Lateral movement rule with threshold tuning discussion
- Rule Analysis Worksheet — all 5 rules documented in the structured format
Key Takeaways
- Every Suricata rule has a header (action, protocol, IPs, ports, direction) and an options section (content, pcre, flow, sid, classtype)
- Content matches find specific byte patterns; PCRE provides regex flexibility for complex patterns
- Flow keywords (
to_server,to_client,established) control when rules fire based on connection state - Thresholds prevent alert floods by requiring multiple matches within a time window
- Reading rules is the bridge between "alert responder" and "detection engineer" — it lets you understand, tune, and eventually write detections
What's Next
In Lab 3.3 — Suspicious DNS, you will deep-dive into DNS-based threats using the same Operation Wire Tap data. You will investigate DNS tunneling, queries to known-malicious domains, and DNS-based C2 patterns — putting your rule-reading skills to practical use.
Lab Challenge: Read a Suricata Rule
10 questions · 70% to pass
A Suricata rule begins with 'alert http $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS'. What does this header tell you?
A rule contains 'content:"UNION"; nocase; content:"SELECT"; nocase;' — two separate content keywords. Why not use a single 'content:"UNION SELECT"'?
What does 'flow:established,to_server;' mean in a Suricata rule?
A DNS tunneling rule uses 'dns.query; content:"."; offset:50;'. What does this detect?
A rule has 'threshold:type both,track by_src,count 5,seconds 60;'. How does this affect alert generation?
A web shell detection rule fires on traffic FROM the server TO the external network (flow:to_client). Why inspect outbound responses instead of inbound requests?
What does pipe notation in a content match mean? Example: content:"|ff|SMB";
A C2 beacon rule uses 'dsize:64<>128;'. What does this constraint accomplish?
The SMB lateral movement rule uses '$HOME_NET any -> $HOME_NET 445'. Both source AND destination are $HOME_NET. Why is this significant?
You read a rule and find it uses 'content:"admin"; nocase;' with no additional context or flow keywords. What is the risk of this rule in production?
0/10 answered