* content/uricontent: offset, depth, distance, within
* byte_test: offset, value
-* byte_jump: offset
+* byte_jump: offset, post_offset
* isdataat: offset
===== Examples
content:"bad stuff", offset str_offset, depth str_depth;
msg:"Bad Stuff detected within field";)
+ alert tcp (content:"START"; byte_extract:1, 0, myvar, relative;
+ byte_jump:1, 3, relative, post_offset myvar;
+ content:"END", distance 6, within 3;
+ msg: "byte_jump - pass variable to post_offset";)
+
This example uses two variables.
The first variable keeps the offset of a string, read from a byte at offset 0.
uint32_t bitmask_val;
int8_t offset_var;
uint8_t from_end_flag;
+ int8_t post_offset_var;
} ByteJumpData;
class ByteJumpOption : public IpsOption
mix(a,b,c);
a += data->post_offset;
- b += data->from_end_flag << 8 | data->offset_var;
+ b += data->from_end_flag << 16 | data->offset_var << 8 | data->post_offset_var;
c += data->bitmask_val;
mix(a,b,c);
( left->multiplier == right->multiplier) &&
( left->post_offset == right->post_offset) &&
( left->bitmask_val == right->bitmask_val) &&
- ( left->from_end_flag == right->from_end_flag))
+ ( left->from_end_flag == right->from_end_flag) &&
+ ( left->post_offset_var == right->post_offset_var))
{
return true;
}
ByteJumpData* bjd = (ByteJumpData*)&config;
int32_t offset = 0;
+ int32_t post_offset = 0;
// Get values from byte_extract variables, if present.
if (bjd->offset_var >= 0 && bjd->offset_var < NUM_IPS_OPTIONS_VARS)
{
offset = bjd->offset;
}
+ if (bjd->post_offset_var >= 0 && bjd->post_offset_var < NUM_IPS_OPTIONS_VARS)
+ {
+ uint32_t extract_post_offset;
+ GetVarValueByIndex(&extract_post_offset, bjd->post_offset_var);
+ post_offset = (int32_t)extract_post_offset;
+ }
+ else
+ {
+ post_offset = bjd->post_offset;
+ }
const uint8_t* const start_ptr = c.buffer();
const int dsize = c.size();
else
jump += offset;
- jump += bjd->post_offset;
+ jump += post_offset;
if ( !c.set_pos(jump) )
return NO_MATCH;
{ "align", Parameter::PT_INT, "0:4", "0",
"round the number of converted bytes up to the next 2- or 4-byte boundary" },
- { "post_offset", Parameter::PT_INT, "-65535:65535", "0",
- "also skip forward or backwards (positive of negative value) this number of bytes" },
+ { "post_offset", Parameter::PT_STRING, nullptr, nullptr,
+ "skip forward or backward (positive or negative value) by variable name or number of " \
+ "bytes after the other jump options have been applied" },
{ "big", Parameter::PT_IMPLIED, nullptr, nullptr,
"big endian" },
public:
ByteJumpData data;
string var;
+ string post_var;
};
bool ByteJumpModule::begin(const char*, int, SnortConfig*)
{
memset(&data, 0, sizeof(data));
var.clear();
+ post_var.clear();
data.multiplier = 1;
return true;
}
return false;
}
}
+ if ( post_var.empty() )
+ data.post_offset_var = IPS_OPTIONS_NO_VAR;
+ else
+ {
+ data.post_offset_var = GetVarByName(post_var.c_str());
+
+ if (data.post_offset_var == IPS_OPTIONS_NO_VAR)
+ {
+ ParseError(INVALID_VAR_ERR_STR, "byte_jump", post_var.c_str());
+ return false;
+ }
+ }
if ( !data.endianness )
data.endianness = ENDIAN_BIG;
data.multiplier = v.get_long();
else if ( v.is("post_offset") )
- data.post_offset = v.get_long();
-
+ {
+ long n;
+ if ( v.strtol(n) )
+ data.post_offset = n;
+ else
+ post_var = v.get_string();
+ }
else if ( v.is("big") )
set_byte_order(data.endianness, ENDIAN_BIG, "byte_jump");