next up previous contents
Next: 3.6 Non-payload Detection Rule Up: 3. Writing Snort Rules Previous: 3.4 Meta-Data Rule Options   Contents

Subsections

3.5 Payload Detection Rule Options


3.5.1 content

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 is 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 ($\vert$) character and represented as bytecode. Bytecode represents binary data as hexadecimal numbers and is a good shorthand method for describing complex binary data. Figure [*] contains an example of mixed text and binary data in a Snort rule.

Note that multiple content rules can be specified in one rule. This allows rules to be tailored for less false positives.

If the rule is preceded by a !, the alert will be triggered on packets that do not contain this content. This is useful when writing rules that want to alert on packets that do not match a certain pattern



$\triangle$ $^!$ NOTE


\fbox{
\usebox{
\savepar
}
}

3.5.1.1 Format

content: [!] "<content string>";

3.5.1.2 Example

Figure: Mixed Binary Bytecode and Text in a 'content' keyword
\begin{figure}\begin{verbatim}alert tcp any any -> any 139 (content:''\vert 5c...
...t0\vert I\vert0\vert P\vert0\vert E\vert0 5c\vert'';)\end{verbatim}
\end{figure}

Figure: Negation Example
\begin{figure}\begin{verbatim}alert tcp any any -> any 80 (content:!''GET'';)\end{verbatim}
\end{figure}

3.5.1.3 Changing content behavior

The content keyword has a number of modifier keywords. The modifier keywords change how the previously specified content works. These modifier keywords are:

68.
depth
69.
offset
70.
distance
71.
within
72.
nocase
73.
rawbytes

3.5.2 nocase

The nocase keyword allows the rule writer to specify that the Snort should look for the specific pattern, ignoring case. nocase modifies the previous 'content' keyword in the rule.

3.5.2.1 Format

nocase;

3.5.2.2 Example

Figure: Content rule with nocase modifier
\begin{figure}\begin{verbatim}alert tcp any any -> any 21 (msg:''FTP ROOT''; content:''USER root''; nocase;)\end{verbatim}
\par\end{figure}


3.5.3 rawbytes

The rawbytes keyword allows rules to look at the raw packet data, ignoring any decoding that was done by preprocessors. This acts as a modifier to the previous content [*] option.

3.5.3.1 format

rawbytes;

3.5.3.2 Example

This example tells the content pattern matcher to look at the raw traffic, instead of the decoded traffic provided by the telnet decoder.

alert tcp any any -> any 21 (msg: "Telnet NOP"; content: "|FF F1|"; rawbytes;)


3.5.4 depth

The depth keyword allows the rule writer to specify how far into a packet Snort should search for the specified pattern. depth modifies the previous `content' keyword in the rule.

A depth of 5 would tell Snort to only look look for the specified pattern within the first 5 bytes of the payload.

As the depth keyword is a modifier to the previous `content' keyword, there must be a content in the rule before `depth' is specified.

See Figure [*] for an example of a combined content, offset, and depth search rule.

3.5.4.1 Format

depth: <number>;

3.5.5 offset

The offset keyword allows the rule writer to specify where to start searching for a pattern within a packet. offset modifies the previous 'content' keyword in the rule.

An offset of 5 would tell Snort to start looking for the specified pattern after the first 5 bytes of the payload.

As this keyword is a modifier to the previous 'content' keyword, there must be a content in the rule before 'offset' is specified.

See Figure [*] for an example of a combined content, offset, and depth search rule.

3.5.5.1 Format

offset: <number>;

Figure: Combined Content, Offset and Depth Rule. Skip the first 4 bytes, and look for cgi-bin/phf in the next 20 bytes
\begin{figure}\begin{verbatim}alert tcp any any -> any 80 (content: ''cgi-bin/phf''; offset:4; depth:20;)\end{verbatim}
\par\end{figure}


3.5.6 distance

