byte_math

The byte_math operation extracts bytes from the packet, performs a mathematical operation on the extracted value with specified value or existing variable, and stores the outcome in a new variable. These variables can be referenced later in the rule in the same places that byte_extract variables can be used.

byte_math is declared with the keyword, followed by a colon character, followed by five required arguments separated by commas: (1) "bytes" followed by the number of bytes to extract from the packet, (2) "offset" followed by the offset of the bytes to extract, (3) "oper" followed by the mathematical operation to perform on the extracted value, (4) "rvalue" followed by the value to use with the mathematical operation on the extracted value, and (5) "result" followed by the name of variable that will receive the final result.

There are also a few additional optional arguments that are listed and described below in the formatting section.

Valid math operations that can be used in this option include +, -, *, /, <<, and >>.

Note: The byte_math option does not move the detection cursor forward.

Note: byte_math operations are performed on unsigned 32-bit values, and this should be taken into consideration when writing rules to avoid integer wrap arounds.

Format:

byte_math:bytes count, offset offset, oper operator, rvalue rvalue, result result \
          [, relative][, endian endian][, string[, {dec|hex|oct}]][, dce] \
          [, bitmask bitmask];
ArgumentDescription
countNumber of bytes to pick up from the buffer (valid values include 1:10 if string argument is used and 1:4 if string argument is not used)
offsetVariable name or number of bytes into the buffer to start processing (valid values include (valid values include -65535:65535)
operatorMathematical operation to perform on the extracted value (valid operations include +, -, *, /, <<, and >>)
rvalueValue to use the mathematical operation with the extracted bytes (valid values include 1:4294967295 or an extracted byte_extract variable)
resultName of the variable to store the result in
relativeOffset relative from cursor instead of start of buffer
endian 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 (must be followed by , hex, , oct, or , dec)
hexExtract the string bytes in the packet from a hexadecimal string (must be accompanied by string)
octExtract the string bytes in the packet from an octal string (must be accompanied by string)
decExtract the string bytes in the packet from a decimal string (must be accompanied by string)
bitmask bitmaskPerform an AND bitwise operation with the specified bitmask on the extracted bytes before executing the math operation (valid values are 1:count)

Note: If using either the << or >> operation, then (1) the count value must be between 1 and 4 bytes, and (2) the rvalue must be less than 32.

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:

# extracts 2 bytes at offset 0, multiplies the extracted number by 10,
# and stores the result in the variable "area", and then uses
# the resulting variable in a `byte_test` option
byte_math:bytes 2, offset 0, oper *, rvalue 10, result area;
byte_test:2, >, area, 16;
http_header; 
content:"Content-Length: ",nocase;
# extracts 8 decimal string bytes immediately after "Content-Length: " (if they exist), multiplies
# the value by 10, and stores the result in "content_length"
byte_math:bytes 8, offset 0, oper *, rvalue 10, result content_length, relative, string dec;
content:"ABCD";
# this is a valid byte_math option despite the odd ordering of the arguments
# extracts a single byte 10 bytes from the previous match, adds 10 to it,
# performs on it a bitwise AND with 0x12, and stores the result in "var"
byte_math:oper +, rvalue 10, offset 10, result var, bytes 1, bitmask 0x12, relative;