Includes
The include keyword allows other rule files to be included within
the rules file indicated on the Snort command line. It works much
like an "#include" from the C programming language, reading the contents
of the named file and putting them in place in the file in the place where
the include appears.
Format:
include: <include file path/name>
Note that there is no semicolon at the end of this line. Included
files will substitute any predefined variable values into their own variable
references. See the Variables section for more information on defining
and using variables in Snort rule files.
Variables
Variables may be defined in Snort. These are simple substitution
variables set with the var keyword as in Figure 2.
Format:
var: <name> <value>
var MY_NET [192.168.1.0/24,10.1.1.0/24]
alert tcp any any -> $MY_NET any (flags: S; msg: "SYN packet";)
|
Figure 2 - Example of Variable Definition and Usage
The rule variable names can be modified in several ways. You can
define meta-variables using the "$" operator. These can be
used with the variable modifier operators, "?" and "-".
-
$var - define meta variable
-
$(var) - replace with the contents of variable "var"
-
$(var:-default) - replace with the contents of the variable "var" or with
"default" if "var" is undefined.
-
$(var:?message) - replace with the contents of variable "var" or print
out the error message "message" and exit
See Figure 3 for an example of these rules modifiers in action.
var MY_NET $(MY_NET:-192.168.1.0/24)
log tcp any any -> $(MY_NET:?MY_NET is undefined!) 23
|
Figure 3 - Advanced Variable Usage Example
Rule Actions:
The rule header contains the information that defines the "who, where,
and what" of a packet, as well as what to do in the event that a packet
with all the attributes indicated in the rule should show up. The
first item in a rule is the rule action. The rule action tells
Snort what to do when it finds a packet that matches the rule criteria.
There are five available default actions in Snort, alert, log, pass, activate,
and dynamic.
-
alert - generate an alert using the selected alert method, and then log
the packet
-
log - log the packet
-
pass - ignore the packet
-
activate - alert and then turn on another dynamic rule
-
dynamic - remain idle until activated by an activate rule, then
act as a log rule
You can also define your own rule types and associate one or more output
plugins with them. You can then use the rule types as actions
in Snort rules.
This example will create a type that will log to just tcpdump:
ruletype suspicious
{
type log
output log_tcpdump: suspicious.log
}
This example will create a rule type that will log to syslog and a mysql
database:
ruletype redalert
{
type alert
output alert_syslog: LOG_AUTH LOG_ALERT
output database: log, mysql, user=snort dbname=snort
host=localhost
}
Protocols:
The next field in a rule is the protocol. There are three IP protocols
that Snort currently analyzes for suspicious behavior, tcp, udp, and icmp.
In the future there may be more, such as ARP, IGRP, GRE, OSPF, RIP, IPX,
etc.
IP Addresses:
The next portion of the rule header deals with the IP address and port
information for a given rule. The keyword "any" may be used to define
any address. Snort does not have a mechanism to provide host name
lookup for the IP address fields in the rules file. The addresses
are formed by a straight numeric IP address and a CIDR
block. The CIDR block indicates the netmask that should be applied
to the rule's address and any incoming packets that are tested against
the rule. A CIDR block mask of /24 indicates a Class C network, /16
a Class B network, and /32 indicates a specific machine address.
For example, the address/CIDR combination 192.168.1.0/24 would signify
the block of addresses from 192.168.1.1 to 192.168.1.255. Any rule
that used this designation for, say, the destination address would match
on any address in that range. The CIDR designations give us a nice
short-hand way to designate large address spaces with just a few characters.
In Figure 1, the source IP address was
set to match for any computer talking, and the destination address was
set to match on the 192.168.1.0 Class C network.
There is an operator that can be applied to IP addresses, the negation
operator. This operator tells Snort to match any IP address except
the
one indicated by the listed IP address. The negation operator is
indicated with a "!". For example, an easy modification to the initial
example is to make it alert on any traffic that originates outside of the
local net with the negation operator as shown in Figure 4.
alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 111 (content:
"|00 01 86 a5|"; msg: "external mountd access";)
|
Figure 4 - Example IP Address Negation Rule
This rule's IP addresses indicate "any tcp packet with a source IP address
not
originating from the internal network and a destination address on
the internal network".
You may also specify lists of IP addresses. An IP list is specified
by enclosing a comma separated list of IP addresses and CIDR blocks within
square brackets. For the time being, the IP list may not include spaces
between the addresses. See Figure 3 for an example of an IP list in action.
alert tcp ![192.168.1.0/24,10.1.1.0/24] any -> [192.168.1.0/24,10.1.1.0/24]
111 (content: "|00 01 86 a5|"; msg: "external mountd access";)
|
Port Numbers
Port numbers may be specified in a number of ways, including "any" ports,
static port definitions, ranges, and by negation. "Any" ports are
a wildcard value, meaning literally any port. Static ports are indicated
by a single port number, such as 111 for portmapper, 23 for telnet, or
80 for http, etc. Port ranges are indicated with the range operator
":". The range operator may be applied in a number of ways to take
on different meanings, such as in Figure 5.
log udp any any -> 192.168.1.0/24 1:1024
log udp traffic coming from any port and destination ports ranging
from 1 to 1024
|
log tcp any any -> 192.168.1.0/24 :6000
log tcp traffic from any port going to ports less than or equal
to 6000
|
log tcp any :1024 -> 192.168.1.0/24 500:
log tcp traffic from priveleged ports less than or equal to 1024
going to ports greater than or equal to 500
|
Figure 5 - Port Range Examples
Port negation is indicated by using the negation operator "!".
The negation operator may be applied against any of the other rule types
(except any, which would translate to none, how Zen...). For example,
if for some twisted reason you wanted to log everything except the X Windows
ports, you could do something like the rule in Figure 6.
log tcp any any -> 192.168.1.0/24 !6000:6010
|
Figure 6 - Example of Port Negation
The Direction Operator
The direction operator "->" indicates the orientation, or "direction",
of the traffic that the rule applies to. The IP address and port
numbers on the left side of the direction operator is considered to be
the traffic coming from the source host, and the address and port information
on the right side of the operator is the destination host. There
is also a bidirectional operator, which is indicated with a "<>"
symbol. This tells Snort to consider the address/port pairs in either
the source or destination orientation. This is handy for recording/analyzing
both sides of a conversation, such as telnet or POP3 sessions. An
example of the bidirectional operator being used to record both sides of
a telnet session is shown in Figure 7.
log !192.168.1.0/24 any <> 192.168.1.0/24 23
|
Figure 7 - Snort rules using the Bidirectional Operator
Activate/Dynamic Rules
Activate/dynamic rule pairs give Snort a powerful capability.
You can now have one rule activate another when it's action is performed
for a set number of packets. This is very useful if you want to set
Snort up to perform follow on recording when a specific rule "goes off".
Activate rules act just like alert rules, except they have a *required*
option field: "activates". Dynamic rules act just like log rules,
but they have a different option field: "activated_by". Dynamic rules
have a second required field as well, "count". When the "activate"
rule goes off, it turns on the dynamic rule it is linked to (indicated
by the activates/activated_by option numbers) for "count" number
of packets (50 in this case).
Put 'em together and they look like this:
activate tcp !$HOME_NET any -> $HOME_NET 143 (flags: PA; content:
"|E8C0FFFFFF|\bin|; activates: 1; msg: "IMAP buffer overflow!";)
dynamic tcp !$HOME_NET any -> $HOME_NET 143 (activated_by: 1;
count: 50;)
|
Figure 8 - Activate/Dynamic rule example
These rules tell Snort to alert when it detects an IMAP buffer overflow
and collect the next 50 packets headed for port 143 coming from outside
$HOME_NET headed to $HOME_NET. If the buffer overflow happened and
was successful, there's a very good possibility that useful data will be
contained within the next 50 (or whatever) packets going to that same service
port on the network, so there's value in collecting those packets for later
analysis.
Rule options form the heart of Snort's intrusion detection
engine, combining ease of use with power and flexibility. All Snort
rule options are separated from each other using the semicolon ";" character.
Rule option keywords are separated from their arguments with a colon ":"
character. As of this writing, there are fifteen rule option keywords
available for Snort:
msg - prints a message in alerts and packet logs
logto - log the packet to a user specified filename
instead of the standard output file
ttl - test the IP header's TTL field value
tos - test the IP header's TOS field value
id - test the IP header's fragment ID field for a specific
value
ipoption - watch the IP option fields for specific
codes
fragbits - test the fragmentation bits of the IP
header
dsize - test the packet's payload size against a value
flags - test the TCP flags for certain values
seq - test the TCP sequence number field for a specific
value
ack - test the TCP acknowledgement field for a specific
value
itype - test the ICMP type field against a specific
value
icode - test the ICMP code field against a specific
value
icmp_id - test the ICMP ECHO ID field against a
specific value
icmp_seq - test the ICMP ECHO sequence number against
a specific value
content - search for a pattern in the packet's
payload
content-list - search for a set of patterns
in the packet's payload
offset - modifier for the content option, sets the
offset to begin attempting a pattern match
depth - modifier for the content option, sets the
maximum search depth for a pattern match attempt
nocase - match the preceeding content string with
case insensitivity
session - dumps the application layer information
for a given session
rpc - watch RPC services for specific application/proceedure
calls
resp - active response (knock down connections, etc)
react - active response (block web sites)
|
The msg rule option tells the logging and alerting engine the
message to print along with a packet dump or to an alert. It is a
simple text string that utilizes the "\" as an escape character to indicate
a discrete character that might otherwise confuse Snort's rules parser
(such as the semi-colon ";" character).
Format:
msg: "<message text>";
The logto option tells Snort to log all packets that trigger
this rule to a special output log file. This is especially handy
for combining data from things like NMAP activity, HTTP CGI scans, etc.
It should be noted that this option does not work when Snort is in binary
logging mode.
Format:
logto: "<filename>";
This rule option is used to set a specific time-to-live value to test
against. The test it performs is only sucessful on an exact match.
This option keyword was intended for use in the detection of traceroute
attempts.
Format:
ttl: "<number>";
The "tos" keyword allows you to check the IP header TOS field for a
specific value. The test it performs is only sucessful on an exact
match.
Format:
tos: "<number>";
This option keyword is used to test for an exact match in the IP header
fragment ID field. Some hacking tools (and other programs) set this
field specifically for various purposes, for example the value 31337 is
very popular with some hackers. This can be turned against them by
putting a simple rule in place to test for this and some other "hacker
numbers".
Format:
id: "<number>";
If IP options are present in a packet, this option will search for a
specific option in use, such as source routing. Valid arguments to this
option are:
-
rr - Record route
-
eol - End of list
-
nop - No op
-
ts - Time Stamp
-
sec - IP security option
-
lsrr - Loose source routing
-
ssrr - Strict source routing
-
satid - Stream identifier
The most frequently watched for IP options are strict and loose source
routing which aren't used in any widespread internet applications. Only
a single option may be specified per rule.
Format:
ipopts: <option>;
This rule inspects the fragment and reserved bits in the IP header.
There are three bits that can be checked, the Reserved Bit (RB), More Fragments
(MF) bit, and the Dont Fragment (DF) bit. These bits can be checked
in a variety of combinations. Use the following values to indicate specific
bits:
-
R - Reserved Bit
-
D - DF bit
-
M - MF bit
You can also use modifiers to indicate logical match criteria for the specified
bits:
-
+ - ALL flag, match on specified bits plus any others
-
* - ANY flag, match if any of the specified bits are set
-
! - NOT flag, match if the specified bits are not set
Format:
fragbits: <bit values>;
alert tcp !$HOME_NET any -> $HOME_NET any (fragbits: R+; msg:
"Reserved IP bit set!";)
|
Figure 9 - Example of fragbits detection usage
The dsize option is used to test the packet payload size. It may
be set to any value, plus use the greater than/less than signs to indicate
ranges and limits. For example, if you know that a certain service
has a buffer of a certain size, you can set this option to watch for attempted
buffer overflows. It has the added advantage of being a much faster
way to test for a buffer overflow than a payload content check.
Format:
dsize: [>|<] <number>;
Note: The > and < operators are optional!
The content keyword is one of the more important features of Snort.
It allows the user to set rules that search for specific content in the
packet payload and trigger response based on that data. Whenever
a content option pattern match is performed, the Boyer-Moore pattern match
function is called and the (rather computationally expensive) test is performed
against the packet contents. If data exactly matching the argument
data string os contained anywhere within the packet's payload, the test
is successful and the remainder of the rule option tests are performed.
Be aware that this test is case sensitive.
The option data for the content keyword is somewhat complex; it can
contain mixed text and binary data. The binary data is generally
enclosed within the pipe ("|") character and represented as bytecode.
Bytecode represents binary data as hexidecimal numbers and is a good shorthand
method for describing complex binary data. Figure 7 contains an example
of mixed text and binary data in a Snort rule.
alert tcp any any -> 192.168.1.0/24 143 (content: "|90C8 C0FF
FFFF|/bin/sh"; msg: "IMAP buffer overflow!";)
|
Figure 10 - Mixed Binary Bytecode and Text in a Content Rule Option
Format:
content: "<content string>";
The offset rule option is used as a modifier to rules using the content
option keyword. This keyword modifies the starting search position
for the pattern match function from the beginning of the packet payload.
It is very useful for things like CGI scan detection rules where the content
search string is never found in the first four bytes of the payload.
Care should be taken against setting the offset value too "tightly" and
potentially missing an attack! This rule option keyword cannot be
used without also specifying a content rule option.
Format:
offset: <number>;
Depth is another content rule option modifier. This sets the maximum
search depth for the content pattern match function to search from the
beginning of its search region. It is useful for limiting the pattern
match function from performing inefficient searches once the possible search
region for a given set of content has been exceeded. (Which is to
say, if you're searching for "cgi-bin/phf" in a web-bound packet, you probably
don't need to waste time searching the payload beyond the first 20 bytes!)
See Figure 8 for an example of a combined content, offset, and depth search
rule.
Format:
depth: <number>;
alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf";
offset: 3; depth: 22; msg: "CGI-PHF access";)
|
Figure 11 - Combined Content, Offset and Depth Rule
The nocase option is used to deactivate case sensitivity in a "content"
rule. It is specified alone within a rule and any ASCII characters
that are compared to the packet payload are treated as though they are
either upper of lower case.
Format:
nocase;
alert tcp any any -> 192.168.1.0/24 21 (content: "USER root";
nocase; msg: "FTP root user access attempt";)
|
Figure 12 - Content rule with nocase modifier
This rule tests the TCP flags for a match. There are actually
8
flags
variables available in Snort:
-
F - FIN (LSB in TCP Flags byte)
-
S - SYN
-
R - RST
-
P - PSH
-
A - ACK
-
U - URG
-
2 - Reserved bit 2
-
1 - Reserved bit 1 (MSB in TCP Flags byte)
There are also logical operators that can be used to specify matching criteria
for the indicated flags:
-
+ - ALL flag, match on all specified flags plus any others
-
* - ANY flag, match on any of the specified flags
-
! - NOT flag, match if the specified flags aren't set in the packet
The reserved bits can be used to detect unusual behavior, such as IP stack
fingerprinting attempts or other suspicious activity. Figure 13 shows
a SYN-FIN scan detection rule.
Format:
flags: <flag values>;
alert any any -> 192.168.1.0/24 any (flags: SF; msg: "Possible
SYN FIN scan";)
|
Figure 13 - Sample TCP Flags Specification
This rule option refers to the TCP sequence number. Essentially,
it detects if the packet has a static sequence number set, and is therefore
pretty much unused. It was included for the sake of completeness.
Format:
seq: <number>;
The ack rule option keyword refers to the TCP header's acknowledge field.
This rule has one practical purpose so far: detecting NMAP
TCP pings. A NMAP TCP ping sets this field to zero and sends a packet
with the TCP ACK flag set to determine if a network host is active.
The rule to detect this activity is shown in Figure 14.
Format:
ack: <number>;
alert any any -> 192.168.1.0/24 any (flags: A; ack: 0; msg:
"NMAP TCP ping";)
|
Figure 14 - TCP ACK Field Usage
This rule tests the value of the ICMP type field. It is set using
the numeric value of this field. For a list of the available
values, look in the decode.h file included with Snort or in any ICMP reference.
It should be noted that the values can be set out of range to detect invalid
ICMP type values that are sometimes used in denial of service and flooding
attacks.
Format:
itype: <number>;
The icode rule option keyword is pretty much identical to the itype
rule, just set a numeric value in here and Snort will detect any traffic
using that ICMP code value. Out of range values can also be set to
detect suspicious traffic.
Format:
icode: <number>;
The session keyword is brand new as of version 1.3.1.1 and is used to
extract the user data from TCP sessions. It is extremely useful for
seeing what users are typing in telnet, rlogin, ftp, or even web sessions.
There are two available argument keywords for the session rule option,
printable
or all. The printable keyword only prints out data
that the user would normally see or be able to type. The all
keyword substitutes non-printable characters with their hexadecimal equivalents.
This function can slow Snort down considerably, so it shouldn't be used
in heavy load situations, and is probably best suited for post-processing
binary (tcpdump format) log files. See Figure 15 for a good example
of a telnet session logging rule.
Format:
session: [printable|all];
log tcp any any <> 192.168.1.0/24 23 (session: printable;)
|
Figure 15 - Logging Printable Telnet Session Data
The icmp_id option examines an ICMP ECHO packet's ICMP ID number for
a specific value. This is useful because some covert
channel programs use static ICMP fields when they communicate. This
particular plugin was developed to enable the stacheldraht detection rules
written by Max Vision, but it is
certainly useful for detection of a number of potential attacks.
Format:
icmp_id: <number>;
The icmp_id option examines an ICMP ECHO packet's ICMP sequence field
for a specific value. This is useful because some covert
channel programs use static ICMP fields when they communicate. This
particular plugin was developed to enable the stacheldraht detection rules
written by Max Vision, but it is
certainly useful for detection of a number of potential attacks. (And yes,
I know the info for this field is almost identical to the icmp_id description,
it's practically the same damn thing!)
Format:
icmp_seq: <number>;
This option looks at RPC requests and automatically decodes the application,
procedure, and program version, indicating success when all three variables
are matched. The format of the option call is "application, procedure,
version". Wildcards are valid for both the procedure and version numbers
and are indicated with a "*".
Format:
rpc: <number, [number|*], [number|*]>;
alert tcp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC
getport (TCP)";)
|
alert udp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC
getport (UDP)";)
|
alert udp any any -> 192.168.1.0/24 111 (rpc: 100083,*,*; msg:"RPC
ttdb";)
|
alert udp any any -> 192.168.1.0/24 111 (rpc: 100232,10,*; msg:"RPC
sadmin";)
|
Figure 16 - Various RPC Call Alerts
The resp keyword implements flexible reponse (FlexResp) to traffic that
matches a Snort rule. The FlexResp code allows Snort to actively
close offending connections. The following arguments are valid for
this module:
-
rst_snd - send TCP-RST packets to the sending socket
-
rst_rcv - send TCP-RST packets to the receiving socket
-
rst_all - send TCP_RST packets in both directions
-
icmp_net - send a ICMP_NET_UNREACH to the sender
-
icmp_host - send a ICMP_HOST_UNREACH to the sender
-
icmp_port - send a ICMP_PORT_UNREACH to the sender
-
icmp_all - send all above ICMP packets to the sender
These options can be combined to send multiple responses to the target
host. Multiple arguments are separated by a comma.
Format:
resp: <resp_modifier[, resp_modifier...]>;
alert tcp any any -> 192.168.1.0/24 1524 (flags: S;
resp: rst_all; msg: "Root shell backdoor attempt";) |
alert udp any any -> 192.168.1.0/24 31 (resp: icmp_port,icmp_host;
msg: "Hacker's Paradise access attempt";) |
Figure 17 - FlexResp Usage Examples
The content-list keyword allows multiple content strings to be specified
in the place of a single content option. The patterns to be searched for
must each be on a single line of content-list file as shown in Figure 1,
but they are treated otherwise identically to content strings specified
as an argument to a standard content directive. This option is the
basis for the react keyword.
# adult sites
porn
adults
hard core
www.pornsite.com
# ... |
Figure 18 - Content-list "adults" file example
Format:
content-list: "<file_name>";
The react keyword based on flexible response (Flex Resp) implements
flexible reaction to traffic that matches a Snort rule. The basic reaction
is blocking interesting sites users want to access: New York Times, slashdot,
or something really important - napster and porn sites. The Flex Resp code
allows Snort to actively close offending connections and/or send a visible
notice to the browser (warn modifier available soon). The notice may include
your own comment. The following arguments (basic modifiers) are
valid for this option:
-
block - close connection and send the visible notice
-
warn - send the visible, warning notice (will be available soon)
The basic argument may be combined with the following arguments (additional
modifiers):
-
msg - include the msg option text into the blocking visible notice
-
proxy: <port_nr> - use the proxy port to send the visible notice
(will
be available soon)
Multiple additional arguments are separated by a comma. The react keyword
should be placed as the last one in the option list.
Format:
react: <react_basic_modifier[, react_additional_modifier...]>;
alert tcp any any <> 192.168.1.0/24 80 (content-list:
"adults"; msg: "Not for children!"; react: block, msg;) |
alert tcp any any <> 192.168.1.0/24 any (content-list:
"adults"; msg: "Adults list access attempt"; react: block;) |
Figure 19 - React Usage Examples
Preprocessor Overview
Preprocessors were introduced in version 1.5 of Snort. They allow
the functionality of Snort to be extended by allowing users and programmers
to drop modular "plugins" into Snort fairly easily. Preprocessor
code is run before the detection engine is called, but after the packet
has been decoded. The packet can be modified or analyzed in an "out
of band" manner through this mechanism.
Preprocessors are loaded and configured using the preprocessor
keyword. The format of the preprocessor directive in the Snort rules
file is:
preprocessor <name>: <options>
preprocessor minfrag: 128 |
Figure 20 - Preprocessor Directive Format Example
Available Preprocessor Modules
The minfrag preprocessor examines fragmented packets for a specified
size threshold. When packets are fragmented, it is generally caused
by routers between the source and destination. Generally speaking,
there is no piece of commercial network equipment that fragments packets
in sizes smaller than 512 bytes, so we can use this fact to enable traffic
to be monitored for tiny fragments that are generally indicative of someone
trying to hide their traffic behind fragmentation.
Format:
minfrag: <threshold number>
HTTP Decode is used to process HTTP URI strings and convert their data
to non-obfuscated ASCII strings. This is done to defeat evasive web
URL scanners and hostile attackers that could otherwise elude the content
analysis strings used to examine HTTP traffic for suspicious activity.
The preprocessor module takes HTTP port numbers (separated by spaces) to
be normalized as its arguments (typically 80 and 8080).
Format:
http_decode: <port list>
preprocessor http_decode: 80 8080 |
Figure 21 - HTTP Decode Directive Format Example
The Snort Portscan Preprocessor is developed by Patrick Mullen and (much)
more information is available at his web
page.
What the Snort Portscan Preprocessor does:
Log the start and end of portscans from a single source IP to the standard
logging facility.
If a log file is specified, logs the destination IPs and ports scanned
as well as the type of scan.
A portscan is defined as TCP connection attempts to more than P ports
in T seconds or UDP packets sent to more than P ports in T seconds.
Ports can be spread across any number of destination IP addresses, and
may all be the same port if spread across multiple IPs. This version does
single->single and single->many portscans. The next full release
will do distributed portscans (multiple->single or multiple->multiple).
A portscan is also defined as a single "stealth scan" packet, such as NULL,
FIN, SYNFIN, XMAS, etc. This means that from scan-lib in the standard
distribution of snort you should comment out the section for stealth scan
packets. The benefit is with the portscan module these alerts would
only show once per scan, rather than once for each packet. If you
use the external logging feature you can look at the technique and type
in the log file.
The arguments to this module are:
-
network to monitor - The network/CIDR block to monitor for portscans
-
number of ports - number of ports accessed in the detection period
-
detection period - number of seconds to count that the port access threshold
is considered for
-
logdir/filename - the directory/filename to place alerts in. Alerts are
also written to the standard alert file
Format:
portscan: <network to monitor> <number of ports>
<detection period> <logdir/filename>
preprocessor portscan: 192.168.1.0/24 5 7 /var/log/portscan.log |
Figure 22 - Portscan Module Configuration Example
Another module from Patrick Mullen that modifies the portscan detection
system's operation. If you have servers which tend to trip off the
portscan detector (such as NTP, NFS, and DNS servers), you can tell portscan
to ignore TCP SYN and UDP portscans from certain hosts. The
arguments to this module are a list of IPs/CIDR blocks to be ignored.
Format:
portscan-ignorehosts: <host list>
preprocessor portscan-ignorehosts: 192.168.1.5/32 192.168.3.0/24 |
Figure 23 - Portscan Ignorehosts Module Configuration Example
The defrag module (from Dragos Ruiu) allows Snort to perform full blown
IP defragmentation, making it more difficult for hackers to simply circumvent
the detection capabilities of the system. It is very simple in its
usage, merely requiring the addition of a preprocessor directive to the
configuration file with no arguments. This module generall supercedes
the functionality of the minfrag module (i.e. you don't need to use minfrag
if you're using defrag).
Format:
defrag
Figure 24 - Defrag preprocessor configuration example
This module is still in BETA testing, use with caution!
The stream plugin provides TCP stream reassembly functionality to Snort.
TCP streams on the configured ports with small segments will be reassembled
into a stream of data that Snort can properly evaluate for suspicious activity.
This plugin takes a number of arguments:
-
timeout - the max time in seconds for which a stream will be kept alive
if we haven't seen a packet for it
-
port - a server port to monitor. we don't want to monitor all tcp
streams (do we?)
-
maxbytes - maximum bytes in our reconstructed packets
Format:
stream: timeout <timeout>, ports <ports>,
maxbytes <maxbytes>
preprocessor stream: timeout 5, ports 21 23 80 8080,
maxbytes 16384 |
Figure 25 - TCP stream reassembler configuration example
Spade:
the Statistical Packet Anomaly Detection Engine |
|
In the interest of timeliness and sanity, I'd suggest checking out the
README.Spade in the Snort distrbution as well as checking out http://www.silicondefense.com/spice/
This module allows Snort to be able to perform statistical anomaly detection
on your network, and it's essentially an entire new detection engine for
Snort. If you're interested in this kind of capability, you should
definitely read the documentation in the Snort distribution as well as
that on the SiliconDefense
site.
Output Module Overview
Output modules are new as of version 1.6. They allow Snort to
be much more flexible in the formatting and presentation of output to its
users. The output modules are run when the alert or logging subsystems
of Snort are called, after the preprocessors and detection engine. The
format of the directives in the rules file is very similar to that of the
preprocessors.
Multiple output plugins may be specified in the Snort configuration
file. When multiple plugins of the same type (log, alert) are specified,
they are "stacked" and called in sequence when an event occurs. As
with the standard logging and alerting systems, output plugins send their
data to /var/log/snort by default or to a user directed directory (using
the "-l" command line switch).
Output modules are loaded at runtime by specifying the output
keyword in the rules file:
output <name>: <options>
output alert_syslog: LOG_AUTH LOG_ALERT |
Figure 26 - Output Module Configuration Example
Available Output Modules
This module sends alerts to the syslog facility (much like the -s command
line switch). This module also allows the user to specify the logging
facility and priority within the Snort rules file, giving users greater
flexibility in logging alerts.
Available keywords:
-
Options
-
LOG_CONS
-
LOG_NDELAY
-
LOG_PERROR
-
LOG_PID
-
Facilities
-
LOG_AUTH
-
LOG_AUTHPRIV
-
LOG_DAEMON
-
LOG_LOCAL0
-
LOG_LOCAL1
-
LOG_LOCAL2
-
LOG_LOCAL3
-
LOG_LOCAL4
-
LOG_LOCAL5
-
LOG_LOCAL6
-
LOG_LOCAL7
-
LOG_USER
-
Priorities
-
LOG_EMERG
-
LOG_ALERT
-
LOG_CRIT
-
LOG_ERR
-
LOG_WARNING
-
LOG_NOTICE
-
LOG_INFO
-
LOG_DEBUG
Format:
alert_syslog: <facility> <priority> <options>
This will print Snort alerts in a quick one line format to a specified
output file. It is a faster alerting method than full alerts
because it doesn't need to print all of the packet headers to the output
file
Format:
alert_fast: <output filename>
output alert_fast: alert.fast |
Figure 27 - Fast alert configuration
Print Snort alert messages with full packet headers. This alerting
facility is generall pretty slow because it requires that the program do
a whole lot of data parsing to format the data to be printed. The
alerts will be written in the default logging directory (/var/log/snort)
or in the logging directory specified at the command line.
Format:
alert_full: <output filename>
output alert_full: alert.full |
Figure 28 - Fast alert configuration
This plugin sends WinPopup alert messages to the NETBIOS named machines
indicated within the file specified as an argument to this output plugin.
It should be noted that use of this plugin is not encouraged as
it executes an external executable binary (smbclient) at the same privilege
level as Snort, commonly root. The format of the workstation file
is a list of the NETBIOS names of the hosts that wish to receive alerts,
one per line in the file.
Format:
alert_smb: <alert workstation filename>
output alert_smb: workstation.list |
Figure 29 - SMB alert configuration
Sets up a UNIX domain socket and sends alert reports to it. External
programs/processes can listen in on this socket and receive Snort alert
and packet data in real time. This is currently an experimental interface.
Format:
alert_unixsock
Figure 30 - UnixSock alert configuration
The log_tcpdump module logs packets to a tcpdump-formatted file. This
is useful for performing post process analysis on collected traffic with
the vast number of tools that are avialable for examining tcpdump formatted
files. This module only takes a single argument, the name of the
output file.
Format:
log_tcpdump: <output filename>
output log_tcpdump: snort.log |
Figure 31 - Tcpdump Output Module Configuration Example
The XML plug-in enables snort to log in SNML - simple network markup
language aka (snort markup language) to a file or over a network.
The DTD is available in the contrib directory of the snort distribution
and at: http://www.cert.org/DTD/snml-1.0.dtd. You can use this plug-in
with on one or more snort sensors to log to a central database and create
highly configurable intrusion detection infrastructures within your network.
The plugin will also enable you to automatically report alerts to the CERT
Coordination Center, your response team, or your
managed IDS provider.
This plugin was developed by Jed Pickel and Roman Danyliw at the CERT
Coordination Center as part of the AIRCERT project.
Be aware that the SNML DTD is in its early phases of development and
is likely to be modified as it undergoes public scrutiny.
See http://www.cert.org/kb/snortxml for the most up to date information
and documentation about this plugin.
The configuration line will be of the following format:
output xml: [log | alert], [parameter list]
Arguments:
[log | alert ] - specify log or alert to connect the
xml plugin to the log or alert facility.
[parameter list] - The parameter list consists of key value pairs.
The proper format is a list of key=value pairs each separated a space.
file |
when this is the only parameter it will log to a file on the local
machine. Otherwise, if http or https is employed (see protocol),
this is the script which is to be executed on the remote host. |
protocol |
The possible values for this field are
http - send a POST over HTTP to a webserver (required:
a [file] parameter)
https - just like http but ssl encrypted and mutually authenticated.
(required: a [file], [cert], [key] parameter)
tcp - A simple tcp connection. You need to use some sort
of listener (required: a [port] parameter)
iap - An implementation of the Intrusion Alert Protocol
(This does not work yet)
|
host |
remote host where the logs are to be sent |
port |
The port number to connect to (default ports are)
http 80
https 443
tcp 9000
iap 9000
|
cert |
the client X.509 certificate to use with https (PEM formatted) |
key |
the client private key to use with https (PEM formatted) |
ca |
the CA certificate used to validate the https server's certificate
(PEM formatted) |
server |
the file containing a list of valid servers with which to communicate.
It is used so that Snort canauthenticate the peer server. Each server is
identified by a string formed by concatenating the subject of the server's
X.509 certificate. This string can be created by:
% openssl x509 -subject -in <server certificate>.
Typically only someone deploying the HTTPS will have to perform
this task (since they have access to the server certificate). This entitity
should publish this subject string for configuration inside each snort
sensor.
|
sanatize |
The argument is a a network/netmask combination for an IP range you
wish to be sanitized. Any IP address within the range you specify will
be represented as "xxx.xxx.xxx.xxx". Also, for sanitized alerts, no packet
payload will be logged. You can use the sanitize parameter multiple times
to represent multiple IP ranges. |
encoding |
Packet payload and option data is binary and there is not one standard
way to represent it as ASCII text. You can choose the binary encoding option
that is best suited for your environment. Each has its own advantages
and disadvantages:
hex: (default) Represent binary data as a hex string.
storage requirements - 2x the size of the binary
searchability....... - very good
human readability... - not readable unless you are a true geek requires
post processing
base64: Represent binary data as a base64 string.
storage requirements - ~1.3x the size of the binary
searchability....... - impossible without post processing
human readability... - not readable requires post processing
ascii: Represent binary data as an ascii string. This is the only option
where you will actually loose data. Non ascii data is represented
as a ".". If you choose this option then data for ip and tcp options will
still be represented as "hex" because it does not make any sense for that
data to be ascii.
storage requirements - Slightly larger than the binary because some
characters are escaped (&,<,>)
searchability....... - very good for searching for a text string impossible
if you want to search for binary
human readability... - very good
|
detail |
How much detailed data do you want to store? The options are:
full: (default) log all details of a packet that caused an
alert (including ip/tcp options and the payload)
fast: log only a minimum amount of data. You severely limit the potential
of some analysis applications if you choose this option, but this is still
the best choice for some applications. The following fields are logged-
(timestamp, signature, source ip, destination ip, source port, destination
port, tcp flags, and protocol)
|
Format:
xml: <output facility>
output xml: log, file=output |
output xml: log, protocol=https host=air.cert.org file=alert.snort
cert=mycert.crt key=mykey.pem ca=ca.crt server=srv_list.lst |
Figure 32 - XML output plugin setup examples
This module from Jed Pickel sends Snort data to a variety of SQL databases.
More information on installing and configuring this module can be found
on the Incident.org web page.
The arguments to this plugin are the name of the database to be logged
to and a parameter list. Parameters are specified with the format
parameter
= argument. The following parameters are available:
host |
Host to connect to. If a non-zero-length string is specified, TCP/IP
communication is used. Without a host name, it will connect using a local
Unix domain socket. |
port |
Port number to connect to at the server host, or socket filename extension
for Unix-domain connections. |
dbname |
Database name |
user |
Database username for authentication |
password |
Password used if the database demands password authentication |
sensor_name |
Specify your own name for this snort sensor. If you do not specify
a name one will be generated automatically |
encoding |
Because the packet payload and option data is binary, there is no one
simple and portable way to store it in a database. BLOBS are not used because
they are not portable across databases. So I leave the encoding option
to you. You can choose from the following options. Each has its own advantages
and disadvantages:
hex: (default) Represent binary data as a hex string.
storage requirements - 2x the size of the binary
searchability....... - very good
human readability... - not readable unless you are a true geek requires
post processing
base64: Represent binary data as a base64 string.
storage requirements - ~1.3x the size of the binary
searchability....... - impossible without post processing
human readability... - not readable requires post processing
ascii: Represent binary data as an ascii string. This is the
only option where you will actually loose data. Non ascii data is
represented as a ".". If you choose this option then data for ip and tcp
options will still be represented as "hex" because it does not make any
sense for that data to be ascii.
storage requirements - Slightly larger than the binary because
some characters are escaped (&,<,>)
searchability....... - very good for searching for a text string impossible
if you want to search for binary
human readability... - very good
|
detail |
How much detailed data do you want to store? The options are:
full: (default) log all details of a packet that caused an
alert (including ip/tcp options and the payload)
fast: log only a minimum amount of data. You severely limit
the potential of some analysis applications if you choose this option,
but this is still the best choice for some applications. The following
fields are logged - (timestamp, signature, source ip, destination ip, source
port, destination port, tcp flags, and protocol)
|
Furthermore, there is a logging method and database type that must be
defined. There are two logging types available, log and alert.
Setting the type to log attaches the database logging functionality to
the log facility within the program. If you set the type to log,
the plugin will be called on the log output chain. Setting
the type to alert attaches the plugin to the alert output chain
within the program.
There are four database types available in the current version of the
plugin are MySQL, PostgreSQL, Oracle, and unixODBC compliant databases.
Set the type to match the database you are using.
Format:
database: <log | alert>, <database type>, <parameter
list>
output database: log, mysql, dbname=snort user=snort host=localhost
password=xyz
|
Figure 33 - Database output plugin configuration
There are some general concepts to keep in mind when developing
Snort rules to maximize efficiency and speed. I will add to this
section as my muse wills. :)
Content Rules are Case Sensitive (unless
you use the "nocase" option)
Don't forget that content rules are case sensitive and that many programs
typically use uppercase letters to indicate commands. FTP is a good
example of this. Consider the following two rules:
alert tcp any any -> 192.168.1.0/24 21 (content: "user root"; msg:
"FTP root login";)
alert tcp any any -> 192.168.1.0/24 21 (content: "USER root"; msg:
"FTP root login";)
The second of those two rules will catch most every automated root login
attempt, but none that use lower case characters for "user".
Speeding Up Rules That Have Content Options
The order that rules are tested by the detection engine is completely
independent of the order that they are written in a rule. The last
rule test that is done (when necessary) is always the content rule option.
Take advantage of this fact by using other faster rule options that can
detect whether or not the content needs to be checked at all. For
instance, most of the time when data is sent from client to server after
a TCP session is established, the PSH and ACK TCP flags are set on the
packet containing the data. This fact can be taken advantage of by
rules that need to test payload content coming from the client to the sever
with a simple TCP flag test that is far less computationally expensive
than the pattern match algorithm. Knowing this, a simple way to speed
up rules that use content options is to also perform a flag test, as in
Figure 23. The basic idea is that if the PSH and ACK flags aren't
set, there's no need to test the packet payload for the given rule.
If the flags are set, the additional computing power required to perform
the test is negligible.
alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf";
flags: PA; msg: "CGI-PHF probe";)
|
Figure 34 - Using TCP Flag Tests to Hasten Content Rules
Version 1.2, All rights reserved, © Copyright 1999-2001 Martin
Roesch