]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/analyzer: add per rule mpm block to rules.json
authorVictor Julien <victor@inliniac.net>
Sat, 6 Feb 2021 20:38:31 +0000 (21:38 +0100)
committerVictor Julien <victor@inliniac.net>
Wed, 1 Sep 2021 06:33:52 +0000 (08:33 +0200)
src/detect-engine-analyzer.c

index f401d3b098350e0f67c6a883f5c8cb16fdbee76b..88cce4ca6440b3dbe3a4867c089a53c97dc0392d 100644 (file)
@@ -608,6 +608,31 @@ static bool LooksLikeHTTPUA(const uint8_t *buf, uint16_t len)
     return false;
 }
 
+static void DumpContent(JsonBuilder *js, const DetectContentData *cd)
+{
+    jb_set_string_from_bytes(js, "pattern", cd->content, cd->content_len);
+    jb_set_uint(js, "length", cd->content_len);
+    jb_set_bool(js, "nocase", cd->flags & DETECT_CONTENT_NOCASE);
+    jb_set_bool(js, "negated", cd->flags & DETECT_CONTENT_NEGATED);
+    jb_set_bool(js, "starts_with", cd->flags & DETECT_CONTENT_STARTS_WITH);
+    jb_set_bool(js, "ends_with", cd->flags & DETECT_CONTENT_ENDS_WITH);
+    jb_set_bool(js, "is_mpm", cd->flags & DETECT_CONTENT_MPM);
+    jb_set_bool(js, "no_double_inspect", cd->flags & DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED);
+    if (cd->flags & DETECT_CONTENT_OFFSET) {
+        jb_set_uint(js, "offset", cd->offset);
+    }
+    if (cd->flags & DETECT_CONTENT_DEPTH) {
+        jb_set_uint(js, "depth", cd->depth);
+    }
+    if (cd->flags & DETECT_CONTENT_DISTANCE) {
+        jb_set_uint(js, "distance", cd->distance);
+    }
+    if (cd->flags & DETECT_CONTENT_WITHIN) {
+        jb_set_uint(js, "within", cd->within);
+    }
+    jb_set_bool(js, "fast_pattern", cd->flags & DETECT_CONTENT_FAST_PATTERN);
+}
+
 static void DumpMatches(RuleAnalyzer *ctx, JsonBuilder *js, const SigMatchData *smd)
 {
     if (smd == NULL)
@@ -624,25 +649,7 @@ static void DumpMatches(RuleAnalyzer *ctx, JsonBuilder *js, const SigMatchData *
                 const DetectContentData *cd = (const DetectContentData *)smd->ctx;
 
                 jb_open_object(js, "content");
-                jb_set_string_from_bytes(js, "pattern", cd->content, cd->content_len);
-                jb_set_bool(js, "nocase", cd->flags & DETECT_CONTENT_NOCASE);
-                jb_set_bool(js, "negated", cd->flags & DETECT_CONTENT_NEGATED);
-                jb_set_bool(js, "starts_with", cd->flags & DETECT_CONTENT_STARTS_WITH);
-                jb_set_bool(js, "ends_with", cd->flags & DETECT_CONTENT_ENDS_WITH);
-                jb_set_bool(js, "is_mpm", cd->flags & DETECT_CONTENT_MPM);
-                if (cd->flags & DETECT_CONTENT_OFFSET) {
-                    jb_set_uint(js, "offset", cd->offset);
-                }
-                if (cd->flags & DETECT_CONTENT_DEPTH) {
-                    jb_set_uint(js, "depth", cd->depth);
-                }
-                if (cd->flags & DETECT_CONTENT_DISTANCE) {
-                    jb_set_uint(js, "distance", cd->distance);
-                }
-                if (cd->flags & DETECT_CONTENT_WITHIN) {
-                    jb_set_uint(js, "within", cd->within);
-                }
-                jb_set_bool(js, "fast_pattern", cd->flags & DETECT_CONTENT_FAST_PATTERN);
+                DumpContent(js, cd);
                 if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
                     AnalyzerNote(ctx, (char *)"'fast_pattern:only' option is silently ignored and "
                                               "is interpreted as regular 'fast_pattern'");
@@ -783,6 +790,9 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
     }
     jb_close(ctx.js);
 
+    const DetectEnginePktInspectionEngine *pkt_mpm = NULL;
+    const DetectEngineAppInspectionEngine *app_mpm = NULL;
+
     jb_open_array(ctx.js, "pkt_engines");
     const DetectEnginePktInspectionEngine *pkt = s->pkt_inspect;
     for ( ; pkt != NULL; pkt = pkt->next) {
@@ -805,6 +815,9 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
         jb_set_bool(ctx.js, "is_mpm", pkt->mpm);
         DumpMatches(&ctx, ctx.js, pkt->smd);
         jb_close(ctx.js);
+        if (pkt->mpm) {
+            pkt_mpm = pkt;
+        }
     }
     jb_close(ctx.js);
 
@@ -845,6 +858,9 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
             jb_set_uint(ctx.js, "progress", app->progress);
             DumpMatches(&ctx, ctx.js, app->smd);
             jb_close(ctx.js);
+            if (app->mpm) {
+                app_mpm = app;
+            }
         }
         jb_close(ctx.js);
 
@@ -864,6 +880,39 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
     }
     jb_close(ctx.js);
 
+    if (pkt_mpm || app_mpm) {
+        jb_open_object(ctx.js, "mpm");
+
+        int mpm_list = pkt_mpm ? DETECT_SM_LIST_PMATCH : app_mpm->sm_list;
+        const char *name;
+        if (mpm_list < DETECT_SM_LIST_DYNAMIC_START)
+            name = DetectListToHumanString(mpm_list);
+        else
+            name = DetectBufferTypeGetNameById(de_ctx, mpm_list);
+        jb_set_string(ctx.js, "buffer", name);
+
+        SigMatchData *smd = pkt_mpm ? pkt_mpm->smd : app_mpm->smd;
+        if (smd == NULL && mpm_list == DETECT_SM_LIST_PMATCH) {
+            smd = s->sm_arrays[mpm_list];
+        }
+        do {
+            switch (smd->type) {
+                case DETECT_CONTENT: {
+                    const DetectContentData *cd = (const DetectContentData *)smd->ctx;
+                    if (cd->flags & DETECT_CONTENT_MPM) {
+                        DumpContent(ctx.js, cd);
+                    }
+                    break;
+                }
+            }
+
+            if (smd->is_last)
+                break;
+            smd++;
+        } while (1);
+        jb_close(ctx.js);
+    }
+
     if (ctx.js_warnings) {
         jb_close(ctx.js_warnings);
         jb_set_object(ctx.js, "warnings", ctx.js_warnings);