From 41e2eaa02d0d815c551ed17acab937b441608964 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 1 Mar 2016 14:16:45 -0500 Subject: [PATCH] Source clean up and some fixes for SMB. - Remove the separate string handling for NTLM. - Fixed a crash in RPC Bind handling when no context elements are included. --- scripts/base/protocols/smb/smb1-main.bro | 7 ++-- scripts/base/protocols/smb/smb2-main.bro | 2 +- src/analyzer/protocol/smb/smb-ntlmssp.pac | 44 ++++++++--------------- src/analyzer/protocol/smb/smb-pipe.pac | 33 ++++++++++++----- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/scripts/base/protocols/smb/smb1-main.bro b/scripts/base/protocols/smb/smb1-main.bro index 6c8694e04c..4756554ce0 100644 --- a/scripts/base/protocols/smb/smb1-main.bro +++ b/scripts/base/protocols/smb/smb1-main.bro @@ -168,7 +168,6 @@ event smb1_nt_create_andx_response(c: connection, hdr: SMB1::Header, file_id: co c$smb_state$current_file = c$smb_state$fid_map[file_id]; - SMB::write_file_log(c$smb_state$current_file); } @@ -176,7 +175,8 @@ event smb1_read_andx_request(c: connection, hdr: SMB1::Header, file_id: count, o { SMB::set_current_file(c$smb_state, file_id); c$smb_state$current_file$action = SMB::FILE_READ; - c$smb_state$current_cmd$argument = c$smb_state$current_file$name; + if ( c$smb_state$current_file?$name ) + c$smb_state$current_cmd$argument = c$smb_state$current_file$name; } event smb1_read_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, length: count) &priority=-5 @@ -323,7 +323,8 @@ event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, s event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count) { - c$smb_state$pipe_map[file_id] = c$smb_state$current_file$uuid; + if ( c$smb_state$current_file?$uuid ) + c$smb_state$pipe_map[file_id] = c$smb_state$current_file$uuid; } event smb_pipe_bind_ack_response(c: connection, hdr: SMB1::Header) diff --git a/scripts/base/protocols/smb/smb2-main.bro b/scripts/base/protocols/smb/smb2-main.bro index a27d6a87d0..e668d9b2fd 100644 --- a/scripts/base/protocols/smb/smb2-main.bro +++ b/scripts/base/protocols/smb/smb2-main.bro @@ -142,7 +142,7 @@ event smb2_create_response(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID event smb2_set_info_request(c: connection, hdr: SMB2::Header, request: SMB2::SetInfoRequest) &priority=5 { - c$smb$current_file$size = request$eof; + c$smb_state$current_file$size = request$eof; } event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=5 diff --git a/src/analyzer/protocol/smb/smb-ntlmssp.pac b/src/analyzer/protocol/smb/smb-ntlmssp.pac index bb1c353281..bcb27b9b9b 100644 --- a/src/analyzer/protocol/smb/smb-ntlmssp.pac +++ b/src/analyzer/protocol/smb/smb-ntlmssp.pac @@ -1,18 +1,4 @@ refine connection SMB_Conn += { - function unicode_to_ascii(s: bytestring, length: uint16, is_unicode: bool): bytestring - %{ - if ( !is_unicode ) return s; - - char* buf; - - buf = new char[(length/2) + 1]; - - for ( int i = 0; i < length; i += 2 ) - buf[i/2] = s[i]; - buf[length/2] = 0; - return bytestring((uint8*) buf, (length/2)); - %} - function build_negotiate_flag_record(val: SMB_NTLM_Negotiate_Flags): BroVal %{ RecordVal* flags = new RecordVal(BifType::Record::SMB::NTLMNegotiateFlags); @@ -63,19 +49,19 @@ refine connection SMB_Conn += { for ( uint i = 0; ${val.pairs[i].id} != 0; i++ ) { switch ( ${val.pairs[i].id} ) { case 1: - result->Assign(0, bytestring_to_val(${val.pairs[i].nb_computer_name.data})); + result->Assign(0, uint8s_to_stringval(${val.pairs[i].nb_computer_name.data})); break; case 2: - result->Assign(1, bytestring_to_val(${val.pairs[i].nb_domain_name.data})); + result->Assign(1, uint8s_to_stringval(${val.pairs[i].nb_domain_name.data})); break; case 3: - result->Assign(2, bytestring_to_val(${val.pairs[i].dns_computer_name.data})); + result->Assign(2, uint8s_to_stringval(${val.pairs[i].dns_computer_name.data})); break; case 4: - result->Assign(3, bytestring_to_val(${val.pairs[i].dns_domain_name.data})); + result->Assign(3, uint8s_to_stringval(${val.pairs[i].dns_domain_name.data})); break; case 5: - result->Assign(4, bytestring_to_val(${val.pairs[i].dns_tree_name.data})); + result->Assign(4, uint8s_to_stringval(${val.pairs[i].dns_tree_name.data})); break; case 6: result->Assign(5, new Val(${val.pairs[i].constrained_auth}, TYPE_BOOL)); @@ -87,7 +73,7 @@ refine connection SMB_Conn += { result->Assign(7, new Val(${val.pairs[i].single_host.machine_id}, TYPE_COUNT)); break; case 9: - result->Assign(8, bytestring_to_val(${val.pairs[i].target_name.data})); + result->Assign(8, uint8s_to_stringval(${val.pairs[i].target_name.data})); break; } } @@ -119,10 +105,10 @@ refine connection SMB_Conn += { result->Assign(0, build_negotiate_flag_record(${val.flags})); if ( ${val.flags.negotiate_oem_domain_supplied} ) - result->Assign(1, bytestring_to_val(${val.domain_name.string.data})); + result->Assign(1, uint8s_to_stringval(${val.domain_name.string.data})); if ( ${val.flags.negotiate_oem_workstation_supplied} ) - result->Assign(2, bytestring_to_val(${val.workstation.string.data})); + result->Assign(2, uint8s_to_stringval(${val.workstation.string.data})); if ( ${val.flags.negotiate_version} ) result->Assign(3, build_version_record(${val.version})); @@ -138,7 +124,7 @@ refine connection SMB_Conn += { result->Assign(0, build_negotiate_flag_record(${val.flags})); if ( ${val.flags.request_target} ) - result->Assign(1, bytestring_to_val(${val.target_name.string.data})); + result->Assign(1, uint8s_to_stringval(${val.target_name.string.data})); if ( ${val.flags.negotiate_version} ) result->Assign(2, build_version_record(${val.version})); @@ -157,13 +143,13 @@ refine connection SMB_Conn += { result->Assign(0, build_negotiate_flag_record(${val.flags})); if ( ${val.domain_name_fields.length} > 0 ) - result->Assign(1, bytestring_to_val(${val.domain_name.string.data})); + result->Assign(1, uint8s_to_stringval(${val.domain_name.string.data})); if ( ${val.user_name_fields.length} > 0 ) - result->Assign(2, bytestring_to_val(${val.user_name.string.data})); + result->Assign(2, uint8s_to_stringval(${val.user_name.string.data})); if ( ${val.workstation_fields.length} > 0 ) - result->Assign(3, bytestring_to_val(${val.workstation.string.data})); + result->Assign(3, uint8s_to_stringval(${val.workstation.string.data})); if ( ${val.flags.negotiate_version} ) result->Assign(4, build_version_record(${val.version})); @@ -320,9 +306,7 @@ type SMB_NTLM_StringData = record { }; type SMB_Fixed_Length_String(unicode: bool) = record { - s: bytestring &restofdata; -} &let { - data: bytestring = $context.connection.unicode_to_ascii(s, sizeof(s), unicode); + data: uint8[] &restofdata; }; type SMB_NTLM_String(fields: SMB_NTLM_StringData, offset: uint16, unicode: bool) = record { @@ -356,7 +340,7 @@ type SMB_NTLM_AV_Pair = record { # av_flags refinement constrained_auth: bool = (av_flags & 0x00000001) > 0 &if ( id == 0x0006); mic_present : bool = (av_flags & 0x00000002) > 0 &if ( id == 0x0006); - untrusted_source: bool = (av_flags & 0x00000004) > 0 &if ( id == 0x0006); + untrusted_source: bool = (av_flags & 0x00000004) > 0 &if ( id == 0x0006); }; type SMB_NTLM_Single_Host = record { diff --git a/src/analyzer/protocol/smb/smb-pipe.pac b/src/analyzer/protocol/smb/smb-pipe.pac index 46d589a140..f09cb6d53c 100644 --- a/src/analyzer/protocol/smb/smb-pipe.pac +++ b/src/analyzer/protocol/smb/smb-pipe.pac @@ -31,23 +31,40 @@ refine connection SMB_Conn += { switch ( ${val.rpc_header.PTYPE} ) { case DCE_RPC_REQUEST: if ( smb_pipe_request ) - BifEvent::generate_smb_pipe_request(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), \ - ${val.rpc_body.request.opnum}); + BifEvent::generate_smb_pipe_request(bro_analyzer(), + bro_analyzer()->Conn(), + BuildHeaderVal(header), + ${val.rpc_body.request.opnum}); break; case DCE_RPC_RESPONSE: if ( smb_pipe_response ) - BifEvent::generate_smb_pipe_response(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header)); + BifEvent::generate_smb_pipe_response(bro_analyzer(), + bro_analyzer()->Conn(), + BuildHeaderVal(header)); break; case DCE_RPC_BIND_ACK: if ( smb_pipe_bind_ack_response ) - BifEvent::generate_smb_pipe_bind_ack_response(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header)); + BifEvent::generate_smb_pipe_bind_ack_response(bro_analyzer(), + bro_analyzer()->Conn(), + BuildHeaderVal(header)); break; case DCE_RPC_BIND: if ( smb_pipe_bind_request ) - // TODO - the version number needs to be calculated properly - BifEvent::generate_smb_pipe_bind_request(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), \ - new StringVal(analyzer::dce_rpc::uuid_to_string(bytestring_to_val(${val.rpc_body.bind.p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid})->Bytes())), new StringVal(fmt("%d.0", ${val.rpc_body.bind.p_context_elem.p_cont_elem[0].abstract_syntax.if_version}))); - break; + { + // TODO - the version number needs to be calculated properly + if ( ${val.rpc_body.bind.p_context_elem.n_context_elem} > 0 ) + { + const char * uuid = analyzer::dce_rpc::uuid_to_string(${val.rpc_body.bind.p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid}.begin()); + uint32_t version = ${val.rpc_body.bind.p_context_elem.p_cont_elem[0].abstract_syntax.if_version}; + + BifEvent::generate_smb_pipe_bind_request(bro_analyzer(), + bro_analyzer()->Conn(), + BuildHeaderVal(header), + new StringVal(uuid), + new StringVal(fmt("%d.0", version))); + } + } + break; } return true;