From d318bfc934da5d28bf1b71c159416869c9e7202a Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 22 Dec 2016 16:55:43 +0100 Subject: [PATCH] dcerpc: simplify common detect code --- src/app-layer-smb.c | 10 ++--- src/app-layer-smb.h | 3 +- src/detect-dce-iface.c | 20 ++++++++- src/detect-dce-iface.h | 4 ++ src/detect-dce-opnum.c | 3 +- src/detect-engine-dcepayload.c | 4 +- src/detect-engine-state.c | 75 ++++++++-------------------------- 7 files changed, 52 insertions(+), 67 deletions(-) diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index e5c6c10afb..32ca196a30 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -670,7 +670,7 @@ static int32_t DataParser(void *smb_state, AppLayerParserState *pstate, int32_t parsed = 0; if (sstate->andx.paddingparsed) { - parsed = DCERPCParser(&sstate->dcerpc, input, input_len); + parsed = DCERPCParser(&sstate->ds.dcerpc, input, input_len); if (parsed == -1 || parsed > sstate->bytecount.bytecountleft || parsed > (int32_t)input_len) { SCReturnInt(-1); } else { @@ -1435,7 +1435,7 @@ static void *SMBStateAlloc(void) SCReturnPtr(NULL, "void"); } - DCERPCInit(&s->dcerpc); + DCERPCInit(&s->ds.dcerpc); SCReturnPtr(s, "void"); } @@ -1448,7 +1448,7 @@ static void SMBStateFree(void *s) SCEnter(); SMBState *sstate = (SMBState *) s; - DCERPCCleanup(&sstate->dcerpc); + DCERPCCleanup(&sstate->ds.dcerpc); SCFree(s); SCReturn; @@ -1705,7 +1705,7 @@ int SMBParserTest02(void) goto end; } - printUUID("BIND", smb_state->dcerpc.dcerpcbindbindack.uuid_entry); + printUUID("BIND", smb_state->ds.dcerpc.dcerpcbindbindack.uuid_entry); result = 1; end: if (alp_tctx != NULL) @@ -2012,7 +2012,7 @@ int SMBParserTest03(void) goto end; } FLOWLOCK_UNLOCK(&f); - printUUID("BIND", smb_state->dcerpc.dcerpcbindbindack.uuid_entry); + printUUID("BIND", smb_state->ds.dcerpc.dcerpcbindbindack.uuid_entry); result = 1; end: if (alp_tctx != NULL) diff --git a/src/app-layer-smb.h b/src/app-layer-smb.h index 48d4fa8430..8e7ec4fadc 100644 --- a/src/app-layer-smb.h +++ b/src/app-layer-smb.h @@ -30,6 +30,7 @@ #include "stream.h" #include "app-layer-nbss.h" #include "app-layer-dcerpc-common.h" +#include "app-layer-dcerpc.h" typedef struct SMBHdr_ { uint8_t protocol[4]; @@ -83,7 +84,7 @@ typedef struct SMBState_ { SMBWordCount wordcount; SMBByteCount bytecount; SMBAndX andx; - DCERPC dcerpc; + DCERPCState ds; uint8_t dcerpc_present; uint8_t data_needed_for_dir; } SMBState; diff --git a/src/detect-dce-iface.c b/src/detect-dce-iface.c index 8bdf278f6a..5daf7e814f 100644 --- a/src/detect-dce-iface.c +++ b/src/detect-dce-iface.c @@ -229,6 +229,24 @@ static inline int DetectDceIfaceMatchIfaceVersion(uint16_t version, } } +#include "app-layer-smb.h" +DCERPCState *DetectDceGetState(AppProto alproto, void *alstate) +{ + switch(alproto) { + case ALPROTO_DCERPC: + return alstate; + case ALPROTO_SMB: { + SMBState *smb_state = (SMBState *)alstate; + return &smb_state->ds; + } + case ALPROTO_SMB2: + // not implemented + return NULL; + } + + return NULL; +} + /** * \brief App layer match function for the "dce_iface" keyword. * @@ -253,7 +271,7 @@ static int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, DCERPCUuidEntry *item = NULL; int i = 0; DetectDceIfaceData *dce_data = (DetectDceIfaceData *)m->ctx; - DCERPCState *dcerpc_state = (DCERPCState *)state; + DCERPCState *dcerpc_state = DetectDceGetState(f->alproto, f->alstate); if (dcerpc_state == NULL) { SCLogDebug("No DCERPCState for the flow"); SCReturnInt(0); diff --git a/src/detect-dce-iface.h b/src/detect-dce-iface.h index 564cf5522c..3eb18b1c72 100644 --- a/src/detect-dce-iface.h +++ b/src/detect-dce-iface.h @@ -24,6 +24,8 @@ #ifndef __DETECT_DCE_IFACE_H__ #define __DETECT_DCE_IFACE_H__ +#include "app-layer-dcerpc.h" + typedef enum DetectDceIfaceOperators_ { DETECT_DCE_IFACE_OP_NONE = 0, DETECT_DCE_IFACE_OP_LT, @@ -41,4 +43,6 @@ typedef struct DetectDceIfaceData_ { void DetectDceIfaceRegister(void); +DCERPCState *DetectDceGetState(AppProto alproto, void *alstate); + #endif /* __DETECT_DCE_IFACE_H__ */ diff --git a/src/detect-dce-opnum.c b/src/detect-dce-opnum.c index 75b291a4d3..124b88aa3b 100644 --- a/src/detect-dce-opnum.c +++ b/src/detect-dce-opnum.c @@ -41,6 +41,7 @@ #include "queue.h" #include "stream-tcp-reassemble.h" #include "detect-dce-opnum.h" +#include "detect-dce-iface.h" #include "util-debug.h" #include "util-unittest.h" @@ -247,7 +248,7 @@ static int DetectDceOpnumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m->ctx; DetectDceOpnumRange *dor = dce_data->range; - DCERPCState *dcerpc_state = (DCERPCState *)state; + DCERPCState *dcerpc_state = DetectDceGetState(f->alproto, f->alstate); if (dcerpc_state == NULL) { SCLogDebug("No DCERPCState for the flow"); SCReturnInt(0); diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index aa323d71ed..cfb60a54fc 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -47,6 +47,8 @@ #include "util-unittest.h" #include "util-unittest-helper.h" +#include "detect-dce-iface.h" + /** * \brief Do the content inspection & validation for a signature against dce stub. * @@ -66,7 +68,7 @@ int DetectEngineInspectDcePayload(DetectEngineCtx *de_ctx, Flow *f, uint8_t flags, void *alstate) { SCEnter(); - DCERPCState *dcerpc_state = (DCERPCState *)alstate; + DCERPCState *dcerpc_state = DetectDceGetState(f->alproto, alstate); uint8_t *dce_stub_data = NULL; uint16_t dce_stub_data_len; int r = 0; diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index b64aec418f..865d34668d 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -628,20 +628,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_DMATCH); - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present && - DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, &smb_state->dcerpc) == 1) { - inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; - dmatch = 1; - } - } else { - if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, alstate) == 1) { - inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; - dmatch = 1; - } + if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, alstate) == 1) { + inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; + dmatch = 1; } } @@ -658,20 +648,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, while (1) { if (sigmatch_table[smd->type].AppLayerMatch != NULL) { int match = 0; - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present) { - KEYWORD_PROFILING_START; - match = sigmatch_table[smd->type]. - AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, smd); - KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); - } - } else { - KEYWORD_PROFILING_START; - match = sigmatch_table[smd->type]. - AppLayerMatch(tv, det_ctx, f, flags, alstate, s, smd); - KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); - } + KEYWORD_PROFILING_START; + match = sigmatch_table[smd->type]. + AppLayerMatch(tv, det_ctx, f, flags, alstate, s, smd); + KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); if (match == 0) { break; @@ -968,20 +948,10 @@ static int DoInspectFlowRule(ThreadVars *tv, while(1) { if (sigmatch_table[smd->type].AppLayerMatch != NULL) { int match = 0; - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present) { - KEYWORD_PROFILING_START; - match = sigmatch_table[smd->type]. - AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, smd); - KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); - } - } else { - KEYWORD_PROFILING_START; - match = sigmatch_table[smd->type]. - AppLayerMatch(tv, det_ctx, f, flags, alstate, s, smd); - KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); - } + KEYWORD_PROFILING_START; + match = sigmatch_table[smd->type]. + AppLayerMatch(tv, det_ctx, f, flags, alstate, s, smd); + KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); if (match == 0) break; @@ -1014,22 +984,11 @@ static int DoInspectFlowRule(ThreadVars *tv, void *alstate = FlowGetAppState(f); if (alstate != NULL) { KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_DMATCH); - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present && - DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, &smb_state->dcerpc) == 1) - { - total_matches++; - inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; - } - } else { - if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, alstate) == 1) - { - total_matches++; - inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; - } + if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, + flags, alstate) == 1) + { + total_matches++; + inspect_flags |= DE_STATE_FLAG_DCE_PAYLOAD_INSPECT; } } }