Snort Options and iptables Packet Filtering

So far, we have discussed those Snort rule options for which there is only logging support in iptables. Now we'll look at Snort rule options for which iptables also provides both explicit matching and filtering support. Snort rules that use these options can be translated into equivalent iptables rules (subject to certain constraints discussed later in this section), and any of the standard iptables targets (DROP, LOG, REJECT, and so on) can be applied to a matching packet. Snort rule options that fall into this category include:






ip proto












The content option in the Snort rules language requires an argument in the form of a sequence of bytes, say /bin/sh, and Snort uses the Boyer-Moore string search algorithm to search application layer data for these bytes. The iptables string match extension uses an in-kernel implementation of the same algorithm (selected by the user) to also search for sequences of bytes within the application payload of packets as they enter into the networking stack.

Given the string "/bin/sh" in a content option within a Snort rule, the equivalent iptables arguments are -m string --string --algo bm "/bin/sh". For example, the following Snort rule detects when the string "/bin/sh" is directed at a DNS server over UDP port 53:

alert udp any any -> any 53 (msg: "DNS /bin/sh attempt"; content: "/bin/sh"; sid: 100001)

This Snort rule can be cleanly translated into an equivalent iptables rule by executing:

[iptablesfw]# iptables -A FORWARD -p udp --dport 53 -m string --string "/bin/sh" --algo bm -j LOG --log-prefix "SID100001 "


The uricontent Snort option enables Snort to handle URL-encoded application data that is transferred over HTTP. This option is integrated directly with the Snort rules language (as opposed to only being implemented in a preprocessor) because of the rise in importance of web-application communications and the subsequent need to detect attacks that target these applications. An attack against a webserver that supports URL-encoded data


Adding some limited regular expression support to iptables (with features such as back references and repetition operations removed) has been proposed before* to the iptables project maintained. However, implementing a generalized regular expression engine within the kernel such as a nondeterministic finite automaton or NFA (similar to what is used in various languages, utilities, and editors such as Perl, Python, GNU Emacs, vi, and grep) is a risky proposition. Sometimes it is possible to construct some pathological data for which the run time of a particular regular expression against the data can be in the thousands of years. We don't want to make it easy to crash the entire kernel simply by waving a maliciously constructed packet past the system interfaces!

* See the L7-filter packet classifier project at

can take any form that it wishes within the constraints of the encoding scheme, and the result is that an attack can exhibit a degree of variability on the wire that can be difficult to decode without a way to normalize the data. For example, the string "/bin/sh" and its URL-encoded equivalent "%2f%62%69%6e%2f%73%68" are absolutely identical in the eyes of a webserver after the decoding process, and yet these raw byte sequences look completely different on the wire. Strictly speaking, there is no direct translation for the uricontent Snort option within iptables, because the string match extension cannot decode URL-encoded data directly.

While the encoded string "%2f%62%69%6e%2f%73%68" can be included by fwsnort within a separate rule, an attacker can sidestep this just by mixing the encoding—for example, the attacker could send "/bin2f%73%68". The number of possible encodings for a string n characters long quickly gets large as n

However, at the same time, there is no requirement on the part of an attacker to URL-encode an attack at all, and seeing the string "/bin/sh" in the HTTP stream is suspicious—whether it is encoded or not. In addition, certain automated attacks may not include the ability to change the encoding of a portion of an exploit sent against a webserver, so a single string is all that is needed to detect the attack. Thus, fwsnort equates the content and uricontent Snort options, although clearly this comes at the expense of potentially missing URL-encoded attacks.


The offset Snort option instructs Snort to begin application content matching operations at a specified number of bytes past the beginning of the payload data within a packet. This is an absolute number that applies to all content matches in the Snort rule, and it is not subject to the relative number of bytes between multiple content matches (the distance Snort option is used for this). The offset option is supported in iptables by using the --from command-line argument to the string match extension when looking for a pattern in payload data (this is only supported in kernel versions 2.6.14


and later). The following example constructs an iptables rule that drops all TCP packets destined for port 80 that contain the string "/etc/passwd" in the packet payload anywhere after the hundredth byte:7

[iptablesfw]# iptables -A INPUT -p tcp --dport 80 -m string --string "/etc/ passwd" --from 100 --algo bm -j DROP


The depth Snort option requires that all attempts to match content within packet payload data do not exceed a specified number of bytes beyond the beginning of the payload. Like the offset option above, using the depth criteria within a Snort rule applies globally to all content matches. To search for patterns that cannot be more than a given number of bytes apart, one would use the within Snort rule option. For kernel versions 2.6.14 and later, the --to command-line argument to the string match extension is used to emulate the depth option within iptables.

The following example demonstrates the usage of the --to command-line argument to have iptables drop all TCP packets destined for port 80 that contain the string "/etc/passwd" within the packet payload anywhere before the thousandth byte:

[iptablesfw]# iptables -A INPUT -p tcp --dport 80 -m string --string "/etc/ passwd" --to 1000 --algo bm -j DROP


The distance option is used by Snort to specify the number of bytes to skip between pattern matches. There is no direct way to tell the string match extension how many bytes to skip from a previous pattern match, but fwsnort uses an approximation based on the length of the previous pattern match and any offset modifier. To disable the translation of Snort rules that contain the distance keyword, you can use the --strict option on the fwsnort command line.


The within option instructs Snort to require that a subsequent pattern match after an initial match must take place within a specified number of bytes. This is similar to the distance option and is supported in fwsnort by making an approximation based on the length of the previous pattern (--strict on the fwsnort command line disables this behavior).


