diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index a969c500f8..d18f0cc822 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -582,6 +582,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, s->flags |= SIG_FLAG_MPM_PACKET; s->mpm_pattern_id_div_8 = cd->id / 8; s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); + if (cd->flags & DETECT_CONTENT_NEGATED) { + SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); + s->flags |= SIG_FLAG_MPM_PACKET_NEG; + } } if (SignatureHasStreamContent(s) && (sgh->flags & SIG_GROUP_HAVESTREAMCONTENT && @@ -604,6 +608,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, s->flags |= SIG_FLAG_MPM_STREAM; s->mpm_stream_pattern_id_div_8 = cd->id / 8; s->mpm_stream_pattern_id_mod_8 = 1 << (cd->id % 8); + if (cd->flags & DETECT_CONTENT_NEGATED) { + SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); + s->flags |= SIG_FLAG_MPM_STREAM_NEG; + } } } else { @@ -665,6 +673,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, s->flags |= SIG_FLAG_MPM_PACKET; s->mpm_pattern_id_div_8 = cd->id / 8; s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); + if (cd->flags & DETECT_CONTENT_NEGATED) { + SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); + s->flags |= SIG_FLAG_MPM_PACKET_NEG; + } } if (SignatureHasStreamContent(s) && (sgh->flags & SIG_GROUP_HAVESTREAMCONTENT @@ -686,10 +698,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, s->flags |= SIG_FLAG_MPM_STREAM; s->mpm_stream_pattern_id_div_8 = cd->id / 8; s->mpm_stream_pattern_id_mod_8 = 1 << (cd->id % 8); - } - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); - s->flags |= SIG_FLAG_MPM_NEGCONTENT; + if (cd->flags & DETECT_CONTENT_NEGATED) { + SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); + s->flags |= SIG_FLAG_MPM_STREAM_NEG; + } } } diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index b37e525dab..271ff8475e 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -97,11 +97,13 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx, * (if there is any other reason why we'd want to avoid checking * it here, please fill it in) */ if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_INSPECTING_PACKET) { - if (cd->flags & DETECT_CONTENT_PACKET_MPM) + if (cd->flags & DETECT_CONTENT_PACKET_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) { goto match; + } } else if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM) { - if (cd->flags & DETECT_CONTENT_STREAM_MPM) + if (cd->flags & DETECT_CONTENT_STREAM_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) { goto match; + } } /* rule parsers should take care of this */ @@ -824,6 +826,31 @@ static int PayloadTestSig13(void) return result; } +/** + * \test normal & negated matching, both absolute and relative + */ +static int PayloadTestSig14(void) +{ + uint8_t *buf = (uint8_t *)"User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.6 GTB5"; + uint16_t buflen = strlen((char *)buf); + Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); + int result = 0; + + char sig[] = "alert tcp any any -> any any (content:\"User-Agent|3A| Mozilla/5.0 |28|Macintosh|3B| \"; content:\"Firefox/3.\"; distance:0; content:!\"Firefox/3.6.12\"; distance:-10; content:!\"Mozilla/5.0 |28|Macintosh|3B| U|3B| Intel Mac OS X 10.5|3B| en-US|3B| rv|3A|1.9.1b4|29| Gecko/20090423 Firefox/3.6 GTB5\"; sid:1; rev:1;)"; + + //char sig[] = "alert tcp any any -> any any (content:\"User-Agent: Mozilla/5.0 (Macintosh; \"; content:\"Firefox/3.\"; distance:0; content:!\"Firefox/3.6.12\"; distance:-10; content:!\"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.6 GTB5\"; sid:1; rev:1;)"; + + if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 1) { + goto end; + } + + result = 1; +end: + if (p != NULL) + UTHFreePacket(p); + return result; +} + #endif /* UNITTESTS */ void PayloadRegisterTests(void) { @@ -841,5 +868,6 @@ void PayloadRegisterTests(void) { UtRegisterTest("PayloadTestSig11", PayloadTestSig11, 1); UtRegisterTest("PayloadTestSig12", PayloadTestSig12, 1); UtRegisterTest("PayloadTestSig13", PayloadTestSig13, 1); + UtRegisterTest("PayloadTestSig14", PayloadTestSig14, 1); #endif /* UNITTESTS */ } diff --git a/src/detect.c b/src/detect.c index c9ab200154..912a96c313 100644 --- a/src/detect.c +++ b/src/detect.c @@ -641,7 +641,7 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, //if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id / 8)] & (1<<(s->mpm_pattern_id % 8)))) { //SCLogDebug("mpm sig without matches (pat id %"PRIu32" check in content).", s->mpm_pattern_id); - if (!(s->flags & SIG_FLAG_MPM_NEGCONTENT)) { + if (!(s->flags & SIG_FLAG_MPM_PACKET_NEG)) { /* pattern didn't match. There is one case where we will inspect * the signature anyway: if the packet payload was added to the * stream it is not scanned itself: the stream data is inspected. @@ -662,7 +662,7 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_stream_pattern_id_div_8)] & s->mpm_stream_pattern_id_mod_8)) { //SCLogDebug("mpm stream sig without matches (pat id %"PRIu32" check in content).", s->mpm_stream_pattern_id); - if (!(s->flags & SIG_FLAG_MPM_NEGCONTENT)) { + if (!(s->flags & SIG_FLAG_MPM_STREAM_NEG)) { /* pattern didn't match. There is one case where we will inspect * the signature anyway: if the packet payload was added to the * stream it is not scanned itself: the stream data is inspected. @@ -1111,7 +1111,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh /* filter out sigs that want pattern matches, but * have no matches */ if (!(det_ctx->smsg_pmq[pmq_idx].pattern_id_bitarray[(s->mpm_stream_pattern_id_div_8)] & s->mpm_stream_pattern_id_mod_8) && - (s->flags & SIG_FLAG_MPM) && !(s->flags & SIG_FLAG_MPM_NEGCONTENT)) { + (s->flags & SIG_FLAG_MPM_STREAM) && !(s->flags & SIG_FLAG_MPM_STREAM_NEG)) { SCLogDebug("no match in this smsg"); continue; } diff --git a/src/detect.h b/src/detect.h index 3b54c3decb..ab1b2b6204 100644 --- a/src/detect.h +++ b/src/detect.h @@ -231,11 +231,13 @@ typedef struct DetectPort_ { #define SIG_FLAG_HCBDMATCH 0x00200000 #define SIG_FLAG_MPM_PACKET 0x00400000 -#define SIG_FLAG_MPM_STREAM 0x00800000 -#define SIG_FLAG_MPM_URICONTENT 0x01000000 -#define SIG_FLAG_MPM_URICONTENT_NEG 0x02000000 +#define SIG_FLAG_MPM_PACKET_NEG 0x00800000 +#define SIG_FLAG_MPM_STREAM 0x01000000 +#define SIG_FLAG_MPM_STREAM_NEG 0x02000000 +#define SIG_FLAG_MPM_URICONTENT 0x04000000 +#define SIG_FLAG_MPM_URICONTENT_NEG 0x08000000 -#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x04000000 +#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x10000000 /* signature mask flags */ #define SIG_MASK_REQUIRE_PAYLOAD 0x01