From be9f97d8b4f37848c5542875efbe692c8cff1a95 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Fri, 6 Apr 2018 13:09:24 -0400 Subject: [PATCH 1/2] Updates to NTLM script handling. - This separates NTLM handling away from SMB. - It logs more accurately when logins are succeed or fail or even if the resulting status of an authentication is unknown. - Adds some new fields where the server is indicating information about itself (server_nb_computer_name, server_dns_computer_name, and server_tree_name) --- scripts/base/protocols/ntlm/main.bro | 83 +++++++++++----------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/scripts/base/protocols/ntlm/main.bro b/scripts/base/protocols/ntlm/main.bro index 0e3b869efc..88a484e090 100644 --- a/scripts/base/protocols/ntlm/main.bro +++ b/scripts/base/protocols/ntlm/main.bro @@ -1,4 +1,3 @@ -@load base/protocols/smb @load base/frameworks/dpd module NTLM; @@ -21,32 +20,20 @@ export { ## Domainname given by the client. domainname : string &log &optional; + ## NetBIOS name given by the server in a CHALLENGE. + server_nb_computer_name: string &log &optional; + ## DNS name given by the server in a CHALLENGE. + server_dns_computer_name: string &log &optional; + ## Tree name given by the server in a CHALLENGE. + server_tree_name: string &log &optional; + ## Indicate whether or not the authentication was successful. success : bool &log &optional; - ## A string representation of the status code that was - ## returned in response to the authentication attempt. - status : string &log &optional; ## Internally used field to indicate if the login attempt ## has already been logged. done: bool &default=F; }; - - ## DOS and NT status codes that indicate authentication failure. - const auth_failure_statuses: set[count] = { - 0x052e0001, # logonfailure - 0x08c00002, # badClient - 0x08c10002, # badLogonTime - 0x08c20002, # passwordExpired - 0xC0000022, # ACCESS_DENIED - 0xC0000061, # PRIVILEGE_NOT_HELD - 0xC000006A, # WRONG_PASSWORD - 0xC000006D, # LOGON_FAILURE - 0xC000006F, # INVALID_LOGON_HOURS - 0xC0000070, # INVALID_WORKSTATION - 0xC0000071, # PASSWORD_EXPIRED - 0xC0000072, # ACCOUNT_DISABLED - } &redef; } redef DPD::ignore_violations += { Analyzer::ANALYZER_NTLM }; @@ -60,17 +47,37 @@ event bro_init() &priority=5 Log::create_stream(NTLM::LOG, [$columns=Info, $path="ntlm"]); } +function set_session(c: connection) + { + if ( ! c?$ntlm ) + c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id); + } + event ntlm_negotiate(c: connection, request: NTLM::Negotiate) &priority=5 { + set_session(c); } event ntlm_challenge(c: connection, challenge: NTLM::Challenge) &priority=5 { + set_session(c); + + if ( challenge?$target_info ) + { + local ti = challenge$target_info; + if ( ti?$nb_domain_name ) + c$ntlm$server_nb_computer_name = ti$nb_computer_name; + if ( ti?$dns_domain_name ) + c$ntlm$server_dns_computer_name = ti$dns_computer_name; + if ( ti?$dns_tree_name ) + c$ntlm$server_tree_name = ti$dns_tree_name; + } } event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5 { - c$ntlm = NTLM::Info($ts=network_time(), $uid=c$uid, $id=c$id); + set_session(c); + if ( request?$domain_name ) c$ntlm$domainname = request$domain_name; if ( request?$workstation ) @@ -81,7 +88,8 @@ event ntlm_authenticate(c: connection, request: NTLM::Authenticate) &priority=5 event gssapi_neg_result(c: connection, state: count) &priority=3 { - if ( c?$ntlm ) + # Ignore "incomplete" replies (state==1) + if ( c?$ntlm && state != 1 ) c$ntlm$success = (state == 0); } @@ -89,7 +97,8 @@ event gssapi_neg_result(c: connection, state: count) &priority=-3 { if ( c?$ntlm && ! c$ntlm$done ) { - if ( c$ntlm?$username || c$ntlm?$hostname ) + # Only write if success is actually set to something... + if ( c$ntlm?$success ) { Log::write(NTLM::LOG, c$ntlm); c$ntlm$done = T; @@ -97,36 +106,10 @@ event gssapi_neg_result(c: connection, state: count) &priority=-3 } } -event smb1_message(c: connection, hdr: SMB1::Header, is_orig: bool) &priority=3 - { - if ( c?$ntlm && ! c$ntlm$done && - ( c$ntlm?$username || c$ntlm?$hostname ) ) - { - c$ntlm$success = (hdr$status !in auth_failure_statuses); - c$ntlm$status = SMB::statuses[hdr$status]$id; - - Log::write(NTLM::LOG, c$ntlm); - c$ntlm$done = T; - } - } - -event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) &priority=3 - { - if ( c?$ntlm && ! c$ntlm$done && - ( c$ntlm?$username || c$ntlm?$hostname ) ) - { - c$ntlm$success = (hdr$status !in auth_failure_statuses); - c$ntlm$status = SMB::statuses[hdr$status]$id; - - Log::write(NTLM::LOG, c$ntlm); - c$ntlm$done = T; - } - } - event connection_state_remove(c: connection) &priority=-5 { if ( c?$ntlm && ! c$ntlm$done ) { Log::write(NTLM::LOG, c$ntlm); } - } \ No newline at end of file + } From 340cb556dbe18f23e96a1ab7c5ba303936f18b16 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Fri, 6 Apr 2018 13:49:13 -0400 Subject: [PATCH 2/2] Test baseline updates. --- .../canonified_loaded_scripts.log | 8 ++++---- .../scripts.base.protocols.dce-rpc.mapi/ntlm.log | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) 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 8a56fcfbac..c79d79d08b 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 @@ -322,10 +322,6 @@ scripts/base/init-default.bro scripts/base/protocols/mysql/consts.bro scripts/base/protocols/ntlm/__load__.bro scripts/base/protocols/ntlm/main.bro - scripts/base/protocols/smb/__load__.bro - scripts/base/protocols/smb/consts.bro - scripts/base/protocols/smb/const-dos-error.bro - scripts/base/protocols/smb/const-nt-status.bro scripts/base/protocols/pop3/__load__.bro scripts/base/protocols/radius/__load__.bro scripts/base/protocols/radius/main.bro @@ -339,6 +335,10 @@ scripts/base/init-default.bro scripts/base/protocols/sip/main.bro scripts/base/protocols/snmp/__load__.bro scripts/base/protocols/snmp/main.bro + scripts/base/protocols/smb/__load__.bro + scripts/base/protocols/smb/consts.bro + scripts/base/protocols/smb/const-dos-error.bro + scripts/base/protocols/smb/const-nt-status.bro scripts/base/protocols/smtp/__load__.bro scripts/base/protocols/smtp/main.bro scripts/base/protocols/smtp/entities.bro diff --git a/testing/btest/Baseline/scripts.base.protocols.dce-rpc.mapi/ntlm.log b/testing/btest/Baseline/scripts.base.protocols.dce-rpc.mapi/ntlm.log index ffe3248400..c664248d88 100644 --- a/testing/btest/Baseline/scripts.base.protocols.dce-rpc.mapi/ntlm.log +++ b/testing/btest/Baseline/scripts.base.protocols.dce-rpc.mapi/ntlm.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ntlm -#open 2016-10-08-03-48-34 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p username hostname domainname success status -#types time string addr port addr port string string string bool string -1056991898.902392 C37jN32gN3y3AZzyf6 192.168.0.173 1068 192.168.0.2 4997 ALeonard ALEONARD-XP CNAMIS - - -1056991899.594334 CFLRIC3zaTU1loLGxh 192.168.0.173 1073 192.168.0.2 1032 ALeonard ALEONARD-XP CNAMIS - - -#close 2016-10-08-03-48-34 +#open 2018-04-06-17-44-41 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p username hostname domainname server_nb_computer_name server_dns_computer_name server_tree_name success +#types time string addr port addr port string string string string string string bool +1056991898.900518 C37jN32gN3y3AZzyf6 192.168.0.173 1068 192.168.0.2 4997 ALeonard ALEONARD-XP CNAMIS SATURN - - - +1056991899.591337 CFLRIC3zaTU1loLGxh 192.168.0.173 1073 192.168.0.2 1032 ALeonard ALEONARD-XP CNAMIS SATURN - - - +#close 2018-04-06-17-44-41