From a5572890a9be85cf790687d53826e878e1d64245 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 3 Apr 2020 09:16:24 +0200 Subject: [PATCH] detect: adds engine for u8 keywords --- src/detect-engine-uint.c | 160 +++++++++++++++++++++++++++++++++++++-- src/detect-engine-uint.h | 13 +++- src/detect-icmpv6-mtu.c | 2 +- 3 files changed, 168 insertions(+), 7 deletions(-) diff --git a/src/detect-engine-uint.c b/src/detect-engine-uint.c index 927cb35b38..7d33bd29cd 100644 --- a/src/detect-engine-uint.c +++ b/src/detect-engine-uint.c @@ -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; +} diff --git a/src/detect-engine-uint.h b/src/detect-engine-uint.h index 76ec1630a7..f76a50121f 100644 --- a/src/detect-engine-uint.h +++ b/src/detect-engine-uint.h @@ -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 */ diff --git a/src/detect-icmpv6-mtu.c b/src/detect-icmpv6-mtu.c index 340b4f4280..8a5c76f8d2 100644 --- a/src/detect-icmpv6-mtu.c +++ b/src/detect-icmpv6-mtu.c @@ -59,7 +59,7 @@ void DetectICMPv6mtuRegister(void) sigmatch_table[DETECT_ICMPV6MTU].SupportsPrefilter = PrefilterIcmpv6mtuIsPrefilterable; sigmatch_table[DETECT_ICMPV6MTU].SetupPrefilter = PrefilterSetupIcmpv6mtu; - DetectU32Register(); + DetectUintRegister(); return; }