Adding one more case to the DCE_RPC defrag logic.

(and fixing a couple of compiler warnings)
This commit is contained in:
Robin Sommer 2016-10-25 16:44:50 -07:00
parent aab3819c70
commit 1f36ae61ba
4 changed files with 24 additions and 15 deletions

@ -1 +1 @@
Subproject commit 17d1c1547678bfd54ef1202db5415bc85c7ae794 Subproject commit 625dbecfd63022d79a144b9651085e68cdf99ce4

View file

@ -7,8 +7,8 @@ export {
## a weird and skip further input. ## a weird and skip further input.
const max_cmd_reassembly = 20 &redef; const max_cmd_reassembly = 20 &redef;
## The maximum number of fragmented bytes that will be tolerated ## The maximum number of fragmented bytes that will be tolerated
## on a command before the analyzer will generate a weird and ## on a command before the analyzer will generate a weird and
## skip further input. ## skip further input.
const max_frag_data = 30000 &redef; const max_frag_data = 30000 &redef;
@ -100,15 +100,15 @@ export {
["2f5f3220-c126-1076-b549-074d078619da"] = "nddeapi", ["2f5f3220-c126-1076-b549-074d078619da"] = "nddeapi",
} &redef &default=function(uuid: string): string { return fmt("unknown-%s", uuid); }; } &redef &default=function(uuid: string): string { return fmt("unknown-%s", uuid); };
## This table is to map pipe names to the most common ## This table is to map pipe names to the most common
## service used over that pipe. It helps in cases ## service used over that pipe. It helps in cases
## where the pipe binding wasn't seen. ## where the pipe binding wasn't seen.
const pipe_name_to_common_uuid: table[string] of string = { const pipe_name_to_common_uuid: table[string] of string = {
["winreg"] = "338cd001-2244-31f1-aaaa-900038001003", ["winreg"] = "338cd001-2244-31f1-aaaa-900038001003",
["spoolss"] = "12345678-1234-abcd-ef00-0123456789ab", ["spoolss"] = "12345678-1234-abcd-ef00-0123456789ab",
["srvsvc"] = "4b324fc8-1670-01d3-1278-5a47bf6ee188", ["srvsvc"] = "4b324fc8-1670-01d3-1278-5a47bf6ee188",
} &redef; } &redef;
const operations: table[string,count] of string = { const operations: table[string,count] of string = {
# atsvc # atsvc
["1ff70682-0a51-30e8-076d-740be8cee98b",0] = "NetrJobAdd", ["1ff70682-0a51-30e8-076d-740be8cee98b",0] = "NetrJobAdd",
@ -1470,7 +1470,7 @@ export {
["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x14] = "DRSAddSidHistory", ["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x14] = "DRSAddSidHistory",
["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x15] = "DRSGetMemberships2", ["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x15] = "DRSGetMemberships2",
["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x16] = "DRSReplicaVerifyObjects", ["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x16] = "DRSReplicaVerifyObjects",
["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x17] = "DRSGetObjectExistence", ["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x17] = "DRSGetObjectExistence",
["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x18] = "DRSQuerySitesByCost", ["e3514235-4b06-11d1-ab04-00c04fc2dcd2",0x18] = "DRSQuerySitesByCost",
# winspipe # winspipe

View file

@ -7,7 +7,7 @@ bro_plugin_begin(Bro DCE_RPC)
bro_plugin_cc(DCE_RPC.cc Plugin.cc) bro_plugin_cc(DCE_RPC.cc Plugin.cc)
bro_plugin_bif(consts.bif types.bif events.bif) bro_plugin_bif(consts.bif types.bif events.bif)
bro_plugin_pac( bro_plugin_pac(
dce_rpc.pac dce_rpc.pac
dce_rpc-protocol.pac dce_rpc-protocol.pac
dce_rpc-analyzer.pac dce_rpc-analyzer.pac
dce_rpc-auth.pac dce_rpc-auth.pac

View file

@ -182,12 +182,21 @@ flow DCE_RPC_Flow(is_orig: bool) {
%{ %{
if ( ${header.firstfrag} ) if ( ${header.firstfrag} )
{ {
if ( fb.count(${header.call_id}) > 0 )
{
// We already had a first frag earlier.
reporter->Weird(connection()->bro_analyzer()->Conn(),
"multiple_first_fragments_in_dce_rpc_reassembly");
connection()->bro_analyzer()->SetSkip(true);
return false;
}
if ( ${header.lastfrag} ) if ( ${header.lastfrag} )
{ {
// all-in-one packet // all-in-one packet
return true; return true;
} }
else else
{ {
// first frag, but not last so we start a flowbuffer // first frag, but not last so we start a flowbuffer
fb[${header.call_id}] = std::unique_ptr<FlowBuffer>(new FlowBuffer()); fb[${header.call_id}] = std::unique_ptr<FlowBuffer>(new FlowBuffer());
@ -196,14 +205,14 @@ flow DCE_RPC_Flow(is_orig: bool) {
if ( fb.size() > BifConst::DCE_RPC::max_cmd_reassembly ) if ( fb.size() > BifConst::DCE_RPC::max_cmd_reassembly )
{ {
reporter->Weird(connection()->bro_analyzer()->Conn(), reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_many_dce_rpc_msgs_in_reassembly"); "too_many_dce_rpc_msgs_in_reassembly");
connection()->bro_analyzer()->SetSkip(true); connection()->bro_analyzer()->SetSkip(true);
} }
if ( fb[${header.call_id}]->data_length() > BifConst::DCE_RPC::max_frag_data ) if ( fb[${header.call_id}]->data_length() > (int)BifConst::DCE_RPC::max_frag_data )
{ {
reporter->Weird(connection()->bro_analyzer()->Conn(), reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_much_dce_rpc_fragment_data"); "too_much_dce_rpc_fragment_data");
connection()->bro_analyzer()->SetSkip(true); connection()->bro_analyzer()->SetSkip(true);
} }
@ -216,9 +225,9 @@ flow DCE_RPC_Flow(is_orig: bool) {
// not the first frag, but we have a flow buffer so add to it // not the first frag, but we have a flow buffer so add to it
fb[${header.call_id}]->BufferData(frag.begin(), frag.end()); fb[${header.call_id}]->BufferData(frag.begin(), frag.end());
if ( fb[${header.call_id}]->data_length() > BifConst::DCE_RPC::max_frag_data ) if ( fb[${header.call_id}]->data_length() > (int)BifConst::DCE_RPC::max_frag_data )
{ {
reporter->Weird(connection()->bro_analyzer()->Conn(), reporter->Weird(connection()->bro_analyzer()->Conn(),
"too_much_dce_rpc_fragment_data"); "too_much_dce_rpc_fragment_data");
connection()->bro_analyzer()->SetSkip(true); connection()->bro_analyzer()->SetSkip(true);
} }
@ -244,7 +253,7 @@ flow DCE_RPC_Flow(is_orig: bool) {
bd = const_bytestring(fb[${h.call_id}]->begin(), fb[${h.call_id}]->end()); bd = const_bytestring(fb[${h.call_id}]->begin(), fb[${h.call_id}]->end());
fb.erase(${h.call_id}); fb.erase(${h.call_id});
} }
return bd; return bd;
%} %}
}; };