From d42b594b5cb347d3c96810cb08e288fd5920740c Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Thu, 22 Dec 2011 15:55:58 +0530 Subject: [PATCH] bug #341 - support for urilen check on both norm and raw buffers --- src/detect-engine-uri.c | 537 +++++++++++++++++++++++++++++++++++++++++++++- src/detect-urilen.c | 155 +++++++++++++- src/detect-urilen.h | 1 + 3 files changed, 669 insertions(+), 24 deletions(-) diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index 3b78a3d..4569377 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -78,7 +78,8 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) + uint8_t *payload, uint32_t payload_len, + htp_tx_t *tx) { SCEnter(); @@ -272,7 +273,7 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, /* see if the next payload keywords match. If not, we will * search for another occurence of this uricontent and see * if the others match then until we run out of matches */ - int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len); + int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len, tx); if (r == 1) { SCReturnInt(1); } @@ -314,7 +315,7 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, * search for another occurence of this pcre and see * if the others match, until we run out of matches */ r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, - payload, payload_len); + payload, payload_len, tx); if (r == 1) { SCReturnInt(1); } @@ -359,23 +360,26 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, int r = 0; DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx; + uint32_t p_len = payload_len; + if (urilend->raw_buffer) + p_len = bstr_len(tx->request_uri); switch (urilend->mode) { case DETECT_URILEN_EQ: - if (payload_len == urilend->urilen1) + if (p_len == urilend->urilen1) r = 1; break; case DETECT_URILEN_LT: - if (payload_len < urilend->urilen1) + if (p_len < urilend->urilen1) r = 1; break; case DETECT_URILEN_GT: - if (payload_len > urilend->urilen1) + if (p_len > urilend->urilen1) r = 1; break; case DETECT_URILEN_RA: - if (payload_len > urilend->urilen1 && - payload_len < urilend->urilen2) + if (p_len > urilend->urilen1 && + p_len < urilend->urilen2) r = 1; break; } @@ -409,7 +413,7 @@ match: * the payload portion of the signature matched. */ if (sm->next != NULL) { int r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, payload, - payload_len); + payload_len, tx); SCReturnInt(r); } else { SCReturnInt(1); @@ -481,9 +485,8 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx, /* Inspect all the uricontents fetched on each * transaction at the app layer */ r = DoInspectPacketUri(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH], - (uint8_t *) bstr_ptr(tx->request_uri_normalized), - bstr_len(tx->request_uri_normalized)); - + (uint8_t *)bstr_ptr(tx->request_uri_normalized), + bstr_len(tx->request_uri_normalized), tx); if (r == 1) { break; } @@ -3747,6 +3750,510 @@ end: return result; } +static int UriTestSig33(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:15; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 didn't alert, but it should have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +static int UriTestSig34(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:15, norm; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 didn't alert, but it should have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +static int UriTestSig35(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:16; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 alerted, but it shouldn't have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +static int UriTestSig36(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:16, norm; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 alerted, but it shouldn't have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +static int UriTestSig37(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:17, raw; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 didn't alert, but it should have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +static int UriTestSig38(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " + "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative uricontents\"; " + "urilen:18, raw; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 alerted, but it shouldn't have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + #endif /* UNITTESTS */ void UriRegisterTests(void) @@ -3786,6 +4293,12 @@ void UriRegisterTests(void) UtRegisterTest("UriTestSig30", UriTestSig30, 1); UtRegisterTest("UriTestSig31", UriTestSig31, 1); UtRegisterTest("UriTestSig32", UriTestSig32, 1); + UtRegisterTest("UriTestSig33", UriTestSig33, 1); + UtRegisterTest("UriTestSig34", UriTestSig34, 1); + UtRegisterTest("UriTestSig35", UriTestSig35, 1); + UtRegisterTest("UriTestSig36", UriTestSig36, 1); + UtRegisterTest("UriTestSig37", UriTestSig37, 1); + UtRegisterTest("UriTestSig38", UriTestSig38, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-urilen.c b/src/detect-urilen.c index 14e1b21..1349453 100644 --- a/src/detect-urilen.c +++ b/src/detect-urilen.c @@ -42,7 +42,7 @@ /** * \brief Regex for parsing our urilen */ -#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?(?:\\s*)$" +#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?\\s*(?:,\\s*(norm|raw))?\\s*$" static pcre *parse_regex; static pcre_extra *parse_regex_study; @@ -176,13 +176,14 @@ DetectUrilenData *DetectUrilenParse (char *urilenstr) char *arg2 = NULL; char *arg3 = NULL; char *arg4 = NULL; + char *arg5 = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; ret = pcre_exec(parse_regex, parse_regex_study, urilenstr, strlen(urilenstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 5) { + if (ret < 3 || ret > 6) { SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32 "", ret); goto error; } @@ -224,13 +225,21 @@ DetectUrilenData *DetectUrilenParse (char *urilenstr) arg4 = (char *) str_ptr; SCLogDebug("Arg4 \"%s\"", arg4); } + if (ret > 5) { + res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 5, &str_ptr); + if (res < 0) { + SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); + goto error; + } + arg5 = (char *) str_ptr; + SCLogDebug("Arg5 \"%s\"", arg5); + } } urilend = SCMalloc(sizeof (DetectUrilenData)); if (urilend == NULL) goto error; - urilend->urilen1 = 0; - urilend->urilen2 = 0; + memset(urilend, 0, sizeof(DetectUrilenData)); if (arg1[0] == '<') urilend->mode = DETECT_URILEN_LT; @@ -274,14 +283,22 @@ DetectUrilenData *DetectUrilenParse (char *urilenstr) } } + if (arg5 != NULL) { + if (strcasecmp("raw", arg5) == 0) { + urilend->raw_buffer = 1; + } + } + if (arg1 != NULL) - SCFree(arg1); + pcre_free_substring(arg1); if (arg2 != NULL) - SCFree(arg2); + pcre_free_substring(arg2); if (arg3 != NULL) - SCFree(arg3); + pcre_free_substring(arg3); if (arg4 != NULL) - SCFree(arg4); + pcre_free_substring(arg4); + if (arg5 != NULL) + pcre_free_substring(arg5); return urilend; error: @@ -367,7 +384,8 @@ static int DetectUrilenParseTest01(void) urilend = DetectUrilenParse("10"); if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ) + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ && + !urilend->raw_buffer) ret = 1; DetectUrilenFree(urilend); @@ -383,7 +401,8 @@ static int DetectUrilenParseTest02(void) urilend = DetectUrilenParse(" < 10 "); if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT) + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && + !urilend->raw_buffer) ret = 1; DetectUrilenFree(urilend); @@ -399,7 +418,8 @@ static int DetectUrilenParseTest03(void) urilend = DetectUrilenParse(" > 10 "); if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT) + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && + !urilend->raw_buffer) ret = 1; DetectUrilenFree(urilend); @@ -416,7 +436,112 @@ static int DetectUrilenParseTest04(void) urilend = DetectUrilenParse(" 5 <> 10 "); if (urilend != NULL) { if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && - urilend->mode == DETECT_URILEN_RA) + urilend->mode == DETECT_URILEN_RA && + !urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest05(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse("5<>10,norm"); + if (urilend != NULL) { + if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && + urilend->mode == DETECT_URILEN_RA && + !urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest06(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse("5<>10,raw"); + if (urilend != NULL) { + if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && + urilend->mode == DETECT_URILEN_RA && + urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest07(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse(">10, norm "); + if (urilend != NULL) { + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && + !urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest08(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse("<10, norm "); + if (urilend != NULL) { + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && + !urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest09(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse(">10, raw "); + if (urilend != NULL) { + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && + urilend->raw_buffer) + ret = 1; + + DetectUrilenFree(urilend); + } + return ret; +} + +/** \test Test the Urilen keyword setup */ +static int DetectUrilenParseTest10(void) +{ + int ret = 0; + DetectUrilenData *urilend = NULL; + + urilend = DetectUrilenParse("<10, raw "); + if (urilend != NULL) { + if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && + urilend->raw_buffer) ret = 1; DetectUrilenFree(urilend); @@ -610,6 +735,12 @@ void DetectUrilenRegisterTests(void) UtRegisterTest("DetectUrilenParseTest02", DetectUrilenParseTest02, 1); UtRegisterTest("DetectUrilenParseTest03", DetectUrilenParseTest03, 1); UtRegisterTest("DetectUrilenParseTest04", DetectUrilenParseTest04, 1); + UtRegisterTest("DetectUrilenParseTest05", DetectUrilenParseTest05, 1); + UtRegisterTest("DetectUrilenParseTest06", DetectUrilenParseTest06, 1); + UtRegisterTest("DetectUrilenParseTest07", DetectUrilenParseTest07, 1); + UtRegisterTest("DetectUrilenParseTest08", DetectUrilenParseTest08, 1); + UtRegisterTest("DetectUrilenParseTest09", DetectUrilenParseTest09, 1); + UtRegisterTest("DetectUrilenParseTest10", DetectUrilenParseTest10, 1); UtRegisterTest("DetectUrilenSetpTest01", DetectUrilenSetpTest01, 1); UtRegisterTest("DetectUrilenSigTest01", DetectUrilenSigTest01, 1); #endif /* UNITTESTS */ diff --git a/src/detect-urilen.h b/src/detect-urilen.h index b83892f..c853011 100644 --- a/src/detect-urilen.h +++ b/src/detect-urilen.h @@ -33,6 +33,7 @@ typedef struct DetectUrilenData_ { uint16_t urilen1; /**< 1st Uri Length value in the signature*/ uint16_t urilen2; /**< 2nd Uri Length value in the signature*/ uint8_t mode; /**< operator used in the signature */ + uint8_t raw_buffer; }DetectUrilenData; int DetectUrilenMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, -- 1.7.1