Payload Keywords

Payload keywords inspect the content of a packet or a specific buffer.

content

The content keyword is the basis for all signatures. Its value must be a string between double quotes:

content: "lorem ipsum";

It is possible to use several contents in a signature.

Contents are matched on bytes. You can match on all printable characters by writing them in the content keyword. For non-printable characters, use their hexadecimal notations between pipes.

For example:

content: "GET /|69 6E 64 65 78 2E 68 74 6D 6C| HTTP/1.0";

Note that there are reserved characters you cannot use in the content keyword because they are meaningful in the signature. To match on these characters, you have to use hexadecimal notation. It is a convention to write the hexadecimal notation in upper case characters. Reserved characters are:

Character

Hexadecimal Notation

|22|

;

|3B|

:

|3A|

|

|7C|

Refer to the ASCII table for a comprehensive list of characters and their hexadecimal values.

Furthermore, it is possible to use ! for exceptions in contents.

For example:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Outdated Firefox on
Windows"; content:"User-Agent|3A| Mozilla/5.0 |28|Windows|3B| ";
content:"Firefox/3."; distance:0; content:!"Firefox/3.6.13";
distance:-10; sid:9000000; rev:1;)

Here, content:!"Firefox/3.6.13"; means that an alert will be generated if the used version of Firefox is not 3.6.13.

By default, the pattern matching is case sensitive.

nocase

If you do not want to make a distinction between uppercase and lowercase characters, you can use the nocase content modifier.

Place it after the content you want to modify, for example:

content: "abc"; nocase;

depth

The depth content modifier comes with a mandatory numeric value, for example:

depth:12;

The number after depth designates how many bytes from the beginning of the payload will be checked.

offset

The offset keyword designates from which byte on the payload will be checked for a match.

The keywords offset and depth can be combined and are often used together.

For example:

content:"def"; offset:3; depth:3;

In this example, the payload is checked from the third byte to the sixth byte.

distance

The distance keyword is a relative content modifier. This means it indicates a relation between the current content keyword and the content preceding it. distance takes effect after the preceding match.

The distance keyword comes with a mandatory signed value. This value determines the byte from which the payload will be checked for a match relative to the previous match.

distance determines where cognitix Threat Defender will start looking for a pattern. For example, distance:5; means the pattern can be anywhere after the previous match plus 5 bytes. To limit how far after the last match cognitix Threat Defender needs to look, use within.

within

The within keyword is relative to the preceding match. The keyword within comes with a mandatory positive value. Using within makes sure there will only be a match if the content matches the payload within the set amount of bytes.

isdataat

The purpose of isdataat is to look if there is still data at a specific part of the payload. The keyword starts with a positive number (the position) and optionally followed by relative separated by a comma. Use relative to know if there is still data at a specific part of the payload relative to the last match.

The following example illustrates a signature which searches for byte 512 of the payload:

isdataat:512;

The second example illustrates a signature searching for byte 50 after the last match:

isdataat:50, relative;

The option rawbytes is not supported.

dsize

With the dsize keyword, you can match on the size of the packet payload. For example, you can use the keyword to look for abnormal sizes of payloads. This may be convenient in detecting buffer overflows.

byte_test

The byte_test keyword extracts the number of bytes specified in bytes_to_convert and performs an operation selected with operator against value at offset.

Format:

byte_test:<bytes_to_convert>, [!]<operator>, <value>, <offset> \
         [, relative][, <endian>][, string, <num>][, dce]  \
         [, bitmask <bitmask_value>];
bytes_to_convert

The number of bytes selected from the packet to be converted; between 1 - 8.

value

Value to test the converted value against; between 0 - 4294967295.

offset

Number of bytes into the payload.

operator
  • ! negation, can prefix other operators

  • < less than

  • > greater than

  • = equal to

  • <= less than or equal to

  • >= greater than or equal to

  • & bitwise AND

  • ^ bitwise OR

relative

Offset relative to last content match.

endian
  • big (most significant byte at lowest address)

  • little (most significant byte at the highest address)

string

not supported

dce

not supported

bitmask

not supported

Example:

alert tcp any any -> any any (msg:" Matches User-Agent 'genua'"; \
content:"User-Agent: "; http_header; \
byte_test:5, =, 113685342544138, 0, relative, big; sid:1; rev:1)

