From 84ba9cf9df9b0693d02dd9f8199e8e71899c881c Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 22 Dec 2016 19:03:44 +0100 Subject: [PATCH] smb/dcerpc: use tx api --- src/app-layer-dcerpc.c | 67 ++++++++++++++++++++++++++++++++++++++ src/app-layer-dcerpc.h | 1 + src/app-layer-smb.c | 66 +++++++++++++++++++++++++++++++++++++ src/detect-dce-stub-data.c | 33 ++++--------------- src/detect-engine-state.c | 4 +-- 5 files changed, 142 insertions(+), 29 deletions(-) diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c index 407ed819f1..38416a50d8 100644 --- a/src/app-layer-dcerpc.c +++ b/src/app-layer-dcerpc.c @@ -2018,9 +2018,61 @@ static void DCERPCStateFree(void *s) DCERPCCleanup(&sstate->dcerpc); + if (sstate->de_state != NULL) { + DetectEngineStateFree(sstate->de_state); + } + SCFree(s); } +static int DCERPCStateHasTxDetectState(void *state) +{ + DCERPCState *dce_state = (DCERPCState *)state; + if (dce_state->de_state) + return 1; + return 0; +} + +static int DCERPCSetTxDetectState(void *state, void *vtx, DetectEngineState *de_state) +{ + DCERPCState *dce_state = (DCERPCState *)state; + dce_state->de_state = de_state; + return 0; +} + +static DetectEngineState *DCERPCGetTxDetectState(void *vtx) +{ + DCERPCState *dce_state = (DCERPCState *)vtx; + return dce_state->de_state; +} + +static void DCERPCStateTransactionFree(void *state, uint64_t tx_id) +{ + /* do nothing */ +} + +static void *DCERPCGetTx(void *state, uint64_t tx_id) +{ + DCERPCState *dce_state = (DCERPCState *)state; + return dce_state; +} + +static uint64_t DCERPCGetTxCnt(void *state) +{ + /* single tx */ + return 1; +} + +static int DCERPCGetAlstateProgressCompletionStatus(uint8_t direction) +{ + return 1; +} + +static int DCERPCGetAlstateProgress(void *tx, uint8_t direction) +{ + return 0; +} + static int DCERPCRegisterPatternsForProtocolDetection(void) { if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC, @@ -2059,6 +2111,21 @@ void RegisterDCERPCParsers(void) AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCStateAlloc, DCERPCStateFree); AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOSERVER); + + + AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCStateTransactionFree); + + AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCStateHasTxDetectState, + DCERPCGetTxDetectState, DCERPCSetTxDetectState); + + AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetTx); + + AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetTxCnt); + + AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetAlstateProgress); + + AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DCERPC, + DCERPCGetAlstateProgressCompletionStatus); } else { SCLogInfo("Parsed disabled for %s protocol. Protocol detection" "still on.", proto_name); diff --git a/src/app-layer-dcerpc.h b/src/app-layer-dcerpc.h index db90461e04..5a8410c761 100644 --- a/src/app-layer-dcerpc.h +++ b/src/app-layer-dcerpc.h @@ -34,6 +34,7 @@ typedef struct DCERPCState_ { DCERPC dcerpc; uint8_t data_needed_for_dir; + DetectEngineState *de_state; } DCERPCState; void DCERPCInit(DCERPC *dcerpc); diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 32ca196a30..9c8031261f 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -1450,10 +1450,62 @@ static void SMBStateFree(void *s) DCERPCCleanup(&sstate->ds.dcerpc); + if (sstate->ds.de_state) { + DetectEngineStateFree(sstate->ds.de_state); + } + SCFree(s); SCReturn; } +static int SMBStateHasTxDetectState(void *state) +{ + SMBState *smb_state = (SMBState *)state; + if (smb_state->ds.de_state) + return 1; + return 0; +} + +static int SMBSetTxDetectState(void *state, void *vtx, DetectEngineState *de_state) +{ + SMBState *smb_state = (SMBState *)state; + smb_state->ds.de_state = de_state; + return 0; +} + +static DetectEngineState *SMBGetTxDetectState(void *vtx) +{ + SMBState *smb_state = (SMBState *)vtx; + return smb_state->ds.de_state; +} + +static void SMBStateTransactionFree(void *state, uint64_t tx_id) +{ + /* do nothing */ +} + +static void *SMBGetTx(void *state, uint64_t tx_id) +{ + SMBState *smb_state = (SMBState *)state; + return smb_state; +} + +static uint64_t SMBGetTxCnt(void *state) +{ + /* single tx */ + return 1; +} + +static int SMBGetAlstateProgressCompletionStatus(uint8_t direction) +{ + return 1; +} + +static int SMBGetAlstateProgress(void *tx, uint8_t direction) +{ + return 0; +} + #define SMB_PROBING_PARSER_MIN_DEPTH 8 static uint16_t SMBProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset) @@ -1547,6 +1599,20 @@ void RegisterSMBParsers(void) AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOSERVER, SMBParseRequest); AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOCLIENT, SMBParseResponse); AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SMB, SMBStateAlloc, SMBStateFree); + + AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_SMB, SMBStateTransactionFree); + + AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_SMB, SMBStateHasTxDetectState, + SMBGetTxDetectState, SMBSetTxDetectState); + + AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_SMB, SMBGetTx); + + AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_SMB, SMBGetTxCnt); + + AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_SMB, SMBGetAlstateProgress); + + AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_SMB, + SMBGetAlstateProgressCompletionStatus); } else { SCLogInfo("Parsed disabled for %s protocol. Protocol detection " "still on.", proto_name); diff --git a/src/detect-dce-stub-data.c b/src/detect-dce-stub-data.c index aa51dd8333..68d944748a 100644 --- a/src/detect-dce-stub-data.c +++ b/src/detect-dce-stub-data.c @@ -705,7 +705,6 @@ static int DetectDceStubDataTestParse02(void) */ static int DetectDceStubDataTestParse03(void) { - int result = 0; Signature *s = NULL; ThreadVars th_v; Packet *p = NULL; @@ -1157,8 +1156,7 @@ static int DetectDceStubDataTestParse03(void) StreamTcpInitConfig(TRUE); de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; + FAIL_IF(de_ctx == NULL); de_ctx->flags |= DE_QUIET; @@ -1167,53 +1165,34 @@ static int DetectDceStubDataTestParse03(void) "(msg:\"DCERPC\"; " "dce_stub_data; content:\"|42 42 42 42|\";" "sid:1;)"); - if (s == NULL) - goto end; + FAIL_IF(s == NULL); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - FLOWLOCK_WRLOCK(&f); r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, dcerpc_request, dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); + FAIL_IF(r != 0); dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } + FAIL_IF (dcerpc_state == NULL); p->flowflags &=~ FLOW_PKT_TOCLIENT; p->flowflags |= FLOW_PKT_TOSERVER; /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + FAIL_IF(!PacketAlertCheck(p, 1)); - if (!PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); - StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); - return result; + PASS; } static int DetectDceStubDataTestParse04(void) diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 865d34668d..18d97d08a8 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -616,9 +616,9 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, if (next_tx_no_progress) break; } /* for */ - + } /* DCERPC matches */ - } else if (s->sm_arrays[DETECT_SM_LIST_DMATCH] != NULL && + if (s->sm_arrays[DETECT_SM_LIST_DMATCH] != NULL && (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2)) {