byte_test
The byte_test
rule option tests a byte field against a specific value with a specified operator. This option is able to test binary values right from the packet, and it can also convert string-representations of numbers (e.g., decimal, hexadecimal, and octal-representations) for testing purposes as well.
byte_test
is declared with the keyword, followed by a colon character, followed by four required arguments separated by commas: (1) number of bytes to grab from the packet, (2) the operator to test against the bytes in the packet, (3) the value to test the bytes in the packet against, and (4) the offset of the bytes to grab. These four arguments MUST be specified in this exact order.
There are also a few optional arguments that can be declared after the four required arguments, which are also separated by commas. They are listed and described below.
Snort uses C operators for testing, and valid ones include <
, >
, <=
, >=
, =
, &
, and ^
.
The &
operator does an AND bitwise test:
if (packet_data_bytes & value)
Conversely, the ^
does an XOR bitwise test:
if (packet_data_bytes ^ value)
A byte_test
operator can also look for the negation of the test result by adding !
before the selected operator.
Note: A
byte_test
option does not move the detection cursor.
Format:
byte_test:count, [!]operator, compare, offset[, relative][, endian] \
[, string[, {dec|hex|oct}]][, dce][, bitmask bitmask];
Argument | Description |
---|---|
count | Number of bytes to pick up from the buffer (valid values include 1:10 ) |
operator | Operation to test against the bytes in the packet (valid operators include < , > , <= , >= , = , & , and ^ ) |
compare | Variable name or value to test the converted result against (valid values include 0:4294967295 and can be represented as decimal or hexadecimal) |
offset | Variable name or number of bytes into the payload to start processing (valid values include -65535:65535 ) |
relative | Offset from cursor instead of start of buffer |
endian | Set to either big or little to specify whether to process the data as little-endian or big-endian (packet bytes are processed as big-endian by default) |
dce | Use the DCE/RPC 2 inspector engine to determine the byte endianness |
string | Pick up bytes from packet that are stored in string format |
hex | Grab the string bytes in the packet from a hexadecimal string (must be accompanied by string ) |
oct | Grab the string bytes in the packet from an octal string (must be accompanied by string ) |
dec | Grab the string bytes in the packet from a decimal string (the default option when string is set) |
bitmask bitmask | Perform an AND bitwise operation with the specified bitmask on the picked-up bytes before testing it against value (valid values are 0x01:0xFFFFFFFF ) |
Note: The
bitmask
argument result will be right-shifted by the number of bits equal to the number of trailing zeros in the mask.
Examples:
content:"ABCD", depth 4;
# grabs the 2 bytes immediately after "ABCD"
# that are represented as little-endian
# and checks that those bytes are greater than 0x7fff
byte_test:2, >, 0x7fff, 0, relative, little;
# grabs 2 bytes at offset 0, performs a
# bitwise AND with 0x3FF0, right-shifts the result by 4 bits,
# and compares the final result to 568 to see if they are equal
byte_test:2, =, 568, 0, bitmask 0x3FF0;
# grabs 4 bytes af offset 0, converts those bytes
# as a decimal string, and tests that the converted number
# is greater than 1234
byte_test:4, >, 1234, 0, string, dec;
content:"AAAA";
byte_extract:4, 0, a_sz, relative;
content:"BBBB";
# grabs 4 bytes right after "BBBB"
# and tests if those bytes are greater than
# the extracted bytes from earlier
byte_test:4, >, a_sz, 0, relative;