diff --git a/src/detect-engine-hhd.c b/src/detect-engine-hhd.c index 651cde7823..814a23daee 100644 --- a/src/detect-engine-hhd.c +++ b/src/detect-engine-hhd.c @@ -138,7 +138,7 @@ static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id, if (flags & STREAM_TOSERVER) { if (size1 == 6 && - SCMemcmpLowercase("cookie", bstr_ptr(h->name), 6)) { + SCMemcmpLowercase("cookie", bstr_ptr(h->name), 6) == 0) { continue; } } else { @@ -3231,6 +3231,101 @@ end: return result; } +/** \test reassembly bug where headers with names of length 6 were + * skipped + */ +static int DetectEngineHttpHeaderTest31(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Accept: blah\r\n" + "Cookie: blah\r\n" + "Crazy6: blah\r\n" + "SixZix: blah\r\n\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Accept|3a|\"; http_header; " + "content:!\"Cookie|3a|\"; http_header; " + "content:\"Crazy6|3a|\"; http_header; " + "content:\"SixZix|3a|\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (!(PacketAlertCheck(p1, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + #endif /* UNITTESTS */ void DetectEngineHttpHeaderRegisterTests(void) @@ -3297,6 +3392,8 @@ void DetectEngineHttpHeaderRegisterTests(void) DetectEngineHttpHeaderTest29, 1); UtRegisterTest("DetectEngineHttpHeaderTest30", DetectEngineHttpHeaderTest30, 1); + UtRegisterTest("DetectEngineHttpHeaderTest31", + DetectEngineHttpHeaderTest31, 1); #if 0 UtRegisterTest("DetectEngineHttpHeaderTest30", DetectEngineHttpHeaderTest30, 1);