My outreachy project: Increasing Suricata’s rule keyword/ log output parity

By

As an intern at Outreachy I have been working with the Open Information Security Foundation (OISF) on their network intrusion detection and prevention software, Suricata. For my outreachy project, I have been working on “Increasing Suricata’s rule keyword/log output parity.” Now, this might sound complex, but I’ll be doing my best to explain it as clearly as possible.

Among other things, Suricata helps security analysts identify potential threats and anomalous traffic in a network. In order to achieve this goal, rules are created that let the Suricta engine know what to look for in the network traffic that it is inspecting. These rules are made from different keywords. For my project, I’m only working on the fields that refer to application layer protocol buffers and headers. The application layer protocols include DNS, FTP, and HTTP, to name a few. Some of the output that Suricata produces after examining the application layer protocols is not yet exposed to the rule language, and there are some rule keywords that have not been created and linked to the EVE output in Suricata. The EVE output facility outputs alerts, anomalies, metadata, file info and protocol-specific records through JSON.

So far, I have focused on increasing the rule keyword/log output parity for the DNS protocol. As shown in the links below, there are a greater number of DNS log output fields than there are rule keywords associated with them.

DNS log output: https://docs.suricata.io/en/latest/output/eve/eve-json-format.html#event-type-dns

DNS rule keywords: https://docs.suricata.io/en/latest/rules/dns-keywords.html#dns-query

The aim of this task is to use the pre-existing output fields that Suricata already has buffers for and expose them to the rule language to improve Suricata’s detection of potential risks and provide rule writers with additional functionality.

In order to achieve this, I have been tasked with creating rule keyword buffers from a pre-existing list of application layer protocol outputs. If we continue with our DNS example, I made a note that the DNS outputs the rcode field, but there are no rule keywords associated with it. So I start by implementing the rule keyword for the rcode field in Rust and C.

After a keyword has been implemented, I often develop unit tests and proceed with creating Suricata Verify tests to include the keyword. These tests are made for quality assurance purposes to ensure that Suricata will alert the system appropriately once it encounters the rule keyword. An example of a Suricata rule for the rcode keyword for DNS is the following:

# Should alert in client direction.<br>alert dns any any -> any any (dns.rcode:3; sid:1; rev:1;)

While creating Suricata Verify tests, I often have to create test.rules and test.yaml files while using PCAP files. PCAP files are data files that are used to analyse network characteristics and contain packet data from a network. They also aid in deciding the condition of the network and managing traffic on it. I will often reuse pre-existing pcap files that contain the packets that most closely resemble the requirements for my keyword. By reusing pre-existing code, I am able to focus more time on implementing new code. Aside from all the coding, I’m also tasked with creating documentation for the rule keywords that I am implementing in order to describe my code and make it easier for other developers to understand.

Resources

1- Suricata rules
2- EVE output
3- Application layer protocols
4- Suricata live coding session
5- Intro to writing Suricata rules

Design a site like this with WordPress.com
Get started