Store the first frag flag in the uuid as the pfc_flags field is overwritten. Part of fixing #206.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent 14a12f5fb7
commit f1ea68e316

@ -131,6 +131,9 @@ typedef struct DCERPCHdrUdp_ {
#define DCERPC_UDP_HDR_LEN 80 #define DCERPC_UDP_HDR_LEN 80
#define DCERPC_UUID_ENTRY_FLAG_FF 0x0001 /**< FIRST flag set on the packet
that contained this uuid entry */
typedef struct DCERPCUuidEntry_ { typedef struct DCERPCUuidEntry_ {
uint16_t ctxid; uint16_t ctxid;
uint16_t internal_id; uint16_t internal_id;
@ -138,6 +141,7 @@ typedef struct DCERPCUuidEntry_ {
uint8_t uuid[16]; uint8_t uuid[16];
uint16_t version; uint16_t version;
uint16_t versionminor; uint16_t versionminor;
uint16_t flags; /**< DCERPC_UUID_ENTRY_FLAG_* flags */
TAILQ_ENTRY(DCERPCUuidEntry_) next; TAILQ_ENTRY(DCERPCUuidEntry_) next;
} DCERPCUuidEntry; } DCERPCUuidEntry;

@ -239,20 +239,29 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t
dcerpc->dcerpcbindbindack.versionminor |= *(p + 23) << 8; dcerpc->dcerpcbindbindack.versionminor |= *(p + 23) << 8;
//if (dcerpc->dcerpcbindbindack.ctxid == dcerpc->dcerpcbindbindack.numctxitems //if (dcerpc->dcerpcbindbindack.ctxid == dcerpc->dcerpcbindbindack.numctxitems
// - dcerpc->dcerpcbindbindack.numctxitemsleft) { // - dcerpc->dcerpcbindbindack.numctxitemsleft) {
dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *)
SCCalloc(1, sizeof(DCERPCUuidEntry)); dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *)SCCalloc(1, sizeof(DCERPCUuidEntry));
if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) {
SCLogDebug("UUID Entry is NULL"); SCLogDebug("UUID Entry is NULL");
SCReturnUInt(0); SCReturnUInt(0);
} else { }
dcerpc->dcerpcbindbindack.uuid_entry->internal_id =
dcerpc->dcerpcbindbindack.uuid_internal_id++; dcerpc->dcerpcbindbindack.uuid_entry->internal_id = dcerpc->dcerpcbindbindack.uuid_internal_id++;
memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid,
dcerpc->dcerpcbindbindack.uuid, dcerpc->dcerpcbindbindack.uuid,
sizeof(dcerpc->dcerpcbindbindack.uuid)); sizeof(dcerpc->dcerpcbindbindack.uuid));
dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid; dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid;
dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version; dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version;
dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor; dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor;
/* store the first frag flag in the uuid as pfc_flags will
* be overwritten by new packets. */
if (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG) {
dcerpc->dcerpcbindbindack.uuid_entry->flags |= DCERPC_UUID_ENTRY_FLAG_FF;
}
TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list, TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list,
dcerpc->dcerpcbindbindack.uuid_entry, dcerpc->dcerpcbindbindack.uuid_entry,
next); next);
@ -265,7 +274,7 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t
dcerpc->bytesprocessed += (44); dcerpc->bytesprocessed += (44);
dcerpc->dcerpcbindbindack.ctxbytesprocessed += (44); dcerpc->dcerpcbindbindack.ctxbytesprocessed += (44);
SCReturnUInt(44U); SCReturnUInt(44U);
}
//} else { //} else {
// SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid, // SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid,
// dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft); // dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft);
@ -455,7 +464,8 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t
if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) {
SCLogDebug("UUID Entry is NULL\n"); SCLogDebug("UUID Entry is NULL\n");
SCReturnUInt(0); SCReturnUInt(0);
} else { }
dcerpc->dcerpcbindbindack.uuid_entry->internal_id = dcerpc->dcerpcbindbindack.uuid_entry->internal_id =
dcerpc->dcerpcbindbindack.uuid_internal_id++; dcerpc->dcerpcbindbindack.uuid_internal_id++;
memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid,
@ -464,6 +474,13 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t
dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid; dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid;
dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version; dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version;
dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor; dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor;
/* store the first frag flag in the uuid as pfc_flags will
* be overwritten by new packets. */
if (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG) {
dcerpc->dcerpcbindbindack.uuid_entry->flags |= DCERPC_UUID_ENTRY_FLAG_FF;
}
TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list, TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list,
dcerpc->dcerpcbindbindack.uuid_entry, dcerpc->dcerpcbindbindack.uuid_entry,
next); next);
@ -476,7 +493,7 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t
dcerpc->bytesprocessed += (p - input); dcerpc->bytesprocessed += (p - input);
dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input); dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input);
SCReturnUInt((uint32_t)(p - input)); SCReturnUInt((uint32_t)(p - input));
}
//} else { //} else {
// SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid, // SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid,
// dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft); // dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft);

