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 number of bytes.
startswith
The startswith
keyword is similar to depth:<length of pattern>;
. It takes no arguments
and must follow a content
keyword. It modifies the content
to match
exactly at the start of a buffer.
Example:
content:"GET|20|"; startswith;
startswith
is a short hand notation for:
content:"GET|20|"; depth:4; offset:0;
startswith
cannot be mixed with depth
, offset
, within
or
distance
for the same pattern.
endswith
The endswith
keyword is similar to isdataat:!1,relative;
. It takes no
arguments and must follow a content
keyword. It modifies the content
to
match exactly at the end of a buffer.
Example:
content:".php"; endswith;
endswith
is a short hand notation for:
content:".php"; isdatat:!1,relative;
Note
You can combine startswith
and endswith
to check whether a pattern fills
the complete buffer. Example:
http.uri; content:"/index.html"; startswith; endswith;
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.
bsize
With the bsize
keyword, you can match on the length of the buffer to add precision to the content match.
Previously this could be done with isdataat
.
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'"; \
http.header; content:"User-Agent: "; \
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 regular expression is only run if the content
matches first.
Format of pcre
:
pcre:"/<regex>/<modifiers>";
In the following example, the signature will match if the payload contains six consecutive numbers:
pcre:"/[0-9]{6}/";
Note
The following characters must be escaped inside the content:
;
\
"
Perl/PCRE-compatible Modifiers
The matching behavior and the syntax interpretation of PCREs can be altered by several flags. The ones supported are listed here, with a short description and their internal PCRE name in parentheses.
i
(PCRE_CASELESS)If this modifier is set, letters in the pattern match both upper- and lowercase letters.
m
(PCRE_MULTILINE)By default, PCRE treats the subject string as consisting of a single “line” of characters (even if it actually contains several newlines). The “start of line” metacharacter (
^
) matches only at the start of the string, while the “end of line” metacharacter ($
) matches only at the end of the string, or before a terminating newline (unlessE
modifier is set). When this modifier is set:^
additionally matches after every newline character (and the start of the string)$
additionally matches before every newline character (and the end of the string)
If there are no
\n
characters in a subject string, or no occurrences of^
or$
in a pattern, setting this modifier has no effect.
s
(PCRE_DOTALL)If this modifier is set, a dot metacharacter in the pattern matches all characters, including newlines. Without it, newlines are excluded. A negative class such as
[^a]
always matches a newline character, independent of the setting of this modifier.
x
(PCRE_EXTENDED)If this modifier is set, whitespace characters in the pattern are totally ignored except when escaped or inside a character class. In this mode,
#
also introduces a line comment (that extends to the next\n
character (inclusive)).#
characters that are escaped or inside a character class are treated as normal. Whitespace characters may never appear within special character sequences in a pattern, for example within the sequence(?(
which introduces a conditional subpattern.
A
(PCRE_ANCHORED)If this modifier is set, the pattern is forced to be “anchored”, that is, it is constrained to match only at the start of the string which is being searched (the “subject string”). This effect can also be achieved by appropriate constructs (
^
) in the pattern itself.
E
(PCRE_DOLLAR_ENDONLY)If this modifier is set, a dollar metacharacter in the pattern matches only at the end of the subject string. Without this modifier, a dollar also matches immediately before the final character if it is a newline (but not before any other newlines). This modifier is ignored if
m
modifier is set.
Note
This modifier is sometimes represented with the letter D
(e.g. PHP).
G
(PCRE_UNGREEDY)This modifier inverts the “greediness” of the quantifiers so that they are not greedy by default, but become greedy if followed by
?
. It can also be set by a(?U)
modifier setting within the pattern. This can also be achieved by inverting the greediness of every quantifier individually by appending a question mark (e.g..*
->.*?
,.+
->.+?
,x?
->x??
).
Note
This modifier is usually represented with the letter U
.
Custom Modifiers
The following custom modifiers are available:
R
: Match relative to the last pattern match. It is similar todistance:0;
.B
: Compatibilitypcre
modifier. This modifier has no effect.O
: not supported
Custom Target Modifiers
There are several custom modifiers available to specify the buffer the pattern should match on. These stem mostly from the time modifier keywords were used to specify the target buffer, instead of the now prevalent sticky buffer keywords. They should be considered deprecated and the use of sticky buffer keywords should be preferred.
C
: Matches on the same buffer ashttp.cookie
.D
: not supportedH
: Matches on the same buffer ashttp.header
.I
: Matches on the same buffer ashttp.uri.raw
.M
: Matches on the same buffer ashttp.method
.P
: Matches on the same buffer ashttp.request_body
.Q
: Matches on the same buffer ashttp.response_body
.S
: Matches on the same buffer ashttp.stat_code
.U
: Synonym ofI
.V
: Matches on the same buffer ashttp.user_agent
.W
: Matches on the same buffer ashttp.host
.Y
: Matches on the same buffer ashttp.stat_msg
.Z
: Matches on the same buffer ashttp.host.raw
.