Friday, August 26, 2011

Snort 2.9.1: Where does file_data point?

For the first article in our Snort 2.9.1 series, we thought we'd talk about file_data. Its function has changed from Snort version 2.9.0.5, so it's important that we discuss the differences.

Where does file_data point?

Prior to Snort 2.9.1:

* In the earlier versions of Snort, file_data pointed to one of the following:
  1. The decompressed/dechunked/normalized HTTP response body (when the data was chunked/compressed/encoded)
  2. SMTP attachments or data body when file_data was used with the argument "mime".
In Snort 2.9.1:

* file_data will set the cursor used for detection to one of the following buffers based on the traffic.

1. HTTP response body (Raw/encoded/chunked/compressed)

Example:
Consider the following HTTP response:

HTTP/1.0 200 OK
Date: Wed, 24 Aug 2011 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354
<html>
<body>
<h1>Snort 2.9.1 released!</h1>
(more file contents)
.
.
.

</body>
</html>

For this packet file_data points to the start of the HTML text. This response body can be chunked/compressed/encoded/etc, and in such cases, file_data points to the dechunked/decompressed/normalized data.

2. SMTP/POP/IMAP data body.

When the traffic is SMTP/POP/IMAP the file_data points to the decoded attachments when decoding is enabled for those preprocessors, otherwise to the entire data body.

The argument "mime" to file_data is deprecated. However, rules that use this argument will still function as they did before.

How does file_data work?

Prior to Snort 2.9.1:

* file_data had to be followed by a relative rule option. Any absolute (non relative) rule options start their search from the beginning of the payload. To access the file_data buffer again, a rule had to specify file_data rule option again.

Examples:
Rules that will work

alert tcp any any -> any any (file_data; content:"<html>"; within:10; ...)
alert tcp any any -> any any (file_data; content:"HTTP/1.0"; depth:10; file_data; content:"<html>"; within:10; ...)

Rules that will not work

alert tcp any any -> any any (file_data; content:"<html>"; depth:10; content:"<body>"; within:10;...)
alert tcp any any -> any any (file_data; content:"<html>"; depth:10;...)

In Snort 2.9.1:

* Any non-HTTP (without the HTTP modifiers http_uri/http_header/etc.) content matches (relative or absolute) without the keyword "rawbytes" or payload detecting rule options that follow the file_data in a rule will apply to the cursor set by file_data until explicitly reset by other rule options such as pkt_data/base64_data/SIP modifiers.

A new rule option in Snort 2.9.1, "pkt_data", will reset the cursor to the start of the TCP payload. This rule option is intended to give the rule writer the ability to change the context of subsequent detection options. Any content matches (excluding HTTP/rawbytes) and other detection options (such as "byte_test", "byte_jump", etc.) will apply to the TCP payload.

Other rule options that change the cursor are base64_data, sip_header, sip_body, etc.

Example:
Rules that will work

alert tcp any any -> any any (file_data; content:"<html>"; within:10; ...)
alert tcp any any -> any any (file_data; content:"<html>"; ...)
alert tcp any any -> any any (file_data; content:"<html>"; depth:10; content:"<body>"; within:10;...)
alert tcp any any -> any any (file_data; content:"<html>"; depth:10;...)
alert tcp any any -> any any (file_data; content:"<html>"; within:10; pkt_data; content:"HTTP/1.0"; depth:10; ....)

Rules that will not work

alert tcp any any -> any any (file_data; content:"<html>"; depth:10; rawbytes;...)
alert tcp any any -> any any (file_data; pkt_data; content:"<html>"; depth:10; rawbytes;...)