Foreword
Snort is a powerful and lightweight network intrusion detection system. It has the capability of real-time traffic
analysis and logging of IP network packets, enabling it to perform
protocol analysis and search/match content. It can detect various types of attacks and raise real-time alerts for them. Furthermore, Snort is highly extensible and portable. This article will explain how to develop Snort rules.
1. Basics
Snort uses a simple rule description language that is easy to extend and quite powerful. Here are some basic concepts:
– Each Snort rule must be written on a single line, as its parser cannot interpret multi-line rules. Note: Due to formatting constraints, some examples in this document may span two lines.
– Each Snort rule is logically divided into two parts: the rule header and the rule options. The rule header includes: Rule action (rule’s behavior),
protocol, source/destination IP address, subnet mask, and source/destination port. The rule options include alert messages and information about anomalous packets (signatures) used to determine if the rule’s action should be executed.
Here’s an example:
alert tcp any any -> 192.168.1.0/24 111(content:”|00 01 86 a5|”;msg:”mountd access”;)
Table 1. A basic Snort rule
Everything from the beginning of the line to the leftmost parenthesis belongs to the rule header. The portion within the parentheses constitutes the rule options. The words preceding the colon in the rule options are called option keywords. Note that rule options are not mandatory for every rule; they help fine-tune the collection or alerting of packets. Snort will only execute the rule action for packets that match all defined options. When multiple options are combined, they operate in a logical AND relationship. Let’s start with the rule header.
1.1 `include`
The rule file that Snort uses is specified on the command line. The `include` keyword allows this rule file to include rules from other files, much like `include` in the C programming language. Snort reads the content of the included file and replaces the `include` keyword with it.
Syntax:
include
Note: A semicolon is not required at the end of the line.
1.2 Variables
You can define variables in Snort rule files.
Syntax:
var VARIABLE_NAME value
Example:
var MY_NET 192.168.1.0/24,10.1.1.0/24 $MY_NET any (flags:S;msg:’SYNMETA packet’;)
Table 2. Definition and use of variables
Rule variable names can be modified in many ways. You can define meta-variables using the `$` operator. These modifications can also incorporate variable modification operators `?` and `-`.
– `$var`: Defines a meta-variable.
– `$(var)`: Uses the content of `var` as the variable name.
– `$(var:-default)`: Uses the content of `var` as the variable name, or `default` if `var` is undefined.
– `$(var:?message)`: Uses the content of `var` as the variable name or prints the error message `message` and exits if not successful.
Example:
var MY_NET $(MYU_NET:-192.168.1.0/24) tcp any any -> $(MY_NET:?MY_NET is undefined!) 23
Table 3. Advanced variable usage
2. Rule Headers
2.1 Rule Action
The rule header includes several types of information, including: Which packets to examine, the packet source, the type of packet, and how to handle matching packets. The first part of every rule is the rule action. The rule action directs Snort on how to handle packets that match the rule’s criteria. In Snort, there are five default action types: alert, log, pass, activate, and dynamic.
– alert: Generates an alert using the selected alerting method and logs the packet.
– log: Logs the packet.
– pass: Ignores the packet.
– activate: Generates an alert and then activates other dynamic rules.
– dynamic: Remains idle until activated by an activate rule, then acts as a log rule.
You can also define your own rule types and associate them with one or more output plugins, allowing the custom rule types to be used in Snort rules.
Example: Defining a type that logs only in tcpdump format:
ruletype suspicious
{
type log
output log_tcpdump: suspicious.log
}
Defining a type that sends logs to syslog and a MySQL database:
ruletype redalert
{
type alert
output alert_syslog: LOG_AUTH LOG_ALERT
output database: log, user=snort dbname=snort host=localhost
}
2.2 `Protocol`
The second element of each rule is the protocol field. Currently, Snort can
analyze protocols such as:
TCP,
UDP, and ICMP. In the future, there may be added support for other protocols such as ARP, IGRP, GRE,
OSPF,
RIP,
IPX, etc.
2.3 IP Address
The next part of the rule header is the IP address and port information. The `any` keyword can be used to define any IP address. Snort does not support hostname resolution, so addresses must be in numeric/CIDR format. `/24` represents a Class C network, `/16` represents a Class B network, and `/32` represents a specific host address. For example: `192.168.1.0/24` defines the range `192.168.1.1` to `192.168.1.255`.
In rules, you can use the negation operator `!` to exclude specific IP addresses. It tells Snort to match all IP addresses except the listed ones. The negation operator is represented by `!`.
Example:
alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 111(content:”|00 01 86 a5|”;msg:”external mountd access”;)
Table 4. Rule with IP address negation operator
The IP address in this rule indicates all source IP addresses not belonging to the internal network, with destinations belonging to the internal network.
You can also define an IP address list. The format of an IP address list is:
[IP address 1/CIDR, IP address/CIDR,….]