diff --git a/src/app-layer-dcerpc-common.h b/src/app-layer-dcerpc-common.h index 3511c9f396..fb239bbc38 100644 --- a/src/app-layer-dcerpc-common.h +++ b/src/app-layer-dcerpc-common.h @@ -133,6 +133,7 @@ typedef struct DCERPCHdrUdp_ { typedef struct DCERPCUuidEntry_ { uint16_t ctxid; + uint16_t internal_id; uint16_t result; uint8_t uuid[16]; uint16_t version; @@ -150,12 +151,16 @@ typedef struct DCERPCBindBindAck_ { uint16_t versionminor; DCERPCUuidEntry *uuid_entry; TAILQ_HEAD(, DCERPCUuidEntry_) uuid_list; + /* the interface uuids that the server has accepted */ + TAILQ_HEAD(, DCERPCUuidEntry_) accepted_uuid_list; + uint16_t uuid_internal_id; uint16_t secondaryaddrlen; uint16_t secondaryaddrlenleft; uint16_t result; } DCERPCBindBindAck; typedef struct DCERPCRequest_ { + uint16_t ctxid; uint16_t opnum; /* holds the stub data for the request */ uint8_t *stub_data_buffer; @@ -163,6 +168,7 @@ typedef struct DCERPCRequest_ { uint32_t stub_data_buffer_len; /* used by the dce preproc to indicate fresh entry in the stub data buffer */ uint8_t stub_data_fresh; + uint8_t first_request_seen; } DCERPCRequest; typedef struct DCERPCResponse_ { diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c index f477634429..b85ea042fe 100644 --- a/src/app-layer-dcerpc.c +++ b/src/app-layer-dcerpc.c @@ -244,6 +244,8 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t SCLogDebug("UUID Entry is NULL"); SCReturnUInt(0); } else { + dcerpc->dcerpcbindbindack.uuid_entry->internal_id = + dcerpc->dcerpcbindbindack.uuid_internal_id++; memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, dcerpc->dcerpcbindbindack.uuid, sizeof(dcerpc->dcerpcbindbindack.uuid)); @@ -453,6 +455,8 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t SCLogDebug("UUID Entry is NULL\n"); SCReturnUInt(0); } else { + dcerpc->dcerpcbindbindack.uuid_entry->internal_id = + dcerpc->dcerpcbindbindack.uuid_internal_id++; memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, dcerpc->dcerpcbindbindack.uuid, sizeof(dcerpc->dcerpcbindbindack.uuid)); @@ -502,17 +506,33 @@ static uint32_t DCERPCParseBINDACKCTXItem(DCERPC *dcerpc, uint8_t *input, uint32 dcerpc->dcerpcbindbindack.result = *p; dcerpc->dcerpcbindbindack.result |= *(p + 1) << 8; TAILQ_FOREACH(uuid_entry, &dcerpc->dcerpcbindbindack.uuid_list, next) { - if (uuid_entry->ctxid == dcerpc->dcerpcbindbindack.numctxitems - - dcerpc->dcerpcbindbindack.numctxitemsleft) { + if (uuid_entry->internal_id == dcerpc->dcerpcbindbindack.uuid_internal_id) { uuid_entry->result = dcerpc->dcerpcbindbindack.result; #ifdef UNITTESTS if (RunmodeIsUnittests()) { printUUID("BIND_ACK", uuid_entry); } #endif + if (uuid_entry->result != 0) + break; + + dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *) + SCCalloc(1, sizeof(DCERPCUuidEntry)); + if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, + "Error allocating memory\n"); + exit(EXIT_FAILURE); + } + memcpy(dcerpc->dcerpcbindbindack.uuid_entry, + uuid_entry, + sizeof(DCERPCUuidEntry)); + TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.accepted_uuid_list, + dcerpc->dcerpcbindbindack.uuid_entry, + next); break; } } + dcerpc->dcerpcbindbindack.uuid_internal_id++; dcerpc->dcerpcbindbindack.numctxitemsleft--; dcerpc->bytesprocessed += (24); dcerpc->dcerpcbindbindack.ctxbytesprocessed += (24); @@ -614,17 +634,33 @@ static uint32_t DCERPCParseBINDACKCTXItem(DCERPC *dcerpc, uint8_t *input, uint32 break; case 23: TAILQ_FOREACH(uuid_entry, &dcerpc->dcerpcbindbindack.uuid_list, next) { - if (uuid_entry->ctxid == dcerpc->dcerpcbindbindack.numctxitems - - dcerpc->dcerpcbindbindack.numctxitemsleft) { + if (uuid_entry->internal_id == dcerpc->dcerpcbindbindack.uuid_internal_id) { uuid_entry->result = dcerpc->dcerpcbindbindack.result; #ifdef UNITTESTS if (RunmodeIsUnittests()) { printUUID("BIND_ACK", uuid_entry); } #endif + if (uuid_entry->result != 0) + break; + + dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *) + SCCalloc(1, sizeof(DCERPCUuidEntry)); + if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, + "Error allocating memory\n"); + exit(EXIT_FAILURE); + } + memcpy(dcerpc->dcerpcbindbindack.uuid_entry, + uuid_entry, + sizeof(DCERPCUuidEntry)); + TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.accepted_uuid_list, + dcerpc->dcerpcbindbindack.uuid_entry, + next); break; } } + dcerpc->dcerpcbindbindack.uuid_internal_id++; dcerpc->dcerpcbindbindack.numctxitemsleft--; p++; --input_len; @@ -650,9 +686,17 @@ static uint32_t DCERPCParseBIND(DCERPC *dcerpc, uint8_t *input, uint32_t input_l TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.uuid_list, item, next); SCFree(item); } - TAILQ_INIT(&dcerpc->dcerpcbindbindack.uuid_list); + if (dcerpc->dcerpchdr.type == BIND) { + while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.accepted_uuid_list))) { + TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.accepted_uuid_list, item, next); + SCFree(item); + } + TAILQ_INIT(&dcerpc->dcerpcbindbindack.accepted_uuid_list); + } + dcerpc->dcerpcbindbindack.uuid_internal_id = 0; dcerpc->dcerpcbindbindack.numctxitems = *(p + 8); dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; + TAILQ_INIT(&dcerpc->dcerpcbindbindack.uuid_list); dcerpc->bytesprocessed += 12; SCReturnUInt(12U); } else { @@ -701,6 +745,14 @@ static uint32_t DCERPCParseBIND(DCERPC *dcerpc, uint8_t *input, uint32_t input_l TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.uuid_list, item, next); SCFree(item); } + if (dcerpc->dcerpchdr.type == BIND) { + while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.accepted_uuid_list))) { + TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.accepted_uuid_list, item, next); + SCFree(item); + } + TAILQ_INIT(&dcerpc->dcerpcbindbindack.accepted_uuid_list); + } + dcerpc->dcerpcbindbindack.uuid_internal_id = 0; dcerpc->dcerpcbindbindack.numctxitems = *(p++); dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; TAILQ_INIT(&dcerpc->dcerpcbindbindack.uuid_list); @@ -737,6 +789,7 @@ static uint32_t DCERPCParseBINDACK(DCERPC *dcerpc, uint8_t *input, uint32_t inpu switch (dcerpc->bytesprocessed) { case 16: + dcerpc->dcerpcbindbindack.uuid_internal_id = 0; dcerpc->dcerpcbindbindack.numctxitems = 0; if (input_len >= 10) { if (dcerpc->dcerpchdr.packed_drep[0] == 0x10) { @@ -823,12 +876,17 @@ static uint32_t DCERPCParseREQUEST(DCERPC *dcerpc, uint8_t *input, uint32_t inpu if (input_len >= 8) { if (dcerpc->dcerpchdr.type == REQUEST) { if (dcerpc->dcerpchdr.packed_drep[0] == 0x10) { + dcerpc->dcerpcrequest.ctxid = *(p + 4); + dcerpc->dcerpcrequest.ctxid |= *(p + 5) << 8; dcerpc->dcerpcrequest.opnum = *(p + 6); dcerpc->dcerpcrequest.opnum |= *(p + 7) << 8; } else { + dcerpc->dcerpcrequest.ctxid = *(p + 4) << 8; + dcerpc->dcerpcrequest.ctxid |= *(p + 5); dcerpc->dcerpcrequest.opnum = *(p + 6) << 8; dcerpc->dcerpcrequest.opnum |= *(p + 7); } + dcerpc->dcerpcrequest.first_request_seen = 1; } dcerpc->bytesprocessed += 8; SCReturnUInt(8U); @@ -855,12 +913,16 @@ static uint32_t DCERPCParseREQUEST(DCERPC *dcerpc, uint8_t *input, uint32_t inpu break; case 20: /* context id 1 */ - p++; + dcerpc->dcerpcrequest.ctxid = *(p++) << 8; if (!(--input_len)) break; case 21: /* context id 2 */ - p++; + dcerpc->dcerpcrequest.ctxid |= *(p++); + if (dcerpc->dcerpchdr.packed_drep[0] == 0x10) { + dcerpc->dcerpcrequest.ctxid = SCByteSwap16(dcerpc->dcerpcrequest.ctxid); + } + dcerpc->dcerpcrequest.first_request_seen = 1; if (!(--input_len)) break; case 22: @@ -1510,7 +1572,6 @@ static void *DCERPCStateAlloc(void) { if (s == NULL) { SCReturnPtr(NULL, "void"); } - memset(s, 0, sizeof(DCERPCState)); s->dcerpc.transaction_id = 1; @@ -4430,7 +4491,7 @@ int DCERPCParserTest12(void) { result &= (dcerpc_state->dcerpc.bytesprocessed == 24); result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack2, bind_ack2_len); if (r != 0) { printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); @@ -4507,15 +4568,18 @@ int DCERPCParserTest13(void) { 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}; DCERPCUuidEntry *item = NULL; + int internal_id = 0; TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { int i = 0; /* check the interface uuid */ for (i = 0; i < 16; i++) { if (ctx_uuid_from_pcap[i] != item->uuid[i]) { + result = 0; goto end; } } result = 1; + result &= (item->internal_id == internal_id++); } end: @@ -4619,7 +4683,7 @@ int DCERPCParserTest15(void) { StreamTcpInitConfig(TRUE); FlowL7DataPtrInit(&f); - r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); if (r != 0) { printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); @@ -4641,6 +4705,762 @@ end: return result; } +/** + * \test Check for correct internal ids for bind_acks. + */ +int DCERPCParserTest16(void) { + int result = 1; + Flow f; + int r = 0; + + uint8_t bind1[] = { + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x50, 0x08, 0x43, 0x95, 0x43, 0x5a, 0x8b, 0xb2, + 0xf4, 0xc5, 0xb9, 0xee, 0x67, 0x55, 0x7c, 0x19, + 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0xda, 0xc2, 0xbc, 0x9b, + 0x35, 0x2e, 0xd4, 0xc9, 0x1f, 0x85, 0x01, 0xe6, + 0x4e, 0x5a, 0x5e, 0xd4, 0x04, 0x00, 0x03, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0xb2, 0x97, 0xcc, 0x14, 0x6f, 0x70, 0x0d, 0xa5, + 0x33, 0xd7, 0xf4, 0xe3, 0x8e, 0xb2, 0x2a, 0x1e, + 0x05, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x96, 0x4e, 0xa6, 0xf6, + 0xb2, 0x4b, 0xae, 0xb3, 0x21, 0xf4, 0x97, 0x7c, + 0xcd, 0xa7, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, + 0xbc, 0xc0, 0xf7, 0x71, 0x3f, 0x71, 0x54, 0x44, + 0x22, 0xa8, 0x55, 0x0f, 0x98, 0x83, 0x1f, 0xfe, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x01, 0x00, 0xbe, 0x52, 0xf2, 0x58, + 0x4a, 0xc3, 0xb5, 0xd0, 0xba, 0xac, 0xda, 0xf0, + 0x12, 0x99, 0x38, 0x6e, 0x04, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, + 0xdb, 0xfa, 0x73, 0x01, 0xb3, 0x81, 0x01, 0xd4, + 0x7f, 0xa0, 0x36, 0xb1, 0x97, 0xae, 0x29, 0x7f, + 0x01, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x00, 0x89, 0xbe, 0x41, 0x1d, + 0x38, 0x75, 0xf5, 0xb5, 0xad, 0x27, 0x73, 0xf1, + 0xb0, 0x7a, 0x28, 0x82, 0x05, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0xf6, 0x87, 0x09, 0x93, 0xb8, 0xa8, 0x20, 0xc4, + 0xb8, 0x63, 0xe6, 0x95, 0xed, 0x59, 0xee, 0x3f, + 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x01, 0x00, 0x92, 0x77, 0x92, 0x68, + 0x3e, 0xa4, 0xbc, 0x3f, 0x44, 0x33, 0x0e, 0xb8, + 0x33, 0x0a, 0x2f, 0xdf, 0x01, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, + 0xa1, 0x03, 0xd2, 0xa9, 0xd2, 0x16, 0xc9, 0x89, + 0x67, 0x18, 0x3e, 0xb1, 0xee, 0x6b, 0xf9, 0x18, + 0x02, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x01, 0x00, 0x2f, 0x09, 0x5e, 0x74, + 0xec, 0xa0, 0xbb, 0xc1, 0x60, 0x18, 0xf1, 0x93, + 0x04, 0x17, 0x11, 0xf9, 0x01, 0x00, 0x03, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, + 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01, + 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind1_len = sizeof(bind1); + + uint8_t bind_ack1[] = { + 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0xc1, 0x2b, 0x00, 0x00, + 0x0e, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, + 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind_ack1_len = sizeof(bind_ack1); + + uint8_t bind2[] = { + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0xdc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xc7, 0x70, 0x0d, 0x3e, 0x71, 0x37, 0x39, 0x0d, + 0x3a, 0x4f, 0xd3, 0xdc, 0xca, 0x49, 0xe8, 0xa3, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x84, 0xb6, 0x55, 0x75, + 0xdb, 0x9e, 0xba, 0x54, 0x56, 0xd3, 0x45, 0x10, + 0xb7, 0x7a, 0x2a, 0xe2, 0x04, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x6e, 0x39, 0x21, 0x24, 0x70, 0x6f, 0x41, 0x57, + 0x54, 0x70, 0xb8, 0xc3, 0x5e, 0x89, 0x3b, 0x43, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x39, 0x6a, 0x86, 0x5d, + 0x24, 0x0f, 0xd2, 0xf7, 0xb6, 0xce, 0x95, 0x9c, + 0x54, 0x1d, 0x3a, 0xdb, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x12, 0xa5, 0xdd, 0xc5, 0x55, 0xce, 0xc3, 0x46, + 0xbd, 0xa0, 0x94, 0x39, 0x3c, 0x0d, 0x9b, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x87, 0x1c, 0x8b, 0x6e, + 0x11, 0xa8, 0x67, 0x98, 0xd4, 0x5d, 0xf6, 0x8a, + 0x2f, 0x33, 0x24, 0x7b, 0x05, 0x00, 0x03, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x9b, 0x82, 0x13, 0xd1, 0x28, 0xe0, 0x63, 0xf3, + 0x62, 0xee, 0x76, 0x73, 0xf9, 0xac, 0x3d, 0x2e, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x00, 0xa9, 0xd4, 0x73, 0xf2, + 0xed, 0xad, 0xe8, 0x82, 0xf8, 0xcf, 0x9d, 0x9f, + 0x66, 0xe6, 0x43, 0x37, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x06, 0x2b, 0x85, 0x38, 0x4f, 0x73, 0x96, 0xb1, + 0x73, 0xe1, 0x59, 0xbe, 0x9d, 0xe2, 0x6c, 0x07, + 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x01, 0x00, 0xbf, 0xfa, 0xbb, 0xa4, + 0x9e, 0x5c, 0x80, 0x61, 0xb5, 0x8b, 0x79, 0x69, + 0xa6, 0x32, 0x88, 0x77, 0x01, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, + 0x39, 0xa8, 0x2c, 0x39, 0x73, 0x50, 0x06, 0x8d, + 0xf2, 0x37, 0x1e, 0x1e, 0xa8, 0x8f, 0x46, 0x98, + 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x01, 0x00, 0x91, 0x13, 0xd0, 0xa7, + 0xef, 0xc4, 0xa7, 0x96, 0x0c, 0x4a, 0x0d, 0x29, + 0x80, 0xd3, 0xfe, 0xbf, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, + 0xcc, 0x2b, 0x55, 0x1d, 0xd4, 0xa4, 0x0d, 0xfb, + 0xcb, 0x6f, 0x86, 0x36, 0xa6, 0x57, 0xc3, 0x21, + 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x01, 0x00, 0x43, 0x7b, 0x07, 0xee, + 0x85, 0xa8, 0xb9, 0x3a, 0x0f, 0xf9, 0x83, 0x70, + 0xe6, 0x0b, 0x4f, 0x33, 0x02, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, + 0x9c, 0x6a, 0x15, 0x8c, 0xd6, 0x9c, 0xa6, 0xc3, + 0xb2, 0x9e, 0x62, 0x9f, 0x3d, 0x8e, 0x47, 0x73, + 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x01, 0x00, 0xc8, 0x4f, 0x32, 0x4b, + 0x70, 0x16, 0xd3, 0x01, 0x12, 0x78, 0x5a, 0x47, + 0xbf, 0x6e, 0xe1, 0x88, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind2_len = sizeof(bind2); + + uint8_t bind_ack2[] = { + 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, + 0xac, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0xc2, 0x2b, 0x00, 0x00, + 0x0e, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, + 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind_ack2_len = sizeof(bind_ack2); + + uint8_t bind3[] = { + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x2c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xa4, 0x7f, 0x8e, 0xc6, 0xef, 0x56, 0x9b, 0x63, + 0x92, 0xfa, 0x08, 0xb3, 0x35, 0xe2, 0xa5, 0x81, + 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x9f, 0xfc, 0x78, 0xd2, + 0x5f, 0x16, 0x0b, 0xbc, 0xc6, 0xdb, 0x5d, 0xef, + 0xde, 0x54, 0xa2, 0x6f, 0x04, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x78, 0xb8, 0x96, 0xc7, 0x2f, 0xda, 0x11, 0x6b, + 0xd1, 0x28, 0x68, 0xe1, 0xd6, 0x71, 0xac, 0x9d, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x01, 0x00, 0xcf, 0xf4, 0xd7, 0x37, + 0x03, 0xda, 0xcc, 0xe3, 0x3e, 0x34, 0x7f, 0x67, + 0x99, 0x91, 0x41, 0x3d, 0x01, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x48, 0xeb, 0x32, 0xf0, 0x27, 0xd5, 0x9d, 0xd0, + 0x1e, 0xc6, 0x48, 0x46, 0x97, 0xe9, 0xdb, 0x09, + 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x82, 0xec, 0x0d, 0x08, + 0xf2, 0x8f, 0x22, 0x57, 0x42, 0x9b, 0xce, 0xa8, + 0x74, 0x16, 0xc6, 0xec, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x2e, 0x00, 0x70, 0x44, 0xee, 0xc9, 0x30, 0x6b, + 0xf4, 0x34, 0x1e, 0x3d, 0x35, 0x0f, 0xf7, 0xf7, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x00, 0x59, 0x04, 0x39, 0x3f, + 0x59, 0x87, 0x14, 0x0e, 0x76, 0x8d, 0x17, 0xc2, + 0x47, 0xfa, 0x67, 0x7f, 0x04, 0x00, 0x02, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x30, 0xd6, 0xed, 0x2e, 0x57, 0xfa, 0xf4, 0x72, + 0x6c, 0x10, 0x0d, 0xe5, 0x51, 0x7f, 0xd0, 0x39, + 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x01, 0x00, 0xea, 0x8b, 0x84, 0x4d, + 0x44, 0x43, 0xc1, 0x94, 0x75, 0xe2, 0x81, 0x48, + 0xd8, 0x77, 0xd9, 0xce, 0x05, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, + 0x89, 0x4f, 0xe7, 0x95, 0xa3, 0xc1, 0x62, 0x36, + 0x26, 0x9e, 0x67, 0xdb, 0x2c, 0x52, 0x89, 0xd3, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x01, 0x00, 0x78, 0x56, 0x34, 0x12, + 0x34, 0x12, 0xcd, 0xab, 0xef, 0x00, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xab, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind3_len = sizeof(bind3); + + uint8_t bind_ack3[] = { + 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0x1a, 0x33, 0x00, 0x00, + 0x0e, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, + 0x73, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x73, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind_ack3_len = sizeof(bind_ack3); + + TcpSession ssn; + DCERPCUuidEntry *item = NULL; + int count = 0; + + uint8_t accepted_uuids[3][16] = { + {0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, + 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88}, + {0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, + 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88}, + {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0xab, 0xcd, + 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab} + }; + + uint16_t accepted_ctxids[3] = {12, 15, 11}; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + bind1, bind1_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + DCERPCState *dcerpc_state = f.aldata[AlpGetStateIdx(ALPROTO_DCERPC)]; + if (dcerpc_state == NULL) { + printf("no dcerpc state: "); + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, + bind_ack1, bind_ack1_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + int i = 0; + /* check the interface uuid */ + for (i = 0; i < 16; i++) { + if (accepted_uuids[0][i] != item->uuid[i]) { + result = 0; + goto end; + } + } + if (accepted_ctxids[0] != item->ctxid) { + result = 0; + goto end; + } + count++; + } + if (count != 1) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + bind2, bind2_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + count++; + } + if (count != 0) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, + bind_ack2, bind_ack2_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + int i = 0; + /* check the interface uuid */ + for (i = 0; i < 16; i++) { + if (accepted_uuids[1][i] != item->uuid[i]) { + result = 0; + goto end; + } + } + if (accepted_ctxids[1] != item->ctxid) { + result = 0; + goto end; + } + count++; + } + if (count != 1) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + bind3, bind3_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + count++; + } + if (count != 0) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, + bind_ack3, bind_ack3_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + int i = 0; + /* check the interface uuid */ + for (i = 0; i < 16; i++) { + if (accepted_uuids[2][i] != item->uuid[i]) { + result = 0; + goto end; + } + } + if (accepted_ctxids[2] != item->ctxid) { + result = 0; + goto end; + } + count++; + } + if (count != 1) { + result = 0; + goto end; + } + +end: + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + return result; +} + + +/** + * \test Check for correct internal ids for bind_acks + alter_contexts + */ +int DCERPCParserTest17(void) { + int result = 1; + Flow f; + int r = 0; + + uint8_t bind[] = { + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, + 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind_len = sizeof(bind); + + uint8_t bind_ack[] = { + 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, + 0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, + 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t bind_ack_len = sizeof(bind_ack); + + uint8_t alter_context[] = { + 0x05, 0x00, 0x0e, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0xd0, 0x4c, 0x67, 0x57, 0x00, 0x52, 0xce, 0x11, + 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t alter_context_len = sizeof(alter_context); + + uint8_t alter_context_resp[] = { + 0x05, 0x00, 0x0f, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t alter_context_resp_len = sizeof(alter_context_resp); + + + TcpSession ssn; + DCERPCUuidEntry *item = NULL; + int count = 0; + + uint8_t accepted_uuids[2][16] = { + {0x57, 0x67, 0x4c, 0xd0, 0x52, 0x00, 0x11, 0xce, + 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d}, + {0x34, 0x2c, 0xfd, 0x40, 0x3c, 0x6c, 0x11, 0xce, + 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d}, + }; + + uint16_t accepted_ctxids[2] = {1, 0}; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + bind, bind_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + DCERPCState *dcerpc_state = f.aldata[AlpGetStateIdx(ALPROTO_DCERPC)]; + if (dcerpc_state == NULL) { + printf("no dcerpc state: "); + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, + bind_ack, bind_ack_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + int i = 0; + /* check the interface uuid */ + for (i = 0; i < 16; i++) { + if (accepted_uuids[1][i] != item->uuid[i]) { + result = 0; + goto end; + } + } + if (accepted_ctxids[1] != item->ctxid) { + result = 0; + goto end; + } + count++; + } + if (count != 1) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, + alter_context, alter_context_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + count++; + } + if (count != 1) { + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, + alter_context_resp, alter_context_resp_len); + if (r != 0) { + printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + count = 0; + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { + int i = 0; + /* check the interface uuid */ + for (i = 0; i < 16; i++) { + if (accepted_uuids[count][i] != item->uuid[i]) { + result = 0; + goto end; + } + } + if (accepted_ctxids[count] != item->ctxid) { + result = 0; + goto end; + } + count++; + } + if (count != 2) { + result = 0; + goto end; + } + +end: + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + return result; +} + #endif /* UNITTESTS */ void DCERPCParserRegisterTests(void) { @@ -4661,6 +5481,8 @@ void DCERPCParserRegisterTests(void) { UtRegisterTest("DCERPCParserTest13", DCERPCParserTest13, 1); UtRegisterTest("DCERPCParserTest14", DCERPCParserTest14, 1); UtRegisterTest("DCERPCParserTest15", DCERPCParserTest15, 1); + UtRegisterTest("DCERPCParserTest16", DCERPCParserTest16, 1); + UtRegisterTest("DCERPCParserTest17", DCERPCParserTest17, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-dce-iface.c b/src/detect-dce-iface.c index f7902c2989..65d037f24a 100644 --- a/src/detect-dce-iface.c +++ b/src/detect-dce-iface.c @@ -274,7 +274,7 @@ static inline int DetectDceIfaceMatchIfaceVersion(uint16_t version, int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) { - int ret = 1; + int ret = 0; DCERPCUuidEntry *item = NULL; int i = 0; DetectDceIfaceData *dce_data = (DetectDceIfaceData *)m->ctx; @@ -286,21 +286,27 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, SCMutexLock(&f->m); + /* we still haven't seen a request */ + if (!dcerpc_state->dcerpc.dcerpcrequest.first_request_seen) + goto end; + + if (!(dcerpc_state->dcerpc.dcerpchdr.type == REQUEST)) + 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 */ - ret = 0; goto end; } - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { + TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { ret = 1; /* if the uuid has been rejected(item->result == 1), we skip to the * next uuid */ - if (item->result == 1) + if (item->result != 0) continue; /* check the interface uuid */ @@ -310,6 +316,9 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, break; } } + ret &= (item->ctxid == dcerpc_state->dcerpc.dcerpcrequest.ctxid); + if (ret == 0) + continue; /* check the interface version */ if (dce_data->op != DETECT_DCE_IFACE_OP_NONE && @@ -837,8 +846,16 @@ static int DetectDceIfaceTestParse12(void) 0x02, 0x00, 0x00, 0x00 }; + uint8_t dcerpc_request[] = { + 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, + 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); + uint32_t dcerpc_request_len = sizeof(dcerpc_request); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); @@ -890,7 +907,7 @@ static int DetectDceIfaceTestParse12(void) /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { + if (PacketAlertCheck(p, 1)) { printf("sid 1 didn't match (1): "); goto end; } @@ -912,6 +929,21 @@ static int DetectDceIfaceTestParse12(void) goto end; } + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_request, + dcerpc_request_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sid 1 matched, but shouldn't have: "); + goto end; + } + result = 1; end: @@ -1106,7 +1138,7 @@ static int DetectDceIfaceTestParse13(void) /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { + if (PacketAlertCheck(p, 1)) { printf("sig 1 didn't match after bind request: "); goto end; } @@ -1299,8 +1331,16 @@ static int DetectDceIfaceTestParse14(void) 0x02, 0x00, 0x00, 0x00 }; + uint8_t dcerpc_request[] = { + 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, + 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); + uint32_t dcerpc_request_len = sizeof(dcerpc_request); memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); @@ -1351,7 +1391,206 @@ static int DetectDceIfaceTestParse14(void) /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) + if (PacketAlertCheck(p, 1)) + goto end; + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, + dcerpc_bindack_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_request, + dcerpc_request_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + result = 1; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + * \test Test a valid dce_iface entry for a bind and bind_ack + */ +static int DetectDceIfaceTestParse15(void) +{ + int result = 0; + Signature *s = NULL; + ThreadVars th_v; + Packet *p = NULL; + Flow f; + TcpSession ssn; + DetectEngineThreadCtx *det_ctx = NULL; + DetectEngineCtx *de_ctx = NULL; + DCERPCState *dcerpc_state = NULL; + int r = 0; + + uint8_t dcerpc_bind[] = { + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, + 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); + + uint8_t dcerpc_bindack[] = { + 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, + 0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, + 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00 + }; + uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); + + uint8_t dcerpc_alter_context[] = { + 0x05, 0x00, 0x0e, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0xd0, 0x4c, 0x67, 0x57, 0x00, 0x52, 0xce, 0x11, + 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t dcerpc_alter_context_len = sizeof(dcerpc_alter_context); + + uint8_t dcerpc_alter_context_resp[] = { + 0x05, 0x00, 0x0f, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + uint32_t dcerpc_alter_context_resp_len = sizeof(dcerpc_alter_context_resp); + + uint8_t dcerpc_request1[] = { + 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xdd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); + + uint8_t dcerpc_response1[] = { + 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf5, 0x66, 0xbf, 0x54, + 0xc4, 0xdb, 0xdb, 0x4f, 0xa0, 0x01, 0x6d, 0xf4, + 0xf6, 0xa8, 0x44, 0xb3, 0x00, 0x00, 0x00, 0x00 + }; + uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); + + uint8_t dcerpc_request2[] = { + 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, + }; + uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); + + memset(&th_v, 0, sizeof(th_v)); + memset(&p, 0, sizeof(p)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_DCERPC; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " + "(msg:\"DCERPC\"; " + "dce_iface:57674cd0-5200-11ce-a897-08002b2e9c6d; " + "sid:1;)"); + if (s == NULL) + goto end; + + s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " + "(msg:\"DCERPC\"; " + "dce_iface:342cfd40-3c6c-11ce-a893-08002b2e9c6d; " + "sid:2;)"); + if (s == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, + dcerpc_bind, dcerpc_bind_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + dcerpc_state = f.aldata[AlpGetStateIdx(ALPROTO_DCERPC)]; + if (dcerpc_state == NULL) { + SCLogDebug("no dcerpc state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) + goto end; + if (PacketAlertCheck(p, 2)) goto end; r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, @@ -1368,6 +1607,105 @@ static int DetectDceIfaceTestParse14(void) printf("sig 1 matched but shouldn't have: "); goto end; } + if (PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_alter_context, + dcerpc_alter_context_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + if (PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_alter_context_resp, + dcerpc_alter_context_resp_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + if (PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, + dcerpc_request1_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + if (PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, + dcerpc_response1_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + if (PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, + dcerpc_request2_len); + if (r != 0) { + SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } + if (!PacketAlertCheck(p, 2)) { + printf("sig 1 matched but shouldn't have: "); + goto end; + } result = 1; @@ -1405,6 +1743,7 @@ void DetectDceIfaceRegisterTests(void) UtRegisterTest("DetectDceIfaceTestParse12", DetectDceIfaceTestParse12, 1); UtRegisterTest("DetectDceIfaceTestParse13", DetectDceIfaceTestParse13, 1); UtRegisterTest("DetectDceIfaceTestParse14", DetectDceIfaceTestParse14, 1); + UtRegisterTest("DetectDceIfaceTestParse15", DetectDceIfaceTestParse15, 1); #endif return; diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index 3d076f4d1b..01578e2a72 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -2516,11 +2516,11 @@ int DcePayloadTest02(void) } /* detection phase */ SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!(PacketAlertCheck(p[0], 1))) { + if (PacketAlertCheck(p[0], 1)) { printf("sid 1 didn't match but should have for packet 0: "); goto end; } - if ((PacketAlertCheck(p[0], 2))) { + if (PacketAlertCheck(p[0], 2)) { printf("sid 2 matched but shouldn't have for packet 0: "); goto end; }