Introduction
Intrusion Detection Systems (IDS) like Snort rely heavily on rules to identify malicious network traffic. A well-crafted rule acts as a signature, allowing the system to trigger an alert when specific patterns are observed in the data packets.
Signature-based detection works by recognizing known patterns, not by understanding attacker intent directly. That makes it fast and useful, but also imperfect. If the pattern is too broad, it creates false positives. If it is too narrow, attackers can evade it with small changes. Good rule writing is therefore an exercise in balancing precision and coverage.
In this lab, you will step into the shoes of a security analyst. You will write content-matching Snort rules capable of detecting application-layer attacks. Specifically, you will analyze a simulated SQL Injection attack payload captured in a PCAP (Packet Capture) file, and craft precise Snort rules using both basic content matching and advanced Regular Expressions (PCRE) to inspect HTTP traffic and alert whenever that malicious string is detected.
Analyze Attack Payload (PCAP)
In this step, you will analyze a network packet capture file to understand what a malicious payload looks like. Before writing a detection rule, a security analyst must first know exactly what they are trying to detect.
This order matters. A common beginner mistake is to start writing signatures before inspecting the real traffic. In practice, defenders usually begin with evidence: a PCAP, a log sample, or an exploit proof of concept. Only after understanding the observable pattern do they translate it into a rule.
Your environment has been pre-configured with a file named sqli_attack.pcap in your ~/project directory. This file contains a simulated network packet where an attacker is attempting an SQL Injection attack against a web server.
To inspect the contents of this PCAP file, you can use a tool called tcpdump. The tcpdump command is a powerful command-line packet analyzer. By using the -A flag, you can print the packet contents in ASCII (plain text), which is perfect for reading HTTP requests. The -r flag tells tcpdump to read from a file instead of a live network interface.
Run the following command in your terminal to analyze the payload:
tcpdump -A -r sqli_attack.pcap
You should see output similar to the following:
reading from file sqli_attack.pcap, link-type EN10MB (Ethernet), snapshot length 262144
10:23:45.123456 IP 192.168.1.100.12345 > 192.168.1.10.http: Flags [P.], seq 1:78, ack 1, win 8192, length 77: HTTP: GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
E..u..@.@............9.P..P.P.......+......GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
Host: example.com
Look closely at the plain text portion of the output. You can see an HTTP GET request being made to /login.php. Notice the user parameter: admin'%20UNION%20SELECT%201,2,3--.
The %20 is the URL-encoded representation of a space character. The phrase UNION SELECT is a classic signature of an SQL Injection attack, where an attacker attempts to combine the results of their own malicious database query with the original query. This is the exact signature we want to detect.
Write Content-Matching Rules
In this step, you will write your first custom Snort rule to detect the SQL Injection signature you discovered in the previous step.
The content keyword is the simplest form of payload inspection. It is fast and easy to reason about because it searches for a literal string. Literal matching is often the right first draft for a signature because it makes the detection logic transparent.
Snort rules are written in a specific syntax. A basic rule consists of a rule header and rule options.
- The header defines the action, protocol, source/destination IP addresses, and ports.
- The options define the specific content to look for and the message to display when an alert is triggered.
We will create a rule that looks for the exact string UNION%20SELECT in any TCP traffic destined for port 80 (the standard HTTP port).
Open the custom rules file using the nano text editor:
nano ~/project/rules/local.rules
Add the following line to the file:
alert tcp any any -> any 80 (msg:"Basic SQL Injection Detected"; content:"UNION%20SELECT"; sid:1000001; rev:1;)
Let's break down what this rule means:
alert: The action to take when the rule matches (generate an alert).tcp: The protocol to inspect.any any -> any 80: Source IP and port (any) going to Destination IP (any) on port 80.msg:"...": The alert message to display to the analyst.content:"UNION%20SELECT": The exact string Snort will search for in the packet payload.sid:1000001: The Snort ID. Custom rules should have an ID of 1,000,000 or higher.rev:1: The revision number of the rule.
After adding the line, save the file and exit nano by pressing Ctrl+O, Enter, and then Ctrl+X.
You can verify the contents of your rule file by using the cat command:
cat ~/project/rules/local.rules
Configure PCRE (Regular Expressions)
In this step, you will enhance your detection capabilities by using PCRE (Perl Compatible Regular Expressions).
Regular expressions increase flexibility because they describe families of patterns rather than one exact byte sequence. That is powerful, but it also raises the risk of overmatching. Defenders use PCRE when attackers are likely to vary formatting while keeping the underlying behavior recognizable.
While the content keyword is fast and effective, it is very rigid. Attackers often try to evade detection by slightly altering their payloads. For example, instead of %20 (URL-encoded space), an attacker might use a regular space (``), multiple spaces, or a plus sign (+). A simple content match would miss these variations.
PCRE allows you to write flexible patterns. We will write a second rule that uses a regular expression to catch variations of the UNION SELECT attack.
Open your rules file again:
nano ~/project/rules/local.rules
Add the following new rule on a new line below your first rule:
alert tcp any any -> any 80 (msg:"Advanced SQL Injection Detected"; pcre:"/UNION(%20|\s|\+)SELECT/i"; sid:1000002; rev:1;)
Let's break down the pcre option:
pcre:"/ ... /i": The slashes denote the beginning and end of the regular expression. Theiat the end makes the search case-insensitive (it will matchunion,UNION,UnIoN, etc.).UNION: Matches the word UNION.(%20|\s|\+): This is a capture group with OR logic (|). It matches either%20, OR a whitespace character (\s), OR a plus sign (\+).SELECT: Matches the word SELECT.
Save the file and exit nano (Ctrl+O, Enter, Ctrl+X).
Your local.rules file should now contain two distinct rules designed to catch SQL Injection attempts.
Validate Rule Detection
In this final step, you will put your custom rules to the test. You will run Snort in offline mode, instructing it to read the sqli_attack.pcap file and apply the rules you just wrote in local.rules.
Testing against a known sample is essential because a rule that looks correct on paper may still fail operationally. Validation confirms that the rule actually fires on the traffic you intended, which is the minimum requirement before trusting it in a live environment.
Snort can be run with various flags. Here is what we will use:
-q: Quiet mode. This suppresses the large banner and initialization text, making the output easier to read.-c: Specifies the configuration or rules file to use.-r: Specifies the PCAP file to read.-A console: Tells Snort to print alerts directly to the terminal console.
Run the following command to test your rules against the malicious payload:
sudo snort -q -c rules/local.rules -r sqli_attack.pcap -A console
If your rules were written correctly, you should see output similar to this:
10/23-10:23:45.123456 [**] [1:1000001:1] Basic SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
10/23-10:23:45.123456 [**] [1:1000002:1] Advanced SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
Congratulations! Both of your rules successfully triggered. The first rule matched the exact string, and the second rule matched the pattern using regular expressions. You have successfully acted as a security analyst, identifying a threat and deploying a signature to detect it.
Summary
In this lab, you gained hands-on experience with network intrusion detection by writing custom Snort rules. You started by analyzing a raw packet capture to identify the specific signature of an SQL Injection attack. You then learned how to translate that signature into a basic content-matching Snort rule. Finally, you upgraded your detection capabilities by implementing Perl Compatible Regular Expressions (PCRE) to catch variations of the attack, and successfully validated your rules by running Snort against the malicious traffic. These skills are fundamental for any cybersecurity professional tasked with defending network infrastructure.



