From ead29dc6918f4524f1fae7e892d3f86dac117c0a Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Sat, 24 Jul 2010 00:53:18 +0530 Subject: [PATCH] make detection engine use dce alstate(if present), on seeing smb traffic --- src/app-layer-smb.c | 1 + src/app-layer-smb.h | 1 + src/detect-bytejump.c | 148 +++++++------ src/detect-bytetest.c | 148 +++++++------ src/detect-dce-stub-data.c | 19 +- src/detect-engine-dcepayload.c | 391 +++++++++++++++++++++++++++++++-- src/detect-engine-state.c | 98 ++++++--- src/detect-isdataat.c | 148 +++++++------ src/detect-pcre.c | 9 +- 9 files changed, 687 insertions(+), 276 deletions(-) diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 6ac27e73a5..48e4a402ac 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -585,6 +585,7 @@ static int32_t DataParser(void *smb_state, AppLayerParserState *pstate, if (parsed == -1) { SCReturnInt(-1); } else { + sstate->dcerpc_present = 1; sstate->bytesprocessed += parsed; sstate->bytecount.bytecountleft -= parsed; input_len -= parsed; diff --git a/src/app-layer-smb.h b/src/app-layer-smb.h index 52d3dc7e43..9234c01fa1 100644 --- a/src/app-layer-smb.h +++ b/src/app-layer-smb.h @@ -84,6 +84,7 @@ typedef struct SMBState_ { SMBAndX andx; uint16_t bytesprocessed; DCERPC dcerpc; + uint8_t dcerpc_present; uint32_t tail; uint16_t transaction_id; } SMBState; diff --git a/src/detect-bytejump.c b/src/detect-bytejump.c index 5fd5962dfd..475bbdaaf5 100644 --- a/src/detect-bytejump.c +++ b/src/detect-bytejump.c @@ -33,6 +33,7 @@ #include "detect-bytejump.h" #include "detect-content.h" +#include "detect-uricontent.h" #include "util-byte.h" #include "util-unittest.h" @@ -546,78 +547,6 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) } } - if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - 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); - } - - 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; - } - } else { - 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; - - case DETECT_BYTEJUMP: - SCLogDebug("No setting relative_next for bytejump. We " - "have no use for it"); - - 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; @@ -645,6 +574,81 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) SigMatchAppendPayload(s, sm); } + if ( !(data->flags & DETECT_BYTEJUMP_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 (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("No preceding content or pcre keyword. Possible " + "since this is an alproto sig."); + SCReturnInt(0); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " + "or uricontent or pcre option"); + goto error; + } + } + + DetectContentData *cd = NULL; + DetectUricontentData *ud = NULL; + DetectPcreData *pe = NULL; + + switch (prev_sm->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)prev_sm->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_URICONTENT: + /* Set the relative next flag on the prev sigmatch */ + ud = (DetectUricontentData *)prev_sm->ctx; + if (ud == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *)prev_sm->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + case DETECT_BYTEJUMP: + SCLogDebug("No setting relative_next for bytejump. We " + "have no use for it"); + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + return 0; error: diff --git a/src/detect-bytetest.c b/src/detect-bytetest.c index b67a3a48bc..d1e3df4cf1 100644 --- a/src/detect-bytetest.c +++ b/src/detect-bytetest.c @@ -31,6 +31,7 @@ #include "detect-parse.h" #include "detect-content.h" +#include "detect-uricontent.h" #include "detect-bytetest.h" #include "detect-bytejump.h" #include "app-layer.h" @@ -562,78 +563,6 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) } } - if (data->flags & DETECT_BYTETEST_RELATIVE) { - 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); - } - - 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; - } - } else { - 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; - - case DETECT_BYTEJUMP: - SCLogDebug("No setting relative_next for bytejump. We " - "have no use for it"); - - 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; @@ -661,6 +590,81 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) SigMatchAppendPayload(s, sm); } + if ( !(data->flags & DETECT_BYTETEST_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 (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("No preceding content or pcre keyword. Possible " + "since this is an alproto sig."); + SCReturnInt(0); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " + "or uricontent or pcre option"); + goto error; + } + } + + DetectContentData *cd = NULL; + DetectUricontentData *ud = NULL; + DetectPcreData *pe = NULL; + + switch (prev_sm->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)prev_sm->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_URICONTENT: + /* Set the relative next flag on the prev sigmatch */ + ud = (DetectUricontentData *)prev_sm->ctx; + if (ud == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *)prev_sm->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + case DETECT_BYTEJUMP: + SCLogDebug("No setting relative_next for bytejump. We " + "have no use for it"); + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + return 0; error: diff --git a/src/detect-dce-stub-data.c b/src/detect-dce-stub-data.c index 7b4af698d1..5c8460c57b 100644 --- a/src/detect-dce-stub-data.c +++ b/src/detect-dce-stub-data.c @@ -94,23 +94,12 @@ int DetectDceStubDataMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow * return 0; } - if (flags & STREAM_TOSERVER) { - if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL || - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 0) { - return 0; - } - det_ctx->dce_stub_data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer; - det_ctx->dce_stub_data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len; + if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL || + dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer != NULL) { + return 1; } else { - if (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL || - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) { - return 0; - } - det_ctx->dce_stub_data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer; - det_ctx->dce_stub_data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len; + return 0; } - - return 1; } /** diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index 7fb1a7c6c9..057b7555f9 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -413,31 +413,36 @@ int DetectEngineInspectDcePayload(DetectEngineCtx *de_ctx, SCReturnInt(0); } - /* we are not relying on the stub pointer being set by the dce_stub_data - * match function. Instead we will retrieve it directly from the app layer. */ - if (flags & STREAM_TOSERVER) { - if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL || - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 0) { - SCReturnInt(0); - } + if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && + dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh != 0) { + /* the request stub and stub_len */ dce_stub_data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer; dce_stub_data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len; - } else { - if (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL || - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) { - SCReturnInt(0); + + det_ctx->payload_offset = 0; + det_ctx->discontinue_matching = 0; + + r = DoInspectDcePayload(de_ctx, det_ctx, s, s->dmatch, f, + dce_stub_data, dce_stub_data_len, dcerpc_state); + if (r == 1) { + SCReturnInt(1); } + } + + if (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer != NULL && + dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) { + /* the response stub and stub_len */ dce_stub_data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer; dce_stub_data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len; - } - det_ctx->payload_offset = 0; - det_ctx->discontinue_matching = 0; + det_ctx->payload_offset = 0; + det_ctx->discontinue_matching = 0; - r = DoInspectDcePayload(de_ctx, det_ctx, s, s->dmatch, f, - dce_stub_data, dce_stub_data_len, dcerpc_state); - if (r == 1) { - SCReturnInt(1); + r = DoInspectDcePayload(de_ctx, det_ctx, s, s->dmatch, f, + dce_stub_data, dce_stub_data_len, dcerpc_state); + if (r == 1) { + SCReturnInt(1); + } } SCReturnInt(0); @@ -10136,6 +10141,352 @@ end: return result; } +/** + * \test Test content for dce sig. + */ +int DcePayloadParseTest44(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 1; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *data = NULL; + DetectIsdataatData *isd = 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; " + "dce_iface:12345678-1234-1234-1234-123456789012; " + "dce_opnum:10; dce_stub_data; " + "isdataat:10,relative; " + "content:one; within:4; distance:8; " + "content:two; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->dmatch_tail == NULL) { + result = 0; + goto end; + } + if (s->pmatch_tail == NULL) { + result = 0; + goto end; + } + + sm = s->dmatch; + if (sm->type != DETECT_ISDATAAT) { + result = 0; + goto end; + } + isd = (DetectIsdataatData *)sm->ctx; + if ( isd->flags & ISDATAAT_RAWBYTES || + !(isd->flags & ISDATAAT_RELATIVE)) { + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + result = 0; + printf("two failed\n"); + goto end; + } + result &= (strncmp((char *)data->content, "one", 3) == 0); + if (result == 0) + goto end; + + result &= (sm->next == NULL); + + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + printf("three failed\n"); + 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 ) { + printf("two failed\n"); + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "two", 3) == 0); + if (result == 0) + goto end; + + result &= (sm->next == NULL); + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test content for dce sig. + */ +int DcePayloadParseTest45(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 1; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *data = NULL; + DetectBytejumpData *bjd = 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\"; " + "dce_iface:12345678-1234-1234-1234-123456789012; " + "content:one; " + "dce_opnum:10; dce_stub_data; " + "byte_jump:1,2,relative,align,dce; " + "content:two; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->dmatch_tail == NULL) { + result = 0; + goto end; + } + if (s->pmatch_tail == NULL) { + result = 0; + goto end; + } + + sm = s->dmatch; + if (sm->type != DETECT_BYTEJUMP) { + result = 0; + goto end; + } + bjd = (DetectBytejumpData *)sm->ctx; + if (bjd->flags & DETECT_BYTEJUMP_BEGIN || + bjd->flags & DETECT_BYTEJUMP_LITTLE || + bjd->flags & DETECT_BYTEJUMP_BIG || + bjd->flags & DETECT_BYTEJUMP_STRING || + !(bjd->flags & DETECT_BYTEJUMP_RELATIVE) || + !(bjd->flags & DETECT_BYTEJUMP_ALIGN) || + !(bjd->flags & DETECT_BYTEJUMP_DCE) ) { + result = 0; + printf("one failed\n"); + goto end; + } + + result &= (sm->next == NULL); + + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + printf("two failed\n"); + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "two", 3) == 0); + if (result == 0) + goto end; + + result &= (sm->next == NULL); + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test content for dce sig. + */ +int DcePayloadParseTest46(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 1; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *data = NULL; + DetectBytetestData *btd = 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\"; " + "dce_iface:12345678-1234-1234-1234-123456789012; " + "content:one; " + "dce_opnum:10; dce_stub_data; " + "byte_test:1,=,2,0,relative,dce; " + "content:two; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->dmatch_tail == NULL) { + result = 0; + goto end; + } + if (s->pmatch_tail == NULL) { + result = 0; + goto end; + } + + sm = s->dmatch; + if (sm->type != DETECT_BYTETEST) { + result = 0; + goto end; + } + btd = (DetectBytetestData *)sm->ctx; + if (btd->flags & DETECT_BYTETEST_LITTLE || + btd->flags & DETECT_BYTETEST_BIG || + btd->flags & DETECT_BYTETEST_STRING || + !(btd->flags & DETECT_BYTETEST_RELATIVE) || + !(btd->flags & DETECT_BYTETEST_DCE) ) { + result = 0; + printf("one failed\n"); + goto end; + } + + result &= (sm->next == NULL); + + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + 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_RELATIVE_NEXT || + data->flags & DETECT_CONTENT_NEGATED ) { + printf("two failed\n"); + result = 0; + goto end; + } + result &= (strncmp((char *)data->content, "two", 3) == 0); + if (result == 0) + goto end; + + result &= (sm->next == NULL); + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + #endif /* UNITTESTS */ void DcePayloadRegisterTests(void) @@ -10187,6 +10538,10 @@ void DcePayloadRegisterTests(void) UtRegisterTest("DcePayloadTest42", DcePayloadTest42, 1); UtRegisterTest("DcePayloadTest43", DcePayloadTest43, 1); + + UtRegisterTest("DcePayloadParseTest44", DcePayloadParseTest44, 1); + UtRegisterTest("DcePayloadParseTest45", DcePayloadParseTest45, 1); + UtRegisterTest("DcePayloadParseTest46", DcePayloadParseTest46, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index a7adac2190..fb932af10c 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -40,6 +40,9 @@ #include "app-layer-parser.h" #include "app-layer-protos.h" #include "app-layer-htp.h" +#include "app-layer-smb.h" +#include "app-layer-dcerpc-common.h" +#include "app-layer-dcerpc.h" #include "util-unittest.h" #include "util-profiling.h" @@ -322,18 +325,26 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, SCLogDebug("inspecting dce payload"); - void *real_alstate = alstate; if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - real_alstate = f->aldata[AlpGetStateIdx(ALPROTO_DCERPC)]; - } - - if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, real_alstate) == 1) - { - SCLogDebug("dce payload matched"); - dmatch = 1; + SMBState *smb_state = (SMBState *)alstate; + //DCERPCState dcerpc_state; + //dcerpc_state.dcerpc = smb_state->dcerpc; + if (smb_state->dcerpc_present && + DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, &smb_state->dcerpc) == 1) { + SCLogDebug("dce payload matched"); + dmatch = 1; + } else { + SCLogDebug("dce payload inspected but no match"); + } } else { - SCLogDebug("dce payload inspected but no match"); + if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, alstate) == 1) { + SCLogDebug("dce payload matched"); + dmatch = 1; + } else { + SCLogDebug("dce payload inspected but no match"); + } } } } @@ -346,10 +357,23 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, SCLogDebug("sm %p, sm->next %p", sm, sm->next); if (sigmatch_table[sm->type].AppLayerMatch != NULL && - alproto == sigmatch_table[sm->type].alproto) + (alproto == sigmatch_table[sm->type].alproto || + alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) ) { - match = sigmatch_table[sm->type].AppLayerMatch(tv, det_ctx, f, - flags, alstate, s, sm); + if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { + SMBState *smb_state = (SMBState *)alstate; + //DCERPCState dcerpc_state; + //dcerpc_state.dcerpc = smb_state->dcerpc; + if (smb_state->dcerpc_present) { + match = sigmatch_table[sm->type]. + AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, + s, sm); + } + } else { + match = sigmatch_table[sm->type]. + AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm); + } + if (match == 0) { break; } else if (sm->next == NULL) { @@ -476,20 +500,30 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete SCLogDebug("inspecting dce payload"); dinspect = 1; - void *real_alstate = alstate; if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - real_alstate = f->aldata[AlpGetStateIdx(ALPROTO_DCERPC)]; - } - - if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, real_alstate) == 1) - { - SCLogDebug("dce payload matched"); - item->flags |= DE_STATE_FLAG_DCE_MATCH; - dmatch = 1; + SMBState *smb_state = (SMBState *)alstate; + //DCERPCState dcerpc_state; + //dcerpc_state.dcerpc = smb_state->dcerpc; + if (smb_state->dcerpc_present && + DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, &smb_state->dcerpc) == 1) { + SCLogDebug("dce payload matched"); + item->flags |= DE_STATE_FLAG_DCE_MATCH; + dmatch = 1; + } else { + SCLogDebug("dce payload inspected but no match"); + } } else { - SCLogDebug("dce payload inspected but no match"); + if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, alstate) == 1) { + SCLogDebug("dce payload matched"); + item->flags |= DE_STATE_FLAG_DCE_MATCH; + dmatch = 1; + } else { + SCLogDebug("dce payload inspected but no match"); + } } + } else { SCLogDebug("dce payload already inspected"); } @@ -505,8 +539,20 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete if (item->nm != NULL) { SigMatch *sm; for (sm = item->nm; sm != NULL; sm = sm->next) { - match = sigmatch_table[sm->type].AppLayerMatch(tv, - det_ctx, f, flags, alstate, s, sm); + if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { + SMBState *smb_state = (SMBState *)alstate; + //DCERPCState dcerpc_state; + //dcerpc_state.dcerpc = smb_state->dcerpc; + if (smb_state->dcerpc_present) { + match = sigmatch_table[sm->type]. + AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, + s, sm); + } + } else { + match = sigmatch_table[sm->type]. + AppLayerMatch(tv, det_ctx, f, flags, alstate, + s, sm); + } /* no match, break out */ if (match == 0) { item->nm = sm; diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index f594a8187d..d1941d497a 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -36,6 +36,7 @@ #include "detect-isdataat.h" #include "detect-content.h" +#include "detect-uricontent.h" #include "flow.h" #include "flow-var.h" @@ -232,7 +233,6 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst { DetectIsdataatData *idad = NULL; SigMatch *sm = NULL; - DetectContentData *cd = NULL; idad = DetectIsdataatParse(isdataatstr); if (idad == NULL) @@ -245,77 +245,6 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst sm->type = DETECT_ISDATAAT; sm->ctx = (void *)idad; - 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; - 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); - } - - 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; - } - } else { - 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; - - case DETECT_BYTEJUMP: - SCLogDebug("No setting relative_next for bytejump. We " - "have no use for it"); - - 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; @@ -343,6 +272,81 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst SigMatchAppendPayload(s, sm); } + 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 (s->alproto == ALPROTO_DCERPC) { + SCLogDebug("No preceding content or pcre keyword. Possible " + "since this is an alproto sig."); + SCReturnInt(0); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " + "or uricontent or pcre option"); + goto error; + } + } + + DetectContentData *cd = NULL; + DetectUricontentData *ud = NULL; + DetectPcreData *pe = NULL; + + switch (prev_sm->type) { + case DETECT_CONTENT: + /* Set the relative next flag on the prev sigmatch */ + cd = (DetectContentData *)prev_sm->ctx; + if (cd == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + + break; + + case DETECT_URICONTENT: + /* Set the relative next flag on the prev sigmatch */ + ud = (DetectUricontentData *)prev_sm->ctx; + if (ud == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT; + + break; + + case DETECT_PCRE: + pe = (DetectPcreData *)prev_sm->ctx; + if (pe == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + goto error; + } + pe->flags |= DETECT_PCRE_RELATIVE_NEXT; + + break; + + case DETECT_BYTEJUMP: + SCLogDebug("No setting relative_next for bytejump. We " + "have no use for it"); + + break; + + default: + /* this will never hit */ + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" + "previous keyword!"); + break; + } /* switch */ + return 0; error: diff --git a/src/detect-pcre.c b/src/detect-pcre.c index 70c240feec..ddc110f020 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -888,9 +888,10 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst SCReturnInt(0); } - prev_sm = SigMatchGetLastSMFromLists(s, 6, + 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 (s->alproto == ALPROTO_DCERPC) { @@ -941,6 +942,12 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst break; + case DETECT_BYTEJUMP: + SCLogDebug("No setting relative_next for bytejump. We " + "have no use for it"); + + break; + default: /* this will never hit */ SCLogError(SC_ERR_INVALID_SIGNATURE, "prev sigmatch has unknown type: %"PRIu16,