From ec6c5258b6b5188ae5c25238e75c20dc268514e4 Mon Sep 17 00:00:00 2001 From: Brian Rectanus Date: Fri, 23 Oct 2009 12:46:27 -0700 Subject: [PATCH] Sameip Keyword --- src/Makefile.am | 1 + src/detect-sameip.c | 235 ++++++++++++++++++++++++++++++++++++++++++++ src/detect-sameip.h | 7 ++ src/detect.c | 2 + src/detect.h | 1 + 5 files changed, 246 insertions(+) create mode 100644 src/detect-sameip.c create mode 100644 src/detect-sameip.h diff --git a/src/Makefile.am b/src/Makefile.am index bfc572c859..d2610ccfe9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,6 +53,7 @@ detect-recursive.c detect-recursive.h \ detect-rawbytes.c detect-rawbytes.h \ detect-bytetest.c detect-bytetest.h \ detect-bytejump.c detect-bytejump.h \ +detect-sameip.c detect-sameip.h \ detect-ipproto.c detect-ipproto.h \ detect-within.c detect-within.h \ detect-distance.c detect-distance.h \ diff --git a/src/detect-sameip.c b/src/detect-sameip.c new file mode 100644 index 0000000000..aab7e313ca --- /dev/null +++ b/src/detect-sameip.c @@ -0,0 +1,235 @@ +/* Copyright (c) 2009 Open Information Security Foundation */ + +/** + * \file + * \author Brian Rectanus + * + * Implements the "sameip" keyword. + */ + +#include "eidps-common.h" +#include "debug.h" +#include "decode.h" +#include "detect.h" + +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" + +#include "detect-sameip.h" + +#include "util-unittest.h" + +static int DetectSameipMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, + Signature *, SigMatch *); +static int DetectSameipSetup(DetectEngineCtx *, Signature *, SigMatch *, + char *); +static void DetectSameipRegisterTests(void); + +/** + * \brief Registration function for sameip: keyword + * \todo add support for no_stream and stream_only + */ +void DetectSameipRegister(void) +{ + sigmatch_table[DETECT_SAMEIP].name = "sameip"; + sigmatch_table[DETECT_SAMEIP].Match = DetectSameipMatch; + sigmatch_table[DETECT_SAMEIP].Setup = DetectSameipSetup; + sigmatch_table[DETECT_SAMEIP].Free = NULL; + sigmatch_table[DETECT_SAMEIP].RegisterTests = DetectSameipRegisterTests; +} + +/** + * \internal + * \brief This function is used to match packets with same src/dst IPs + * + * \param t pointer to thread vars + * \param det_ctx pointer to the pattern matcher thread + * \param p pointer to the current packet + * \param m pointer to the sigmatch that we will cast into DetectSameipData + * + * \retval 0 no match + * \retval 1 match + */ +static int DetectSameipMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, + Packet *p, Signature *s, SigMatch *m) +{ + return CMP_ADDR(&p->src, &p->dst) ? 1 : 0; +} + +/** + * \internal + * \brief this function is used to add the sameip option into the signature + * + * \param de_ctx pointer to the Detection Engine Context + * \param s pointer to the Current Signature + * \param m pointer to the Current SigMatch + * \param optstr pointer to the user provided options + * + * \retval 0 on Success + * \retval -1 on Failure + */ +static int DetectSameipSetup(DetectEngineCtx *de_ctx, Signature *s, + SigMatch *m, char *optstr) +{ + SigMatch *sm = NULL; + + // printf("DetectSameipSetup: \'%s\'\n", optstr); + + /* Get this into a SigMatch and put it in the Signature. */ + sm = SigMatchAlloc(); + if (sm == NULL) + goto error; + + sm->type = DETECT_SAMEIP; + sm->ctx = NULL; + + SigMatchAppend(s, m, sm); + + return 0; + +error: + if (sm != NULL) + free(sm); + return -1; + +} + +#ifdef UNITTESTS + +/* NOTE: No parameters, so no parse tests */ + +/** + * \internal + * \brief This test tests sameip success and failure. + */ +static int DetectSameipSigTest01Real(int mpm_type) +{ + uint8_t *buf = (uint8_t *) + "GET / HTTP/1.0\r\n" + "\r\n"; + uint16_t buflen = strlen((char *)buf); + Packet p[2]; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + + /* First packet has same IPs */ + memset(&p[0], 0, sizeof(p[0])); + p[0].src.family = AF_INET; + p[0].dst.family = AF_INET; + p[0].src.addr_data32[0] = 0x01020304; + p[0].dst.addr_data32[0] = 0x01020304; + p[0].payload = buf; + p[0].payload_len = buflen; + p[0].proto = IPPROTO_TCP; + + /* Second packet does not have same IPs */ + memset(&p[1], 0, sizeof(p[1])); + p[1].src.family = AF_INET; + p[1].dst.family = AF_INET; + p[1].src.addr_data32[0] = 0x01020304; + p[1].dst.addr_data32[0] = 0x04030201; + p[1].payload = buf; + p[1].payload_len = buflen; + p[1].proto = IPPROTO_TCP; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing sameip\";sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + de_ctx->sig_list->next = SigInit(de_ctx, + "alert tcp any any -> any any " + "(msg:\"Testing sameip\";sameip;sid:2;)"); + if (de_ctx->sig_list->next == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + PatternMatchPrepare(mpm_ctx, mpm_type); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[0]); + if (PacketAlertCheck(&p[0], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[0], 2) == 0) { + printf("sid 2 did not alert, but should have: "); + goto cleanup; + } + + SigMatchSignatures(&th_v, de_ctx, det_ctx, &p[1]); + if (PacketAlertCheck(&p[1], 1) != 0) { + printf("sid 1 alerted, but should not have: "); + goto cleanup; + } + if (PacketAlertCheck(&p[1], 2) != 0) { + printf("sid 2 alerted, but should not have: "); + goto cleanup; + } + + result = 1; + +cleanup: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + PatternMatchDestroy(mpm_ctx); + DetectEngineCtxFree(de_ctx); + +end: + return result; +} + +/** + * \test DetectSameipSigTest01B2g tests sameip under B2g MPM + */ +static int DetectSameipSigTest01B2g(void) +{ + return DetectSameipSigTest01Real(MPM_B2G); +} + +/** + * \test DetectSameipSigTest01B2g tests sameip under B3g MPM + */ +static int DetectSameipSigTest01B3g(void) +{ + return DetectSameipSigTest01Real(MPM_B3G); +} + +/** + * \test DetectSameipSigTest01B2g tests sameip under WuManber MPM + */ +static int DetectSameipSigTest01Wm(void) +{ + return DetectSameipSigTest01Real(MPM_WUMANBER); +} + +#endif /* UNITTESTS */ + +/** + * \internal + * \brief This function registers unit tests for DetectSameip + */ +static void DetectSameipRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectSameipSigTest01B2g", DetectSameipSigTest01B2g, 1); + UtRegisterTest("DetectSameipSigTest01B3g", DetectSameipSigTest01B3g, 1); + UtRegisterTest("DetectSameipSigTest01Wm", DetectSameipSigTest01Wm, 1); +#endif /* UNITTESTS */ +} diff --git a/src/detect-sameip.h b/src/detect-sameip.h new file mode 100644 index 0000000000..0c69b73ede --- /dev/null +++ b/src/detect-sameip.h @@ -0,0 +1,7 @@ +#ifndef __DETECT_SAMEIP_H__ +#define __DETECT_SAMEIP_H__ + +/* prototypes */ +void DetectSameipRegister(void); + +#endif /* __DETECT_SAMEIP_H__ */ diff --git a/src/detect.c b/src/detect.c index 397abf3450..1068ff88ca 100644 --- a/src/detect.c +++ b/src/detect.c @@ -31,6 +31,7 @@ #include "detect-rawbytes.h" #include "detect-bytetest.h" #include "detect-bytejump.h" +#include "detect-sameip.h" #include "detect-ipproto.h" #include "detect-within.h" #include "detect-distance.h" @@ -2579,6 +2580,7 @@ void SigTableSetup(void) { DetectRawbytesRegister(); DetectBytetestRegister(); DetectBytejumpRegister(); + DetectSameipRegister(); DetectIPProtoRegister(); DetectWithinRegister(); DetectDistanceRegister(); diff --git a/src/detect.h b/src/detect.h index 068587eb53..6ec782e3e4 100644 --- a/src/detect.h +++ b/src/detect.h @@ -411,6 +411,7 @@ enum { DETECT_RAWBYTES, DETECT_BYTETEST, DETECT_BYTEJUMP, + DETECT_SAMEIP, DETECT_IPPROTO, DETECT_FLOW, DETECT_WINDOW,