From: Jeff Lucovsky Date: Sun, 14 Jul 2019 18:16:23 +0000 (-0400) Subject: detect/transform: add dotprefix keyword X-Git-Tag: suricata-5.0.0-rc1~59 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7808b946e302b23c96c13890cf66d92905a3b033;p=thirdparty%2Fsuricata.git detect/transform: add dotprefix keyword --- diff --git a/src/Makefile.am b/src/Makefile.am index b6b6c173eb..587fa492cc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -275,6 +275,7 @@ detect-transform-strip-whitespace.c detect-transform-strip-whitespace.h \ detect-transform-md5.c detect-transform-md5.h \ detect-transform-sha1.c detect-transform-sha1.h \ detect-transform-sha256.c detect-transform-sha256.h \ +detect-transform-dotprefix.c detect-transform-dotprefix.h \ detect-ttl.c detect-ttl.h \ detect-uricontent.c detect-uricontent.h \ detect-urilen.c detect-urilen.h \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index b49a42a771..294a4b7d76 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -193,6 +193,7 @@ #include "detect-transform-md5.h" #include "detect-transform-sha1.h" #include "detect-transform-sha256.h" +#include "detect-transform-dotprefix.h" #include "util-rule-vars.h" @@ -554,6 +555,7 @@ void SigTableSetup(void) DetectTransformMd5Register(); DetectTransformSha1Register(); DetectTransformSha256Register(); + DetectTransformDotPrefixRegister(); /* close keyword registration */ DetectBufferTypeCloseRegistration(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index 835858fd69..7cc05f33c3 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -249,6 +249,7 @@ enum { DETECT_TRANSFORM_MD5, DETECT_TRANSFORM_SHA1, DETECT_TRANSFORM_SHA256, + DETECT_TRANSFORM_DOTPREFIX, /* make sure this stays last */ DETECT_TBLSIZE, diff --git a/src/detect-transform-dotprefix.c b/src/detect-transform-dotprefix.c new file mode 100644 index 0000000000..070dfade7f --- /dev/null +++ b/src/detect-transform-dotprefix.c @@ -0,0 +1,185 @@ +/* Copyright (C) 2019 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. + */ + +/** + * \file + * + * \author Jeff Lucovsky + * + * Implements the dotprefix transformation + */ + +#include "suricata-common.h" + +#include "detect.h" +#include "detect-engine.h" +#include "detect-engine-prefilter.h" +#include "detect-parse.h" +#include "detect-transform-dotprefix.h" + +#include "util-unittest.h" +#include "util-print.h" +#include "util-memrchr.h" +#include "util-memcpy.h" + +static int DetectTransformDotPrefixSetup (DetectEngineCtx *, Signature *, const char *); +static void DetectTransformDotPrefixRegisterTests(void); + +static void TransformDotPrefix(InspectionBuffer *buffer); + +void DetectTransformDotPrefixRegister(void) +{ + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].name = "dotprefix"; + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].desc = + "modify buffer to extract the dotprefix"; + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].url = + DOC_URL DOC_VERSION "/rules/transforms.html#dotprefix"; + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].Transform = TransformDotPrefix; + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].Setup = DetectTransformDotPrefixSetup; + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].RegisterTests = + DetectTransformDotPrefixRegisterTests; + + sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].flags |= SIGMATCH_NOOPT; +} + +/** + * \internal + * \brief Extract the dotprefix, if any, the last pattern match, either content or uricontent + * \param det_ctx detection engine ctx + * \param s signature + * \param nullstr should be null + * \retval 0 ok + * \retval -1 failure + */ +static int DetectTransformDotPrefixSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) +{ + SCEnter(); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_DOTPREFIX); + SCReturnInt(r); +} + +/** + * \brief Return the dotprefix, if any, in the last pattern match. + * + * Input values are modified by prefixing with a ".". + * + * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".google.com"; sid:1;)" + * 1. hello.google.com --> match + * 2. hey.agoogle.com --> no match + * 3. agoogle.com --> no match + * 4. something.google.com.au --> match + * 5. google.com --> match + * + * To match on the dotprefix only: + * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".google.com"; endswith; sid:1;)" + * + * 1. hello.google.com --> match + * 2. hey.agoogle.com --> no match + * 3. agoogle.com --> no match + * 4. something.google.com.au --> no match + * 5. google.com --> match + * + * To match on a TLD: + * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".co.uk"; endswith; sid:1;)" + * + * 1. hello.google.com --> no match + * 2. hey.agoogle.com --> no match + * 3. agoogle.com --> no match + * 4. something.google.co.uk --> match + * 5. google.com --> no match + */ +static void TransformDotPrefix(InspectionBuffer *buffer) +{ + const size_t input_len = buffer->inspect_len; + + if (input_len) { + uint8_t output[input_len + 1]; // For the leading '.' + + output[0] = '.'; + memcpy(&output[1], buffer->inspect, input_len); + InspectionBufferCopy(buffer, output, input_len + 1); + } +} + +#ifdef UNITTESTS +static int DetectTransformDotPrefixTest01(void) +{ + const uint8_t *input = (const uint8_t *)"example.com"; + uint32_t input_len = strlen((char *)input); + + const char *result = ".example.com"; + uint32_t result_len = strlen((char *)result); + + InspectionBuffer buffer; + InspectionBufferInit(&buffer, input_len); + InspectionBufferSetup(&buffer, input, input_len); + PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); + TransformDotPrefix(&buffer); + PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); + FAIL_IF_NOT(buffer.inspect_len == result_len); + FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); + InspectionBufferFree(&buffer); + PASS; +} + +static int DetectTransformDotPrefixTest02(void) +{ + const uint8_t *input = (const uint8_t *)"hello.example.com"; + uint32_t input_len = strlen((char *)input); + + const char *result = ".hello.example.com"; + uint32_t result_len = strlen((char *)result); + + InspectionBuffer buffer; + InspectionBufferInit(&buffer, input_len); + InspectionBufferSetup(&buffer, input, input_len); + PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); + TransformDotPrefix(&buffer); + PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); + FAIL_IF_NOT(buffer.inspect_len == result_len); + FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); + InspectionBufferFree(&buffer); + PASS; +} + +static int DetectTransformDotPrefixTest03(void) +{ + const char rule[] = "alert dns any any -> any any (dns.query; dotprefix; content:\".google.com\"; sid:1;)"; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx = NULL; + memset(&th_v, 0, sizeof(th_v)); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + Signature *s = DetectEngineAppendSig(de_ctx, rule); + FAIL_IF_NULL(s); + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + DetectEngineCtxFree(de_ctx); + PASS; +} +#endif + +static void DetectTransformDotPrefixRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectTransformDotPrefixTest01", DetectTransformDotPrefixTest01); + UtRegisterTest("DetectTransformDotPrefixTest02", DetectTransformDotPrefixTest02); + UtRegisterTest("DetectTransformDotPrefixTest03", DetectTransformDotPrefixTest03); +#endif +} diff --git a/src/detect-transform-dotprefix.h b/src/detect-transform-dotprefix.h new file mode 100644 index 0000000000..3512689b64 --- /dev/null +++ b/src/detect-transform-dotprefix.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2019 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. + */ + +/** + * \file + * + * \author Jeff Lucovsky + */ + +#ifndef __DETECT_TRANSFORM_DOTPREFIX_H__ +#define __DETECT_TRANSFORM_DOTPREFIX_H__ + +/* prototypes */ +void DetectTransformDotPrefixRegister (void); + +#endif /* __DETECT_TRANSFORM_DOTPREFIX_H__ */