]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: adds engine for u8 keywords
authorPhilippe Antoine <contact@catenacyber.fr>
Fri, 3 Apr 2020 07:16:24 +0000 (09:16 +0200)
committerVictor Julien <victor@inliniac.net>
Sun, 2 Aug 2020 18:09:21 +0000 (20:09 +0200)
src/detect-engine-uint.c
src/detect-engine-uint.h
src/detect-icmpv6-mtu.c

index 927cb35b38a8cd2a0cc10ba58af54237f3ccfb7e..7d33bd29cd0a1596826a451a8ed2ba52228fa721 100644 (file)
@@ -83,7 +83,6 @@ DetectU32Data *DetectU32Parse (const char *u32str)
     char arg2[16] = "";
     char arg3[16] = "";
 
-#define MAX_SUBSTRINGS 30
     int ret = 0, res = 0;
     int ov[MAX_SUBSTRINGS];
 
@@ -218,13 +217,164 @@ PrefilterPacketU32Compare(PrefilterPacketHeaderValue v, void *smctx)
     return false;
 }
 
-static bool g_detect_u32_registered = false;
+static bool g_detect_uint_registered = false;
 
-void DetectU32Register(void)
+void DetectUintRegister(void)
 {
-    if (g_detect_u32_registered == false) {
+    if (g_detect_uint_registered == false) {
         // register only once
         DetectSetupParseRegexes(PARSE_REGEX, &uint_pcre);
-        g_detect_u32_registered = true;
+        g_detect_uint_registered = true;
     }
 }
+
+//same as u32 but with u8
+int DetectU8Match(const uint8_t parg, const DetectU8Data *du8)
+{
+    switch (du8->mode) {
+        case DETECT_UINT_EQ:
+            if (parg == du8->arg1) {
+                return 1;
+            }
+            return 0;
+        case DETECT_UINT_LT:
+            if (parg < du8->arg1) {
+                return 1;
+            }
+            return 0;
+        case DETECT_UINT_GT:
+            if (parg > du8->arg1) {
+                return 1;
+            }
+            return 0;
+        case DETECT_UINT_RA:
+            if (parg > du8->arg1 && parg < du8->arg2) {
+                return 1;
+            }
+            return 0;
+        default:
+            BUG_ON("unknown mode");
+    }
+    return 0;
+}
+
+/**
+ * \brief This function is used to parse u8 options passed via some u8 keyword
+ *
+ * \param u8str Pointer to the user provided u8 options
+ *
+ * \retval DetectU8Data pointer to DetectU8Data on success
+ * \retval NULL on failure
+ */
+
+DetectU8Data *DetectU8Parse (const char *u8str)
+{
+    DetectU8Data u8da;
+    DetectU8Data *u8d = NULL;
+    char arg1[16] = "";
+    char arg2[16] = "";
+    char arg3[16] = "";
+
+    int ret = 0, res = 0;
+    int ov[MAX_SUBSTRINGS];
+
+    ret = DetectParsePcreExec(&uint_pcre, u8str, 0, 0, ov, MAX_SUBSTRINGS);
+    if (ret < 2 || ret > 4) {
+        SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret);
+        return NULL;
+    }
+
+    res = pcre_copy_substring((char *) u8str, ov, MAX_SUBSTRINGS, 1, arg1, sizeof(arg1));
+    if (res < 0) {
+        SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+        return NULL;
+    }
+    SCLogDebug("Arg1 \"%s\"", arg1);
+
+    if (ret >= 3) {
+        res = pcre_copy_substring((char *) u8str, ov, MAX_SUBSTRINGS, 2, arg2, sizeof(arg2));
+        if (res < 0) {
+            SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+            return NULL;
+        }
+        SCLogDebug("Arg2 \"%s\"", arg2);
+
+        if (ret >= 4) {
+            res = pcre_copy_substring((char *) u8str, ov, MAX_SUBSTRINGS, 3, arg3, sizeof(arg3));
+            if (res < 0) {
+                SCLogError(SC_ERR_PCRE_COPY_SUBSTRING, "pcre_copy_substring failed");
+                return NULL;
+            }
+            SCLogDebug("Arg3 \"%s\"", arg3);
+        }
+    }
+
+    if (strlen(arg2) > 0) {
+        /*set the values*/
+        switch(arg2[0]) {
+            case '<':
+            case '>':
+                if (StringParseUint8(&u8da.arg1, 10, strlen(arg3), arg3) < 0) {
+                    SCLogError(SC_ERR_BYTE_EXTRACT_FAILED, "ByteExtractStringUint8 failed");
+                    return NULL;
+                }
+
+                SCLogDebug("u8 is %"PRIu8"",u8da.arg1);
+                if (strlen(arg1) > 0)
+                    return NULL;
+
+                if (arg2[0] == '<') {
+                    u8da.mode = DETECT_UINT_LT;
+                } else { // arg2[0] == '>'
+                    u8da.mode = DETECT_UINT_GT;
+                }
+                break;
+            case '-':
+                u8da.mode = DETECT_UINT_RA;
+                if (StringParseUint8(&u8da.arg1, 10, strlen(arg1), arg1) < 0) {
+                    SCLogError(SC_ERR_BYTE_EXTRACT_FAILED, "ByteExtractStringUint8 failed");
+                    return NULL;
+                }
+                if (StringParseUint8(&u8da.arg2, 10, strlen(arg3), arg3) < 0) {
+                    SCLogError(SC_ERR_BYTE_EXTRACT_FAILED, "ByteExtractStringUint8 failed");
+                    return NULL;
+                }
+
+                SCLogDebug("u8 is %"PRIu8" to %"PRIu8"", u8da.arg1, u8da.arg2);
+                if (u8da.arg1 >= u8da.arg2) {
+                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid u8 range. ");
+                    return NULL;
+                }
+                break;
+            default:
+                u8da.mode = DETECT_UINT_EQ;
+
+                if (strlen(arg2) > 0 ||
+                    strlen(arg3) > 0)
+                    return NULL;
+
+                if (StringParseUint8(&u8da.arg1, 10, strlen(arg1), arg1) < 0) {
+                    SCLogError(SC_ERR_BYTE_EXTRACT_FAILED, "ByteExtractStringUint8 failed");
+                    return NULL;
+                }
+        }
+    } else {
+        u8da.mode = DETECT_UINT_EQ;
+
+        if (strlen(arg3) > 0)
+            return NULL;
+
+        if (StringParseUint8(&u8da.arg1, 10, strlen(arg1), arg1) < 0) {
+            SCLogError(SC_ERR_BYTE_EXTRACT_FAILED, "ByteExtractStringUint8 failed");
+            return NULL;
+        }
+    }
+    u8d = SCCalloc(1, sizeof (DetectU8Data));
+    if (unlikely(u8d == NULL))
+        return NULL;
+    u8d->arg1 = u8da.arg1;
+    u8d->arg2 = u8da.arg2;
+    u8d->mode = u8da.mode;
+
+    return u8d;
+}
index 76ec1630a7166c41067c5ff5a8abc8c257a1d809..f76a50121fc684461cdff311ba00253737b959d9 100644 (file)
@@ -44,6 +44,17 @@ int DetectU32Match(const uint32_t parg, const DetectU32Data *du32);
 DetectU32Data *DetectU32Parse (const char *u32str);
 void PrefilterPacketU32Set(PrefilterPacketHeaderValue *v, void *smctx);
 bool PrefilterPacketU32Compare(PrefilterPacketHeaderValue v, void *smctx);
-void DetectU32Register(void);
+
+void DetectUintRegister(void);
+
+typedef struct DetectU8Data_ {
+    uint8_t arg1;   /**< first arg value in the signature*/
+    uint8_t arg2;   /**< second arg value in the signature, in case of range
+                          operator*/
+    DetectUintMode mode;    /**< operator used in the signature */
+} DetectU8Data;
+
+int DetectU8Match(const uint8_t parg, const DetectU8Data *du8);
+DetectU8Data *DetectU8Parse (const char *u8str);
 
 #endif /* __DETECT_UTIL_UINT_H */
index 340b4f4280bff579bb288c07aa06c5d2e6963452..8a5c76f8d2be81ee92c8667df7f2a0dd621c0af1 100644 (file)
@@ -59,7 +59,7 @@ void DetectICMPv6mtuRegister(void)
     sigmatch_table[DETECT_ICMPV6MTU].SupportsPrefilter = PrefilterIcmpv6mtuIsPrefilterable;
     sigmatch_table[DETECT_ICMPV6MTU].SetupPrefilter = PrefilterSetupIcmpv6mtu;
 
-    DetectU32Register();
+    DetectUintRegister();
     return;
 }