Snort Rules

At its core, Snort is an intrusion detection system (IDS) and an intrusion prevention system (IPS), which means that it has the capability to detect intrusions on a network, and also prevent them. A configuration tells Snort how to process network traffic. It is the rules that determine whether Snort acts on a particular packet.

Snort rules can be placed directly in one's Lua configuration file(s) via the ips module, but for the most part they will live in distinct .rules files that get "included". For example, say we had a malware.rules file in the same directory as our Lua configuration file. We could "include" that rules file like so:

ips = { include = 'malware.rules' }

If users want to include multiple .rules files, then they can do so like:

ips = 
{
    rules = [[
        include /path/to/rulesfile1.rules
        include /path/to/rulesfile2.rules
        …
    ]]
}

Alternatively, a single rules file or a path to a rules directory can be passed directly to Snort on the command line. This is done either with the -R option for a single rules file or the --rule-path option to pass in a whole directory of rules files. This is convenient for when you need to verify or troubleshoot a rule or rules against a pcap.

For example, the below command will run all the rules present in malware.rules against the traffic in bad.pcap:

$ snort -c $my_path/lua/snort.lua -R malware.rules -r bad.pcap

Generating Alerts

The above command by default will output various statistics about the particular run. These include details about any identified applications, any detection events, types of services detected, and much more. The detection events will show how many alerts fired on the provided traffic, but sometimes we want to know more than that.

Snort provides a few different "alert mode" options that can be set on the command line to tweak the way alerts are displayed. These modes include cmg which displays alerts alongside a hexdump of the alerting packet(s), as well as a few different alert_* modes shown below:

$ snort --help-modules | grep alert
alert_csv (logger): output event in csv format
alert_fast (logger): output event with brief text format
alert_full (logger): output event with full packet dump
alert_json (logger): output event in json format
alert_syslog (logger): output event to syslog
alert_talos (logger): output event in Talos alert format
alert_unixsock (logger): output event over unix socket
alerts (basic): configure alerts

These modes are set with the -A option followed by the desired alert mode, and we can focus solely on the alerts by also including the -q (quiet) flag. The cmg alert mode, for example, will look something like:

$ snort -q -c $my_path/lua/snort.lua -q -r get.pcap -R local.rules -A cmg
10/14-14:59:14.186063 [**] [1:0:0] "GET request" [**] [Classification: Web Application Attack] [Priority: 1] {TCP} 10.1.2.3:50284 -> 10.9.8.7:80

http_inspect.http_method[3]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
47 45 54                                          GET
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_version[8]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
48 54 54 50 2F 31 2E 31                           HTTP/1.1
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_uri[6]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
2F 68 65 6C 6C 6F                                 /hello
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

http_inspect.http_header[78]:
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -
48 6F 73 74 3A 20 61 62  63 69 70 2D 68 6F 73 74  Host: ab cip-host
2E 6C 6F 63 61 6C 0D 0A  55 73 65 72 2D 41 67 65  .local.. User-Age
6E 74 3A 20 61 62 63 69  70 0D 0A 41 63 63 65 70  nt: abci p..Accep
74 2D 4C 61 6E 67 75 61  67 65 3A 20 65 6E 2D 75  t-Langua ge: en-u
73 0D 0A 41 63 63 65 70  74 3A 20 2A 2F 2A        s..Accep t: */*
- - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - -

The alert_talos is another useful mode that displays alerts in a format that is simple and easy-to-understand.

$ snort -q -c $my_path/lua/snort.lua -q -r get.pcap -R local.rules -A alert_talos

##### get.pcap #####
        [1:0:0] GET request (alerts: 1)
#####

Lastly, Some of the alert_* modes are customizable. alert_csv for example allows for customization of the different "fields" that can be outputted. The following example demonstrates a custom CSV alert configuration using the --lua command line flag:

$ snort -q -c $my_path/lua/snort/lua -r cmd_injection.pcap -R local.rules --lua 'alert_csv = { fields = "action pkt_num gid sid rev msg service src_addr src_port dst_addr dst_port", separator = "," }'
would_block,5,1,1000000,0,"Command injection detected",http,10.1.2.3,50284,10.9.8.7,80
would_block,6,1,1000000,0,"Command injection detected",http,10.1.2.3,50284,10.9.8.7,80

Testing Rules Inline

To protect networks, it's also important to make sure that our rules are blocking attacks appropriately, and the dump DAQ enables us to do just that.

Specifying the -Q option to enable inline mode and then setting the --daq to dump will "dump" the traffic that would've been passed through, emulating a real inline operation. The resulting traffic will be dumped, by default, to a file named inline-out.pcap:

$ snort3 -Q --daq dump -q -r get.pcap -R local.rules

In the above example, if the local.rules file contains a block rule that fires on some traffic in the get.pcap file, then the resulting inline-out.pcap file will contain only the traffic that was not blocked. We can use this functionality to test that our rules are preventing the actual attack packet(s) from getting through.

Converting Snort 2 Rules to Snort 3

Lastly, just like with configuration files, snort2lua can also be used to convert old Snort 2 rules to Snort 3 ones. Pass the Snort 2 rules file to the -c option and then provide a filename for the new Snort 3 rules file to the -r option:

$ snort2lua -c in.rules -r out.rules

Note that if any errors occur during the conversion, snort2lua will output a snort.rej file that explains what went wrong:

$ snort2lua -c 2.rules -r 3.rules
ERROR: 1 errors occurred while converting
ERROR: see snort.rej for details