Lab5 Effectively Using Suricata
Lab5 Effectively Using Suricata
A test instance of Suricata has already been set up and is waiting for you!
The learning objective of this lab is not only to get familiar with the detection capabilities of
Suricata but also to learn effective rule writing of Suricata rules.
Specifically, you will learn how to use Suricata’s capabilities in order to:
• Have better visibility over a network
• Respond to incidents timely and effectively
• Proactively hunt for threats
Don’t get discouraged, if you are not familiar with regular expressions. Regular expressions
will be covered as the course progresses.
Rules are not always oriented towards detecting malicious traffic. Rules can also be written
to provide blue team members with actionable and/or contextual information regarding
activity that is occurring on a network.
Threat intelligence and infosec communities usually offer critical information based on
which rules are developed.
Each active rule consumes some of the host’s CPU and memory. Specific guidelines exist to
assist effective Suricata rule writing.
action protocol from_ip port -> to_ip port (msg:"we are under attack
by X"; content:"something"; content:"something else"; sid:10000000;
rev:1;)
Header: This rule portion includes what action we want the rule to have along with the
protocol Suricata should expect this rule to be found in. It also includes IPs and ports, as
well as an arrow indicating directionality.
Rule message & Contents: The rule message is the message we want the analysts (or our
self) to be presented with, whereas the contents are the portions of the traffic that we have
deemed critical in order to detect activity that we want to be informed of.
Rule metadata: This rule portion mainly helps to keep track of rule modifications. Sid is a
unique rule identifier.
action tells the Suricata engine what to do should the contents are matched. It can be:
• Alert <- Generate alert and log matching packets, but let the traffic through
Then, we need a way to declare the directionality of the traffic; this can be done through:
• Rule Host Variables. We have seen those variables when analyzing the
suricata.yaml file. As a reminder, $HOME_NET refers to internal networks specified
in the suricata.yaml file and $EXTERNAL_NET usually refers to whatever is not
included in the $HOME_NET variable.
• Rule Direction. Between the 2 IP-Port pairs an arrow exists. This arrow tells the
Suricata engine the direction in which the traffic is flowing. Examples:
Rule Ports declare the port(s) in which traffic for this rule will be evaluated. Examples:
Now, let’s suppose you were required to create a header based on the PCAP below.
The rule header should be alert dns $HOME_NET any -> any any
Rule Message. Arbitrary text that appears when the rule is triggered. For better
understanding, it would nice if the rule messages you create contain malware architecture,
malware family and malware action.
• Flow. Declares the originator and the responder. Remember while developing rules
that you want to have the engine looking at “established” tcp sessions. Examples:
o flow:<established>,<to_server|to_client>;
▪ flow:established,to_server;
▪ flow:to_server;
• Dsize. Allows matching using the size of the packet payload (not http, only tcp, and
udp). It is based on TCP segment length, NOT total packet length (Wireshark filter:
tcp.len). Examples:
o dsize:312;
o dsize:300<>400;
Rule Content. Values that identify a specific network traffic or activity. Suricata matches
this unique content in packets for detection. Note that for certain characters, the use of hex
is required. Examples:
o content:"some thing";
o content:"some|20|thing";
o content:"User-Agent|3a 20|";
• Rule Options. Additional modifiers to assist detection. They can help the
Suricata engine in finding the exact location of contents.
o nocase. Helps rules to not get bypassed through case changes. Example:
o offset. Informs the Suricata engine about the position inside the packet
where is should start matching. This option is used in conjunction with
“depth”. Examples:
▪ content:"whatever"; offset:5;
o distance. Informs the Suricata engine to look for the specified content n
bytes relative to the previous match. This option is used in conjunction
with “within”. Examples:
o We are looking for the string “whatever” (with nocase enabled) in the first 9
bytes of the packet. An offset of 0 is implied. Then, we are looking for the
string “some thing” occurring anywhere after the first match of “whatever”.
o We are looking for outbound TCP traffic on any port with a size of 45 bytes.
The string “suspicious” should start 33 bytes in the packet. 33+12=45.
Essentially, we are looking for the string at the last 12 bytes.
• reference. This is the first rule metadata field we usually come across. It indicates
where the initial information to develop this rule came from. Example:
o reference:url,securingtomorrow.mcafee.com/2017-11-20-dridex;
• sid. This is the signature ID number. It is a unique number given by the rule writer.
Example:
o sid:10000000;
• revision. This field informs about the version of the rule. Example:
o rev:5;
Note: To conclude covering Suricata rules, let’s talk about PCRE (Pearl Compatible Regular
Expression). PCRE is a very powerful ally while developing rules. One can use PCRE
through the pcre statement (followed by a regular expression). Note that PCRE must be
wrapped in leading and trailing forward slashes and any flags will go after the last slash.
Examples:
• pcre:"/something/flags";
• pcre:"/^\/[a-z0-9]{6}\.php$/Ui";
Note that anchors go after and before wrapped slashes and certain characters need to be
escaped with a backslash. Additionally, never write a PCRE-only rule.
1. https://rules.emergingthreats.net/open/
2. https://github.com/EmergingThreats/et-luajit-scripts
3. https://github.com/ptresearch/AttackDetection
4. Other Sources
• You can study more on Suricata rules on the official documentation site
https://suricata.readthedocs.io/en/latest/rules/index.html
• Suricata
• Wireshark
• Suricata: 172.16.69.100
All provided PCAPs are inside the /home/elsuser/PCAPs directory. They can be transferred
to the machine from inside, which you connected to this lab as follows.
cd PCAPs
sudo python -m SimpleHTTPServer 80
Now, you can simply launch a browser of your choice inside the machine from inside which
you connected to this lab and browse to http://172.16.69.100 to download the provided
PCAP files.
Rule 1:
alert dns $HOME_NET any -> any any (msg:"TROJAN X Rogue DNS Query
Observed" dns_query; content:"searchcdn.gooogle.com";
isdataat:!1,relative; reference:url,threatintelprovider.com/trojanx;
classtype:trojan-activity; sid:1; rev:1;)
Rule 2:
Now it’s time to develop your own rules. Analyze the Sofacy.pcap, Qadars.pcap, 7ev3n.pcap
and Malicious_document.pcap PCAP files using Wireshark. Then, try to identify how you can
instruct a Suricata sensor in order to detect the malicious traffic they contain and
ultimately, develop a Suricata rule for each case.
Things won’t always be straightforward while developing Suricata rules. Complex cases
will always come up. Analyze the DDoSClient.pcap and Adobe.pcap PCAP files using
Wireshark. Then, try to identify how you can instruct a Suricata sensor in order to detect
the malicious traffic they contain and ultimately, develop a Suricata rule for each case.
alert dns $HOME_NET any -> any any (msg:"TROJAN X Rogue DNS Query
Observed" dns_query; content:"default27061330-a.akamaihd.net";
isdataat:!1,relative; reference:url,threatintelprovider.com/trojanx;
classtype:trojan-activity; sid:1; rev:1;)
❑ This rule specifies the DNS protocol rather than UDP or something else. dns is a
Suricata protocol keyword that allows the engine to detect DNS traffic based on the
protocol and not the port. This protocol keyword (dns) should always be used when
inspecting DNS traffic.
❑ The destination host is set to any. As mentioned previously, this is because some
networks include internal DNS resolvers and we don’t want to rule out that traffic.
❑ The destination port is set to any as well (instead of port 53); this is because we are
using the dns protocol keyword which will help inspect DNS traffic regardless of the
port used.
❑ Then, there is a typical message that will inform us about the detected activity.
❑ The main content of the rule starts with the dns_query keyword. dns_query is
essentially a sticky buffer used to inspect the value of a DNS request. Being a sticky
buffer results in all content following being included in the buffer. So, for this rule,
we first declare the dns_query keyword and then the content, which contains the
normalized domain that was included in the request. The dns_query buffer is
normalized, so, one can use a literal period as opposed to the hexadecimal
representation in the raw packet. Note that the DNS buffer doesn’t include the null
byte after the end of the domain. This is where the isdataat keyword comes into
play. !1,relative means that there should be no data 1 byte relative to the
previous match, which is effectively the domain name. Basically, this is a way to
“lock” the match and avoid matching anything past the .net part.
❑ This rule specifies the TLS protocol. tls is a Suricata protocol keyword that allows
the engine to detect TLS traffic based on the protocol and not the port. By looking
further down the rule, we are obviously checking for the delivery of a TLS certificate
from an external server, hence the $EXTERNAL_NET any -> $HOME_NET any
directionality. Once again, any is set for both ports since the tls keyword is utilized.
❑ Then, there is a typical message that will inform us about the detected activity.
flow:established,to_client; established is used due to TCP and to_client due
to the inbound traffic.
❑ tls_cert_subject is once again a buffer, and the rule content is a unique string
included in the TLS certificate’s CN portion.
By opening Sofacy.pcap in Wireshark, the first thing we notice is two (2) DNS queries and
the respective DNS responses.
alert dns $HOME_NET any -> any any (msg:"TROJAN Activity Detected DNS Query
to Known Sofacy Domain 1"; dns_query; content:"drivres-update.info"; nocase;
isdataat:!1,relative; sid:1; rev:1;)
alert dns $HOME_NET any -> any any (msg:"TROJAN Activity Detected DNS Query
to Known Sofacy Domain 2"; dns_query; content:"softupdates.info"; nocase;
isdataat:!1,relative; sid:2; rev:1;)
Put these two (2) rules inside the customsig.rules directory residing in the home directory
of the elsanalyst user. You can do so, by executing sudo vim customsig.rules
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/Sofacy.pcap
-----------------------------
Let’s continue with the Citi.pcap file. If you are unfamiliar with Citi, Citi is a global bank.
By opening the Citi.pcap in Wireshark, the first thing we notice is a phishy-looking DNS
query (note that online.citi.com is a legitimate URL).
alert dns $HOME_NET any -> any any (msg:"Possible Citi Phishing
Attempt Observed in DNS Query "; dns_query; content:"online.citi.com";
nocase; isdataat:1,relative; sid:3; rev:1;)
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/Citi.pcap
-----------------------------
• https://www.countercept.com/blog/decrypting-qadars-banking-trojan-c2-traffic/
• https://sslbl.abuse.ch/ssl-
certificates/sha1/1862c777babf298fe5a93406e4dc8456d718abcf/
We’ll develop a Suricata rule based on our analysis of the Qadars.pcap file, considering that
what we see inside the PCAP is malicious.
By opening Qadars.pcap in Wireshark, the first thing we notice is a DNS query and a DNS
response regarding susana24.com. Then, we notice TLS traffic initiating.
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/Qadars.pcap
-----------------------------
To learn more about the 7ev3n ransomware, refer to the following link
https://www.vmray.com/cyber-security-blog/7ev3n-honet-ransomware-rest-us/.
We’ll develop a Suricata rule based on our analysis of the 7ev3n.pcap file, considering that
what we see inside the PCAP is malicious.
By opening 7ev3n.pcap in Wireshark and filtering so that we can see HTTP traffic only, the
first thing we notice is this curious-looking request.
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:" TROJAN 7ev3n
Ransomware Encryption Activity"; flow:established,to_server;
content:"GET"; http_method; content:".php?SSTART="; http_uri;
content:"&CRYPTED_DATA="; http_uri; distance:0; content:"&ID=";
http_uri; distance:0; content:"&FILES="; http_uri; distance:0;
content:"&UI="; http_uri; distance:0; content:"Internet|20|Explorer";
http_user_agent; depth:17; isdataat:!1,relative; http_header_names;
content:!"Referer"; content:!"Accept"; sid:6; rev:1;)
depth:17; isdataat:!1,relative; is looking to see if there are any data after the last
“r” of the “Internet Explorer” string, ensuring that the User Agent field only contains
“Internet Explorer”. http_header_names; content:!"Referer";
content:!"Accept"; is leveraging the lack of usual headers for detection purposes.
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/7ev3n.pcap
The request above can provide us with a lot of clues on how to develop an effective Suricata
rule. A viable rule can be found below.
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/Malicious_document.pcap
We’ll develop a Suricata rule based on our analysis of the DDoSClient.pcap file, considering
that what we see inside the PCAP is malicious.
The traffic above can provide us with enough clues on how to develop an effective Suricata
rule. A viable rule can be found below.
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN DDoS
Client Information Checkin"; flow:established,to_server;
content:"Windows"; nocase; depth:7; content:"MHZ|00 00 00 00 00 00|";
distance:0; nocase; content:"|00 00 00 00 00 00|Win"; distance:0;
nocase; classtype:trojan-activity; sid:8; rev:1;)
Notice that we are using “Windows” and “MHZ” instead of “Windows 7” and “1795 MHZ”, to
detect variations. depth:7; is used because “Windows” is seven character’s long. The first
distance:0; is used because the nulls appear right after “Windows” (the number of nulls
in the rule was chosen randomly).
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/DDoSClient.pcap
-----------------------------
We’ll develop a Suricata rule based on our analysis of the Adobe.pcap, considering that
what we see inside the PCAP is malicious.
By opening Adobe.pcap in Wireshark and filtering so that we can see HTTP traffic only, the
first thing we notice is this curious-looking POST request. Let’s follow the whole stream.
This is quite uncommon, so let’s make a rule out of it. A viable rule can be found below.
It’s time to test the rule above. You can do so, as follows.
cd Desktop
sudo ./automate_suricata.sh ../PCAPs/Adobe.pcap
2. https://resources.sei.cmu.edu/asset_files/Presentation/2016_017_001_449890.pdf
3. https://blog.inliniac.net/2014/04/08/detecting-openssl-heartbleed-with-suricata/
4. https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/decoding-
hancitor-malware-with-suricata-and-lua/
5. https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/advanced-
malware-detection-with-suricata-lua-scripting/