diff --git a/CHANGES b/CHANGES index 5a4ac6a052..2f62ddce5d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,24 @@ +2.5-beta-135 | 2016-11-02 09:47:20 -0700 + + * SMB fixes and cleanup. Includes better SMB error handling, improved DCE_RPC + handling in edge cases where drive_mapping is not seen. The concept of unknown + shares has been removed with this change. Also fixes SMB tree connect handling and + removes files that are not parsed. SMB2 error parsing is disabled because it never + was implemented correctly. (Seth Hall) + + * Including a test for raw NTLM in SMB (Seth Hall) + + * Updates for SMB auth handling from Martin van Hensbergen. + + - Raw NTLM (not in GSSAPI) over SMB is now handled correctly. + - The encrypted NTLM session key is now passed into scriptland + through the ntlm_authenticate event. (Seth Hall) + + * Add a files framework signature for VIM tmp files. (Seth Hall) + + * Version parsing scripts now supports several beta versions. (Johanna Amann) + 2.5-beta-123 | 2016-11-01 09:40:49 -0700 * Add a new site policy script local-logger.bro. (Daniel Thayer) diff --git a/VERSION b/VERSION index 860c185190..df178c76ba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-beta-123 +2.5-beta-135 diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 60697b8c01..f84157716f 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2505,11 +2505,13 @@ export { ## The negotiate flags flags : NTLM::NegotiateFlags; ## The domain or computer name hosting the account - domain_name : string; + domain_name : string &optional; ## The name of the user to be authenticated. - user_name : string; + user_name : string &optional; ## The name of the computer to which the user was logged on. - workstation : string; + workstation : string &optional; + ## The session key + session_key : string &optional; ## The Windows version information, if supplied version : NTLM::Version &optional; }; @@ -2533,6 +2535,13 @@ export { ## The time when the file was last modified. changed : time &log; } &log; + + ## A set of file names used as named pipes over SMB. This + ## only comes into play as a heuristic to identify named + ## pipes when the drive mapping wasn't seen by Bro. + ## + ## .. bro:see::smb_pipe_connect_heuristic + const SMB::pipe_filenames: set[string] &redef; } module SMB1; diff --git a/scripts/base/protocols/dce-rpc/main.bro b/scripts/base/protocols/dce-rpc/main.bro index 5ec5ded2d8..0ee908d13e 100644 --- a/scripts/base/protocols/dce-rpc/main.bro +++ b/scripts/base/protocols/dce-rpc/main.bro @@ -158,13 +158,14 @@ event dce_rpc_response(c: connection, fid: count, opnum: count, stub_len: count) { if ( c?$dce_rpc ) { - # If there is not an endpoint, there isn't much reason to log. + # If there is noendpoint, there isn't much reason to log. # This can happen if the request isn't seen. - if ( (c$dce_rpc?$endpoint && c$dce_rpc$endpoint !in ignored_operations) - || - (c$dce_rpc?$endpoint && c$dce_rpc?$operation && - c$dce_rpc$operation !in ignored_operations[c$dce_rpc$endpoint] && - "*" !in ignored_operations[c$dce_rpc$endpoint]) ) + if ( ( c$dce_rpc?$endpoint && c$dce_rpc?$operation ) && + ( c$dce_rpc$endpoint !in ignored_operations + || + ( c$dce_rpc?$endpoint && c$dce_rpc?$operation && + c$dce_rpc$operation !in ignored_operations[c$dce_rpc$endpoint] && + "*" !in ignored_operations[c$dce_rpc$endpoint] ) ) ) { Log::write(LOG, c$dce_rpc); } @@ -195,11 +196,12 @@ event connection_state_remove(c: connection) } } - if ( (c$dce_rpc?$endpoint && c$dce_rpc$endpoint !in ignored_operations) - || - (c$dce_rpc?$endpoint && c$dce_rpc?$operation && - c$dce_rpc$operation !in ignored_operations[c$dce_rpc$endpoint] && - "*" !in ignored_operations[c$dce_rpc$endpoint]) ) + if ( ( c$dce_rpc?$endpoint && c$dce_rpc?$operation ) && + ( c$dce_rpc$endpoint !in ignored_operations + || + ( c$dce_rpc?$endpoint && c$dce_rpc?$operation && + c$dce_rpc$operation !in ignored_operations[c$dce_rpc$endpoint] && + "*" !in ignored_operations[c$dce_rpc$endpoint] ) ) ) { Log::write(LOG, c$dce_rpc); } diff --git a/scripts/base/protocols/smb/consts.bro b/scripts/base/protocols/smb/consts.bro index 86c470024c..b74b75fb37 100644 --- a/scripts/base/protocols/smb/consts.bro +++ b/scripts/base/protocols/smb/consts.bro @@ -10,20 +10,18 @@ export { [0x00000000] = [$id="SUCCESS", $desc="The operation completed successfully."], } &redef &default=function(i: count):StatusCode { local unknown=fmt("unknown-%d", i); return [$id=unknown, $desc=unknown]; }; - ## These are files names that are used for special - ## cases by the file system and would not be - ## considered "normal" files. - const pipe_names: set[string] = { - "\\netdfs", - "\\spoolss", - "\\NETLOGON", - "\\winreg", - "\\lsarpc", - "\\samr", - "\\srvsvc", + ## Heuristic detection of named pipes when the pipe + ## mapping isn't seen. This variable is defined in + ## init-bare.bro. + redef SMB::pipe_filenames = { + "spoolss", + "winreg", + "samr", "srvsvc", + "netdfs", + "lsarpc", + "wkssvc", "MsFteWds", - "\\wkssvc", }; ## The UUIDs used by the various RPC endpoints diff --git a/scripts/policy/protocols/smb/main.bro b/scripts/policy/protocols/smb/main.bro index 0399e92a9a..61a2548f6c 100644 --- a/scripts/policy/protocols/smb/main.bro +++ b/scripts/policy/protocols/smb/main.bro @@ -28,11 +28,6 @@ export { PRINT_WRITE, PRINT_OPEN, PRINT_CLOSE, - - UNKNOWN_READ, - UNKNOWN_WRITE, - UNKNOWN_OPEN, - UNKNOWN_CLOSE, }; ## The file actions which are logged. @@ -43,8 +38,6 @@ export { PRINT_OPEN, PRINT_CLOSE, - - UNKNOWN_OPEN, } &redef; ## The server response statuses which are *not* logged. @@ -225,7 +218,6 @@ function write_file_log(state: State) { local f = state$current_file; if ( f?$name && - f$name !in pipe_names && f$action in logged_file_actions ) { # Everything in this if statement is to avoid overlogging @@ -252,6 +244,12 @@ function write_file_log(state: State) } } +event smb_pipe_connect_heuristic(c: connection) &priority=5 + { + c$smb_state$current_tree$path = ""; + c$smb_state$current_tree$share_type = "PIPE"; + } + event file_state_remove(f: fa_file) &priority=-5 { if ( f$source != "SMB" ) diff --git a/scripts/policy/protocols/smb/smb1-main.bro b/scripts/policy/protocols/smb/smb1-main.bro index c1b8ead509..3e7f43cf45 100644 --- a/scripts/policy/protocols/smb/smb1-main.bro +++ b/scripts/policy/protocols/smb/smb1-main.bro @@ -108,11 +108,6 @@ event smb1_negotiate_response(c: connection, hdr: SMB1::Header, response: SMB1:: event smb1_negotiate_response(c: connection, hdr: SMB1::Header, response: SMB1::NegotiateResponse) &priority=-5 { - if ( SMB::write_cmd_log && - c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) - { - Log::write(SMB::CMD_LOG, c$smb_state$current_cmd); - } } event smb1_tree_connect_andx_request(c: connection, hdr: SMB1::Header, path: string, service: string) &priority=5 @@ -141,12 +136,6 @@ event smb1_tree_connect_andx_response(c: connection, hdr: SMB1::Header, service: event smb1_tree_connect_andx_response(c: connection, hdr: SMB1::Header, service: string, native_file_system: string) &priority=-5 { Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree); - - if ( SMB::write_cmd_log && - c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) - { - Log::write(SMB::CMD_LOG, c$smb_state$current_cmd); - } } event smb1_nt_create_andx_request(c: connection, hdr: SMB1::Header, name: string) &priority=5 @@ -192,17 +181,7 @@ event smb1_read_andx_request(c: connection, hdr: SMB1::Header, file_id: count, o if ( c$smb_state$current_tree?$path && !c$smb_state$current_file?$path ) c$smb_state$current_file$path = c$smb_state$current_tree$path; - # We don't even try to log reads and writes to the files log. - #write_file_log(c$smb_state); - } - -event smb1_read_andx_response(c: connection, hdr: SMB1::Header, data_len: count) &priority=5 - { - if ( SMB::write_cmd_log && - c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) - { - Log::write(SMB::CMD_LOG, c$smb_state$current_cmd); - } + SMB::write_file_log(c$smb_state); } event smb1_write_andx_request(c: connection, hdr: SMB1::Header, file_id: count, offset: count, data_len: count) &priority=5 @@ -281,11 +260,7 @@ event smb1_session_setup_andx_request(c: connection, hdr: SMB1::Header, request: event smb1_session_setup_andx_response(c: connection, hdr: SMB1::Header, response: SMB1::SessionSetupAndXResponse) &priority=-5 { - if ( SMB::write_cmd_log && - c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) - { - Log::write(SMB::CMD_LOG, c$smb_state$current_cmd); - } + # No behavior yet. } event smb1_transaction_request(c: connection, hdr: SMB1::Header, name: string, sub_cmd: count) diff --git a/scripts/policy/protocols/smb/smb2-main.bro b/scripts/policy/protocols/smb/smb2-main.bro index 31b3abf0db..726851dee4 100644 --- a/scripts/policy/protocols/smb/smb2-main.bro +++ b/scripts/policy/protocols/smb/smb2-main.bro @@ -101,13 +101,9 @@ event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2:: event smb2_negotiate_response(c: connection, hdr: SMB2::Header, response: SMB2::NegotiateResponse) &priority=5 { - if ( SMB::write_cmd_log && - c$smb_state$current_cmd$status !in SMB::ignored_command_statuses ) - { - Log::write(SMB::CMD_LOG, c$smb_state$current_cmd); - } + # No behavior yet. } - + event smb2_tree_connect_request(c: connection, hdr: SMB2::Header, path: string) &priority=5 { c$smb_state$current_tree$path = path; @@ -123,6 +119,16 @@ event smb2_tree_connect_response(c: connection, hdr: SMB2::Header, response: SMB Log::write(SMB::MAPPING_LOG, c$smb_state$current_tree); } +event smb2_tree_disconnect_request(c: connection, hdr: SMB2::Header) &priority=5 + { + if ( hdr$tree_id in c$smb_state$tid_map ) + { + delete c$smb_state$tid_map[hdr$tree_id]; + delete c$smb_state$current_tree; + delete c$smb_state$current_cmd$referenced_tree; + } + } + event smb2_create_request(c: connection, hdr: SMB2::Header, name: string) &priority=5 { if ( name == "") @@ -142,7 +148,6 @@ event smb2_create_request(c: connection, hdr: SMB2::Header, name: string) &prior c$smb_state$current_file$action = SMB::PRINT_OPEN; break; default: - #c$smb_state$current_file$action = SMB::UNKNOWN_OPEN; c$smb_state$current_file$action = SMB::FILE_OPEN; break; } @@ -150,6 +155,8 @@ event smb2_create_request(c: connection, hdr: SMB2::Header, name: string) &prior event smb2_create_response(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, file_size: count, times: SMB::MACTimes, attrs: SMB2::FileAttrs) &priority=5 { + SMB::set_current_file(c$smb_state, file_id$persistent+file_id$volatile); + c$smb_state$current_file$fid = file_id$persistent+file_id$volatile; c$smb_state$current_file$size = file_size; @@ -188,13 +195,14 @@ event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, o c$smb_state$current_file$action = SMB::PRINT_READ; break; default: - c$smb_state$current_file$action = SMB::FILE_OPEN; + c$smb_state$current_file$action = SMB::FILE_READ; break; } } event smb2_read_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5 { + SMB::write_file_log(c$smb_state); } event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=5 @@ -213,7 +221,6 @@ event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, c$smb_state$current_file$action = SMB::PRINT_WRITE; break; default: - #c$smb_state$current_file$action = SMB::UNKNOWN_WRITE; c$smb_state$current_file$action = SMB::FILE_WRITE; break; } @@ -221,6 +228,7 @@ event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, event smb2_write_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, offset: count, length: count) &priority=-5 { + SMB::write_file_log(c$smb_state); } event smb2_file_rename(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, dst_filename: string) &priority=5 @@ -254,7 +262,9 @@ event smb2_file_delete(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID, de if ( ! delete_pending ) { - print "huh..."; + # This is weird beause it would mean that someone didn't + # set the delete bit in a delete request. + return; } switch ( c$smb_state$current_tree$share_type ) @@ -289,7 +299,6 @@ event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) c$smb_state$current_file$action = SMB::PRINT_CLOSE; break; default: - #c$smb_state$current_file$action = SMB::UNKNOWN_CLOSE; c$smb_state$current_file$action = SMB::FILE_CLOSE; break; } diff --git a/src/analyzer/protocol/ntlm/ntlm-analyzer.pac b/src/analyzer/protocol/ntlm/ntlm-analyzer.pac index e1850f8b45..55756b61e9 100644 --- a/src/analyzer/protocol/ntlm/ntlm-analyzer.pac +++ b/src/analyzer/protocol/ntlm/ntlm-analyzer.pac @@ -148,8 +148,11 @@ refine connection NTLM_Conn += { if ( ${val}->has_workstation() > 0 ) result->Assign(3, utf16_bytestring_to_utf8_val(bro_analyzer()->Conn(), ${val.workstation.string.data})); + if ( ${val}->has_encrypted_session_key() > 0 ) + result->Assign(4, bytestring_to_val(${val.encrypted_session_key.string.data})); + if ( ${val}->has_version() ) - result->Assign(4, build_version_record(${val.version})); + result->Assign(5, build_version_record(${val.version})); BifEvent::generate_ntlm_authenticate(bro_analyzer(), bro_analyzer()->Conn(), diff --git a/src/analyzer/protocol/ntlm/ntlm-protocol.pac b/src/analyzer/protocol/ntlm/ntlm-protocol.pac index c553330760..8862be1f22 100644 --- a/src/analyzer/protocol/ntlm/ntlm-protocol.pac +++ b/src/analyzer/protocol/ntlm/ntlm-protocol.pac @@ -61,7 +61,7 @@ type NTLM_Authenticate(offset: uint16) = record { domain_name : NTLM_String(domain_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(domain_name_fields.length > 0); user_name : NTLM_String(user_name_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(user_name_fields.length > 0); workstation : NTLM_String(workstation_fields, absolute_offset , flags.negotiate_unicode) withinput payload &if(workstation_fields.length > 0); - encrypted_session_key : NTLM_String(encrypted_session_key_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(flags.negotiate_key_exch); + encrypted_session_key : NTLM_String(encrypted_session_key_fields, absolute_offset, flags.negotiate_unicode) withinput payload &if(encrypted_session_key_fields.length > 0); }; type NTLM_Version = record { diff --git a/src/analyzer/protocol/smb/CMakeLists.txt b/src/analyzer/protocol/smb/CMakeLists.txt index 2ea745d51d..bf44501b96 100644 --- a/src/analyzer/protocol/smb/CMakeLists.txt +++ b/src/analyzer/protocol/smb/CMakeLists.txt @@ -26,17 +26,18 @@ bro_plugin_bif( smb2_com_close.bif smb2_com_create.bif - #smb2_com_ioctl.bif - #smb2_com_lock.bif smb2_com_negotiate.bif smb2_com_read.bif smb2_com_session_setup.bif smb2_com_set_info.bif smb2_com_tree_connect.bif - #smb2_com_tree_disconnect.bif + smb2_com_tree_disconnect.bif smb2_com_write.bif smb2_events.bif + events.bif + consts.bif + types.bif) bro_plugin_pac( smb.pac diff --git a/src/analyzer/protocol/smb/SMB.cc b/src/analyzer/protocol/smb/SMB.cc index da202f5269..97178545ef 100644 --- a/src/analyzer/protocol/smb/SMB.cc +++ b/src/analyzer/protocol/smb/SMB.cc @@ -10,38 +10,34 @@ SMB_Analyzer::SMB_Analyzer(Connection *conn) : tcp::TCP_ApplicationAnalyzer("SMB", conn) { chunks=0; - interp=0; + interp = new binpac::SMB::SMB_Conn(this); + need_sync=true; } SMB_Analyzer::~SMB_Analyzer() { - if ( interp ) - delete interp; + delete interp; } void SMB_Analyzer::Done() { TCP_ApplicationAnalyzer::Done(); - if ( interp ) - { - interp->FlowEOF(true); - interp->FlowEOF(false); - } + interp->FlowEOF(true); + interp->FlowEOF(false); } void SMB_Analyzer::EndpointEOF(bool is_orig) { TCP_ApplicationAnalyzer::EndpointEOF(is_orig); - if ( interp ) - interp->FlowEOF(is_orig); + interp->FlowEOF(is_orig); } void SMB_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); - + NeedResync(); } @@ -54,24 +50,28 @@ bool SMB_Analyzer::HasSMBHeader(int len, const u_char* data) strncmp((const char*) data+4, "\xfeSMB", 4) == 0); } +void SMB_Analyzer::NeedResync() + { + interp->upflow()->flow_buffer()->DiscardData(); + interp->downflow()->flow_buffer()->DiscardData(); + need_sync=true; + } + void SMB_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); - // Either instantiate an interpreter or bail. - if ( ! interp ) - { - if ( HasSMBHeader(len, data) ) - interp = new binpac::SMB::SMB_Conn(this); - else - return; - } + // It we need to resync and we don't have an SMB header, bail! + if ( need_sync && ! HasSMBHeader(len, data) ) + return; + else + need_sync=false; try { - // If we get here, it means we have an interpreter. + // If we get here, it means we have an SMB header in the message. interp->NewData(orig, data, data + len); // Let's assume that if there are no binpac exceptions after diff --git a/src/analyzer/protocol/smb/SMB.h b/src/analyzer/protocol/smb/SMB.h index 2edeecf506..ea9ec2e6a5 100644 --- a/src/analyzer/protocol/smb/SMB.h +++ b/src/analyzer/protocol/smb/SMB.h @@ -17,10 +17,7 @@ public: void EndpointEOF(bool is_orig) override; bool HasSMBHeader(int len, const u_char* data); - void NeedResync() { - delete interp; - interp = 0; - } + void NeedResync(); static analyzer::Analyzer* Instantiate(Connection* conn) { return new SMB_Analyzer(conn); } @@ -31,6 +28,8 @@ protected: // Count the number of chunks received by the analyzer // but only used to count the first few. uint8 chunks; + + bool need_sync; }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/smb/consts.bif b/src/analyzer/protocol/smb/consts.bif new file mode 100644 index 0000000000..321875b43d --- /dev/null +++ b/src/analyzer/protocol/smb/consts.bif @@ -0,0 +1 @@ +const SMB::pipe_filenames: string_set; \ No newline at end of file diff --git a/src/analyzer/protocol/smb/events.bif b/src/analyzer/protocol/smb/events.bif new file mode 100644 index 0000000000..d0091589fe --- /dev/null +++ b/src/analyzer/protocol/smb/events.bif @@ -0,0 +1,10 @@ +## Generated for :abbr:`SMB (Server Message Block)` connections when a +## named pipe has been detected heuristically. The case when this comes +## up is when the drive mapping isn't seen so the analyzer is not able +## to determine whether to send the data to the files framework or to +## the DCE_RPC analyzer. This heuristic can be tuned by adding or +## removing "named pipe" names from the :bro:see:`SMB::pipe_filenames` +## const. +## +## c: The connection. +event smb_pipe_connect_heuristic%(c: connection%); diff --git a/src/analyzer/protocol/smb/smb-gssapi.pac b/src/analyzer/protocol/smb/smb-gssapi.pac index 0a933e8286..2bde6e9e8f 100644 --- a/src/analyzer/protocol/smb/smb-gssapi.pac +++ b/src/analyzer/protocol/smb/smb-gssapi.pac @@ -2,10 +2,12 @@ refine connection SMB_Conn += { %member{ analyzer::Analyzer *gssapi; + analyzer::Analyzer *ntlm; %} %init{ gssapi = 0; + ntlm = 0; %} %cleanup{ @@ -14,6 +16,12 @@ refine connection SMB_Conn += { gssapi->Done(); delete gssapi; } + + if ( ntlm ) + { + ntlm->Done(); + delete ntlm; + } %} function forward_gssapi(data: bytestring, is_orig: bool): bool @@ -21,9 +29,24 @@ refine connection SMB_Conn += { if ( ! gssapi ) gssapi = analyzer_mgr->InstantiateAnalyzer("GSSAPI", bro_analyzer()->Conn()); - if ( gssapi ) - gssapi->DeliverStream(${data}.length(), ${data}.begin(), is_orig); + if ( ! ntlm ) + ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn()); + // SMB allows raw NTLM instead of GSSAPI in certain messages. + // We check if this is the case and run the NTLM analyzer directly. + if ( ${data}.length() >= 8 ) + { + if ( strncmp((const char*)${data}.begin(), "NTLMSSP",7) == 0 ) + { + if ( ntlm ) + ntlm->DeliverStream(${data}.length(), ${data}.begin(), is_orig); + } + else + { + if ( gssapi ) + gssapi->DeliverStream(${data}.length(), ${data}.begin(), is_orig); + } + } return true; %} }; diff --git a/src/analyzer/protocol/smb/smb-pipe.pac b/src/analyzer/protocol/smb/smb-pipe.pac index 5c32f1f17c..2407c63dd3 100644 --- a/src/analyzer/protocol/smb/smb-pipe.pac +++ b/src/analyzer/protocol/smb/smb-pipe.pac @@ -5,7 +5,7 @@ refine connection SMB_Conn += { %member{ map tree_is_pipe_map; - map fid_to_analyzer_map;; + map fid_to_analyzer_map; %} %cleanup{ @@ -20,18 +20,20 @@ refine connection SMB_Conn += { } %} - function get_tree_is_pipe(tree_id: uint16): bool %{ - if ( tree_is_pipe_map.count(tree_id) > 0 ) - return tree_is_pipe_map.at(tree_id); - else - return false; + return ( tree_is_pipe_map.count(tree_id) > 0 ); %} - function set_tree_is_pipe(tree_id: uint16, is_pipe: bool): bool + function unset_tree_is_pipe(tree_id: uint16): bool %{ - tree_is_pipe_map[tree_id] = is_pipe; + tree_is_pipe_map.erase(tree_id); + return true; + %} + + function set_tree_is_pipe(tree_id: uint16): bool + %{ + tree_is_pipe_map[tree_id] = true; return true; %} diff --git a/src/analyzer/protocol/smb/smb.pac b/src/analyzer/protocol/smb/smb.pac index e0dffd2484..156037f614 100644 --- a/src/analyzer/protocol/smb/smb.pac +++ b/src/analyzer/protocol/smb/smb.pac @@ -9,6 +9,8 @@ #include "smb2_events.bif.h" #include "types.bif.h" +#include "events.bif.h" +#include "consts.bif.h" #include "smb1_com_check_directory.bif.h" #include "smb1_com_close.bif.h" @@ -29,14 +31,12 @@ #include "smb2_com_close.bif.h" #include "smb2_com_create.bif.h" -//#include "smb2_com_ioctl.bif.h" -//#include "smb2_com_lock.bif.h" #include "smb2_com_negotiate.bif.h" #include "smb2_com_read.bif.h" #include "smb2_com_session_setup.bif.h" #include "smb2_com_set_info.bif.h" #include "smb2_com_tree_connect.bif.h" -//#include "smb2_com_tree_disconnect.bif.h" +#include "smb2_com_tree_disconnect.bif.h" #include "smb2_com_write.bif.h" %} diff --git a/src/analyzer/protocol/smb/smb1-com-close.pac b/src/analyzer/protocol/smb/smb1-com-close.pac index 4aa6c5c3a0..092f8f4020 100644 --- a/src/analyzer/protocol/smb/smb1-com-close.pac +++ b/src/analyzer/protocol/smb/smb1-com-close.pac @@ -8,14 +8,8 @@ refine connection SMB_Conn += { BuildHeaderVal(h), ${val.file_id}); - // This is commented out for the moment because it caused problems - // with extraction because the file kept having the same name due - // to repeatedly having the same file uid. This results in files - // effectively falling of SMB solely by expiration instead of - // manually being closed. - - //file_mgr->EndOfFile(bro_analyzer()->GetAnalyzerTag(), - // bro_analyzer()->Conn(), h->is_orig()); + file_mgr->EndOfFile(bro_analyzer()->GetAnalyzerTag(), + bro_analyzer()->Conn(), h->is_orig()); return true; %} diff --git a/src/analyzer/protocol/smb/smb1-com-nt-create-andx.pac b/src/analyzer/protocol/smb/smb1-com-nt-create-andx.pac index 36a583696e..0cdae1cefb 100644 --- a/src/analyzer/protocol/smb/smb1-com-nt-create-andx.pac +++ b/src/analyzer/protocol/smb/smb1-com-nt-create-andx.pac @@ -1,13 +1,27 @@ refine connection SMB_Conn += { function proc_smb1_nt_create_andx_request(header: SMB_Header, val: SMB1_nt_create_andx_request): bool %{ + StringVal *filename = smb_string2stringval(${val.filename}); + if ( ! ${header.is_pipe} && + BifConst::SMB::pipe_filenames->AsTable()->Lookup(filename->CheckString()) ) + { + set_tree_is_pipe(${header.tid}); + BifEvent::generate_smb_pipe_connect_heuristic(bro_analyzer(), + bro_analyzer()->Conn()); + } + if ( smb1_nt_create_andx_request ) { BifEvent::generate_smb1_nt_create_andx_request(bro_analyzer(), bro_analyzer()->Conn(), BuildHeaderVal(header), - smb_string2stringval(${val.filename})); + filename); } + else + { + delete filename; + } + return true; %} @@ -26,14 +40,6 @@ refine connection SMB_Conn += { ${val.last_change_time})); } - if ( ${val.end_of_file} > 0 ) - { - //file_mgr->SetSize(${val.end_of_file}, - // bro_analyzer()->GetAnalyzerTag(), - // bro_analyzer()->Conn(), - // header->is_orig()); - } - return true; %} diff --git a/src/analyzer/protocol/smb/smb1-com-open-andx.pac b/src/analyzer/protocol/smb/smb1-com-open-andx.pac deleted file mode 100644 index c7e7bea03a..0000000000 --- a/src/analyzer/protocol/smb/smb1-com-open-andx.pac +++ /dev/null @@ -1,85 +0,0 @@ -refine connection SMB_Conn += { - - function proc_smb1_open_andx_request(h: SMB_Header, val: SMB1_open_andx_request): bool - %{ - if ( smb1_open_andx_request ) - BifEvent::generate_smb1_open_andx_request(bro_analyzer(), - bro_analyzer()->Conn(), - BuildHeaderVal(h), - ${val.flags}, - ${val.access_mode}, - ${val.search_attrs}, - ${val.file_attrs}, - ${val.creation_time}, - ${val.open_mode}, - ${val.allocation_size}, - ${val.timeout}, - smb_string2stringval(${val.filename})); - - return true; - %} - - function proc_smb1_open_andx_response(h: SMB_Header, val: SMB1_open_andx_response): bool - %{ - if ( smb1_open_andx_response ) - BifEvent::generate_smb1_open_andx_response(bro_analyzer(), - bro_analyzer()->Conn(), - BuildHeaderVal(h), - ${val.fid}, - ${val.file_attrs}, - ${val.last_write_time}, - ${val.file_data_size}, - ${val.access_rights}, - ${val.resource_type}, - ${val.nm_pipe_status}, - ${val.open_results}); - - return true; - %} - -}; - - - -type SMB1_open_andx_request(header: SMB_Header, offset: uint16) = record { - word_count : uint8; - andx : SMB_andx; - flags : uint16; - access_mode : uint16; - search_attrs : uint16; - file_attrs : uint16; - creation_time : uint32; - open_mode : uint16; - allocation_size : uint32; - timeout : uint32; - reserved : padding[4]; - byte_count : uint16; - filename : SMB_string(header.unicode, offsetof(filename); - - extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters))); - - andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command); -} &let { - proc : bool = $context.connection.proc_smb1_open_andx_request(header, this); -} &byteorder=littleendian; - -type SMB1_open_andx_response(header: SMB_Header, offset: uint16) = record { - word_count : uint8; - andx : SMB_andx; - fid : uint16; - file_attrs : uint16; - last_write_time : uint32; - file_data_size : uint32; - access_rights : uint16; - resource_type : uint16; - nm_pipe_status : uint16; - open_results : uint16; - reserved : padding[6]; - byte_count : uint16; - - extra_byte_parameters : bytestring &transient &length=(andx.offset == 0 || andx.offset >= (offset+offsetof(extra_byte_parameters))+2) ? 0 : (andx.offset-(offset+offsetof(extra_byte_parameters))); - - andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command); -} &let { - proc : bool = $context.connection.proc_smb1_open_andx_response(header, this); -} &byteorder=littleendian; diff --git a/src/analyzer/protocol/smb/smb1-com-read-andx.pac b/src/analyzer/protocol/smb/smb1-com-read-andx.pac index 89e367206d..712ad8948b 100644 --- a/src/analyzer/protocol/smb/smb1-com-read-andx.pac +++ b/src/analyzer/protocol/smb/smb1-com-read-andx.pac @@ -28,7 +28,7 @@ refine connection SMB_Conn += { BuildHeaderVal(h), ${val.data_len}); - if ( ! ${val.is_pipe} && ${val.data_len} > 0 ) + if ( ! ${h.is_pipe} && ${val.data_len} > 0 ) { uint64 offset = read_offsets[${h.mid}]; read_offsets.erase(${h.mid}); @@ -93,8 +93,7 @@ type SMB1_read_andx_response(header: SMB_Header, offset: uint16) = record { andx_command : SMB_andx_command(header, 0, offset+offsetof(andx_command), andx.command); } &let { - is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid); - pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, false) &if(is_pipe); + pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, false) &if(header.is_pipe); padding_len : uint8 = (header.unicode == 1) ? 1 : 0; data_len : uint32 = (data_len_high << 16) + data_len_low; diff --git a/src/analyzer/protocol/smb/smb1-com-tree-connect-andx.pac b/src/analyzer/protocol/smb/smb1-com-tree-connect-andx.pac index 756a28bc96..526febce39 100644 --- a/src/analyzer/protocol/smb/smb1-com-tree-connect-andx.pac +++ b/src/analyzer/protocol/smb/smb1-com-tree-connect-andx.pac @@ -13,7 +13,11 @@ refine connection SMB_Conn += { function proc_smb1_tree_connect_andx_response(header: SMB_Header, val: SMB1_tree_connect_andx_response): bool %{ - set_tree_is_pipe(${header.tid}, strncmp((const char*) smb_string2stringval(${val.service})->Bytes(), "IPC", 3) == 0); + if ( strncmp((const char*) smb_string2stringval(${val.service})->Bytes(), + "IPC", 3) == 0 ) + { + set_tree_is_pipe(${header.tid}); + } if ( smb1_tree_connect_andx_response ) { diff --git a/src/analyzer/protocol/smb/smb1-com-write-andx.pac b/src/analyzer/protocol/smb/smb1-com-write-andx.pac index 79d36c52b5..8b4eed7056 100644 --- a/src/analyzer/protocol/smb/smb1-com-write-andx.pac +++ b/src/analyzer/protocol/smb/smb1-com-write-andx.pac @@ -10,7 +10,7 @@ refine connection SMB_Conn += { ${val.write_offset}, ${val.data_len}); - if ( ! ${val.is_pipe} && ${val.data}.length() > 0 ) + if ( ! ${h.is_pipe} && ${val.data}.length() > 0 ) { file_mgr->DataIn(${val.data}.begin(), ${val.data}.length(), ${val.write_offset}, @@ -58,8 +58,7 @@ type SMB1_write_andx_request(header: SMB_Header, offset: uint16) = record { andx_command : SMB_andx_command(header, 1, offset+offsetof(andx_command), andx.command); } &let { - is_pipe : bool = $context.connection.get_tree_is_pipe(header.tid); - pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, true) &if(is_pipe); + pipe_proc : bool = $context.connection.forward_dce_rpc(data, 0, true) &if(header.is_pipe); data_len : uint32 = (data_len_high << 16) + data_len_low; offset_high : uint32 = (word_count == 0x0E) ? offset_high_tmp : 0; diff --git a/src/analyzer/protocol/smb/smb1-protocol.pac b/src/analyzer/protocol/smb/smb1-protocol.pac index b7ad6af140..4b38feefcb 100644 --- a/src/analyzer/protocol/smb/smb1-protocol.pac +++ b/src/analyzer/protocol/smb/smb1-protocol.pac @@ -127,7 +127,7 @@ type SMB_andx_command(header: SMB_Header, is_orig: bool, offset: uint16, command type SMB_Message_Request(header: SMB_Header, offset: uint16, command: uint8, is_orig: bool) = case command of { # SMB1 Command Extensions - #SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_request(header); + #SMB_COM_OPEN_ANDX -> open_andx : SMB1_open_andx_request(header); SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_request(header, offset); SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_request(header, offset); SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_request(header); @@ -205,7 +205,7 @@ type SMB_Message_Request(header: SMB_Header, offset: uint16, command: uint8, is_ type SMB_Message_Response(header: SMB_Header, offset: uint16, command: uint8, is_orig: bool) = case command of { # SMB1 Command Extensions - #SMB_COM_OPEN_ANDX -> open_andx : SMB_open_andx_response(header, offset); + #SMB_COM_OPEN_ANDX -> open_andx : SMB1_open_andx_response(header, offset); SMB_COM_READ_ANDX -> read_andx : SMB1_read_andx_response(header, offset); SMB_COM_WRITE_ANDX -> write_andx : SMB1_write_andx_response(header, offset); SMB_COM_TRANSACTION2 -> transaction2 : SMB1_transaction2_response(header); @@ -298,7 +298,8 @@ type SMB_Header(is_orig: bool) = record { err_status_type = (flags2 >> 14) & 1; unicode = (flags2 >> 15) & 1; pid = (pid_high * 0x10000) + pid_low; - proc : bool = $context.connection.proc_smb_message(this, is_orig); + is_pipe: bool = $context.connection.get_tree_is_pipe(tid); + proc : bool = $context.connection.proc_smb_message(this, is_orig); } &byteorder=littleendian; # TODO: compute this as diff --git a/src/analyzer/protocol/smb/smb1_com_open_andx.bif b/src/analyzer/protocol/smb/smb1_com_open_andx.bif deleted file mode 100644 index 1ce418e33a..0000000000 --- a/src/analyzer/protocol/smb/smb1_com_open_andx.bif +++ /dev/null @@ -1,41 +0,0 @@ -## Generated for :abbr:`SMB (Server Message Block)`/:abbr:`CIFS (Common Internet File System)` -## version 1 requests of type *open andx*. This is sent by the client to create and open a new -## file or open an existing regular file and chain additional messages along with the request. -## -## For more information, see MS-CIFS:2.2.4.41 -## -## c: The connection. -## -## hdr: The parsed header of the :abbr:`SMB (Server Message Block)` version 1 message. -## -## flags: Flags requesting attribute data and locking. -## -## access_mode: The requested access mode. -## -## search_attrs: The set of attributes that the file MUST have in order to be found. -## -## file_attrs: The set of attributes that the file is to have if the file needs to be created. -## -## creation_time: The time of creation if the file is created. -## -## open_mode: The way a file s -## -## length: The number of bytes being requested. -## -## .. bro:see:: smb1_message smb1_open_andx_response -event smb1_open_andx_request%(c: connection, hdr: SMB1::Header, file_id: count, offset: count, length: count%); - -## Generated for :abbr:`SMB (Server Message Block)`/:abbr:`CIFS (Common Internet File System)` -## version 1 responses of type *open andx*. This is the server response to the *open andx* request. -## -## For more information, see MS-CIFS:2.2.4.41 -## -## c: The connection. -## -## hdr: The parsed header of the :abbr:`SMB (Server Message Block)` version 1 message. -## -## data_len: The length of data from the requested file. -## -## .. bro:see:: smb1_message smb1_open_andx_request -event smb1_open_andx_response%(c: connection, hdr: SMB1::Header, data_len: count%); - diff --git a/src/analyzer/protocol/smb/smb2-com-close.pac b/src/analyzer/protocol/smb/smb2-com-close.pac index bb3b1bab49..0c90897d84 100644 --- a/src/analyzer/protocol/smb/smb2-com-close.pac +++ b/src/analyzer/protocol/smb/smb2-com-close.pac @@ -10,6 +10,9 @@ refine connection SMB_Conn += { BuildSMB2GUID(${val.file_id})); } + file_mgr->EndOfFile(bro_analyzer()->GetAnalyzerTag(), + bro_analyzer()->Conn(), h->is_orig()); + return true; %} diff --git a/src/analyzer/protocol/smb/smb2-com-create.pac b/src/analyzer/protocol/smb/smb2-com-create.pac index 0072e75adf..4d7c70bbe7 100644 --- a/src/analyzer/protocol/smb/smb2-com-create.pac +++ b/src/analyzer/protocol/smb/smb2-com-create.pac @@ -2,12 +2,25 @@ refine connection SMB_Conn += { function proc_smb2_create_request(h: SMB2_Header, val: SMB2_create_request): bool %{ + StringVal *filename = smb2_string2stringval(${val.filename}); + if ( ! ${h.is_pipe} && + BifConst::SMB::pipe_filenames->AsTable()->Lookup(filename->CheckString()) ) + { + set_tree_is_pipe(${h.tree_id}); + BifEvent::generate_smb_pipe_connect_heuristic(bro_analyzer(), + bro_analyzer()->Conn()); + } + if ( smb2_create_request ) { BifEvent::generate_smb2_create_request(bro_analyzer(), bro_analyzer()->Conn(), BuildSMB2HeaderVal(h), - smb2_string2stringval(${val.filename})); + filename); + } + else + { + delete filename; } return true; @@ -29,14 +42,6 @@ refine connection SMB_Conn += { smb2_file_attrs_to_bro(${val.file_attrs})); } - if ( ${val.eof} > 0 ) - { - //file_mgr->SetSize(${val.eof}, - // bro_analyzer()->GetAnalyzerTag(), - // bro_analyzer()->Conn(), - // h->is_orig()); - } - return true; %} }; diff --git a/src/analyzer/protocol/smb/smb2-com-lock.pac b/src/analyzer/protocol/smb/smb2-com-lock.pac index d6b1f5c2c8..3efd5f4e55 100644 --- a/src/analyzer/protocol/smb/smb2-com-lock.pac +++ b/src/analyzer/protocol/smb/smb2-com-lock.pac @@ -1,5 +1,5 @@ refine connection SMB_Conn += { - + # Needs to be implemented. }; type SMB2_lock = record { diff --git a/src/analyzer/protocol/smb/smb2-com-read.pac b/src/analyzer/protocol/smb/smb2-com-read.pac index 1fa409a5f0..cf5d2ae065 100644 --- a/src/analyzer/protocol/smb/smb2-com-read.pac +++ b/src/analyzer/protocol/smb/smb2-com-read.pac @@ -42,7 +42,7 @@ refine connection SMB_Conn += { uint64 offset = smb2_read_offsets[${h.message_id}]; smb2_read_offsets.erase(${h.message_id}); - if ( ! ${val.is_pipe} && ${val.data_len} > 0 ) + if ( ! ${h.is_pipe} && ${val.data_len} > 0 ) { file_mgr->DataIn(${val.data}.begin(), ${val.data_len}, offset, bro_analyzer()->GetAnalyzerTag(), @@ -83,9 +83,8 @@ type SMB2_read_response(header: SMB2_Header) = record { pad : padding to data_offset - header.head_length; data : bytestring &length=data_len; } &let { - is_pipe : bool = $context.connection.get_tree_is_pipe(header.tree_id); fid : uint64 = $context.connection.get_file_id(header.message_id); - pipe_proc : bool = $context.connection.forward_dce_rpc(data, fid, false) &if(is_pipe); + pipe_proc : bool = $context.connection.forward_dce_rpc(data, fid, false) &if(header.is_pipe); proc: bool = $context.connection.proc_smb2_read_response(header, this); }; diff --git a/src/analyzer/protocol/smb/smb2-com-tree-connect.pac b/src/analyzer/protocol/smb/smb2-com-tree-connect.pac index 1c8b4d5978..fe59ecb74d 100644 --- a/src/analyzer/protocol/smb/smb2-com-tree-connect.pac +++ b/src/analyzer/protocol/smb/smb2-com-tree-connect.pac @@ -13,7 +13,8 @@ refine connection SMB_Conn += { function proc_smb2_tree_connect_response(header: SMB2_Header, val: SMB2_tree_connect_response): bool %{ - set_tree_is_pipe(${header.tree_id}, ${val.share_type} == SMB2_SHARE_TYPE_PIPE); + if ( ${val.share_type} == SMB2_SHARE_TYPE_PIPE ) + set_tree_is_pipe(${header.tree_id}); if ( smb2_tree_connect_response ) { diff --git a/src/analyzer/protocol/smb/smb2-com-tree-disconnect.pac b/src/analyzer/protocol/smb/smb2-com-tree-disconnect.pac index 4413b56952..cba7b0deb3 100644 --- a/src/analyzer/protocol/smb/smb2-com-tree-disconnect.pac +++ b/src/analyzer/protocol/smb/smb2-com-tree-disconnect.pac @@ -1,9 +1,45 @@ + +refine connection SMB_Conn += { + + function proc_smb2_tree_disconnect_request(header: SMB2_Header): bool + %{ + unset_tree_is_pipe(${header.tree_id}); + + if ( smb2_tree_disconnect_request ) + { + BifEvent::generate_smb2_tree_disconnect_request(bro_analyzer(), + bro_analyzer()->Conn(), + BuildSMB2HeaderVal(header)); + } + + return true; + %} + + function proc_smb2_tree_disconnect_response(header: SMB2_Header): bool + %{ + if ( smb2_tree_disconnect_response ) + { + BifEvent::generate_smb2_tree_disconnect_response(bro_analyzer(), + bro_analyzer()->Conn(), + BuildSMB2HeaderVal(header)); + } + + return true; + %} + +}; + type SMB2_tree_disconnect_request(header: SMB2_Header) = record { structure_size : uint16; reserved : uint16; +} &let { + proc: bool = $context.connection.proc_smb2_tree_disconnect_request(header); + }; type SMB2_tree_disconnect_response(header: SMB2_Header) = record { structure_size : uint16; reserved : uint16; +} &let { + proc: bool = $context.connection.proc_smb2_tree_disconnect_response(header); }; diff --git a/src/analyzer/protocol/smb/smb2-com-write.pac b/src/analyzer/protocol/smb/smb2-com-write.pac index f463afc767..177a3a84bd 100644 --- a/src/analyzer/protocol/smb/smb2-com-write.pac +++ b/src/analyzer/protocol/smb/smb2-com-write.pac @@ -12,7 +12,7 @@ refine connection SMB_Conn += { ${val.data_len}); } - if ( ! ${val.is_pipe} && ${val.data}.length() > 0 ) + if ( ! ${h.is_pipe} && ${val.data}.length() > 0 ) { file_mgr->DataIn(${val.data}.begin(), ${val.data_len}, ${val.offset}, bro_analyzer()->GetAnalyzerTag(), @@ -44,8 +44,7 @@ type SMB2_write_request(header: SMB2_Header) = record { pad : padding to data_offset - header.head_length; data : bytestring &length=data_len; } &let { - is_pipe: bool = $context.connection.get_tree_is_pipe(header.tree_id); - pipe_proc : bool = $context.connection.forward_dce_rpc(data, file_id.persistent+file_id._volatile, true) &if(is_pipe); + pipe_proc : bool = $context.connection.forward_dce_rpc(data, file_id.persistent+file_id._volatile, true) &if(header.is_pipe); proc : bool = $context.connection.proc_smb2_write_request(header, this); }; diff --git a/src/analyzer/protocol/smb/smb2-protocol.pac b/src/analyzer/protocol/smb/smb2-protocol.pac index 523ab3b890..1cad6e130e 100644 --- a/src/analyzer/protocol/smb/smb2-protocol.pac +++ b/src/analyzer/protocol/smb/smb2-protocol.pac @@ -35,10 +35,10 @@ type SMB2_PDU(is_orig: bool) = record { # Status 0 indicates success. In the case of a # request this should just happen to work out due to # how the fields are set. - 0 -> msg : SMB2_Message(header, is_orig); - STATUS_BUFFER_OVERFLOW -> buffer_overflow : SMB2_Message(header, is_orig); + 0 -> msg : SMB2_Message(header, is_orig); + STATUS_BUFFER_OVERFLOW -> buffer_overflow : SMB2_Message(header, is_orig); STATUS_MORE_PROCESSING_REQUIRED -> more_processing_required : SMB2_Message(header, is_orig); - default -> err : SMB2_error_response(header); + default -> err : SMB2_error_response(header); }; }; @@ -199,6 +199,7 @@ type SMB2_Header(is_orig: bool) = record { related = (flags >> 26) & 1; msigned = (flags >> 27) & 1; dfs = (flags) & 1; + is_pipe: bool = $context.connection.get_tree_is_pipe(tree_id); proc : bool = $context.connection.proc_smb2_message(this, is_orig); } &byteorder=littleendian; @@ -242,7 +243,9 @@ type SMB2_error_response(header: SMB2_Header) = record { structure_size : uint16; reserved : padding[2]; byte_count : uint32; - error_data : SMB2_error_data(header, byte_count); + # This is implemented incorrectly and is disabled for now. + #error_data : SMB2_error_data(header, byte_count); + stuff : bytestring &restofdata &transient; } &byteorder = littleendian; type SMB2_logoff_request(header: SMB2_Header) = record { diff --git a/src/analyzer/protocol/smb/smb2_com_ioctl.bif b/src/analyzer/protocol/smb/smb2_com_ioctl.bif deleted file mode 100644 index 996cee9ad8..0000000000 --- a/src/analyzer/protocol/smb/smb2_com_ioctl.bif +++ /dev/null @@ -1 +0,0 @@ -# Empty. diff --git a/src/analyzer/protocol/smb/smb2_com_lock.bif b/src/analyzer/protocol/smb/smb2_com_lock.bif deleted file mode 100644 index b22403cef0..0000000000 --- a/src/analyzer/protocol/smb/smb2_com_lock.bif +++ /dev/null @@ -1 +0,0 @@ -# Empty. \ No newline at end of file diff --git a/src/analyzer/protocol/smb/smb2_com_tree_disconnect.bif b/src/analyzer/protocol/smb/smb2_com_tree_disconnect.bif index 996cee9ad8..fdcd5d9d8b 100644 --- a/src/analyzer/protocol/smb/smb2_com_tree_disconnect.bif +++ b/src/analyzer/protocol/smb/smb2_com_tree_disconnect.bif @@ -1 +1,22 @@ -# Empty. +## Generated for :abbr:`SMB (Server Message Block)`/:abbr:`CIFS (Common Internet File System)` +## version 2 requests of type *tree disconnect*. This is sent by the client to logically disconnect +## client access to a server resource. +## +## c: The connection. +## +## hdr: The parsed header of the :abbr:`SMB (Server Message Block)` version 2 message. +## +## .. bro:see:: smb2_message +event smb2_tree_disconnect_request%(c: connection, hdr: SMB2::Header%); + + +## Generated for :abbr:`SMB (Server Message Block)`/:abbr:`CIFS (Common Internet File System)` +## version 2 requests of type *tree disconnect*. This is sent by the server to logically disconnect +## client access to a server resource. +## +## c: The connection. +## +## hdr: The parsed header of the :abbr:`SMB (Server Message Block)` version 2 message. +## +## .. bro:see:: smb2_message +event smb2_tree_disconnect_response%(c: connection, hdr: SMB2::Header%); diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 71c1743860..6587112ef2 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2016-10-26-00-05-53 +#open 2016-11-02-17-25-26 #fields name #types string scripts/base/init-bare.bro @@ -129,8 +129,11 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_session_setup.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_set_info.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_tree_connect.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.smb2_com_tree_disconnect.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_write.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.consts.bif.bro build/scripts/base/bif/plugins/Bro_SMB.types.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro @@ -168,4 +171,4 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2016-10-26-00-05-53 +#close 2016-11-02-17-25-26 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 3e2a83dfd2..7a7b127752 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2016-10-26-00-05-59 +#open 2016-11-02-17-25-18 #fields name #types string scripts/base/init-bare.bro @@ -129,8 +129,11 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_session_setup.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_set_info.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_tree_connect.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.smb2_com_tree_disconnect.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_com_write.bif.bro build/scripts/base/bif/plugins/Bro_SMB.smb2_events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro + build/scripts/base/bif/plugins/Bro_SMB.consts.bif.bro build/scripts/base/bif/plugins/Bro_SMB.types.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMTP.functions.bif.bro @@ -356,4 +359,4 @@ scripts/base/init-default.bro scripts/base/misc/find-filtered-trace.bro scripts/base/misc/version.bro scripts/policy/misc/loaded-scripts.bro -#close 2016-10-26-00-05-59 +#close 2016-11-02-17-25-18 diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 76a47699a4..a71f864a5c 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -247,7 +247,7 @@ 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Cluster::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Communication::LOG)) -> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, , (Conn::LOG)) -> @@ -377,7 +377,7 @@ 0.000000 MetaHookPost CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) -> 0.000000 MetaHookPost CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -> -0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T])) -> +0.000000 MetaHookPost CallFunction(Log::write, , (PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(NetControl::check_plugins, , ()) -> 0.000000 MetaHookPost CallFunction(NetControl::init, , ()) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, , ()) -> @@ -410,7 +410,7 @@ 0.000000 MetaHookPost CallFunction(reading_live_traffic, , ()) -> 0.000000 MetaHookPost CallFunction(reading_traces, , ()) -> 0.000000 MetaHookPost CallFunction(set_to_regex, , ({}, (^\.?|\.)(~~)$)) -> -0.000000 MetaHookPost CallFunction(strftime, , (%Y, 1477440372.839693)) -> +0.000000 MetaHookPost CallFunction(strftime, , (%Y, 1478107500.981565)) -> 0.000000 MetaHookPost CallFunction(string_to_pattern, , ((^\.?|\.)()$, F)) -> 0.000000 MetaHookPost CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) -> 0.000000 MetaHookPost CallFunction(to_count, , (2016)) -> @@ -476,6 +476,8 @@ 0.000000 MetaHookPost LoadFile(./Bro_RPC.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_RawReader.raw.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SIP.events.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMB.consts.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMB.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb1_com_check_directory.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb1_com_close.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb1_com_create_directory.bif.bro) -> -1 @@ -500,6 +502,7 @@ 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_com_session_setup.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_com_set_info.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_com_tree_connect.bif.bro) -> -1 +0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_com_tree_disconnect.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_com_write.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.smb2_events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_SMB.types.bif.bro) -> -1 @@ -967,7 +970,7 @@ 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::__write, , (PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, , (Conn::LOG)) @@ -1097,7 +1100,7 @@ 0.000000 MetaHookPre CallFunction(Log::create_stream, , (Weird::LOG, [columns=, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (X509::LOG, [columns=, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, , (mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql])) -0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T])) +0.000000 MetaHookPre CallFunction(Log::write, , (PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(NetControl::check_plugins, , ()) 0.000000 MetaHookPre CallFunction(NetControl::init, , ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, , ()) @@ -1130,7 +1133,7 @@ 0.000000 MetaHookPre CallFunction(reading_live_traffic, , ()) 0.000000 MetaHookPre CallFunction(reading_traces, , ()) 0.000000 MetaHookPre CallFunction(set_to_regex, , ({}, (^\.?|\.)(~~)$)) -0.000000 MetaHookPre CallFunction(strftime, , (%Y, 1477440372.839693)) +0.000000 MetaHookPre CallFunction(strftime, , (%Y, 1478107500.981565)) 0.000000 MetaHookPre CallFunction(string_to_pattern, , ((^\.?|\.)()$, F)) 0.000000 MetaHookPre CallFunction(sub, , ((^\.?|\.)(~~)$, <...>/, )) 0.000000 MetaHookPre CallFunction(to_count, , (2016)) @@ -1196,6 +1199,8 @@ 0.000000 MetaHookPre LoadFile(./Bro_RPC.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_RawReader.raw.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SIP.events.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMB.consts.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMB.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb1_com_check_directory.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb1_com_close.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb1_com_create_directory.bif.bro) @@ -1220,6 +1225,7 @@ 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_com_session_setup.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_com_set_info.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_com_tree_connect.bif.bro) +0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_com_tree_disconnect.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_com_write.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.smb2_events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_SMB.types.bif.bro) @@ -1686,7 +1692,7 @@ 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) @@ -1816,7 +1822,7 @@ 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=, ev=MySQL::log_mysql, path=mysql]) -0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1477440372.840195, node=bro, filter=ip or not ip, init=T, success=T]) +0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1478107500.981885, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction NetControl::check_plugins() 0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction Notice::want_pp() @@ -1849,7 +1855,7 @@ 0.000000 | HookCallFunction reading_live_traffic() 0.000000 | HookCallFunction reading_traces() 0.000000 | HookCallFunction set_to_regex({}, (^\.?|\.)(~~)$) -0.000000 | HookCallFunction strftime(%Y, 1477440372.839693) +0.000000 | HookCallFunction strftime(%Y, 1478107500.981565) 0.000000 | HookCallFunction string_to_pattern((^\.?|\.)()$, F) 0.000000 | HookCallFunction sub((^\.?|\.)(~~)$, <...>/, ) 0.000000 | HookCallFunction to_count(2016) diff --git a/testing/btest/Baseline/scripts.base.protocols.smb.raw-ntlm/.stdout b/testing/btest/Baseline/scripts.base.protocols.smb.raw-ntlm/.stdout new file mode 100644 index 0000000000..054c38f738 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smb.raw-ntlm/.stdout @@ -0,0 +1 @@ +\xebr\x96\x86\xfc\xaa\xcf\xad\xb14\x18\xfaIG`\xde diff --git a/testing/btest/Baseline/scripts.base.protocols.smb.smb2/files.log b/testing/btest/Baseline/scripts.base.protocols.smb.smb2/files.log index 66e632e0cb..9dc925e4dc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.smb.smb2/files.log +++ b/testing/btest/Baseline/scripts.base.protocols.smb.smb2/files.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path files -#open 2016-08-16-23-02-30 +#open 2016-10-27-17-16-27 #fields ts fuid tx_hosts rx_hosts conn_uids source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256 extracted #types time string set[addr] set[addr] set[string] string count set[string] string string interval bool bool count count count count bool string string string string string -1323202695.515890 Fg6wjp3BAYahIGAEf7 10.0.0.11 10.0.0.12 CHhAvVGS1DHFjwGM9 SMB 0 (empty) application/pdf WP_SMBPlugin.pdf 0.073970 - T 1508939 - 0 0 T - - - - - -#close 2016-08-16-23-02-30 +1323202695.515890 Fg6wjp3BAYahIGAEf7 10.0.0.11 10.0.0.12 CHhAvVGS1DHFjwGM9 SMB 0 (empty) application/pdf WP_SMBPlugin.pdf 0.073970 - T 1508939 - 0 0 F - - - - - +#close 2016-10-27-17-16-27 diff --git a/testing/btest/Traces/smb/raw_ntlm_in_smb.pcap b/testing/btest/Traces/smb/raw_ntlm_in_smb.pcap new file mode 100644 index 0000000000..8a40175db4 Binary files /dev/null and b/testing/btest/Traces/smb/raw_ntlm_in_smb.pcap differ diff --git a/testing/btest/scripts/base/protocols/smb/raw-ntlm.test b/testing/btest/scripts/base/protocols/smb/raw-ntlm.test new file mode 100644 index 0000000000..8d5f91b881 --- /dev/null +++ b/testing/btest/scripts/base/protocols/smb/raw-ntlm.test @@ -0,0 +1,14 @@ +#@TEST-EXEC: bro -b -C -r $TRACES/smb/raw_ntlm_in_smb.pcap %INPUT +#@TEST-EXEC: btest-diff .stdout + +@load base/protocols/ntlm +@load policy/protocols/smb + +# Just verify that the session key is grabbed correctly from NTLM +# carried raw over SMB. + +event ntlm_authenticate(c: connection, request: NTLM::Authenticate) + { + if ( request?$session_key ) + print request$session_key; + }