From: Jeff Lucovsky Date: Wed, 5 Feb 2025 20:53:30 +0000 (-0500) Subject: detect/entropy: Add entropy keyword X-Git-Tag: suricata-8.0.0-beta1~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fdc0ac590e74639d0cc895792a145e23516be08b;p=thirdparty%2Fsuricata.git detect/entropy: Add entropy keyword 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 --- diff --git a/rust/src/detect/entropy.rs b/rust/src/detect/entropy.rs index 05c0610017..3a63363c65 100644 --- a/rust/src/detect/entropy.rs +++ b/rust/src/detect/entropy.rs @@ -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; } diff --git a/src/Makefile.am b/src/Makefile.am index 849c716337..47fcf90ece 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 8aa70757d6..0664bcb520 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -212,6 +212,7 @@ #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(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index 8c1943cd3b..5ae44b186f 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -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 index 0000000000..31a1ac8481 --- /dev/null +++ b/src/detect-entropy.c @@ -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 index 0000000000..ea6958ee90 --- /dev/null +++ b/src/detect-entropy.h @@ -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