]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/entropy: Add entropy keyword
authorJeff Lucovsky <jlucovsky@oisf.net>
Wed, 5 Feb 2025 20:53:30 +0000 (15:53 -0500)
committerVictor Julien <victor@inliniac.net>
Tue, 1 Apr 2025 19:11:11 +0000 (21:11 +0200)
This commit adds keyword/build support for the entropy keyword. The
entropy keyword compares an entropy value with a value calculated
according to the Shannon entropy on the available content.

Issue: 4162

rust/src/detect/entropy.rs
src/Makefile.am
src/detect-engine-register.c
src/detect-engine-register.h
src/detect-entropy.c [new file with mode: 0644]
src/detect-entropy.h [new file with mode: 0644]

index 05c06100176a18c0bb21066136bc78ce8d38b129..3a63363c658a435bc69b01220b2155e512ad066d 100644 (file)
@@ -139,7 +139,7 @@ fn parse_entropy<'a>(
 }
 
 fn calculate_entropy(data: &[u8]) -> f64 {
-    if data.len() == 0 {
+    if data.is_empty() {
         return 0.0;
     }
 
index 849c7163373921f1b49d210cf888734d84e53acf..47fcf90eceac40f3f6aae795b0ba23b4c0401202 100755 (executable)
@@ -148,6 +148,7 @@ noinst_HEADERS = \
        detect-engine-tag.h \
        detect-engine-threshold.h \
        detect-engine-uint.h \
+       detect-entropy.h \
        detect-fast-pattern.h \
        detect-file-data.h \
        detect-file-hash-common.h \
@@ -731,6 +732,7 @@ libsuricata_c_a_SOURCES = \
        detect-engine-tag.c \
        detect-engine-threshold.c \
        detect-engine-uint.c \
+       detect-entropy.c \
        detect-fast-pattern.c \
        detect-file-data.c \
        detect-file-hash-common.c \
index 8aa70757d66fdeed285fee2ccf77380fee0b330c..0664bcb520108d21953845fdfdd6861b0f60ec2e 100644 (file)
 #include "detect-quic-cyu-string.h"
 #include "detect-ja4-hash.h"
 #include "detect-ftp-command.h"
+#include "detect-entropy.h"
 
 #include "detect-bypass.h"
 #include "detect-ftpdata.h"
@@ -600,6 +601,7 @@ void SigTableSetup(void)
     DetectBytetestRegister();
     DetectBytejumpRegister();
     DetectBytemathRegister();
+    DetectEntropyRegister();
     DetectSameipRegister();
     DetectGeoipRegister();
     DetectL3ProtoRegister();
index 8c1943cd3b6743e97bb1693d11631810a24ada05..5ae44b186f18f869cf44464e37302354d8cbb2b8 100644 (file)
@@ -95,6 +95,7 @@ enum DetectKeywordId {
     DETECT_ISDATAAT,
     DETECT_URILEN,
     DETECT_ABSENT,
+    DETECT_ENTROPY,
     /* end of content inspection */
 
     DETECT_METADATA,
diff --git a/src/detect-entropy.c b/src/detect-entropy.c
new file mode 100644 (file)
index 0000000..31a1ac8
--- /dev/null
@@ -0,0 +1,75 @@
+/* Copyright (C) 2024 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "suricata-common.h"
+
+#include "detect.h"
+#include "detect-parse.h"
+#include "detect-engine.h"
+
+#include "detect-entropy.h"
+
+#include "rust.h"
+
+static int DetectEntropySetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
+{
+    DetectEntropyData *ded = SCDetectEntropyParse(arg);
+    if (ded == NULL) {
+        goto error;
+    }
+
+    int sm_list = DETECT_SM_LIST_PMATCH;
+    if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
+        if (DetectBufferGetActiveList(de_ctx, s) == -1)
+            goto error;
+
+        sm_list = s->init_data->list;
+    }
+
+    if (SigMatchAppendSMToList(de_ctx, s, DETECT_ENTROPY, (SigMatchCtx *)ded, sm_list) != NULL) {
+        SCReturnInt(0);
+    }
+
+    /* fall through */
+
+error:
+    SCLogDebug("error during entropy setup");
+    if (ded != NULL) {
+        SCDetectEntropyFree(ded);
+    }
+    SCReturnInt(-1);
+}
+
+static void DetectEntropyFree(DetectEngineCtx *de_ctx, void *ptr)
+{
+    SCDetectEntropyFree(ptr);
+}
+
+bool DetectEntropyDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
+        const SigMatchCtx *ctx, const uint8_t *buffer, const uint32_t buffer_len)
+{
+    return SCDetectEntropyMatch(buffer, buffer_len, (const DetectEntropyData *)ctx);
+}
+
+void DetectEntropyRegister(void)
+{
+    sigmatch_table[DETECT_ENTROPY].name = "entropy";
+    sigmatch_table[DETECT_ENTROPY].desc = "calculate entropy";
+    sigmatch_table[DETECT_BYTE_EXTRACT].url = "/rules/payload-keywords.html#entropy";
+    sigmatch_table[DETECT_ENTROPY].Free = DetectEntropyFree;
+    sigmatch_table[DETECT_ENTROPY].Setup = DetectEntropySetup;
+}
diff --git a/src/detect-entropy.h b/src/detect-entropy.h
new file mode 100644 (file)
index 0000000..ea6958e
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright (C) 2024 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef SURICATA_DETECT_ENTROPY_H
+#define SURICATA_DETECT_ENTROPY_H
+
+void DetectEntropyRegister(void);
+bool DetectEntropyDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
+        const SigMatchCtx *ctx, const uint8_t *buffer, const uint32_t buffer_len);
+
+#endif