byte_jump

The byte_jump keyword allows for the ability to select bytes_to_convert from an offset and moves the detection pointer to that position. Subsequent content matches will then be based off the new position.

Format:

byte_jump:<bytes_to_convert>, <offset> [, relative][, multiplier <mult_value>] \
      [, <endian>][, string, <number_type>][, align][, from_beginning][, from_end] \
      [, post_offset <adjustment value>][, dce][, bitmask <bitmask_value>];
bytes_to_convert

The number of bytes selected from the packet to be converted, between 1 - 8.

offset

Number of bytes into the payload.

relative

Offset relative to last content match.

multiplier

Multiplies the converted byte by the value.

endian
  • big (most significant byte at lowest address)

  • little (most significant byte at the highest address)

string

not supported

align

Rounds the number up to the next 32-bit boundary.

from_beginning

Jumps forward from the beginning of the packet, instead of where the detection pointer is set.

from_end

not supported

post_offset

After the jump operation has been performed, the specified number of bytes be will jumped additionally.

dce

not supported

bitmask

not supported

Example:

alert tcp any any -> any any (msg:"Jump on binary newline 10 bytes forward"; \
content:"/index.html HTTP/1.0\"; byte_jump:1,1,relative,big; \
content:\"genua\"; distance:0; sid:1; rev:1;)

byte_extract

Note

cognitix Threat Defender does not support this keyword.

pcre (Perl Compatible Regular Expressions)

The pcre keyword matches specifically on regular expressions.

Matching regular expressions causes a lot of processing overhead and is often combined with the content keyword. This way, the the regular expression is only run if the content matches first.

Format of pcre:

pcre:"/<regex>/opts";

In the following example, the signature will match if the payload contains six consecutive numbers:

pcre:"/[0-9]{6}/";

The following qualities of pcre can be modified:

  • By default, pcre is case-sensitive. Use i to render it case-insensitive.

  • The full stop . is a part of regex. It matches on every byte except for newline characters. Use s to have pcre check newline characters.

  • By default, the payload is inspected as one line. Use m to have one line of the payload count as two lines.

These options are Perl-compatible modifiers. To use these modifiers, add them to pcre, behind the regex. For example:

pcre: "/<regex>/i";

pcre-compatible Modifiers

There are a few pcre-compatible modifiers which can change the qualities of pcre as well:

  • A: A pattern has to match at the beginning of a buffer. (In pcre ^ is similar to A.)

  • E: Ignores newline characters at the end of the buffer/payload.

  • G: Inverts the greediness.

Note

The following characters must be escaped inside the content: ; \ "

Custom Modifiers

The following custom pcre modifiers are available:

  • R: Match relative to the last pattern match. It is similar to distance:0;.

  • I: Makes pcre match on the HTTP raw URI. It matches on the same buffer as http_raw_uri. I can be combined with R. Note that R is relative to the previous match so both matches have to be in the http-raw-uri buffer.

  • U: Synonym of I.

  • P: Makes pcre match on the HTTP request body. It matches on the same buffer as http_client_body. P can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP request body.

  • Q: Makes pcre match on the HTTP response body. It matches on the same buffer as http_server_body. Q can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP response body.

  • H: Makes pcre match on the HTTP header. H can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP header.

  • D: not supported

  • M: Makes pcre match on the request method. It matches on the same buffer as http_method. M can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP method buffer.

  • C: Makes pcre match on the HTTP cookie. It matches on the same buffer as http_cookie. C can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP cookie buffer.

  • S: not supported

  • Y: Makes pcre match on the HTTP reason phrase. It matches on the same buffer as http_stat_msg. Y can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP reason phrase buffer.

  • B: Compatibility pcre modifier. This modifier has no effect.

  • O: not supported

  • V: Makes pcre match on the HTTP user agent. It matches on the same buffer as http_user_agent. V can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP User-Agent buffer.

  • W: Makes pcre match on the HTTP host. It matches on the same buffer as http_host. W can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP host buffer. This pcre modifier is always case-insensitive.

  • Z: Makes pcre match on the HTTP raw host buffer. It matches on the same buffer as http_raw_host. Z can be combined with R. Note that R is relative to the previous match so both matches have to be in the HTTP raw host buffer.