Linux Firewalls - Michael Rash [97]
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:
content
uricontent
offset
depth
distance
within
flags
itype
icode
ttl
tos
ipopts
dsize
ip_proto
flow
replace
resp
content
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 "
uricontent
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 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.
REGULAR EXPRESSIONS AND IPTABLES
Adding some limited regular expression support to iptables (with features such as back references and repetition operations removed) has been proposed before[54] to the iptables project maintainers. 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!
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 increases.
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