The distance keyword allows the rule writer to specify how far into a packet Snort should ignore before starting to search for the specified pattern relative to the end of the previous pattern match.

This can be thought of as exactly the same thing as depth (See Section [*]), except it is relative to the end of the last pattern match instead of the beginning of the packet.

3.5.6.1 Format

distance: <byte count>;

3.5.6.2 Example

The rule listed in Figure [*] maps to a regular expression of /ABCDE.{1}EFGH/.

Figure: distance usage example
\begin{figure}\begin{verbatim}alert tcp any any -> any any (content:''ABC''; content: ''DEF''; distance:1;)\end{verbatim}
\end{figure}


3.5.7 within

The within keyword is a content modifier that makes sure that at most N bytes are between pattern matches using the Content ( See Section [*] ). It's designed to be used in conjunction with the distance (Section [*]) rule option.

The rule listed in Figure [*] constrains the search to not go past 10 bytes past the ABCDE match.

3.5.7.1 Format

within: <byte count>;

3.5.7.2 Examples

Figure: within usage example
\begin{figure}\begin{verbatim}alert tcp any any -> any any (content:''ABC''; content: ''EFG''; within:10;)\end{verbatim}
\end{figure}

3.5.8 uricontent

The uricontent parameter in the Snort rule language searches the NORMALIZED request URI field. This means that if you are writing rules that include things that are normalized, such as %2f or directory traversals, these rules will not alert. The reason is that the things you are looking for are normalized out of the URI buffer.

For example, the URI:

/scripts/..%c0%af../winnt/system32/cmd.exe?/c+ver\end{verbatim}
will get normalized into:
\begin{verbatim}/winnt/system32/cmd.exe?/c+ver

Another example, the URI:
\begin{verbatim} /cgi-bin/aaaaaaaaaaaaaaaaaaaaaaaaaa/..%252fp%68f? \end{verbatim}
will get normalized into:
\begin{verbatim}/cgi-bin/phf?

When writing a uricontent rule, write the content that you want to find in the context that the URI will be normalized. For example, if Snort normalizes directory traversals, do not include directory traversals.

You can write rules that look for the non-normalized content by using the content option. (See Section [*])

For a description of the parameters to this function, see the content rule options in Section [*].

This option works in conjunction with the HTTP Inspect preprocessor specified in Section [*].

3.5.8.1 Format

uricontent:[!]<content string>;

3.5.9 isdataat

Verify that the payload has data at a specified location, optionally looking for data relative to the end of the previous content match.

3.5.9.1 Format

isdataat:<int>[,relative];

3.5.9.2 Example

alert tcp any any -> any 111 (content:"PASS"; isdataat:50,relative; \ 
   content:!"|0a|"; distance:0;)
This rule looks for the string PASS exists in the packet, then verifies there is at least 50 bytes after the end of the string PASS, then verifies that there is not a newline character within 50 bytes of the end of the PASS string.


3.5.10 pcre

The pcre keyword allows rules to be written using perl compatible regular expressions. For more detail on what can be done via a pcre regular expression, check out the PCRE web site http://www.pcre.org

3.5.10.1 Format

pcre:[!]"(/<regex>/|m<delim><regex><delim>)[ismxAEGRUB]";
The post-re modifiers set compile time flags for the regular expression.

Table: Perl compatible modifiers
i case insensitive
s include newlines in the dot metacharacter
m By default, the string is treated as one big line of characters. ^ and $ match at the beginning and ending of the string. When m is set, ^ and $ match immediately following or immediately before any newline in the buffer, as well as the very start and very end of the buffer.
x whitespace data characters in the pattern are ignored except when escaped or inside a character class

Table: PCRE compatible modifiers
A the pattern must match only at the start of the buffer (same as ^ )
E Set $ to match only at the end of the subject string. Without E, $ also matches immediately before the final character if it is a newline (but not before any other newlines).
G Inverts the "greediness" of the quantifiers so that they are not greedy by default, but become greedy if followed by "?".