The flags Snort option applies a search criteria to the control bits in the TCP header. The control bits vary depending on the state of a TCP connection, and iptables can match specific combinations via the --tcp-flags argument.

7 Technically, the iptables - -from and - -to arguments to the string match apply at the beginning of the data link layer MAC fields on Ethernet networks.

For example, the Snort rule to detect an Nmap OS fingerprint attempt uses the flags option to search for the Syn, Fin, Push, and Urg flags in the TCP header. The equivalent arguments to the iptables binary are -p tcp --tcp-flags SYN, FIN,PSH,URG SYN,FIN,PSH,URG. The --tcp-flags command-line switch requires two arguments: a list of the flags that should be inspected, followed by a list of those flags that must actually be set. This allows the first argument to act as a mask for the set flag bits that must be examined.

No special kernel configuration option is required to make use of the --tcp-flags option, because it is built in to the core TCP-handling code within iptables. The following example illustrates an iptables rule that detects when a TCP packet has both the SYN and FIN flags set:

[iptablesfw]# iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j LOG --log-prefix "SCAN SYN FIN "

itype and icode

Both the itype and icode options match specified numeric values within the 8-bit ICMP type and code fields, respectively, of the ICMP header. For example, to test for ICMP fragmentation-needed packets within a Snort rule, we would use the options itype: 3; icode: 4;. The specific numeric values that map to the various ICMP types and codes are defined in RFC 792 (see http://www.faqs .org/rfcs/rfc792.html). The iptables ICMP-handling code supports matching against the type and code fields within the ICMP header via the arguments -p icmp --icmp-type type/code, where type/code is the proper ICMP message type spelled out (i.e., source-quench) or its equivalent numeric value. A complete list of all ICMP message types supported by iptables can be obtained by executing # iptables -p icmp -h (this output is quite long and is thus not included here), and their corresponding numeric values can be found within the icmp_codes[] array in the extensions/libipt_icmp.c file within the iptables sources.

Both the Snort itype and icode options support ranges of ICMP types and codes through the use of the < and > operators. For example, to match against all ICMP messages that have a type greater than 10 and code less than 30, one would use itype: >10; icode: <30; within a Snort rule. Unfortunately, the iptables ICMP match does not allow the notion of ranges for the ICMP type or code fields, but it should be noted that no default Snort rules use an itype range, and less than one percent use an icode range.

The following example iptables rule drops all ICMP source-quench messages:

[iptablesfw]# iptables -A INPUT -p icmp --icmp-type 4/0 -j DROP

The ttl option allows Snort to match against the Time-to-Live (TTL) value in the IP header. The ttl option is quite flexible and allows the TTL header value to be compared against a specified integer value where the supported comparisons are less than, equal to, or greater than.

For example, to match a TTL value in the IP header that is exactly 30, the Snort rule option ttl:30; would be given. To match only if the TTL value is less than 30, the option ttl:<30; would suffice, and finally, to match only if the TTL value is greater than 30, we would include ttl:>30;. These operations are supported by iptables with its TTL match via the arguments: -m ttl --ttl-lt value, -m ttl --ttl-eq value, and -m ttl --ttl-gt value, as displayed in the iptables help output:

[iptablesfw]# iptables -m ttl -h TTL match v1.3.7 options:

--ttl-eq value Match Time-to-Live value

--ttl-lt value Match TTL < value

--ttl-gt value Match TTL > value

The iptables TTL match is only available if CONFIG_IP_NF_MATCH_TTL is enabled within the kernel configuration file. An example iptables rule that detects and logs all IP packets with a TTL value of zero can be built as follows:

[iptablesfw]# iptables -A INPUT -p ip -m ttl --ttl-eq 0 -j LOG --log-prefix "ZERO TTL TRAFFIC "

The tos option instructs Snort to inspect the Type Of Service (TOS) bits within the IP header, and this option is relatively simple in Snort since it can only accept a numeric value with an optional ! to negate it. This option is supported by the iptables TOS match with the arguments -m tos --tos value. The TOS match also supports negation, as displayed in the help output:

[iptablesfw]# iptables -m tos -h TOS match v1.3.7 options:

[!] --tos value Match Type of Service field from one of the following numeric or descriptive values: Minimize-Delay 16 (0x10) Maximize-Throughput 8 (0x08) Maximize-Reliability 4 (0x04) Minimize-Cost 2 (0x02) Normal-Service 0 (0x00)

The example command below logs all IP packets that have a TOS value of 16 (Minimize-Delay):

[iptablesfw]# iptables -A INPUT -p ip -m tos --tos 16 -j LOG --log-prefix "MIN-DELAY TOS "


The ipopts Snort option allows searching criteria to be applied to the options portion of the IP header. Although IP options are rarely used in legitimate IP traffic, detecting attempts to use source routing IP options (which an attacker may use in an attempt to route packets through otherwise unreachable networks) is important. Snort supports several tests of the IP options header fields that cannot be emulated within iptables. However, the important tests for the source routing options are supported with the iptables ipv4options match available via patch-o-matic.

For example, to test for the Loose Source Route option, the arguments -m ipv4options --lsrr would be given to iptables. To detect the Strict Source Route option, we would use -m ipv4options --ssrr. To detect the Record Route option, which can be used to assist in the mapping of networks, we would use -m ipv4options --rr (see the complete iptables command example below). The ipv4options match requires that CONFIG_IP_NF_MATCH_IPV4OPTIONS is enabled in the kernel configuration file.

[iptablesfw]# iptables -A INPUT -p ip -m ipv4options --rr -j LOG --log-prefix "RECORD ROUTE IP OPTION "

Was this article helpful?

0 0

Post a comment