Skip to content

Signature Rules

Snort Rule Structure

The Basics

Accessing the community Snort rules is a great way to start writing a rule and verify syntax. The config file will also be a vital resource. Since Snort allows for many ways to structure a given rule, we will follow the following standard moving forward: action protocol source_ip source_port -> destination_ip destination_port (msg:"[message]"; [additional rule options]; sid:[#]; rev:[#];)

Snort's intrusion detection and prevention system relies on the presence of Snort rules to protect networks, and those rules consist of two main sections:

  • The rule header defines the action to take on any matching traffic and the protocols, network addresses, port numbers, and direction of traffic that the rule should apply.

  • The rule body section defines the message associated with a given rule and, most importantly, the payload and non-payload criteria that must be met for a rule to match. Although rule options are not required, they are essential for ensuring a given rule targets the right traffic.

The following is an example of a fully-formed Snort 3 rule with a correct rule header and rule option definitions:

1
2
3
4
5
6
7
8
9
alert tcp $EXTERNAL_NET 80 -> $HOME_NET any
(
    msg:"Attack attempt!";
    flow:to_client,established;
    file_data;
    content:"1337 hackz 1337",fast_pattern,nocase;
    service:http;
    sid:1;
)

Rule Headers

All Snort rules start with a rule header, which consists of five main components. The header helps filter the traffic that the rule's body will evaluate.

alert tcp $EXTERNAL_NET 80 -> $HOME_NET any
- Rule actions tell Snort what to do when a rule "fires":  
alert XXX XXXXXXXXX_XXX XX XX XXXXX_XXX XXX

  • The protocol tells Snort which protocol applies:  

    XXXXX tcp XXXXXXXXX_XXX XX XX XXXXX_XXX XXX
    

  • IP addresses tell Snort what networks to evaluate the rule against:  

    XXXXX XXX $EXTERNAL_NET XX XX $HOME_NET XXX
    

  • Ports tell Snort which ports to evaluate the rule against:
XXXXX XXX XXXXXXXXX_XXX 80 xx XXXXX_XXX any

-The direction operator tells Snort which traffic direction to look for:

XXXXX XXX XXXXXXXX_XXX XX -> XXXXX_XXX XXX

Rule Actions

Rule actions tell Snort how to handle matching packets. There are five basic actions:

  • alert -> generate an alert on the current packet
  • block -> block the current packet and all the subsequent packets in this flow
  • drop -> drop the current packet
  • log -> log the current packet
  • pass -> mark the current packet as passed

There are also what are known as "active responses" that perform some action in response to the packet being detected:

  • react -> send a response to the client and terminate the session.
  • reject -> terminate the session with TCP reset or ICMP unreachable
  • rewrite -> overwrite packet contents based on a "replace" option in the rules

Protocols

The protocol field tells Snort what type of protocols a given rule should look at, and the currently supported ones include:

ip icmp tcp udp A rule can only have one protocol se

IP Addresses

IP addresses in a rule header tell Snort what source and destination IP addresses a given rule should apply to. A rule will only match if a given packet's source and destination IP addresses match the IP addresses set in that rule.

They can be declared in one of four ways:

  • As a numeric IP address with an optional CIDR block (e.g., 192.168.0.5, 192.168.1.0/24)
  • As a variable defined in the Snort config that specifies a network address or a set of network addresses (e.g., $EXTERNAL_NET, $HOME_NET, etc.)
  • The keyword any, meaning any IP address
  • A list of IP addresses, IP address variables, and port ranges, enclosed in square brackets and separated by commas (e.g., [192.168.1.0/24,10.1.1.0/24])

!Note: IP address declarations can also be negated to tell Snort to match any IP address except those listed. This negation is done with the ! operator.

Examples:

1
2
3
4
5
alert tcp 192.168.1.0/24 any -> 192.168.5.0/24 any (
alert tcp $EXTERNAL_NET any -> $HOME_NET 80 (
alert tcp any any -> 192.168.1.3 445 (
alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 23 (
alert tcp ![192.168.1.0/24,10.1.1.0/24] any -> [192.168.1.0/24,10.1.1.0/24] 80 (

Port Numbers

The port numbers in a rule header tell Snort to apply a given rule to traffic sent from or sent to the specified source and destination ports.

Ports are declared in a few different ways:

  • As any ports (meaning match traffic being sent from or to any port)
  • As a static port (e.g., 80, 445, 21)
  • As a variable defined in the Snort config that specifies a port or set of ports (e.g., $HTTP_PORTS)
  • As port ranges indicated with the range operator, : (e.g., 1:1024, 500:)
  • A list of static ports, port variables, and port ranges, enclosed in square brackets and separated by commas (e.g., [1:1024,4444,5555,$HTTP_PORTS])

A rule header should have two port declarations, one for the source ports and another for the destination ports. The source and destination ports are declared after the source and destination IP addresses, respectively.

Examples:

1
2
3
log udp any any -> 192.168.1.0/24 1:1024 (
log tcp any any -> 192.168.1.0/24 :6000 (
log tcp any :1024 -> 192.168.1.0/24 500: (

Direction Operators

A header's direction operator indicates the direction of the traffic to which the rule should apply. There are two valid direction operators:

-> <>

The -> operator is the most common, and it denotes that the IP addresses and port numbers on the left side represent the source, and the IP addresses and port numbers on the right side represent the destination.

The <> operation is the bidirectional operator, and it tells Snort to consider the two IP addresses and port pairs as the source or destination.

The direction operator is placed in the header after the first port declaration.

Examples:

alert tcp $EXTERNAL_NET 80 -> $HOME_NET any (
log tcp !192.168.1.0/24 any <> 192.168.1.0/24 23 (   

Service Rules

Service rules are a new rule type in Snort 3 that allows rule writers to match the traffic of a particular service by using a rule header that consists of only an action and the name of an application-layer service. These headers differ from the "traditional" headers described above in that they do not require declarations of network addresses, ports, or a direction operator.

This type of rule is beneficial for services like HTTP, where it's not uncommon to see web servers running on TCP ports other than 80

For example, the following rule header tells Snort to apply this rule only to traffic that Snort detects as HTTP:

alert http (

Example:

alert http
(
    msg:"SERVER-WEBAPP This rule only looks at HTTP traffic";
    flow:to_server,established;
    http_uri;
    content:"/admin.php",fast_pattern,nocase;
    content:"cmd=",nocase;
    pcre:"/[?&]cmd=[^&]*?\x3b/i";
    sid:1;
)

File Rules

Snort 3's new "file rules" allow rule writers to create rules to match a particular file regardless of the protocol, source IPs, destination IPs, ports, and service.

Snort can process files that are sent using any of the following application-layer protocols:

HTTP SMTP POP3 IMAP SMB FTP

Example:

To see the advantage of such a rule header, consider the two rules below that look for "secret_encryption_key" in a packet. The first rule looks for the string in HTTP and IMAP packets sent to a client, while the second one looks for the string in SMTP packets sent to some SMTP server.

alert tcp $EXTERNAL_NET [80,143] -> $HOME_NET any
(
    msg:"MALWARE-OTHER Win.Ransomware.Agent payload download attempt";
    flow:to_client,established;
    file_data; content:"secret_encryption_key",fast_pattern,nocase;
    service:http, imap;
    classtype:trojan-activity;
    sid:1;
)
alert tcp $EXTERNAL_NET any -> $SMTP_SERVERS 25 
(
    msg:"MALWARE-OTHER Win.Ransomware.Agent payload download attempt";
    flow:to_server,established;
    file_data; content:"secret_encryption_key",fast_pattern,nocase;
    service:smtp;
    classtype:trojan-activity;
    sid:2;
)
However, this pair of rules can be written as a single alert file rule, which will tell Snort to look for "secret_encryption_key" in any file detected on the network, regardless of source, destination, or service.
1
2
3
4
5
6
7
8
alert file
(
    msg:"MALWARE-OTHER Win.Ransomware.Agent payload download attempt";
    file_data;
    content:"secret_encryption_key",fast_pattern,nocase;
    classtype:trojan-activity;
    sid:3;
)

File Identification Rules

File identification rules use Snort's detection engine to enable file type identification. These rules are basic Snort 3 rules, but instead of alerting on and/or blocking traffic, they identify files based on their contents and then define a file type that can be used in subsequent rules with file_type options.

Examples:

1
2
3
4
5
6
7
8
9
file_id (
    msg:"Windows/DOS executable file"; 
    file_meta:type MSEXE, id 21, category "Executables,Dynamic Analysis Capable,Local Malware Analysis Capable"; 
    file_data; 
    content:"| 4D 5A |", depth 2, offset 0; 
    gid:4; 
    sid:16; 
    rev:1;
)

Rule Options

Rule options determine if a given packet should be passed along to its destination if it should instead be stopped, or if it should be alerted. All rule options are enclosed in parentheses after the rule header. Then, each rule option is declared with its name followed optionally by a : character and any option-specific criteria. Lastly, each rule option is terminated with a ; character.

Four Categories of Rule Options:

  • general options provide additional context for a given rule
  • payload options set payload-specific criteria
  • non-payload options set non-payload specific criteria
  • post-detection options set actions to take on a given packet after the rule has "fired."

Examples:

1
2
3
4
5
6
7
8
9
# This is an example of a buffer modifier, "http_uri"
# It tells Snort to look for subsequent content matches only in that buffer
http_uri;
# Content match specific criteria, as well as others, require double quotes
content:"/web_form.php";
# not all options have criteria that require quotes
service:http;
# Some options require specifying a "sub-option."
reference:url,www.example.com;

Rule Option Syntax Key

Each rule option page features a "Format" section that describes how the specific rule option can be formatted. Some rule options are simple and specified with just the option name, while others are more complicated and have a mix of required and optional "arguments."

Click Here for Reference

General Rule Options

General rule options provide information about a rule but do not change what a given rule looks for in a packet.

keyword description
msg msg sets the message to be printed out when a rule matches
reference reference is used to provide additional context to rules in the form of links to relevant attack identification systems
gid gid identifies the specific Snort component that generates a given event
sid sid identifies the unique signature number assigned to a given Snort rule
rev rev identifies the particular revision number of a given Snort rule
classtype classtype assigns a classification to the rule to indicate the type of attack associated with an event
priority priority sets a severity level for appropriate event prioritizing
metadata metadata adds additional and arbitrary information to a rule in the form of name-value pairs
service service sets the list of services to be associated with a given rule
rem rem is used to convey an arbitrary comment in the rule body
file_meta file_meta is used to set the file metadata for a given file identification rule

MSG

The msg rule option adds a message describing the rule. The message should summarize the rule's purpose and be output along with events generated by the rule.

Examples:

msg:"SERVER-WEBAPP /etc/inetd.conf file access attempt";
msg:"Malicious file download attempt";

Reference - GID - Classtype

  • The reference rule option provides additional context to rules in the form of links to relevant attack identification systems
  • The gid keyword stands for "generator id," identifying the specific part of Snort that generated a given event.
  • The classtype assigns a classification to the rule to indicate the type of attack associated with an event.

SID

The sid keyword uniquely identifies a given Snort rule. This rule option takes in a single argument, a numeric value that must be unique to the rule.

  • All Snort rules should have a sid option to quickly identify them if they ever generate an alert.

  • Snort "reserves" sid values 0-99 for future use.

  • Snort also sets aside 100 - 999999 for community rules included with the Snort distribution

  • Users should use sid values that start at 1000000 for local rules, incrementing the sid values by one for each additional local rule.

Example:

sid:44763;
sid:1000001;

REV

The rev keyword uniquely identifies the revision number of a given Snort rule. This option should be used along with the sid keyword and incremented by one each time a rule is changed.

Examples

sid:1000001; rev:1;
sid:1000001; rev:2;

service

The service rule option tells Snort what application-layer service or services you want your rule to apply to. With this rule option, the services specified do not have to match the actual traffic service as long as the ports match. Additionally, the converse of that statement is true; the ports do not have to match as long as the services match.  Another way to look at the service option is like an "OR ports" statement.

For instance, if the source or destination ports present in a rule's header match those used in the traffic, but the service specified in the rule does not match the service present in the traffic, the rule can still match as long as the rest of the rule evaluates to true. The following rule, for example, will apply either to traffic Snort detects as HTTP or traffic that is destined for TCP port 8000:

1
2
3
4
5
alert tcp any any -> any any 8000 (
    msg:"HTTP traffic or dst port 8000 please";
    service:http;
    sid:1000000;
)

Example

service:http;
service:http,imap,pop3;

Payload Detection Rule Options

These options tell Snort what kind of packet data to look for, where to look for that data, and how to find it.

A single Snort rule can contain multiple options, which are evaluated against the packet data in the order in which they are placed in the rule.

When Snort receives network traffic and begins processing, it places the packet data into various "buffers" that rule writers can evaluate payload options against. Snort provides buffers for the raw packet data, normalized packet data, "file" data, individual HTTP elements, and more. Not all buffers will be available for a given packet, so rule writers, you should make sure they are using the appropriate one(s).

content

  • content: is used to perform basic pattern matching against packet data. Matches can also be "negated" with a !. Content matches can contain ASCII strings, hex bytes, or both. Hex bytes must be enclosed in | characters.

Format:

content:[!]"content_string";

Example:

1
2
3
4
# Simple ASCII string match
content:"USER root";
# Combining of ASCII characters and hex bytes
content:"PK|03 04|";
Note: Certain characters must be escaped (with '\' characters) or encoded in hex. These are (semicolon, slash, and quotation marks) ; "

ttl

The ttl rule option is used to check that the IP time-to-live (TTL) value in the IP header is less than, greater than, equal to, not equal to, less than or equal to, or greater than or equal to a specified integer value. This rule option can also check that the header's TTL value is between a range of numbers, using the <> range operator for an exclusive range check or the <=> for an inclusive one.

Examples:

# Check that the TTL equals 64
ttl:64;
# Check that the TTL does not equal 64
ttl:!64;
# Check that the TTL is less than 3 
ttl:<3;
# Check that the TTL is between 3 and 5 (inclusive)
ttl:3<=>5;
# Check that the TTL is equal to 5
ttl:=5;

fragbits

The fragbits option checks the IP header to see if specific fragmentation and reserved bits are set.

Rule writers can check for the following bits:

M -> More Fragments D -> Don't Fragment R -> Reserved Bit

Additionally, rule options can include one of the following optional modifiers to change how the criteria is evaluated:

  • -> Match on the specified bits, plus any others
  • -> Match if any of the specified bits are set ! -> Match if the specified bits are not set

Examples

1
2
3
4
5
## Checks if only the More Fragments bit is set 
fragbits:M;
# Checks if the More Fragments bit and the 
# Do not Fragment bit are set, plus any others
fragbits:+MD;

flags

The flags rule option checks if the specified flag bits are set in the TCP header.

The following flag bits may be checked:

F -> FIN (Finish) S -> SYN (Synchronize sequence numbers) R -> RST (Reset the connection) P -> PSH (Push buffered data) A -> ACK (Acknowledgement) U -> URG (Urgent pointer) C -> CWR (Congestion window reduced) E -> ECE (ECN-Echo) 0 -> No TCP flags set

Specifying more than one flag character allows one to look for multiple flags. Doing this tells Snort to look for all the flags specified in the option.

Additionally, rule options can also include one of the following optional modifiers to change how the criteria are evaluated:

  • -> match any of the specified bits, plus any others
  • -> match if any of the specified bits are set ! -> match if the specified bits are not set

Rule writers can also specify flags to ignore by placing a comma after the initial set of flags followed by a flag character or characters to ignore.

Examples:

1
2
3
4
5
6
7
8
# Check for TCP packets where only the SYN flag is set 
flags:S;
# Check for TCP packets where only the SYN and ACK flags are set 
flags:SA;
# Check for TCP packets where the SYN and ACK flags are set 
flags:*SA;
# Check if the SYN and FIN bits are set, ignoring the CWR and ECN bits
flags:SF,CE;

Important Note:

Modifying these placeholders with incorrect values or using untrusted sources for rule creation can lead to security vulnerabilities. Improperly configured rules can block legitimate traffic or fail to detect actual threats.

For safe and effective Snort rule creation, it's highly recommended to refer to the following resources:

Snort Official Documentation: https://www.snort.org/documents Snort Community Rules: https://docs.snort.org/start/rules