]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1130 in SNORT/snort3 from post_offset_var to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Tue, 13 Mar 2018 16:58:13 +0000 (12:58 -0400)
committerTom Peters (thopeter) <thopeter@cisco.com>
Tue, 13 Mar 2018 16:58:13 +0000 (12:58 -0400)
Squashed commit of the following:

commit b42ac1bc7c328de387da92b93889613156ad988f
Author: Steven Baigal <sbaigal@cisco.com>
Date:   Tue Mar 6 13:03:15 2018 -0500

    byte_jump: updated byte_jump post_offset option to support variable

doc/byte_extract.txt
src/ips_options/ips_byte_jump.cc

index ebed44b19f5c12979f6cd2b7ee87f46b2f5aa5ff..ccaeefe1edc7f527326cf2dc2dd6da0d86c86d57 100644 (file)
@@ -12,7 +12,7 @@ Here is a list of places where byte_extract variables can be used:
 
 * content/uricontent: offset, depth, distance, within
 * byte_test: offset, value
-* byte_jump: offset
+* byte_jump: offset, post_offset
 * isdataat: offset 
 
 ===== Examples
@@ -22,6 +22,11 @@ Here is a list of places where byte_extract variables can be used:
       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.
index fa71aac213cf977c80dec4216658ca5923b11685..650e1e34ccf498032dc17ac15e919869a0f612b7 100644 (file)
@@ -109,6 +109,7 @@ typedef struct _ByteJumpData
     uint32_t bitmask_val;
     int8_t offset_var;
     uint8_t from_end_flag;
+    int8_t post_offset_var;
 } ByteJumpData;
 
 class ByteJumpOption : public IpsOption
@@ -158,7 +159,7 @@ uint32_t ByteJumpOption::hash() const
     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);
@@ -190,7 +191,8 @@ bool ByteJumpOption::operator==(const IpsOption& ips) const
         ( 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;
     }
@@ -205,6 +207,7 @@ IpsOption::EvalStatus ByteJumpOption::eval(Cursor& c, Packet* p)
     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)
@@ -217,6 +220,16 @@ IpsOption::EvalStatus ByteJumpOption::eval(Cursor& c, Packet* p)
     {
         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();
@@ -298,7 +311,7 @@ IpsOption::EvalStatus ByteJumpOption::eval(Cursor& c, Packet* p)
     else
         jump += offset;
 
-    jump += bjd->post_offset;
+    jump += post_offset;
 
     if ( !c.set_pos(jump) )
         return NO_MATCH;
@@ -333,8 +346,9 @@ static const Parameter s_params[] =
     { "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" },
@@ -384,12 +398,14 @@ public:
 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;
 }
@@ -408,6 +424,18 @@ bool ByteJumpModule::end(const char*, int, SnortConfig*)
             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;
 
@@ -460,8 +488,13 @@ bool ByteJumpModule::set(const char*, Value& v, SnortConfig*)
         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");