Just enough Suricata for Starters
Suricata is a high-performance, open-source network analysis, and threat detection software used by most private and public organizations…
Suricata is a high-performance, open-source network analysis, and threat detection software used by most private and public organizations, and embedded by major vendors to protect their assets.
Installationsudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update
sudo apt install suricata jq
setupsudo vim /etc/suricata/suricata.yaml
focus on the setup of the HOME_NET
variable and the network interface configuration. The HOME_NET
variable should include, in most scenarios, the IP address of the monitored interface and all the local networks in use.
Signatures
Suricata uses Signatures to trigger alerts so it’s necessary to install those and keep them updated. Signatures are also called rules, thus the name rule-files. With the tool suricata-update
rules can be fetched, updated, and managed to be provided for Suricata.
In this guide we just run the default mode which fetches the ET Open ruleset:sudo suricata-update
Afterward, the rules are installed at /var/lib/suricata/rules
which is also the default in the config and uses the sole suricata.rules
file.
Running Suricata
With the rules installed, Suricata can run properly and thus we restart it:sudo systemctl restart suricata
To see statistics, check the stats.log
file:sudo tail -f /var/log/suricata/stats.log
How to write Alert Rules
let’s start off by dissecting an example Suricata Rule:alert tcp $EXTERNAL_NET any -> 10.10.0.0/24 80 (msg:"Malicious Attack"; flow:to_server,established; uricontent:"/malicious.exe"; nocase; classtype:malicious-download; sid:1900; rev:3;)
alert: tells Suricata to report this behavior as an alert (it’s mandatory in rules created for the STA).
tcp: means that this rule will only apply to traffic in TCP.
$EXTERNAL_NET: this is a variable defined in Suricata. By default, the variable HOME_NET is defined as any IP within these ranges: 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12, and EXTERNAL_NET is defined as any IP outside of these ranges. You can specify IP addresses either by specifying a single IP like 10.200.0.0, an IP CIDR range like 192.168.0.0/16, or a list of IPs like [192.168.0.0/16,10.0.0.0/8]. Just note that spaces within the list are not allowed.
any: in this context, it means “from any source port”, then there’s an arrow ‘->’ which means “a connection to” (there isn’t a ‘<-‘ operator, but you can simply flip the arguments around the operator. You can use the ‘<>’ operator to indicate that the connection direction is irrelevant for this rule), then an IP range which indicates the destination IP address and then the port. You can indicate a port range by using a colon like 0:1024 which means 0–1024. In the round parenthesis, there are some directives for setting the alert message, metadata about the rule, as well as additional checks.
msg: is a directive that simply sets the message that will be sent in case of matching.
flow: is a directive that indicates whether the content we’re about to define as our signature needs to appear in the communication to the server (“to_server”) or to the client (“to_client”).
established: is a directive that will cause Suricata to limit its search for packets matching this signature to packets that are part of established connections only. (This is useful to minimize the load on Suricata.)
uricontent: is a directive that instructs Suricata to look for a certain text in the normalized HTTP URI content. In this example, we’re looking for a URL that is exactly the text “/root.exe”.
nocase: is a directive that indicates case insensitive search.
class type: is a directive that is a metadata attribute indicating which type of activity this rule detects.
sid: is a directive that is a metadata attribute that indicates the signature ID. If you are creating your own signature (even if you’re just replacing a built-in rule), use a value above 9,000,000 to prevent a collision with another pre-existing rule.
rev: is a directive that indicates the version of the rule.
There’s a lot more to learn about Suricata rules which support RegEx parsing, protocol-specific parsing (just like uricontent for HTTP), looking for binary (non-textual) data by using bytes hex values, and much much more. If you’d like to know more you can start here.
Adding Your Own Rules
Start creating a file for your rule.sudo nano local.rules
Write your rule, see Rules Format and save it.
Update the Suricata configuration file so your rule is included.sudo nano /etc/suricata/suricata.yaml
and make sure your local.rules file is added to the list of rules:default-rule-path: /usr/local/etc/suricata/rulesrule-files:
- suricata.rules
- /path/to/local.rules
Now, run Suricata and see if your rule is being loaded.suricata -c /etc/suricata/suricata.yaml -i wlan0
If the rule failed to load, Suricata will display as much information as it has when it deemed the rule un-loadable. Pay special attention to the details: look for mistakes in special characters, spaces, capital characters, etc.
Next, check if your log files are enabled in the Suricata configuration file suricata.yaml
.
If you had to correct your rule and/or modify Suricata’s YAML configuration file, you’ll have to restart Suricata.
If you see your rule is successfully loaded, you can double-check your rule by doing something that should trigger it.
By default, Suricata will log alerts to two places
eve.json
fast.log
These files will be located in the log output directory which is set by one of two methods:
- Suricata configuration file: see
default-log-dir
for the name of the directory - Suricata command line: Using
-l /path/to/log-dir
creates log files in the named directory.
The following example assumes that the log directory is named /var/log/suricata
tail -f /var/log/suricata/fast.log
If you would make a rule like this:alert http any any -> any any (msg:"Do not read gossip during work";
content:"Scarlett"; nocase; classtype:policy-violation; sid:1; rev:1;)
Your alert should look like this:09/15/2011-16:50:27.725288 [**] [1:1:1] Do not read gossip during work [**]
[Classification: Potential Corporate Privacy Violation] [Priority: 1] {TCP} 192.168.0.32:55604 -> 68.67.185.210:80
Please give me a clap if you found it to be useful and follow me to get more hacking knowledge.
References
- https://www.digitalocean.com/community/tutorials/understanding-suricata-signatures
- https://coralogix.com/blog/writing-effective-suricata-rules-for-the-sta/
- https://alparslanakyildiz.medium.com/creating-custom-suricata-signitures-260fc049b56a
- https://suricata.readthedocs.io/en/suricata-6.0.0/rule-management/adding-your-own-rules.html