diff --git a/src/detect-bytejump.c b/src/detect-bytejump.c index fb705ba68c..e2960f4a13 100644 --- a/src/detect-bytejump.c +++ b/src/detect-bytejump.c @@ -513,13 +513,18 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) { DetectBytejumpData *data = NULL; SigMatch *sm = NULL; - SigMatch *match = NULL; - SigMatch *match_tail = NULL; data = DetectBytejumpParse(optstr); if (data == NULL) goto error; + sm = SigMatchAlloc(); + if (sm == NULL) + goto error; + + sm->type = DETECT_BYTEJUMP; + sm->ctx = (void *)data; + /* check bytejump modifiers against the signature alproto. In case they conflict * chuck out invalid signature */ if (data->flags & DETECT_BYTEJUMP_DCE) { @@ -542,81 +547,105 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) } if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - - switch (s->alproto) { - case ALPROTO_DCERPC: - match = s->dmatch; - match_tail = s->dmatch_tail; - break; - - default: - match = s->pmatch; - match_tail = s->pmatch_tail; - break; + SCLogDebug("Set it in the last parsed content because it is relative " + "to that content based keyword"); + + SigMatch *m = NULL; + if (s->alproto == ALPROTO_DCERPC) { + m = SigMatchGetLastSMFromLists(s, 12, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail, + DETECT_CONTENT, s->dmatch_tail, + DETECT_PCRE, s->dmatch_tail, + DETECT_BYTEJUMP, s->dmatch_tail); + } else { + m = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); } - /* Search for the first previous DetectContent SigMatch (it can be the - * same as this one) */ - SigMatch *pm = NULL; - if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) { - DetectContentData *cd = (DetectContentData *)pm->ctx; - if (cd == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match " - "needs a previous content option"); + DetectContentData *cd = NULL; + DetectPcreData *pe = NULL; + if (m == NULL) { + if (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("bytejump-relative without a previous content based " + "keyword. Holds good only in the case of DCERPC " + "alproto like now."); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No related " + "previous-previous content or pcre keyword"); goto error; } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) { - DetectPcreData *pe = NULL; - pe = (DetectPcreData *) pm->ctx; - if (pe == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - pe->flags |= DETECT_PCRE_RELATIVE; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) { - DetectBytejumpData *data = NULL; - data = (DetectBytejumpData *)pm->ctx; - if (data == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match " - "needs a previous content option"); - goto error; - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_BYTEJUMP; - sm->ctx = (void *)data; - - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ + switch (m->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)m->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *) m->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + } /* else for if (m == NULL) */ + } /* if (data->flags & DETECT_BYTEJUMP_RELATIVE) */ + + if (s->alproto == ALPROTO_DCERPC && + data->flags & DETECT_BYTEJUMP_RELATIVE) { + SigMatch *pm = NULL; + SigMatch *dm = NULL; + + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + dm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + + if (pm == NULL) { SigMatchAppendDcePayload(s, sm); - break; - - default: + } else if (dm == NULL) { + SigMatchAppendDcePayload(s, sm); + } else if (pm->idx > dm->idx) { SigMatchAppendPayload(s, sm); - break; + } else { + SigMatchAppendDcePayload(s, sm); + } + } else { + SigMatchAppendPayload(s, sm); } return 0; error: - if (data != NULL) DetectBytejumpFree(data); - if (sm != NULL) SCFree(sm); + if (data != NULL) + DetectBytejumpFree(data); + if (sm != NULL) + SCFree(sm); return -1; } @@ -814,6 +843,7 @@ int DetectBytejumpTestParse09(void) { result &= (DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1); result &= (DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1); result &= (DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1); + result &= (s->dmatch == NULL && s->pmatch != NULL); SigFree(s); return result; @@ -837,8 +867,10 @@ int DetectBytejumpTestParse10(void) de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,dce; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "byte_jump:4,0,align,multiplier 2, " + "post_offset -16,relative,dce; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; @@ -851,7 +883,7 @@ int DetectBytejumpTestParse10(void) result &= (s->dmatch_tail->type == DETECT_BYTEJUMP); bd = (DetectBytejumpData *)s->dmatch_tail->ctx; if (!(bd->flags & DETECT_BYTEJUMP_DCE) && - (bd->flags & DETECT_BYTEJUMP_RELATIVE) && + !(bd->flags & DETECT_BYTEJUMP_RELATIVE) && (bd->flags & DETECT_BYTEJUMP_STRING) && (bd->flags & DETECT_BYTEJUMP_BIG) && (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { @@ -862,7 +894,9 @@ int DetectBytejumpTestParse10(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_jump:4,0,align,multiplier 2, " + "dce_stub_data; " + "content:one; distance:0; " + "byte_jump:4,0,align,multiplier 2, " "post_offset -16,relative,dce; sid:1;)"); if (s->next == NULL) { result = 0; @@ -887,8 +921,10 @@ int DetectBytejumpTestParse10(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_jump:4,0,align,multiplier 2, " - "post_offset -16; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "byte_jump:4,0,align,multiplier 2, " + "post_offset -16,relative; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -901,7 +937,7 @@ int DetectBytejumpTestParse10(void) result &= (s->dmatch_tail->type == DETECT_BYTEJUMP); bd = (DetectBytejumpData *)s->dmatch_tail->ctx; if ((bd->flags & DETECT_BYTEJUMP_DCE) && - (bd->flags & DETECT_BYTEJUMP_RELATIVE) && + !(bd->flags & DETECT_BYTEJUMP_RELATIVE) && (bd->flags & DETECT_BYTEJUMP_STRING) && (bd->flags & DETECT_BYTEJUMP_BIG) && (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { @@ -934,6 +970,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,string,dce; sid:1;)"); if (s != NULL) { @@ -944,6 +981,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_sub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,big,dce; sid:1;)"); if (s != NULL) { @@ -954,6 +992,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,little,dce; sid:1;)"); if (s != NULL) { @@ -964,6 +1003,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,string,hex,dce; sid:1;)"); if (s != NULL) { @@ -974,6 +1014,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,string,dec,dce; sid:1;)"); if (s != NULL) { @@ -984,6 +1025,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,string,oct,dce; sid:1;)"); if (s != NULL) { @@ -994,6 +1036,7 @@ int DetectBytejumpTestParse11(void) s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "content:one; byte_jump:4,0,align,multiplier 2, " "post_offset -16,from_beginning,dce; sid:1;)"); if (s != NULL) { diff --git a/src/detect-bytetest.c b/src/detect-bytetest.c index 134b8a0e29..a87c0517d2 100644 --- a/src/detect-bytetest.c +++ b/src/detect-bytetest.c @@ -530,15 +530,18 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) { DetectBytetestData *data = NULL; SigMatch *sm = NULL; - SigMatch *match = NULL; - SigMatch *match_tail = NULL; - - //printf("DetectBytetestSetup: \'%s\'\n", optstr); data = DetectBytetestParse(optstr); if (data == NULL) goto error; + sm = SigMatchAlloc(); + if (sm == NULL) + goto error; + + sm->type = DETECT_BYTETEST; + sm->ctx = (void *)data; + /* check bytetest modifiers against the signature alproto. In case they conflict * chuck out invalid signature */ if (data-> flags & DETECT_BYTETEST_DCE) { @@ -560,81 +563,105 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) } if (data->flags & DETECT_BYTETEST_RELATIVE) { - - switch (s->alproto) { - case ALPROTO_DCERPC: - match = s->dmatch; - match_tail = s->dmatch_tail; - break; - - default: - match = s->pmatch; - match_tail = s->pmatch_tail; - break; + SCLogDebug("Set it in the last parsed content because it is relative " + "to that content based keyword"); + + SigMatch *m = NULL; + if (s->alproto == ALPROTO_DCERPC) { + m = SigMatchGetLastSMFromLists(s, 12, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail, + DETECT_CONTENT, s->dmatch_tail, + DETECT_PCRE, s->dmatch_tail, + DETECT_BYTEJUMP, s->dmatch_tail); + } else { + m = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); } - /* Search for the first previous DetectContent SigMatch (it can be the - * same as this one) */ - SigMatch *pm = NULL; - if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) { - DetectContentData *cd = (DetectContentData *) pm->ctx; - if (cd == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match " - "needs a previous content option"); - goto error; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) { - DetectPcreData *pe = NULL; - pe = (DetectPcreData *) pm->ctx; - if (pe == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - pe->flags |= DETECT_PCRE_RELATIVE; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) { - DetectBytejumpData *data = NULL; - data = (DetectBytejumpData *)pm->ctx; - if (data == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); + DetectContentData *cd = NULL; + DetectPcreData *pe = NULL; + if (m == NULL) { + if (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("bytejump-relative without a previous content based " + "keyword. Holds good only in the case of DCERPC " + "alproto like now."); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No related " + "previous-previous content or pcre keyword"); goto error; } - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match " - "needs a previous content option"); - goto error; - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_BYTETEST; - sm->ctx = (void *)data; - - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ + switch (m->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)m->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *) m->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + } /* else for if (m == NULL) */ + } /* if (data->flags & DETECT_BYTETEST_RELATIVE) */ + + if (s->alproto == ALPROTO_DCERPC && + data->flags & DETECT_BYTETEST_RELATIVE) { + SigMatch *pm = NULL; + SigMatch *dm = NULL; + + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + dm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + + if (pm == NULL) { SigMatchAppendDcePayload(s, sm); - break; - - default: + } else if (dm == NULL) { + SigMatchAppendDcePayload(s, sm); + } else if (pm->idx > dm->idx) { SigMatchAppendPayload(s, sm); - break; + } else { + SigMatchAppendDcePayload(s, sm); + } + } else { + SigMatchAppendPayload(s, sm); } return 0; error: - if (data != NULL) DetectBytetestFree(data); - if (sm != NULL) SCFree(sm); + if (data != NULL) + DetectBytetestFree(data); + if (sm != NULL) + SCFree(sm); return -1; } @@ -1064,7 +1091,9 @@ int DetectBytetestTestParse20(void) de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_test:1,=,1,6,dce; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "byte_test:1,=,1,6,relative,dce; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; @@ -1077,7 +1106,7 @@ int DetectBytetestTestParse20(void) result &= (s->dmatch_tail->type == DETECT_BYTETEST); bd = (DetectBytetestData *)s->dmatch_tail->ctx; if (!(bd->flags & DETECT_BYTETEST_DCE) && - (bd->flags & DETECT_BYTETEST_RELATIVE) && + !(bd->flags & DETECT_BYTETEST_RELATIVE) && (bd->flags & DETECT_BYTETEST_STRING) && (bd->flags & DETECT_BYTETEST_BIG) && (bd->flags & DETECT_BYTETEST_LITTLE) && @@ -1089,7 +1118,9 @@ int DetectBytetestTestParse20(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_test:1,=,1,6,relative,dce; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "byte_test:1,=,1,6,relative,dce; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1114,7 +1145,9 @@ int DetectBytetestTestParse20(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; byte_test:1,=,1,6; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "byte_test:1,=,1,6,relative; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1127,7 +1160,7 @@ int DetectBytetestTestParse20(void) result &= (s->dmatch_tail->type == DETECT_BYTETEST); bd = (DetectBytetestData *)s->dmatch_tail->ctx; if ((bd->flags & DETECT_BYTETEST_DCE) && - (bd->flags & DETECT_BYTETEST_RELATIVE) && + !(bd->flags & DETECT_BYTETEST_RELATIVE) && (bd->flags & DETECT_BYTETEST_STRING) && (bd->flags & DETECT_BYTETEST_BIG) && (bd->flags & DETECT_BYTETEST_LITTLE) && diff --git a/src/detect-content.c b/src/detect-content.c index cc4a316959..461dac410b 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -437,24 +437,15 @@ static int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, char *cont DetectContentPrint(cd); - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ - SigMatchAppendDcePayload(s, sm); - break; - - default: - SigMatchAppendPayload(s, sm); - break; - } + SigMatchAppendPayload(s, sm); return 0; error: - if (cd != NULL) DetectContentFree(cd); - if (sm != NULL) SCFree(sm); + if (cd != NULL) + DetectContentFree(cd); + if (sm != NULL) + SCFree(sm); return -1; } @@ -1091,15 +1082,13 @@ int DetectContentParseTest18(void) s->alproto = ALPROTO_DCERPC; result &= (DetectContentSetup(de_ctx, s, "one") == 0); - result &= (s->dmatch != NULL); + result &= (s->dmatch == NULL && s->pmatch != NULL); SigFree(s); s = SigAlloc(); - /* failure since we have no preceding content/pcre/bytejump */ result &= (DetectContentSetup(de_ctx, s, "one") == 0); - result &= (s->dmatch == NULL); - result &= (s->pmatch != NULL); + result &= (s->dmatch == NULL && s->pmatch != NULL); end: SigFree(s); @@ -1126,7 +1115,8 @@ int DetectContentParseTest19(void) de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; @@ -1142,7 +1132,7 @@ int DetectContentParseTest19(void) if (data->flags & DETECT_CONTENT_RAWBYTES || data->flags & DETECT_CONTENT_NOCASE || data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || + !(data->flags & DETECT_CONTENT_DISTANCE) || data->flags & DETECT_CONTENT_FAST_PATTERN || data->flags & DETECT_CONTENT_NEGATED ) { result = 0; @@ -1152,7 +1142,8 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; content:two; within:10; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; content:two; within:10; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1179,7 +1170,9 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; offset:5; depth:9; content:two; within:10; offset:10; depth:13; sid:1;)"); + "dce_stub_data; " + "content:one; offset:5; depth:9; distance:0; " + "content:two; within:10; offset:10; depth:13; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1206,7 +1199,7 @@ int DetectContentParseTest19(void) if (data->flags & DETECT_CONTENT_RAWBYTES || data->flags & DETECT_CONTENT_NOCASE || data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || + !(data->flags & DETECT_CONTENT_DISTANCE) || data->flags & DETECT_CONTENT_FAST_PATTERN || data->flags & DETECT_CONTENT_NEGATED ) { result = 0; @@ -1217,7 +1210,9 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; content:two; distance:2; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "content:two; distance:2; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1244,7 +1239,9 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; content:two; within:10; distance:2; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "content:two; within:10; distance:2; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1271,7 +1268,8 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; offset:10; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; offset:10; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1287,7 +1285,7 @@ int DetectContentParseTest19(void) if (data->flags & DETECT_CONTENT_RAWBYTES || data->flags & DETECT_CONTENT_NOCASE || data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || + !(data->flags & DETECT_CONTENT_DISTANCE) || data->flags & DETECT_CONTENT_FAST_PATTERN || data->flags & DETECT_CONTENT_NEGATED ) { result = 0; @@ -1298,7 +1296,8 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; depth:10; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; depth:10; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1314,7 +1313,7 @@ int DetectContentParseTest19(void) if (data->flags & DETECT_CONTENT_RAWBYTES || data->flags & DETECT_CONTENT_NOCASE || data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || + !(data->flags & DETECT_CONTENT_DISTANCE) || data->flags & DETECT_CONTENT_FAST_PATTERN || data->flags & DETECT_CONTENT_NEGATED ) { result = 0; @@ -1325,7 +1324,8 @@ int DetectContentParseTest19(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; offset:10; depth:2; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; offset:10; depth:2; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -1341,7 +1341,7 @@ int DetectContentParseTest19(void) if (data->flags & DETECT_CONTENT_RAWBYTES || data->flags & DETECT_CONTENT_NOCASE || data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || + !(data->flags & DETECT_CONTENT_DISTANCE) || data->flags & DETECT_CONTENT_FAST_PATTERN || data->flags & DETECT_CONTENT_NEGATED ) { result = 0; diff --git a/src/detect-depth.c b/src/detect-depth.c index 39f959e475..5b556f6e68 100644 --- a/src/detect-depth.c +++ b/src/detect-depth.c @@ -65,10 +65,10 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths switch (s->alproto) { case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); + /* add to the latest content keyword from either dmatch or pmatch */ + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_CONTENT, s->dmatch_tail, + DETECT_CONTENT, s->pmatch_tail); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "depth needs" "preceeding content option for dcerpc sig"); diff --git a/src/detect-distance.c b/src/detect-distance.c index fa3c6fd392..3102d4b555 100644 --- a/src/detect-distance.c +++ b/src/detect-distance.c @@ -35,6 +35,7 @@ #include "detect-content.h" #include "detect-uricontent.h" +#include "detect-pcre.h" #include "flow-var.h" @@ -62,7 +63,6 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, char *str = distancestr; char dubbed = 0; SigMatch *pm = NULL; - SigMatch *match_tail = NULL; /* strip "'s */ if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') { @@ -71,35 +71,104 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, dubbed = 1; } - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); - if (pm == NULL) { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs" - "preceeding content option for dcerpc sig"); - if (dubbed) - SCFree(str); - return -1; - } - - break; - - default: - pm = SigMatchGetLastSMFromLists(s, 4, + /* if we still haven't found that the sig is related to DCERPC, + * it's a direct entry into Signature->pmatch */ + if (s->alproto == ALPROTO_DCERPC) { + SigMatch *dcem = NULL; + SigMatch *dm = NULL; + SigMatch *pm1 = NULL; + SigMatch *pm2 = NULL; + + SigMatch *dm_ots = NULL; + SigMatch *pm1_ots = NULL; + SigMatch *pm2_ots = NULL; + + dcem = SigMatchGetLastSMFromLists(s, 6, + DETECT_DCE_IFACE, s->amatch_tail, + DETECT_DCE_OPNUM, s->amatch_tail, + DETECT_DCE_STUB_DATA, s->amatch_tail); + + dm_ots = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->dmatch_tail, + DETECT_PCRE, s->dmatch_tail, + DETECT_BYTEJUMP, s->dmatch_tail); + pm1_ots = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->pmatch_tail, - DETECT_URICONTENT, s->umatch_tail); - if (pm == NULL) { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs" - "preceeding content or uricontent option"); - if (dubbed) - SCFree(str); - return -1; + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + if (pm1_ots != NULL && pm1_ots->prev != NULL) { + pm2_ots = SigMatchGetLastSMFromLists(s, 2, + DETECT_CONTENT, pm1_ots->prev, + DETECT_PCRE, pm1_ots->prev, + DETECT_BYTEJUMP, pm1_ots->prev); + } + + dm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); + pm1 = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->pmatch_tail); + if (pm1 != NULL && pm1->prev != NULL) { + pm2 = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, pm1->prev); + } + + if (dm == NULL && pm1 == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid signature. within " + "needs a preceding content keyword"); + goto error; + } + + if (dm == NULL) { + if (pm2_ots == NULL) { + if (pm1->idx > dcem->idx) { + /* transfer pm1 to dmatch list and within is against this */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else { + /* within is against pm1 and we continue this way */ + pm = pm1; + } + } else if (pm2_ots->idx > dcem->idx) { + /* within is against pm1, pm = pm1; */ + pm = pm1; + } else if (pm1->idx > dcem->idx) { + /* transfer pm1 to dmatch list and within is against this */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else { + /* within is against pm1 and we continue this way */ + pm = pm1; } - - break; + } else { + if (pm1 == NULL) { + /* within is against dm and continue this way */ + pm = dm; + } else if (dm->idx > pm1->idx) { + /* within is against dm */ + pm = dm; + } else if (pm2_ots == NULL || pm2_ots->idx < dcem->idx) { + /* trasnfer pm1 to dmatch list and pm = pm1 */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else if (pm2_ots->idx > dcem->idx) { + /* within is against pm1, pm = pm1 */ + pm = pm1; + } + } + } else { + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_CONTENT, s->pmatch_tail, + DETECT_URICONTENT, s->umatch_tail); + if (pm == NULL) { + SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" + "preceeding content or uricontent option"); + if (dubbed) + SCFree(str); + return -1; + } } DetectUricontentData *ud = NULL; @@ -155,39 +224,53 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, } } - switch (s->alproto) { - case ALPROTO_DCERPC: - match_tail = s->dmatch_tail; - break; - - default: - match_tail = s->pmatch_tail; - break; - } - - if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_CONTENT)) != NULL) { - /* Set the relative next flag on the prev sigmatch */ - cd = (DetectContentData *)pm->ctx; - if (cd == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" - "previous keyword!"); - goto error; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, pm->prev, + DETECT_PCRE, pm->prev, + DETECT_BYTEJUMP, pm->prev); - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) { - DetectBytejumpData *data = NULL; - data = (DetectBytejumpData *) pm->ctx; - if (data == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); + DetectPcreData *pe = NULL; + if (pm == NULL) { + if (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("content relative without a previous content based " + "keyword. Holds good only in the case of DCERPC " + "alproto like now."); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No related " + "previous-previous content or pcre keyword"); goto error; } - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else { - SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two " - "preceeding content or uricontent options"); - goto error; + switch (pm->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)pm->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *) pm->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } } break; diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index f6bfd52771..62ae4f76c9 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -1553,21 +1553,21 @@ int DcePayloadTest01(void) int i = 0; char *sig1 = "alert tcp any any -> any any (dce_stub_data; " - "content:|26 d0 cf 80|; sid:1;)"; + "content:|26 d0 cf 80|; distance:0; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|43 5b 67 26 65|; sid:2;)"; + "content:|43 5b 67 26 65|; distance:0; sid:2;)"; char *sig3 = "alert tcp any any -> any any (dce_stub_data; " - "content:|71 69 75 3e|; sid:3;)"; + "content:|71 69 75 3e|; distance:0; sid:3;)"; char *sig4 = "alert tcp any any -> any any (dce_stub_data; " - "content:|6a 68 69 3e 72|; sid:4;)"; + "content:|6a 68 69 3e 72|; distance:0; sid:4;)"; char *sig5 = "alert tcp any any -> any any (dce_stub_data; " - "content:|61 50 71 45 29 5b 56 3d 5a|; sid:5;)"; + "content:|61 50 71 45 29 5b 56 3d 5a|; distance:0; sid:5;)"; char *sig6 = "alert tcp any any -> any any (dce_stub_data; " - "content:|23 75 40 5d 32 55|; sid:6;)"; + "content:|23 75 40 5d 32 55|; distance:0; sid:6;)"; char *sig7 = "alert tcp any any -> any any (dce_stub_data; " - "content:|ee 70 32 65 c1|; sid:7;)"; + "content:|ee 70 32 65 c1|; distance:0; sid:7;)"; char *sig8 = "alert tcp any any -> any any (dce_stub_data; " - "content:|79 26 46 f7 bf a1|; sid:8;)"; + "content:|79 26 46 f7 bf a1|; distance:0; sid:8;)"; Signature *s; @@ -2434,7 +2434,7 @@ int DcePayloadTest02(void) "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 2a 4c|; sid:2;)"; + "dce_stub_data; content:|2d 5e 63 2a 4c|; distance:0; sid:2;)"; Signature *s; @@ -2882,9 +2882,9 @@ int DcePayloadTest03(void) char *sig1 = "alert tcp any any -> any any " "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef4; " - "sid:1;)"; + "dce_stub_data; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 2a 4c|; sid:2;)"; + "content:|2d 5e 63 2a 4c|; distance:0; sid:2;)"; Signature *s; @@ -3331,9 +3331,9 @@ int DcePayloadTest04(void) char *sig1 = "alert tcp any any -> any any " "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:|91 27 27 40|; sid:1;)"; + "dce_stub_data; content:|91 27 27 40|; distance:0; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 2a 4c|; sid:2;)"; + "content:|2d 5e 63 2a 4c|; distance:0; sid:2;)"; Signature *s; @@ -3779,9 +3779,9 @@ int DcePayloadTest05(void) char *sig1 = "alert tcp any any -> any any " "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef4; " - "content:|91 27 27 40|; sid:1;)"; + "dce_stub_data; content:|91 27 27 40|; distance:0; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 2a 4c|; sid:2;)"; + "dce_stub_data; content:|2d 5e 63 2a 4c|; distance:0; sid:2;)"; Signature *s; @@ -4228,9 +4228,9 @@ int DcePayloadTest06(void) char *sig1 = "alert tcp any any -> any any " "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:|91 27 27 30|; sid:1;)"; + "dce_stub_data; content:|91 27 27 30|; distance:0; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 2a 4c|; sid:2;)"; + "content:|2d 5e 63 2a 4c|; distance:0; sid:2;)"; Signature *s; @@ -4676,9 +4676,9 @@ int DcePayloadTest07(void) char *sig1 = "alert tcp any any -> any any " "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:|91 27 27 30|; sid:1;)"; + "dce_stub_data; content:|91 27 27 30|; distance:0; sid:1;)"; char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:|2d 5e 63 35 25|; sid:2;)"; + "content:|2d 5e 63 35 25|; distance:0; sid:2;)"; Signature *s; @@ -4963,7 +4963,7 @@ int DcePayloadTest08(void) int i = 0; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5d 5b 35|; content:|9e a3|; " + "(dce_stub_data; content:|5d 5b 35|; distance:0; content:|9e a3|; " "distance:0; within:2; sid:1;)"; Signature *s; @@ -5188,7 +5188,7 @@ int DcePayloadTest09(void) int i = 0; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5d 5b 35|; content:|9e a3|; " + "(dce_stub_data; content:|5d 5b 35|; distance:0; content:|9e a3|; " "distance:0; within:2; sid:1;)"; Signature *s; @@ -5413,7 +5413,7 @@ int DcePayloadTest10(void) int i = 0; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|ad 0d|; content:|ad 0d 00|; " + "(dce_stub_data; content:|ad 0d|; distance:0; content:|ad 0d 00|; " "distance:-10; within:3; sid:1;)"; Signature *s; @@ -5773,7 +5773,7 @@ int DcePayloadTest11(void) int i = 0; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|af, 26, d0|; content:|80 98 6d|; " + "(dce_stub_data; content:|af, 26, d0|; distance:0; content:|80 98 6d|; " "distance:1; within:3; sid:1;)"; Signature *s; @@ -6147,7 +6147,7 @@ int DcePayloadTest12(void) int i = 0; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|af, 26, d0|; content:|80 98 6d|; " + "(dce_stub_data; content:|af, 26, d0|; distance:0; content:|80 98 6d|; " "distance:2; within:3; sid:1;)"; Signature *s; @@ -6751,10 +6751,10 @@ int DcePayloadTest15(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,14080,0,relative,dce; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,46,5,relative,dce; sid:2;)"; Signature *s; @@ -6866,10 +6866,10 @@ int DcePayloadTest16(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,55,0,relative; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,11776,5,relative; sid:2;)"; Signature *s; @@ -6981,10 +6981,10 @@ int DcePayloadTest17(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,55,0,relative,big; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_test:2,=,46,5,relative,little; sid:2;)"; Signature *s; @@ -7096,10 +7096,10 @@ int DcePayloadTest18(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,0,relative,dce; byte_test:2,=,46,0,relative,dce; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,2,relative,dce; byte_test:2,=,14080,0,relative; sid:2;)"; Signature *s; @@ -7211,10 +7211,10 @@ int DcePayloadTest19(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,0,relative; byte_test:2,=,46,0,relative,dce; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,2,relative; byte_test:2,=,14080,0,relative; sid:2;)"; Signature *s; @@ -7326,10 +7326,10 @@ int DcePayloadTest20(void) int r; char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,0,relative,big; byte_test:2,=,46,0,relative,dce; sid:1;)"; char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:|5c 00 5c 00 31|; " + "(dce_stub_data; content:|5c 00 5c 00 31|; distance:0; " "byte_jump:2,2,little,relative; byte_test:2,=,14080,0,relative; sid:2;)"; Signature *s; @@ -7436,7 +7436,7 @@ int DcePayloadTest21(void) char *sig1 = "alert tcp any any -> any any " "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:this; content:is; within:6; content:big; within:8; " + "content:this; distance:0; content:is; within:6; content:big; within:8; " "content:string; within:8; sid:1;)"; Signature *s; @@ -7536,7 +7536,7 @@ int DcePayloadTest22(void) char *sig1 = "alert tcp any any -> any any " "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:this; content:is; within:9; content:big; within:12; " + "content:this; distance:0; content:is; within:9; content:big; within:12; " "content:string; within:8; sid:1;)"; Signature *s; @@ -7636,7 +7636,8 @@ int DcePayloadTest23(void) char *sig1 = "alert tcp any any -> any any " "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:now; content:this; content:is; within:12; content:big; within:8; " + "content:now; distance:0; content:this; distance:-20; " + "content:is; within:12; content:big; within:8; " "content:string; within:8; sid:1;)"; Signature *s; @@ -7735,7 +7736,7 @@ int DcePayloadTest24(void) char *sig1 = "alert tcp any any -> any any " "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:thus; offset:8; content:is; within:6; " + "content:thus; distance:0; offset:8; content:is; within:6; " "content:big; within:8; sid:1;)"; Signature *s; @@ -7807,6 +7808,127 @@ end: return result; } +/** + * \test Test content for dce sig. + */ +int DcePayloadParseTest25(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 1; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *data = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing bytejump_body\"; " + "content:one; content:two; " + "content:three; within:10; " + "content:four; distance:4; " + "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->dmatch_tail != NULL) { + result = 0; + goto end; + } + if (s->dmatch_tail != NULL) { + result = 0; + goto end; + } + + sm = s->pmatch; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + data = (DetectContentData *)sm->ctx; + if (data->flags & DETECT_CONTENT_RAWBYTES || + data->flags & DETECT_CONTENT_NOCASE || + data->flags & DETECT_CONTENT_WITHIN || + data->flags & DETECT_CONTENT_DISTANCE || + data->flags & DETECT_CONTENT_FAST_PATTERN || + data->flags & DETECT_CONTENT_NEGATED ) { + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "one", 3) == 0); + if (result == 0) + goto end; + + sm = sm->next; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + data = (DetectContentData *)sm->ctx; + if (data->flags & DETECT_CONTENT_RAWBYTES || + data->flags & DETECT_CONTENT_NOCASE || + data->flags & DETECT_CONTENT_WITHIN || + data->flags & DETECT_CONTENT_DISTANCE || + data->flags & DETECT_CONTENT_FAST_PATTERN || + data->flags & DETECT_CONTENT_NEGATED ) { + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "two", 3) == 0); + if (result == 0) + goto end; + + sm = sm->next; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + data = (DetectContentData *)sm->ctx; + if (data->flags & DETECT_CONTENT_RAWBYTES || + data->flags & DETECT_CONTENT_NOCASE || + !(data->flags & DETECT_CONTENT_WITHIN) || + data->flags & DETECT_CONTENT_DISTANCE || + data->flags & DETECT_CONTENT_FAST_PATTERN || + data->flags & DETECT_CONTENT_NEGATED ) { + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "three", 5) == 0); + if (result == 0) + goto end; + + sm = sm->next; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + data = (DetectContentData *)sm->ctx; + if (data->flags & DETECT_CONTENT_RAWBYTES || + data->flags & DETECT_CONTENT_NOCASE || + data->flags & DETECT_CONTENT_WITHIN || + !(data->flags & DETECT_CONTENT_DISTANCE) || + data->flags & DETECT_CONTENT_FAST_PATTERN || + data->flags & DETECT_CONTENT_NEGATED ) { + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "four", 4) == 0); + if (result == 0) + goto end; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + #endif /* UNITTESTS */ void DcePayloadRegisterTests(void) @@ -7837,6 +7959,8 @@ void DcePayloadRegisterTests(void) UtRegisterTest("DcePayloadTest22", DcePayloadTest22, 1); UtRegisterTest("DcePayloadTest23", DcePayloadTest23, 1); UtRegisterTest("DcePayloadTest24", DcePayloadTest24, 1); + + UtRegisterTest("DcePayloadParseTest25", DcePayloadParseTest25, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index 788688daf6..8e7f664193 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -232,91 +232,109 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst { DetectIsdataatData *idad = NULL; SigMatch *sm = NULL; - SigMatch *match = NULL; - SigMatch *match_tail = NULL; DetectContentData *cd = NULL; idad = DetectIsdataatParse(isdataatstr); - if (idad == NULL) goto error; + if (idad == NULL) + goto error; - if (idad->flags & ISDATAAT_RELATIVE) { - /* Set it in the last parsed contet because it is relative to that - * content match */ - SCLogDebug("set it in the last parsed content because it is relative " - "to that content match"); - - switch (s->alproto) { - case ALPROTO_DCERPC: - match = s->dmatch; - match_tail = s->dmatch_tail; - break; - - default: - match = s->pmatch; - match_tail = s->pmatch_tail; - break; - } + sm = SigMatchAlloc(); + if (sm == NULL) + goto error; + sm->type = DETECT_ISDATAAT; + sm->ctx = (void *)idad; - if (match_tail == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "No previous content, the flag " - "'relative' cant be used without content"); - goto error; - } + if (idad->flags & ISDATAAT_RELATIVE) { + SCLogDebug("Set it in the last parsed content because it is relative " + "to that content based keyword"); SigMatch *m = NULL; - /* Search for the first previous DetectContent SigMatch (it can be the - * same as this one) */ - if ( (m = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) { - cd = (DetectContentData *)m->ctx; - if (cd == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - - } else if ( (m = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) { - DetectPcreData *pe = NULL; - pe = (DetectPcreData *)m->ctx; - if (pe == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - pe->flags |= DETECT_PCRE_RELATIVE; + if (s->alproto == ALPROTO_DCERPC) { + m = SigMatchGetLastSMFromLists(s, 12, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail, + DETECT_CONTENT, s->dmatch_tail, + DETECT_PCRE, s->dmatch_tail, + DETECT_BYTEJUMP, s->dmatch_tail); + } else { + m = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + } - } else if ( (m = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) { - DetectBytejumpData *data = NULL; - data = (DetectBytejumpData *)m->ctx; - if (data == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); + if (m == NULL) { + if (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("isdataat-relative without a previous content based " + "keyword. Holds good only in the case of DCERPC " + "alproto like now."); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No related " + "previous-previous content or pcre keyword"); goto error; } - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ISDATAAT; - sm->ctx = (void *)idad; - - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ + DetectPcreData *pe = NULL; + switch (m->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)m->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *) m->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + } /* else for if (m == NULL) */ + } /* if (idad->flags & ISDATAAT_RELATIVE) */ + + if (s->alproto == ALPROTO_DCERPC && + idad->flags & ISDATAAT_RELATIVE) { + SigMatch *pm = NULL; + SigMatch *dm = NULL; + + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + dm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + + if (pm == NULL) { SigMatchAppendDcePayload(s, sm); - break; - - default: + } else if (dm == NULL) { + SigMatchAppendDcePayload(s, sm); + } else if (pm->idx > dm->idx) { SigMatchAppendPayload(s, sm); - break; + } else { + SigMatchAppendDcePayload(s, sm); + } + } else { + SigMatchAppendPayload(s, sm); } return 0; @@ -401,9 +419,14 @@ int DetectIsdataatTestParse04(void) s->alproto = ALPROTO_DCERPC; result &= (DetectIsdataatSetup(NULL, s, "30") == 0); - result &= (s->dmatch != NULL); + result &= (s->dmatch == NULL && s->pmatch != NULL); + SigFree(s); + + s = SigAlloc(); + s->alproto = ALPROTO_DCERPC; /* failure since we have no preceding content/pcre/bytejump */ - result &= (DetectIsdataatSetup(NULL, s, "30,relative") == -1); + result &= (DetectIsdataatSetup(NULL, s, "30,relative") == 0); + result &= (s->dmatch != NULL && s->pmatch == NULL); SigFree(s); @@ -428,7 +451,9 @@ int DetectIsdataatTestParse05(void) de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; isdataat:4; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "isdataat:4,relative; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; @@ -440,8 +465,8 @@ int DetectIsdataatTestParse05(void) } result &= (s->dmatch_tail->type == DETECT_ISDATAAT); data = (DetectIsdataatData *)s->dmatch_tail->ctx; - if ( !(!(data->flags & ISDATAAT_RELATIVE) && - !(data->flags & ISDATAAT_RAWBYTES)) ) { + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) ) { result = 0; goto end; } @@ -449,7 +474,9 @@ int DetectIsdataatTestParse05(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; isdataat:4,relative; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "isdataat:4,relative; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -461,8 +488,8 @@ int DetectIsdataatTestParse05(void) } result &= (s->dmatch_tail->type == DETECT_ISDATAAT); data = (DetectIsdataatData *)s->dmatch_tail->ctx; - if ( !((data->flags & ISDATAAT_RELATIVE) && - !(data->flags & ISDATAAT_RAWBYTES)) ) { + if ( !(data->flags & ISDATAAT_RELATIVE) || + (data->flags & ISDATAAT_RAWBYTES) ) { result = 0; goto end; } @@ -470,7 +497,9 @@ int DetectIsdataatTestParse05(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:one; isdataat:4,relative,rawbytes; sid:1;)"); + "dce_stub_data; " + "content:one; distance:0; " + "isdataat:4,relative,rawbytes; sid:1;)"); if (s->next == NULL) { result = 0; goto end; @@ -482,8 +511,8 @@ int DetectIsdataatTestParse05(void) } result &= (s->dmatch_tail->type == DETECT_ISDATAAT); data = (DetectIsdataatData *)s->dmatch_tail->ctx; - if ( !((data->flags & ISDATAAT_RELATIVE) && - (data->flags & ISDATAAT_RAWBYTES)) ) { + if ( !(data->flags & ISDATAAT_RELATIVE) || + !(data->flags & ISDATAAT_RAWBYTES) ) { result = 0; goto end; } diff --git a/src/detect-offset.c b/src/detect-offset.c index 8eceaba8df..6a4351b313 100644 --- a/src/detect-offset.c +++ b/src/detect-offset.c @@ -64,10 +64,10 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr) switch (s->alproto) { case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); + /* add to the latest "content" keyword from either dmatch or pmatch */ + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_CONTENT, s->dmatch_tail, + DETECT_CONTENT, s->pmatch_tail); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs" "preceeding content option for dcerpc sig"); @@ -79,9 +79,9 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr) break; default: - pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->pmatch_tail, - DETECT_URICONTENT, s->umatch_tail); + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_CONTENT, s->pmatch_tail, + DETECT_URICONTENT, s->umatch_tail); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs" "preceeding content or uricontent option"); diff --git a/src/detect-parse.c b/src/detect-parse.c index 975f52cdff..cf4f7f171c 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -514,6 +514,39 @@ SigMatch *SigMatchGetLastSMFromLists(Signature *s, int args, ...) return sm[0]; } +void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, + SigMatch **src_sm_list, SigMatch **src_sm_list_tail, + SigMatch **dst_sm_list, SigMatch **dst_sm_list_tail) +{ + /* we won't do any checks for args */ + + if (sm == *src_sm_list) { + *src_sm_list = sm->next; + } else { + sm->prev->next = sm->next; + sm->next->prev = sm->prev; + } + + if (sm == *src_sm_list_tail) { + *src_sm_list_tail = sm->prev; + } + + if (*dst_sm_list == NULL) { + *dst_sm_list = sm; + *dst_sm_list_tail = sm; + sm->next = NULL; + sm->prev = NULL; + } else { + SigMatch *cur = *dst_sm_list_tail; + cur->next = sm; + sm->prev = cur; + sm->next = NULL; + *dst_sm_list_tail = sm; + } + + return; +} + void SigParsePrepare(void) { char *regexstr = CONFIG_PCRE; const char *eb; diff --git a/src/detect-parse.h b/src/detect-parse.h index dfae8ff096..f5348044ad 100644 --- a/src/detect-parse.h +++ b/src/detect-parse.h @@ -46,7 +46,9 @@ void SigFree(Signature *s); Signature *SigInit(DetectEngineCtx *,char *sigstr); SigMatch *SigMatchGetLastSM(SigMatch *, uint8_t); SigMatch *SigMatchGetLastSMFromLists(Signature *, int, ...); - +void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, + SigMatch **, SigMatch **s, + SigMatch **, SigMatch **); void SigParsePrepare(void); void SigParseRegisterTests(void); Signature *DetectEngineAppendSig(DetectEngineCtx *, char *); diff --git a/src/detect-pcre.c b/src/detect-pcre.c index 9322e2f048..5f06ca48ed 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -853,25 +853,41 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst SigMatchAppendUricontent(s, sm); } else { - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ + if (s->alproto == ALPROTO_DCERPC && + pd->flags & DETECT_PCRE_RELATIVE) { + SigMatch *pm = NULL; + SigMatch *dm = NULL; + + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + dm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->pmatch_tail, + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + + if (pm == NULL) { SigMatchAppendDcePayload(s, sm); - break; - - default: + } else if (dm == NULL) { + SigMatchAppendDcePayload(s, sm); + } else if (pm->idx > dm->idx) { SigMatchAppendPayload(s, sm); - break; + } else { + SigMatchAppendDcePayload(s, sm); + } + } else { + SigMatchAppendPayload(s, sm); } } SCReturnInt(0); error: - if (pd != NULL) DetectPcreFree(pd); - if (sm != NULL) SCFree(sm); + if (pd != NULL) + DetectPcreFree(pd); + if (sm != NULL) + SCFree(sm); SCReturnInt(-1); } @@ -1064,15 +1080,14 @@ int DetectPcreParseTest10(void) s->alproto = ALPROTO_DCERPC; result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->dmatch != NULL); + result &= (s->dmatch == NULL && s->pmatch != NULL); SigFree(s); s = SigAlloc(); /* failure since we have no preceding content/pcre/bytejump */ result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->dmatch == NULL); - result &= (s->pmatch != NULL); + result &= (s->dmatch == NULL && s->pmatch != NULL); end: SigFree(s); @@ -1099,7 +1114,8 @@ int DetectPcreParseTest11(void) de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "pcre:/bamboo/; sid:1;)"); + "dce_stub_data; " + "pcre:/bamboo/R; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; @@ -1112,7 +1128,7 @@ int DetectPcreParseTest11(void) result &= (s->dmatch_tail->type == DETECT_PCRE); data = (DetectPcreData *)s->dmatch_tail->ctx; if (data->flags & DETECT_PCRE_RAWBYTES || - data->flags & DETECT_PCRE_RELATIVE || + !(data->flags & DETECT_PCRE_RELATIVE) || data->flags & DETECT_PCRE_URI) { result = 0; goto end; @@ -1121,6 +1137,7 @@ int DetectPcreParseTest11(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "pcre:/bamboo/R; sid:1;)"); if (s->next == NULL) { result = 0; @@ -1143,6 +1160,7 @@ int DetectPcreParseTest11(void) s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytejump_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " + "dce_stub_data; " "pcre:/bamboo/RB; sid:1;)"); if (s->next == NULL) { result = 0; diff --git a/src/detect-pcre.h b/src/detect-pcre.h index e0bff1c450..4c676445a8 100644 --- a/src/detect-pcre.h +++ b/src/detect-pcre.h @@ -27,6 +27,7 @@ #define DETECT_PCRE_RELATIVE 0x01 #define DETECT_PCRE_RAWBYTES 0x02 #define DETECT_PCRE_URI 0x04 +#define DETECT_PCRE_RELATIVE_NEXT 0x08 #define DETECT_PCRE_CAPTURE_PKT 0x08 #define DETECT_PCRE_CAPTURE_FLOW 0x10 diff --git a/src/detect-within.c b/src/detect-within.c index a8f2397a68..7c25bddbfb 100644 --- a/src/detect-within.c +++ b/src/detect-within.c @@ -65,7 +65,6 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi { char *str = withinstr; char dubbed = 0; - SigMatch *match_tail = NULL; SigMatch *pm = NULL; /* strip "'s */ @@ -75,35 +74,104 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi dubbed = 1; } - switch (s->alproto) { - case ALPROTO_DCERPC: - /* If we have a signature that is related to dcerpc, then we add the - * sm to Signature->dmatch. All content inspections for a dce rpc - * alproto is done inside detect-engine-dcepayload.c */ - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); - if (pm == NULL) { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" - "preceeding content options for this dcerpc sig"); - if (dubbed) - SCFree(str); - return -1; - } - - break; - - default: - pm = SigMatchGetLastSMFromLists(s, 4, + /* if we still haven't found that the sig is related to DCERPC, + * it's a direct entry into Signature->pmatch */ + if (s->alproto == ALPROTO_DCERPC) { + SigMatch *dcem = NULL; + SigMatch *dm = NULL; + SigMatch *pm1 = NULL; + SigMatch *pm2 = NULL; + + SigMatch *dm_ots = NULL; + SigMatch *pm1_ots = NULL; + SigMatch *pm2_ots = NULL; + + dcem = SigMatchGetLastSMFromLists(s, 6, + DETECT_DCE_IFACE, s->amatch_tail, + DETECT_DCE_OPNUM, s->amatch_tail, + DETECT_DCE_STUB_DATA, s->amatch_tail); + + dm_ots = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, s->dmatch_tail, + DETECT_PCRE, s->dmatch_tail, + DETECT_BYTEJUMP, s->dmatch_tail); + pm1_ots = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->pmatch_tail, - DETECT_URICONTENT, s->umatch_tail); - if (pm == NULL) { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" - "preceeding content or uricontent option"); - if (dubbed) - SCFree(str); - return -1; + DETECT_PCRE, s->pmatch_tail, + DETECT_BYTEJUMP, s->pmatch_tail); + if (pm1_ots != NULL && pm1_ots->prev != NULL) { + pm2_ots = SigMatchGetLastSMFromLists(s, 2, + DETECT_CONTENT, pm1_ots->prev, + DETECT_PCRE, pm1_ots->prev, + DETECT_BYTEJUMP, pm1_ots->prev); + } + + dm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail); + pm1 = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->pmatch_tail); + if (pm1 != NULL && pm1->prev != NULL) { + pm2 = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, pm1->prev); + } + + if (dm == NULL && pm1 == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid signature. within " + "needs a preceding content keyword"); + goto error; + } + + if (dm == NULL) { + if (pm2_ots == NULL) { + if (pm1->idx > dcem->idx) { + /* transfer pm1 to dmatch list and within is against this */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else { + /* within is against pm1 and we continue this way */ + pm = pm1; + } + } else if (pm2_ots->idx > dcem->idx) { + /* within is against pm1, pm = pm1; */ + pm = pm1; + } else if (pm1->idx > dcem->idx) { + /* transfer pm1 to dmatch list and within is against this */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else { + /* within is against pm1 and we continue this way */ + pm = pm1; } - - break; + } else { + if (pm1 == NULL) { + /* within is against dm and continue this way */ + pm = dm; + } else if (dm->idx > pm1->idx) { + /* within is against dm */ + pm = dm; + } else if (pm2_ots == NULL || pm2_ots->idx < dcem->idx) { + /* trasnfer pm1 to dmatch list and pm = pm1 */ + SigMatchTransferSigMatchAcrossLists(pm1, + &s->pmatch, &s->pmatch_tail, + &s->dmatch, &s->dmatch_tail); + pm = pm1; + } else if (pm2_ots->idx > dcem->idx) { + /* within is against pm1, pm = pm1 */ + pm = pm1; + } + } + } else { + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_CONTENT, s->pmatch_tail, + DETECT_URICONTENT, s->umatch_tail); + if (pm == NULL) { + SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" + "preceeding content or uricontent option"); + if (dubbed) + SCFree(str); + return -1; + } } DetectUricontentData *ud = NULL; @@ -177,50 +245,56 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi } } - switch (s->alproto) { - case ALPROTO_DCERPC: - match_tail = s->dmatch_tail; - break; + pm = SigMatchGetLastSMFromLists(s, 6, + DETECT_CONTENT, pm->prev, + DETECT_PCRE, pm->prev, + DETECT_BYTEJUMP, s->pmatch_tail); - default: - match_tail = s->pmatch_tail; - break; - } - - if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_CONTENT)) != NULL) { - /* Set the relative next flag on the prev sigmatch */ - cd = (DetectContentData *)pm->ctx; - if (cd == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" - "previous keyword!"); - goto error; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) { - DetectPcreData *pe = NULL; - pe = (DetectPcreData *) pm->ctx; - if (pe == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); - goto error; - } - pe->flags |= DETECT_PCRE_RELATIVE; - - } else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) { - DetectBytejumpData *data = NULL; - data = (DetectBytejumpData *) pm->ctx; - if (data == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); + DetectPcreData *pe = NULL; + if (pm == NULL) { + if (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("content relative without a previous content based " + "keyword. Holds good only in the case of DCERPC " + "alproto like now."); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No related " + "previous-previous content or pcre keyword"); goto error; } - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two " - "preceeding content or uricontent options"); - goto error; + switch (pm->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)pm->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *) pm->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } } + break; default: