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];
Argument | Description |
---|---|
count | Number 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) |
offset | Variable name or number of bytes into the buffer to start processing (valid values include (valid values include -65535:65535 ) |
operator | Mathematical operation to perform on the extracted value (valid operations include + , - , * , / , << , and >> ) |
rvalue | Value to use the mathematical operation with the extracted bytes (valid values include 1:4294967295 or an extracted byte_extract variable) |
result | Name of the variable to store the result in |
relative | Offset relative from cursor instead of start of buffer |
endian 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 (must be followed by , hex , , oct , or , dec ) |
hex | Extract the string bytes in the packet from a hexadecimal string (must be accompanied by string ) |
oct | Extract the string bytes in the packet from an octal string (must be accompanied by string ) |
dec | Extract the string bytes in the packet from a decimal string (must be accompanied by string ) |
bitmask bitmask | Perform an AND bitwise operation with the specified bitmask on the extracted bytes before executing the math operation (valid values are 0x01:0xFFFFFFFF ) |
Note: If using either the
<<
or>>
operation, then (1) thecount
value must be between 1 and 4 bytes, and (2) thervalue
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;