From 6cc4a260375c292e592f762f4efe41d5e01719b6 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Fri, 31 Dec 2010 18:22:38 +0530 Subject: [PATCH 3/3] support isdataat negation. Also fix addiing isdataat to appropriate lists --- src/detect-engine-payload.c | 58 +++++ src/detect-engine-uri.c | 209 ++++++++++++++++++ src/detect-isdataat.c | 495 +++++++++++++++++++++++++++++++++++++++---- src/detect-isdataat.h | 1 + src/detect-parse.c | 18 ++ src/detect-parse.h | 1 + 6 files changed, 743 insertions(+), 39 deletions(-) diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index 23f2b81..3728370 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -269,17 +269,25 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx, if (id->flags & ISDATAAT_RELATIVE) { if (det_ctx->payload_offset + id->dataat > payload_len) { SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; SCReturnInt(0); } else { SCLogDebug("relative isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); goto match; } } else { if (id->dataat < payload_len) { SCLogDebug("absolute isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); goto match; } else { SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; SCReturnInt(0); } } @@ -855,6 +863,52 @@ end: return result; } +static int PayloadTestSig15(void) +{ + uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; + uint16_t buflen = strlen((char *)buf); + Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); + int result = 0; + + char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " + "content:nova; isdataat:18,relative; sid:1;)"; + + if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { + result = 0; + goto end; + } + + result = 1; + +end: + if (p != NULL) + UTHFreePacket(p); + return result; +} + +static int PayloadTestSig16(void) +{ + uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; + uint16_t buflen = strlen((char *)buf); + Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); + int result = 0; + + char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " + "content:nova; isdataat:!20,relative; sid:1;)"; + + if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { + result = 0; + goto end; + } + + result = 1; + +end: + if (p != NULL) + UTHFreePacket(p); + return result; +} + #endif /* UNITTESTS */ void PayloadRegisterTests(void) { @@ -873,5 +927,9 @@ void PayloadRegisterTests(void) { UtRegisterTest("PayloadTestSig12", PayloadTestSig12, 1); UtRegisterTest("PayloadTestSig13", PayloadTestSig13, 1); UtRegisterTest("PayloadTestSig14", PayloadTestSig14, 1); + UtRegisterTest("PayloadTestSig15", PayloadTestSig15, 1); + UtRegisterTest("PayloadTestSig16", PayloadTestSig16, 1); #endif /* UNITTESTS */ + + return; } diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index a4837df..26316b7 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -292,6 +292,35 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, det_ctx->payload_offset = prev_payload_offset; det_ctx->pcre_match_start_offset = prev_offset; } while (1); + } else if (sm->type == DETECT_ISDATAAT) { + SCLogDebug("inspecting isdataat"); + + DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; + if (id->flags & ISDATAAT_RELATIVE) { + if (det_ctx->payload_offset + id->dataat > payload_len) { + SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; + SCReturnInt(0); + } else { + SCLogDebug("relative isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); + goto match; + } + } else { + if (id->dataat < payload_len) { + SCLogDebug("absolute isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); + goto match; + } else { + SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; + SCReturnInt(0); + } + } } else if (sm->type == DETECT_AL_URILEN) { SCLogDebug("inspecting uri len"); @@ -3080,6 +3109,184 @@ end: return result; } +/** + * \test Test multiple relative contents with a negated content. + */ +static int UriTestSig26(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" + "User-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.src.family = AF_INET; + f.dst.family = AF_INET; + + p->flow = &f; + p->flags |= PKT_HAS_FLOW; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + 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\"; " + "uricontent:fix_this; isdataat:4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&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.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + 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; +} + +/** + * \test Test multiple relative contents with a negated content. + */ +static int UriTestSig27(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" + "User-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.src.family = AF_INET; + f.dst.family = AF_INET; + + p->flow = &f; + p->flags |= PKT_HAS_FLOW; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + 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\"; " + "uricontent:fix_this; isdataat:!10,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&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.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + 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; +} + #endif /* UNITTESTS */ void UriRegisterTests(void) @@ -3111,6 +3318,8 @@ void UriRegisterTests(void) UtRegisterTest("UriTestSig23", UriTestSig23, 1); UtRegisterTest("UriTestSig24", UriTestSig24, 1); UtRegisterTest("UriTestSig25", UriTestSig25, 1); + UtRegisterTest("UriTestSig26", UriTestSig26, 1); + UtRegisterTest("UriTestSig27", UriTestSig27, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index a3cba56..21449a3 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -49,7 +49,7 @@ /** * \brief Regex for parsing our isdataat options */ -#define PARSE_REGEX "^\\s*([0-9]{1,5})\\s*(,\\s*relative)?\\s*(,\\s*rawbytes\\s*)?\\s*$" +#define PARSE_REGEX "^\\s*!?([0-9]{1,5})\\s*(,\\s*relative)?\\s*(,\\s*rawbytes\\s*)?\\s*$" static pcre *parse_regex; static pcre_extra *parse_regex_study; @@ -200,6 +200,10 @@ DetectIsdataatData *DetectIsdataatParse (char *isdataatstr) idad->flags |= ISDATAAT_RAWBYTES; } + if (isdataatstr[0] == '!') { + idad->flags |= ISDATAAT_NEGATED; + } + for (i = 0; i < (ret -1); i++) { if (args[i] != NULL) SCFree(args[i]); @@ -235,6 +239,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst { DetectIsdataatData *idad = NULL; SigMatch *sm = NULL; + SigMatch *dm = NULL; + SigMatch *pm = NULL; + SigMatch *prev_pm = NULL; idad = DetectIsdataatParse(isdataatstr); if (idad == NULL) @@ -249,8 +256,6 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst if (s->alproto == ALPROTO_DCERPC && idad->flags & ISDATAAT_RELATIVE) { - SigMatch *pm = NULL; - SigMatch *dm = NULL; pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], @@ -270,40 +275,106 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst } else { SigMatchAppendDcePayload(s, sm); } + prev_pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, sm->prev, + DETECT_BYTEJUMP, sm->prev, + DETECT_PCRE, sm->prev); } else { - SigMatchAppendPayload(s, sm); + pm = SigMatchGetLastSMFromLists(s, 30, + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], + DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], + DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], + DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], + DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); + if (pm == NULL) { + if (idad->flags & ISDATAAT_RELATIVE) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " + "without a previous content uricontent, " + "http_client_body, http_header, http_raw_header, " + "http_method or http_cookie keyword"); + goto error; + } else { + SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); + } + } else { + int list_type; + if (pm->type == DETECT_PCRE || pm->type == DETECT_BYTEJUMP) { + list_type = SigMatchListSMBelongsTo(s, pm); + if (list_type == -1) { + goto error; + } + } else { + switch (pm->type) { + case DETECT_CONTENT: + list_type = DETECT_SM_LIST_PMATCH; + break; + case DETECT_URICONTENT: + list_type = DETECT_SM_LIST_UMATCH; + break; + case DETECT_AL_HTTP_CLIENT_BODY: + list_type = DETECT_SM_LIST_HCBDMATCH; + break; + case DETECT_AL_HTTP_RAW_HEADER: + list_type = DETECT_SM_LIST_HRHDMATCH; + break; + case DETECT_AL_HTTP_HEADER: + list_type = DETECT_SM_LIST_HHDMATCH; + break; + case DETECT_AL_HTTP_METHOD: + list_type = DETECT_SM_LIST_HMDMATCH; + break; + case DETECT_AL_HTTP_COOKIE: + list_type = DETECT_SM_LIST_HCDMATCH; + break; + } /* switch */ + } /* else */ + + SigMatchAppendSMToList(s, sm, list_type); + } /* else - if (pm == NULL) */ + + prev_pm = pm; } - if ( !(idad->flags & ISDATAAT_RELATIVE)) { + if (!(idad->flags & ISDATAAT_RELATIVE)) { return 0; } - SigMatch *prev_sm = NULL; - prev_sm = SigMatchGetLastSMFromLists(s, 8, - DETECT_CONTENT, sm->prev, - DETECT_URICONTENT, sm->prev, - DETECT_BYTEJUMP, sm->prev, - DETECT_PCRE, sm->prev); - if (prev_sm == NULL) { + if (prev_pm == NULL) { if (s->alproto == ALPROTO_DCERPC) { SCLogDebug("No preceding content or pcre keyword. Possible " - "since this is an alproto sig."); + "since this is a dce alproto sig."); return 0; } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " - "or uricontent or pcre option"); - return -1; + SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, " + "uricontent, http_client_body, http_header, " + "http_raw_header, http_method or http_cookie keyword"); + goto error; } } DetectContentData *cd = NULL; - DetectContentData *ud = NULL; DetectPcreData *pe = NULL; - switch (prev_sm->type) { + switch (prev_pm->type) { case DETECT_CONTENT: + case DETECT_URICONTENT: + case DETECT_AL_HTTP_CLIENT_BODY: + case DETECT_AL_HTTP_HEADER: + case DETECT_AL_HTTP_RAW_HEADER: + case DETECT_AL_HTTP_METHOD: + case DETECT_AL_HTTP_COOKIE: /* Set the relative next flag on the prev sigmatch */ - cd = (DetectContentData *)prev_sm->ctx; + cd = (DetectContentData *)prev_pm->ctx; if (cd == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); @@ -313,20 +384,8 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst break; - case DETECT_URICONTENT: - /* Set the relative next flag on the prev sigmatch */ - ud = (DetectContentData *)prev_sm->ctx; - if (ud == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" - "previous keyword!"); - return -1; - } - ud->flags |= DETECT_CONTENT_RELATIVE_NEXT; - - break; - case DETECT_PCRE: - pe = (DetectPcreData *)prev_sm->ctx; + pe = (DetectPcreData *)prev_pm->ctx; if (pe == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); @@ -337,9 +396,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst break; case DETECT_BYTEJUMP: - SCLogDebug("No setting relative_next for bytejump. We " - "have no use for it"); - + SCLogDebug("Do nothing for bytejump"); break; default: @@ -352,10 +409,10 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst return 0; error: - if (idad != NULL) - DetectIsdataatFree(idad); - if (sm != NULL) - SCFree(sm); + //if (idad != NULL) + // DetectIsdataatFree(idad); + //if (sm != NULL) + // SCFree(sm); return -1; } @@ -550,6 +607,358 @@ int DetectIsdataatTestParse05(void) return result; } +int DetectIsdataatTestParse06(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse07(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "uricontent:one; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse08(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_uri; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse09(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_client_body; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse10(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_header; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse11(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_raw_header; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse12(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_method; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectIsdataatTestParse13(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + DetectIsdataatData *data = NULL; + + 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 bytejump_body\"; " + "content:one; http_cookie; " + "isdataat:!4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + s = de_ctx->sig_list; + if (s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] == NULL) { + goto end; + } + + result = 1; + + result &= (s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->type == DETECT_ISDATAAT); + data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) || + !(data->flags & ISDATAAT_NEGATED) ) { + result = 0; + goto end; + } + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + /** * \test DetectIsdataatTestPacket01 is a test to check matches of * isdataat, and isdataat relative @@ -663,6 +1072,14 @@ void DetectIsdataatRegisterTests(void) { UtRegisterTest("DetectIsdataatTestParse03", DetectIsdataatTestParse03, 1); UtRegisterTest("DetectIsdataatTestParse04", DetectIsdataatTestParse04, 1); UtRegisterTest("DetectIsdataatTestParse05", DetectIsdataatTestParse05, 1); + UtRegisterTest("DetectIsdataatTestParse06", DetectIsdataatTestParse06, 1); + UtRegisterTest("DetectIsdataatTestParse07", DetectIsdataatTestParse07, 1); + UtRegisterTest("DetectIsdataatTestParse08", DetectIsdataatTestParse08, 1); + UtRegisterTest("DetectIsdataatTestParse09", DetectIsdataatTestParse09, 1); + UtRegisterTest("DetectIsdataatTestParse10", DetectIsdataatTestParse10, 1); + UtRegisterTest("DetectIsdataatTestParse11", DetectIsdataatTestParse11, 1); + UtRegisterTest("DetectIsdataatTestParse12", DetectIsdataatTestParse12, 1); + UtRegisterTest("DetectIsdataatTestParse13", DetectIsdataatTestParse13, 1); UtRegisterTest("DetectIsdataatTestPacket01", DetectIsdataatTestPacket01, 1); UtRegisterTest("DetectIsdataatTestPacket02", DetectIsdataatTestPacket02, 1); UtRegisterTest("DetectIsdataatTestPacket03", DetectIsdataatTestPacket03, 1); diff --git a/src/detect-isdataat.h b/src/detect-isdataat.h index 2159926..daaa8eb 100644 --- a/src/detect-isdataat.h +++ b/src/detect-isdataat.h @@ -26,6 +26,7 @@ #define ISDATAAT_RELATIVE 0x01 #define ISDATAAT_RAWBYTES 0x02 +#define ISDATAAT_NEGATED 0x04 #define ISDATAAT_MIN 0 #define ISDATAAT_MAX 65535 diff --git a/src/detect-parse.c b/src/detect-parse.c index 1985301..07ebee3 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -581,6 +581,24 @@ void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, return; } +int SigMatchListSMBelongsTo(Signature *s, SigMatch *key_sm) +{ + int list = 0; + + for (list = 0; list < DETECT_SM_LIST_MAX; list++) { + SigMatch *sm = s->sm_lists[list]; + while (sm != NULL) { + if (sm == key_sm) + return list; + sm = sm->next; + } + } + + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unable to find the sm in any of the " + "sm lists"); + return -1; +} + void SigParsePrepare(void) { char *regexstr = CONFIG_PCRE; const char *eb; diff --git a/src/detect-parse.h b/src/detect-parse.h index d37b679..575234d 100644 --- a/src/detect-parse.h +++ b/src/detect-parse.h @@ -64,6 +64,7 @@ void SigMatchAppendUricontent(Signature *, SigMatch *); void SigMatchAppendAppLayer(Signature *, SigMatch *); void SigMatchAppendTag(Signature *, SigMatch *); void SigMatchAppendSMToList(Signature *, SigMatch *, int); +int SigMatchListSMBelongsTo(Signature *, SigMatch *); int DetectParseDupSigHashInit(DetectEngineCtx *); void DetectParseDupSigHashFree(DetectEngineCtx *); -- 1.7.1