offset, depth, distance, and within

These four content modifiers, depth, offset, distance, and within, let rule writers specify where to look for a given pattern relative to either the start of a packet or a previous content match. These four options, however, let users write nuanced rules to look for matches at specific locations. More specifically, depth and offset are used to look for a match relative to the start of a packet or buffer, whereas distance and within are instead relative to a previous content match.

offset

The offset modifier allows the rule writer to specify where to start searching for a pattern relative to the beginning of the packet or buffer. So, an offset of 5 would tell Snort to look for the specified pattern after the first 5 bytes of the payload.

This keyword allows values from -65535 to 65535, and it can also be set to a string value referencing a variable extracted by the byte_extract keyword in the same rule.

Format:

offset {offset|variable_name}

Example:

content:"|FE|SMB", offset 4; 

depth

The depth modifier allows the rule writer the ability to specify how far into a Snort packet or buffer to look for the specified pattern. For example, setting depth to 5 would tell Snort to only look for the pattern within the first 5 bytes of the payload.

Specifying depth without offset will implicitly look at the start of the payload (offset 0), so there's no need to specify an additional offset 0 option in those cases.

The value chosen must be greater than or equal to the length of the content string, and the max value is 65535. It can also be set to a string value referencing a variable extracted by the byte_extract keyword in the same rule.

Format:

depth {depth|variable_name}

Examples:

# Can combine depth and offset for a single content match
content:"|FE|SMB", depth 4, offset 4; 
content:"PK|03 04|", depth 4; 

distance

The distance keyword is similar to offset but is relative to a preceding content match instead of the start of the payload/buffer. It tells Snort to look skip X number of bytes after the last content match before looking for this one.

This keyword allows values from -65535 to 65535, and it can also be set to a string value referencing a variable extracted by the byte_extract keyword in the same rule.

Format:

distance {distance|variable_name}

Example:

content:"ABC"; 
content:"EFG", distance 1;

Note: To put this example in the context of cursors, the "ABC" match moves the detection cursor to point to the byte immediately after the 'C' character. And then the distance 1 modifier in the very next match tells Snort not to reset the cursor back to the beginning of the buffer, but to instead increase the cursor by 1 so that it points to second byte in the buffer after the 'C' character.

within

The within keyword is similar to depth but is relative to a preceding content match instead of the start of the payload. It tells Snort to look this content match within X number of bytes of the last one.

Specifying within without distance will implicitly look immediately after the last content match, so there's no need to specify an additional distance 0 option in those cases.

The value chosen must be greater than or equal to the length of the content string, and the max value is 65535. It can also be set to a string value referencing a variable extracted by the byte_extract keyword in the same rule.

Format:

within {within|variable_name}

Examples:

content:"ABC"; 
content:"EFG", within 10;
# Distance and within can be used together
content:"ABC"; 
content:"EFG", distance 1, within 3;
content:"DEF"; 
content:"GHI", within 3;

Note: Content matches specified without any of these four modifiers will always be looked for starting from the beginning of (1) the default buffer or (2) an explicitly-set sticky buffer.

Note: Rule writers are free to use all four options in a single rule, but only distance and within and offset and depth can appear together attached a single content match. For example, the second content option in content:"DEF"; content:"GHI", offset 6, within 3; is not valid due to the combination of offset and within.