throw out malformed pdus, that result the parser having parsed the required data, but we still havne't thit the frag length limit for the parser

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 1aea3e56be
commit a3280c1a20

@ -1194,6 +1194,21 @@ static inline void DCERPCResetStub(DCERPC *dcerpc) {
return; return;
} }
static inline int DCERPCThrowOutExtraData(DCERPC *dcerpc, uint8_t *input,
uint16_t input_len) {
int parsed = 0;
/* the function always assumes that
* dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length */
if (input_len > (dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed)) {
parsed = dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed;
} else {
parsed = input_len;
}
dcerpc->bytesprocessed += parsed;
return parsed;
}
/** /**
* \todo - Currently the parser is very generic. Modify it to behave * \todo - Currently the parser is very generic. Modify it to behave
* like the target's parser. * like the target's parser.
@ -1329,12 +1344,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) {
SCReturnInt(0); SCReturnInt(0);
} else { } else {
/* temporary fix */ /* temporary fix */
if (dcerpc->dcerpchdr.auth_length != 0 && input_len) { if (input_len) {
retval = DCERPCThrowOutExtraData(dcerpc, input + parsed,
input_len);
input_len -= retval;
parsed += retval;
if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) {
DCERPCResetParsingState(dcerpc); DCERPCResetParsingState(dcerpc);
SCReturnInt(0); } else {
dcerpc->pdu_fragged = 1;
} }
} else {
dcerpc->pdu_fragged = 1; dcerpc->pdu_fragged = 1;
} }
}
break; break;
case BIND_ACK: case BIND_ACK:
@ -1466,12 +1489,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) {
SCReturnInt(0); SCReturnInt(0);
} else { } else {
/* temporary fix */ /* temporary fix */
if (dcerpc->dcerpchdr.auth_length != 0 && input_len) { if (input_len) {
retval = DCERPCThrowOutExtraData(dcerpc, input + parsed,
input_len);
input_len -= retval;
parsed += retval;
if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) {
DCERPCResetParsingState(dcerpc); DCERPCResetParsingState(dcerpc);
SCReturnInt(0); } else {
dcerpc->pdu_fragged = 1;
} }
} else {
dcerpc->pdu_fragged = 1; dcerpc->pdu_fragged = 1;
} }
}
break; break;
case REQUEST: case REQUEST:
@ -1533,12 +1564,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) {
DCERPCResetStub(dcerpc); DCERPCResetStub(dcerpc);
} }
/* temporary fix */ /* temporary fix */
if (dcerpc->dcerpchdr.auth_length != 0 && input_len) { if (input_len) {
retval = DCERPCThrowOutExtraData(dcerpc, input + parsed,
input_len);
input_len -= retval;
parsed += retval;
if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) {
DCERPCResetParsingState(dcerpc); DCERPCResetParsingState(dcerpc);
SCReturnInt(0); } else {
dcerpc->pdu_fragged = 1;
} }
} else {
dcerpc->pdu_fragged = 1; dcerpc->pdu_fragged = 1;
} }
}
/* response and request done */ /* response and request done */
if (dcerpc->dcerpchdr.type == RESPONSE) { if (dcerpc->dcerpchdr.type == RESPONSE) {
@ -1551,9 +1590,16 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) {
default: default:
SCLogDebug("DCERPC Type 0x%02x not implemented yet", dcerpc->dcerpchdr.type); SCLogDebug("DCERPC Type 0x%02x not implemented yet", dcerpc->dcerpchdr.type);
/* \todo Need to walk along till we see the next pdu in the segment */ retval = DCERPCThrowOutExtraData(dcerpc, input + parsed,
dcerpc->bytesprocessed = 0; input_len);
SCReturnInt(0); input_len -= retval;
parsed += retval;
if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) {
DCERPCResetParsingState(dcerpc);
} else {
dcerpc->pdu_fragged = 1;
}
break;
} }
} }

Loading…
Cancel
Save