]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/bytejump: Add "from_end" support
authorJeff Lucovsky <jeff@lucovsky.org>
Sat, 16 May 2020 18:52:25 +0000 (14:52 -0400)
committerVictor Julien <victor@inliniac.net>
Tue, 7 Jul 2020 08:49:45 +0000 (10:49 +0200)
This commit adds support for the byte jump "from_end" keyword and
unittests.

src/detect-bytejump.c
src/detect-bytejump.h

index 8a8b5e4b7d0c72576acb8dff52b9a73c8a0d0ef3..65979a569ef5e374563d431fe5871f0819dcb64e 100644 (file)
@@ -168,8 +168,10 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
     if (flags & DETECT_BYTEJUMP_BEGIN) {
         jumpptr = payload + val;
         //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
-    }
-    else {
+    } else if (flags & DETECT_BYTEJUMP_END) {
+        jumpptr = payload + payload_len + val;
+        //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
+    } else {
         val += extbytes;
         jumpptr = ptr + val;
         //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr);
@@ -435,6 +437,8 @@ static DetectBytejumpData *DetectBytejumpParse(DetectEngineCtx *de_ctx, const ch
             data->flags |= DETECT_BYTEJUMP_LITTLE;
         } else if (strcasecmp("from_beginning", args[i]) == 0) {
             data->flags |= DETECT_BYTEJUMP_BEGIN;
+        } else if (strcasecmp("from_end", args[i]) == 0) {
+            data->flags |= DETECT_BYTEJUMP_END;
         } else if (strcasecmp("align", args[i]) == 0) {
             data->flags |= DETECT_BYTEJUMP_ALIGN;
         } else if (strncasecmp("multiplier ", args[i], 11) == 0) {
@@ -461,6 +465,12 @@ static DetectBytejumpData *DetectBytejumpParse(DetectEngineCtx *de_ctx, const ch
         }
     }
 
+    if ((data->flags & DETECT_BYTEJUMP_END) && (data->flags & DETECT_BYTEJUMP_BEGIN)) {
+        SCLogError(SC_ERR_INVALID_SIGNATURE, "'from_end' and 'from_beginning' "
+                "cannot be used in the same byte_jump statement");
+        goto error;
+    }
+
     if (data->flags & DETECT_BYTEJUMP_STRING) {
         /* 23 - This is the largest string (octal, with a zero prefix) that
          *      will not overflow uint64_t.  The only way this length
@@ -566,6 +576,7 @@ static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char
             (data->flags & DETECT_BYTEJUMP_LITTLE) ||
             (data->flags & DETECT_BYTEJUMP_BIG) ||
             (data->flags & DETECT_BYTEJUMP_BEGIN) ||
+            (data->flags & DETECT_BYTEJUMP_END) ||
             (data->base == DETECT_BYTEJUMP_BASE_DEC) ||
             (data->base == DETECT_BYTEJUMP_BASE_HEX) ||
             (data->base == DETECT_BYTEJUMP_BASE_OCT) ) {
@@ -579,7 +590,7 @@ static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char
         SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s);
         if (bed_sm == NULL) {
             SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
-                       "seen in byte_jump - %s\n", offset);
+                       "seen in byte_jump - %s", offset);
             goto error;
         }
         data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
@@ -1094,6 +1105,29 @@ static int DetectBytejumpTestParse12(void)
     return result;
 }
 
+static int DetectBytejumpTestParse13(void)
+{
+    DetectBytejumpData *data = DetectBytejumpParse(NULL,
+            " 4,0 , relative , little, string, dec, " "align, from_end", NULL);
+    FAIL_IF_NULL(data);
+    FAIL_IF_NOT(data->flags & DETECT_BYTEJUMP_END);
+
+    DetectBytejumpFree(NULL, data);
+
+    PASS;
+}
+
+static int DetectBytejumpTestParse14(void)
+{
+    DetectBytejumpData *data = DetectBytejumpParse(NULL,
+            " 4,0 , relative , little, string, dec, "
+            "align, from_beginning, from_end", NULL);
+
+    FAIL_IF_NOT_NULL(data);
+
+    PASS;
+}
+
 /**
  * \test DetectByteJumpTestPacket01 is a test to check matches of
  * byte_jump and byte_jump relative works if the previous keyword is pcre
@@ -1283,6 +1317,27 @@ end:
     return result;
 }
 
+/**
+ * \test check matches of with from_end
+ */
+static int DetectByteJumpTestPacket08 (void)
+{
+    uint8_t *buf = (uint8_t *)"XX04abcdABCD";
+    uint16_t buflen = strlen((char *)buf);
+    Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
+
+    FAIL_IF_NULL(p);
+
+    char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
+        "relative,string,dec,from_end, post_offset -8; content:\"ABCD\";  sid:1; rev:1;)";
+
+    FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
+
+    UTHFreePacket(p);
+
+    PASS;
+}
+
 #endif /* UNITTESTS */
 
 
@@ -1307,6 +1362,8 @@ static void DetectBytejumpRegisterTests(void)
     UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10);
     UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11);
     UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12);
+    UtRegisterTest("DetectBytejumpTestParse13", DetectBytejumpTestParse13);
+    UtRegisterTest("DetectBytejumpTestParse14", DetectBytejumpTestParse14);
 
     UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
     UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
@@ -1315,6 +1372,7 @@ static void DetectBytejumpRegisterTests(void)
     UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
     UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
     UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
+    UtRegisterTest("DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);
 #endif /* UNITTESTS */
 }
 
index 08455b9553a29ec41cf886768b3b5497d42bd1a5..eccd2f6af154de92e169929566577c09f10d98f6 100644 (file)
 #define DETECT_BYTEJUMP_ALIGN    0x20 /**< "align" offset */
 #define DETECT_BYTEJUMP_DCE      0x40 /**< "dce" enabled */
 #define DETECT_BYTEJUMP_OFFSET_BE 0x80 /**< "byte extract" enabled */
+#define DETECT_BYTEJUMP_END      0x100 /**< "from_end" jump */
 
 typedef struct DetectBytejumpData_ {
     uint8_t nbytes;                   /**< Number of bytes to compare */
     uint8_t base;                     /**< String value base (oct|dec|hex) */
-    uint8_t flags;                    /**< Flags (big|little|relative|string) */
+    uint16_t flags;                    /**< Flags (big|little|relative|string) */
     uint32_t multiplier;              /**< Multiplier for nbytes (multiplier n)*/
     int32_t offset;                   /**< Offset in payload to extract value */
     int32_t post_offset;              /**< Offset to adjust post-jump */