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

  1. Suricata configuration file: see default-log-dir for the name of the directory
  2. 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/suricatatail -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

  1. https://www.digitalocean.com/community/tutorials/understanding-suricata-signatures
  2. https://coralogix.com/blog/writing-effective-suricata-rules-for-the-sta/
  3. https://alparslanakyildiz.medium.com/creating-custom-suricata-signitures-260fc049b56a
  4. https://suricata.readthedocs.io/en/suricata-6.0.0/rule-management/adding-your-own-rules.html