Table: Snort specific modifiers
R Match relative to the end of the last pattern match. (Similar to distance:0;)
U Match the decoded URI buffers (Similar to uricontent)
B Do not use the decoded buffers (Similar to rawbytes)

The modifiers R and B should not be used together.

3.5.10.2 Example

This example performs a case-insensitive search for the string BLAH in the payload.

alert ip any any -> any any (pcre:"/BLAH/i";)


3.5.11 byte_test

Test a byte field against a specific value (with operator). Capable of testing binary values or converting representative byte strings to their binary equivalent and testing them.

For a more detailed explanation, please read Section [*].

3.5.11.1 Format

byte_test: <bytes to convert>, [!]<operator>, <value>, <offset>  \
    [,relative] [,<endian>] [,<number type>, string];

Option Description
bytes_to_convert Number of bytes to pick up from the packet
operator Operation to perform to test the value:
  • $<$ - less than
  • $>$ - greater than
  • = - equal
  • ! - not
  • & - bitwise AND
  • - bitwise OR
value Value to test the converted value against
offset Number of bytes into the payload to start processing
relative Use an offset relative to last pattern match
endian Endian type of the number being read:
  • big - Process data as big endian (default)
  • little - Process data as little endian
string Data is stored in string format in packet
number type Type of number being read:
  • hex - Converted string data is represented in hexadecimal
  • dec - Converted string data is represented in decimal
  • oct - Converted string data is represented in octal

Any of the operators can also include ! to check if the operator is not true. If ! is specified without an operator, then the operator is set to =.



$\triangle$ $^!$ NOTE


\fbox{
\usebox{
\savepar
}
}

Figure: Byte Test Usage Example
\begin{figure}\begin{verbatim}alert udp $EXTERNAL_NET any -> $HOME_NET any \
...
...deadbeef, 0, string, hex; \
msg: ''got DEADBEEF!'';)\end{verbatim}
\end{figure}


3.5.12 byte_jump

The byte_jump option allows rules to be written for length encoded protocols trivially. By having an option that reads the length of a portion of data, then skips that far forward in the packet, rules can be written that skip over specific portions of length-encoded protocols and perform detection in very specific locations.

The byte_jump option does this by reading some number of bytes, convert them to their numeric representation, move that many bytes forward and set a pointer for later detection. This pointer is known as the detect offset end pointer, or doe_ptr.

For a more detailed explanation, please read Section [*].

3.5.12.1 Format

byte_jump: <bytes_to_convert>, <offset> \
        [,relative] [,multiplier <multiplier value>] [,big] [,little][,string]\
        [,hex] [,dec] [,oct] [,align] [,from_beginning];

Option Description
bytes_to_convert Number of bytes to pick up from the packet
offset Number of bytes into the payload to start processing
relative Use an offset relative to last pattern match
multiplier $<$value$>$ Multiply the number of calculated bytes by $<$value$>$ and skip forward that number of bytes.
big Process data as big endian (default)
little Process data as little endian
string Data is stored in string format in packet
hex Converted string data is represented in hexadecimal
dec Converted string data is represented in decimal
oct Converted string data is represented in octal
align Round the number of converted bytes up to the next 32-bit boundary
from_beginning Skip forward from the beginning of the packet payload instead of from the current position in the packet.

Figure: byte jump Usage Example
\begin{figure}\begin{verbatim}alert udp any any -> any 32770:34000 (content: '...
...ve; \
msg: ''statd format string buffer overflow'';)\end{verbatim}
\end{figure}

3.5.13 regex

The regex keyword has been superceded by PCRE. See Section [*].

3.5.14 content-list

The content-list keyword is broken and should not be used.


next up previous contents
Next: 3.6 Non-payload Detection Rule Up: 3. Writing Snort Rules Previous: 3.4 Meta-Data Rule Options   Contents