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
countNumber of bytes to pick up from the buffer (valid values include 1:10)
operatorOperation to test against the bytes in the packet (valid operators include <, >, <=, >=, =, &, and ^)
compareVariable name or value to test the converted result against (valid values include 0:4294967295 and can be represented as decimal or hexadecimal)
offsetVariable name or number of bytes into the payload to start processing (valid values include -65535:65535)
relativeOffset from cursor instead of start of buffer
endianSet 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)
dceUse the DCE/RPC 2 inspector engine to determine the byte endianness
stringPick up bytes from packet that are stored in string format
hexGrab the string bytes in the packet from a hexadecimal string (must be accompanied by string)
octGrab the string bytes in the packet from an octal string (must be accompanied by string)
decGrab the string bytes in the packet from a decimal string (the default option when string is set)
bitmask bitmaskPerform an AND bitwise operation with the specified bitmask on the picked-up bytes before testing it against value (valid values are 1:count)

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;