diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index f593c3fef5..c2760ad160 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -1147,6 +1147,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, if (sstate->bytesprocessed >= sstate->nbss.length + NBSS_HDR_LEN || sstate->andx.maxchainedandx == 0) { sstate->bytesprocessed = 0; + sstate->transaction_id++; } break; default: @@ -1233,10 +1234,26 @@ static void SMBStateFree(void *s) { SCReturn; } +/** + * \brief Update the transaction id based on the SMB state + */ +void SMBUpdateTransactionId(void *state, uint16_t *id) { + SCEnter(); + + SMBState *s = (SMBState *)state; + SCLogDebug("original id %"PRIu16, *id); + (*id) = s->transaction_id; + SCLogDebug("updated id %"PRIu16, *id); + + SCReturn; +} + void RegisterSMBParsers(void) { AppLayerRegisterProto("smb", ALPROTO_SMB, STREAM_TOSERVER, SMBParse); AppLayerRegisterProto("smb", ALPROTO_SMB, STREAM_TOCLIENT, SMBParse); AppLayerRegisterStateFuncs(ALPROTO_SMB, SMBStateAlloc, SMBStateFree); + AppLayerRegisterTransactionIdFuncs(ALPROTO_SMB, + SMBUpdateTransactionId, NULL); } /* UNITTESTS */ diff --git a/src/app-layer-smb.h b/src/app-layer-smb.h index 7ecc16043f..52d3dc7e43 100644 --- a/src/app-layer-smb.h +++ b/src/app-layer-smb.h @@ -85,6 +85,7 @@ typedef struct SMBState_ { uint16_t bytesprocessed; DCERPC dcerpc; uint32_t tail; + uint16_t transaction_id; } SMBState; #define SMB_FLAGS_SERVER_TO_REDIR 0x80 diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index c077b95115..574828768b 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -313,14 +313,19 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, SCLogDebug("uri inspected but no match"); } } - } else if (alproto == ALPROTO_DCERPC) { + } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (s->dmatch != NULL) { dinspect = 1; 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, alstate) == 1) + flags, real_alstate) == 1) { SCLogDebug("dce payload matched"); dmatch = 1; @@ -456,14 +461,19 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete SCLogDebug("uri already inspected"); } } - } else if (alproto == ALPROTO_DCERPC) { + } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (s->dmatch != NULL) { if (!(item->flags & DE_STATE_FLAG_DCE_MATCH)) { 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, alstate) == 1) + flags, real_alstate) == 1) { SCLogDebug("dce payload matched"); item->flags |= DE_STATE_FLAG_DCE_MATCH; diff --git a/src/detect.c b/src/detect.c index 8c5d0db7e0..0a71df1056 100644 --- a/src/detect.c +++ b/src/detect.c @@ -458,8 +458,15 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, /* if the sig has alproto and the session as well they should match */ if (s->alproto != ALPROTO_UNKNOWN) { if (s->alproto != alproto) { - SCLogDebug("alproto mismatch"); - continue; + if (s->alproto == ALPROTO_DCERPC) { + if (alproto != ALPROTO_SMB && alproto != ALPROTO_SMB2) { + SCLogDebug("DCERPC sig, alproto not SMB or SMB2"); + continue; + } + } else { + SCLogDebug("alproto mismatch"); + continue; + } } } @@ -672,6 +679,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh SCEnter(); + SCLogDebug("pcap_cnt %"PRIu64, p->pcap_cnt); + p->alerts.cnt = 0; det_ctx->pkts++; @@ -1017,6 +1026,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh break; } +end: if (alstate != NULL) { SCLogDebug("getting de_state_status"); int de_state_status = DeStateUpdateInspectTransactionId(p->flow, @@ -1030,7 +1040,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } } -end: /* so now let's iterate the alerts and remove the ones after a pass rule * matched (if any). This is done inside PacketAlertFinalize() */ /* PR: installed "tag" keywords are handled after the threshold inspection */