@ -274,6 +274,8 @@ static inline int DetectDceIfaceMatchIfaceVersion(uint16_t version,
int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
uint8_t flags, void *state, Signature *s, SigMatch *m) uint8_t flags, void *state, Signature *s, SigMatch *m)
{ {
SCEnter();
int ret = 0; int ret = 0;
DCERPCUuidEntry *item = NULL; DCERPCUuidEntry *item = NULL;
int i = 0; int i = 0;
@ -281,7 +283,7 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
DCERPCState *dcerpc_state = (DCERPCState *)state; DCERPCState *dcerpc_state = (DCERPCState *)state;
if (dcerpc_state == NULL) { if (dcerpc_state == NULL) {
SCLogDebug("No DCERPCState for the flow"); SCLogDebug("No DCERPCState for the flow");
return 0; SCReturnInt(0);
} }
SCMutexLock(&f->m); SCMutexLock(&f->m);
@ -293,17 +295,15 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
if (!(dcerpc_state->dcerpc.dcerpchdr.type == REQUEST)) if (!(dcerpc_state->dcerpc.dcerpchdr.type == REQUEST))
goto end; goto end;
/* if any_frag is not enabled, we need to match only against the first
* fragment */
if (!dce_data->any_frag &&
!(dcerpc_state->dcerpc.dcerpchdr.pfc_flags & PFC_FIRST_FRAG)) {
/* any_frag has not been set, and apparently it's not the first fragment */
goto end;
}
TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) {
SCLogDebug("item %p", item);
ret = 1; ret = 1;
/* if any_frag is not enabled, we need to match only against the first
* fragment */
if (!dce_data->any_frag && !(item->flags & DCERPC_UUID_ENTRY_FLAG_FF))
continue;
/* if the uuid has been rejected(item->result == 1), we skip to the /* if the uuid has been rejected(item->result == 1), we skip to the
* next uuid */ * next uuid */
if (item->result != 0) if (item->result != 0)
@ -331,9 +331,9 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
goto end; goto end;
} }
end: end:
SCMutexUnlock(&f->m); SCMutexUnlock(&f->m);
return ret; SCReturnInt(ret);
} }
/** /**

@ -263,27 +263,32 @@ static inline DetectDceOpnumData *DetectDceOpnumArgParse(const char *arg)
int DetectDceOpnumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, int DetectDceOpnumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
uint8_t flags, void *state, Signature *s, SigMatch *m) uint8_t flags, void *state, Signature *s, SigMatch *m)
{ {
SCEnter();
DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m->ctx; DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m->ctx;
DetectDceOpnumRange *dor = dce_data->range; DetectDceOpnumRange *dor = dce_data->range;
DCERPCState *dcerpc_state = (DCERPCState *)state; DCERPCState *dcerpc_state = (DCERPCState *)state;
if (dcerpc_state == NULL) { if (dcerpc_state == NULL) {
SCLogDebug("No DCERPCState for the flow"); SCLogDebug("No DCERPCState for the flow");
return 0; SCReturnInt(0);
} }
for ( ; dor != NULL; dor = dor->next) { for ( ; dor != NULL; dor = dor->next) {
if (dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED) { if (dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED) {
if (dor->range1 == dcerpc_state->dcerpc.dcerpcrequest.opnum) if (dor->range1 == dcerpc_state->dcerpc.dcerpcrequest.opnum) {
return 1; SCReturnInt(1);
}
} else { } else {
if (dor->range1 <= dcerpc_state->dcerpc.dcerpcrequest.opnum && if (dor->range1 <= dcerpc_state->dcerpc.dcerpcrequest.opnum &&
dor->range2 >= dcerpc_state->dcerpc.dcerpcrequest.opnum) { dor->range2 >= dcerpc_state->dcerpc.dcerpcrequest.opnum)
return 1; {
SCReturnInt(1);
} }
} }
} }
return 0; SCReturnInt(0);
} }
/** /**

@ -90,17 +90,20 @@ void DetectDceStubDataRegister(void)
int DetectDceStubDataMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, int DetectDceStubDataMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
uint8_t flags, void *state, Signature *s, SigMatch *m) uint8_t flags, void *state, Signature *s, SigMatch *m)
{ {
SCEnter();
DCERPCState *dcerpc_state = (DCERPCState *)state; DCERPCState *dcerpc_state = (DCERPCState *)state;
if (dcerpc_state == NULL) { if (dcerpc_state == NULL) {
SCLogDebug("No DCERPCState for the flow"); SCLogDebug("No DCERPCState for the flow");
return 0; SCReturnInt(0);
} }
if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL || if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL ||
dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer != NULL) { dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer != NULL)
return 1; {
SCReturnInt(1);
} else { } else {
return 0; SCReturnInt(0);
} }
} }

Loading…
Cancel
Save