Fix DCERPC over SMB/SMB2 detection issues. Fix not updating transaction id in a stream direction if there was no sgh.

remotes/origin/master-1.0.x
Victor Julien 16 years ago
parent 2c5c0d54f3
commit bfd167521e

@ -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 */

@ -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

@ -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;

@ -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 */

Loading…
Cancel
Save