From 93becb13878ab10baceb2e5a3437d72f01697bfc Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 7 Oct 2016 16:28:03 -0500 Subject: [PATCH 01/16] Create new SSH events ssh_auth_attempt and ssh_auth_result. Add auth_attempts to SSH::Info. Address BIT-1641. --- scripts/base/protocols/ssh/main.bro | 63 +++++++++++++++++++- src/analyzer/protocol/ssh/events.bif | 89 ++++++++++++++++++---------- 2 files changed, 117 insertions(+), 35 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index d547e92e8f..9eeb892f3f 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -20,6 +20,11 @@ export { version: count &log; ## Authentication result (T=success, F=failure, unset=unknown) auth_success: bool &log &optional; + ## The number of authentication attemps we observed. There's always + ## at least one, since some servers might support no authentication at all. + ## It's important to note that not all of these are failures, since + ## some servers require two-factor auth (e.g. password AND pubkey) + auth_attempts: count &log &optional; ## Direction of the connection. If the client was a local host ## logging into an external host, this would be OUTBOUND. INBOUND ## would be set for the opposite situation. @@ -56,17 +61,62 @@ export { ## to the logging framework. global log_ssh: event(rec: Info); + ## This event is generated when an :abbr:`SSH (Secure Shell)` + ## connection was determined to have had a failed authentication. This + ## determination is based on packet size analysis, and errs on the + ## side of caution - that is, if there's any doubt about the + ## authentication failure, this event is *not* raised. + ## + ## This event is only raised once per connection. + ## + ## c: The connection over which the :abbr:`SSH (Secure Shell)` + ## connection took place. + ## + ## .. bro:see:: ssh_server_version ssh_client_version + ## ssh_auth_successful ssh_auth_result ssh_auth_attempted + ## ssh_capabilities ssh2_server_host_key ssh1_server_host_key + ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params + ## ssh2_gss_error ssh2_ecc_key + global ssh_auth_failed: event (c: connection); + + ## This event is generated when a determination has been made about + ## the final authentication result of an :abbr:`SSH (Secure Shell)` + ## connection. This determination is based on packet size analysis, + ## and errs on the side of caution - that is, if there's any doubt + ## about the result of the authentication, this event is *not* raised. + ## + ## This event is only raised once per connection. + ## + ## c: The connection over which the :abbr:`SSH (Secure Shell)` + ## connection took place. + ## + ## result: True if the authentication was successful, false if not. + ## + ## auth_attempts: The number of authentication attempts that were + ## observed. + ## + ## .. bro:see:: ssh_server_version ssh_client_version + ## ssh_auth_successful ssh_auth_failed ssh_auth_attempted + ## ssh_capabilities ssh2_server_host_key ssh1_server_host_key + ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params + ## ssh2_gss_error ssh2_ecc_key + global ssh_auth_result: event (c: connection, result: bool, auth_attempts: count); + ## Event that can be handled when the analyzer sees an SSH server host ## key. This abstracts :bro:id:`ssh1_server_host_key` and ## :bro:id:`ssh2_server_host_key`. + ## + ## .. bro:see:: ssh_server_version ssh_client_version + ## ssh_auth_successful ssh_auth_failed ssh_auth_result + ## ssh_auth_attempted ssh_capabilities ssh2_server_host_key + ## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params + ## ssh2_gss_error ssh2_ecc_key global ssh_server_host_key: event(c: connection, hash: string); } redef record Info += { # This connection has been logged (internal use) logged: bool &default=F; - # Number of failures seen (internal use) - num_failures: count &default=0; # Store capabilities from the first host for # comparison with the second (internal use) capabilities: Capabilities &optional; @@ -131,6 +181,10 @@ event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=5 return; c$ssh$auth_success = T; + if ( c$ssh?$auth_attempts ) + c$ssh$auth_attempts += 1; + else + c$ssh$auth_attempts = 1; if ( disable_analyzer_after_detection ) disable_analyzer(c$id, c$ssh$analyzer_id); @@ -155,7 +209,10 @@ event ssh_auth_failed(c: connection) &priority=5 return; c$ssh$auth_success = F; - c$ssh$num_failures += 1; + if ( c$ssh?$auth_attempts ) + c$ssh$auth_attempts += 1; + else + c$ssh$auth_attempts = 1; } # Determine the negotiated algorithm diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 2c8079d9b7..cb6c5e248e 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -8,9 +8,10 @@ ## version: The identification string ## ## .. bro:see:: ssh_client_version ssh_auth_successful ssh_auth_failed -## ssh_capabilities ssh2_server_host_key ssh1_server_host_key -## ssh_encrypted_packet ssh2_dh_server_params -## ssh2_gss_error ssh2_ecc_key +## ssh_auth_result ssh_auth_attempted ssh_capabilities +## ssh2_server_host_key ssh1_server_host_key ssh_server_host_key +## ssh_encrypted_packet ssh2_dh_server_params ssh2_gss_error +## ssh2_ecc_key event ssh_server_version%(c: connection, version: string%); ## An :abbr:`SSH (Secure Shell)` Protocol Version Exchange message @@ -23,9 +24,10 @@ event ssh_server_version%(c: connection, version: string%); ## version: The identification string ## ## .. bro:see:: ssh_server_version ssh_auth_successful ssh_auth_failed -## ssh_capabilities ssh2_server_host_key ssh1_server_host_key -## ssh_encrypted_packet ssh2_dh_server_params -## ssh2_gss_error ssh2_ecc_key +## ssh_auth_result ssh_auth_attempted ssh_capabilities +## ssh2_server_host_key ssh1_server_host_key ssh_server_host_key +## ssh_encrypted_packet ssh2_dh_server_params ssh2_gss_error +## ssh2_ecc_key event ssh_client_version%(c: connection, version: string%); ## This event is generated when an :abbr:`SSH (Secure Shell)` @@ -43,25 +45,41 @@ event ssh_client_version%(c: connection, version: string%); ## unauthenticated access, which some servers support. ## ## .. bro:see:: ssh_server_version ssh_client_version ssh_auth_failed -## ssh_capabilities ssh2_server_host_key ssh1_server_host_key -## ssh_encrypted_packet ssh2_dh_server_params -## ssh2_gss_error ssh2_ecc_key +## ssh_auth_result ssh_auth_attempted ssh_capabilities +## ssh2_server_host_key ssh1_server_host_key ssh_server_host_key +## ssh_encrypted_packet ssh2_dh_server_params ssh2_gss_error +## ssh2_ecc_key event ssh_auth_successful%(c: connection, auth_method_none: bool%); ## This event is generated when an :abbr:`SSH (Secure Shell)` -## connection was determined to have had a failed authentication. This -## determination is based on packet size analysis, and errs on the -## side of caution - that is, if there's any doubt about the -## authentication failure, this event is *not* raised. +## connection was determined to have had an authentication attempt. +## This determination is based on packet size analysis, and errs +## on the side of caution - that is, if there's any doubt about +## whether or not an authenication attempt occured, this event is +## *not* raised. +## +## At this point in the protocol, all we can determine is whether +## or not the user is authenticated. We don't know if the particular +## attempt succeeded or failed, since some servers require multiple +## authentications (e.g. require both a password AND a pubkey), and +## could return an authentication failed message which is marked +## as a partial success. +## +## This event will often be raised multiple times per connection. +## In almost all connections, it will be raised once unless ## ## c: The connection over which the :abbr:`SSH (Secure Shell)` ## connection took place. ## +## authenticated: This is true if the analyzer detected a +## successful connection from the authentication attempt. +## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_capabilities ssh2_server_host_key -## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_capabilities ssh2_server_host_key ssh1_server_host_key +## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key -event ssh_auth_failed%(c: connection%); +event ssh_auth_attempted%(c: connection, authenticated: bool%); ## During the initial :abbr:`SSH (Secure Shell)` key exchange, each ## endpoint lists the algorithms that it supports, in order of @@ -79,8 +97,9 @@ event ssh_auth_failed%(c: connection%); ## advertises support for, in order of preference. ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh2_server_host_key -## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh2_server_host_key ssh1_server_host_key +## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key event ssh_capabilities%(c: connection, cookie: string, capabilities: SSH::Capabilities%); @@ -95,8 +114,9 @@ event ssh_capabilities%(c: connection, cookie: string, capabilities: SSH::Capabi ## itself, and not just the fingerprint or hash. ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh_capabilities -## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh1_server_host_key +## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key event ssh2_server_host_key%(c: connection, key: string%); @@ -112,8 +132,9 @@ event ssh2_server_host_key%(c: connection, key: string%); ## e: The exponent for the serer's public host key. ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh_capabilities -## ssh2_server_host_key ssh_encrypted_packet ssh2_dh_server_params +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key event ssh1_server_host_key%(c: connection, p: string, e: string%); @@ -133,8 +154,9 @@ event ssh1_server_host_key%(c: connection, p: string, e: string%); ## bytes. Note that this ignores reassembly, as this is unknown. ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh_capabilities -## ssh2_server_host_key ssh1_server_host_key ssh2_dh_server_params +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh1_server_host_key ssh_server_host_key ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key event ssh_encrypted_packet%(c: connection, orig: bool, len: count%); @@ -149,10 +171,11 @@ event ssh_encrypted_packet%(c: connection, orig: bool, len: count%); ## ## q: The DH generator. ## -## .. bro:see:: ssl_dh_server_params ssh_server_version -## ssh_client_version ssh_auth_successful ssh_auth_failed -## ssh_capabilities ssh2_server_host_key ssh1_server_host_key -## ssh_encrypted_packet ssh2_gss_error ssh2_ecc_key +## .. bro:see:: ssh_server_version ssh_client_version +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh1_server_host_key ssh_server_host_key ssh_encrypted_packet +## ssh2_gss_error ssh2_ecc_key event ssh2_dh_server_params%(c: connection, p: string, q: string%); ## In the event of a GSS-API error on the server, the server MAY send @@ -169,8 +192,9 @@ event ssh2_dh_server_params%(c: connection, p: string, q: string%); ## err_msg: Detailed human-readable error message ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh_capabilities -## ssh2_server_host_key ssh1_server_host_key ssh_encrypted_packet +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh1_server_host_key ssh_server_host_key ssh_encrypted_packet ## ssh2_dh_server_params ssh2_ecc_key event ssh2_gss_error%(c: connection, major_status: count, minor_status: count, err_msg: string%); @@ -188,7 +212,8 @@ event ssh2_gss_error%(c: connection, major_status: count, minor_status: count, e ## q: The ephemeral public key ## ## .. bro:see:: ssh_server_version ssh_client_version -## ssh_auth_successful ssh_auth_failed ssh_capabilities -## ssh2_server_host_key ssh1_server_host_key ssh_encrypted_packet +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh1_server_host_key ssh_server_host_key ssh_encrypted_packet ## ssh2_dh_server_params ssh2_gss_error event ssh2_ecc_key%(c: connection, is_orig: bool, q: string%); From b1c3f1cd9bafd150996bcf4baa35eb092bf57e76 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 7 Oct 2016 16:39:05 -0500 Subject: [PATCH 02/16] Revert "Fixing duplicate SSH authentication failure events." This reverts commit 176d9f23be753c21936b28889d507719f3059c78. --- src/analyzer/protocol/ssh/SSH.cc | 14 +++++--------- src/analyzer/protocol/ssh/SSH.h | 6 ++---- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index 55f424344b..f1f8857e03 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -16,7 +16,7 @@ SSH_Analyzer::SSH_Analyzer(Connection* c) { interp = new binpac::SSH::SSH_Conn(this); had_gap = false; - auth_decision = AUTH_UNKNOWN; + auth_decision_made = false; skipped_banner = false; service_accept_size = 0; userauth_failure_size = 0; @@ -60,7 +60,7 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) BifEvent::generate_ssh_encrypted_packet(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), orig, len); - if ( auth_decision != AUTH_SUCCESS ) + if ( ! auth_decision_made ) ProcessEncrypted(len, orig); return; @@ -105,10 +105,9 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) // -16. if ( ! userauth_failure_size && (len + 16 == service_accept_size) ) { + auth_decision_made = true; if ( ssh_auth_successful ) BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), true); - - auth_decision = AUTH_SUCCESS; return; } @@ -132,20 +131,17 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) // another packet of the same size. if ( len == userauth_failure_size ) { - if ( ssh_auth_failed && auth_decision != AUTH_FAILURE ) + if ( ssh_auth_failed ) BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn()); - - auth_decision = AUTH_FAILURE; return; } // ...or a success packet. if ( len - service_accept_size == -16 ) { + auth_decision_made = true; if ( ssh_auth_successful ) BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), false); - - auth_decision = AUTH_SUCCESS; return; } } diff --git a/src/analyzer/protocol/ssh/SSH.h b/src/analyzer/protocol/ssh/SSH.h index 89668f93d1..dc3a7c5e39 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -35,14 +35,12 @@ namespace analyzer { bool had_gap; // Packet analysis stuff + bool auth_decision_made; bool skipped_banner; + int service_accept_size; int userauth_failure_size; - enum AuthDecision { - AUTH_UNKNOWN, AUTH_FAILURE, AUTH_SUCCESS - } auth_decision; - }; } From 20aef04dc7f232a0f4b0cba08d1f048fe7b7ee50 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 7 Oct 2016 16:47:52 -0500 Subject: [PATCH 03/16] Change SSH.cc to use ssh_auth_attempted instead of ssh_auth_failed. Addresses BIT-1641. --- src/analyzer/protocol/ssh/SSH.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index f1f8857e03..3b94f1f26c 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -131,8 +131,8 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) // another packet of the same size. if ( len == userauth_failure_size ) { - if ( ssh_auth_failed ) - BifEvent::generate_ssh_auth_failed(interp->bro_analyzer(), interp->bro_analyzer()->Conn()); + if ( ssh_auth_attempted ) + BifEvent::generate_ssh_auth_attempted(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), false); return; } @@ -140,6 +140,8 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) if ( len - service_accept_size == -16 ) { auth_decision_made = true; + if ( ssh_auth_attempted ) + BifEvent::generate_ssh_auth_attempted(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), true); if ( ssh_auth_successful ) BifEvent::generate_ssh_auth_successful(interp->bro_analyzer(), interp->bro_analyzer()->Conn(), false); return; From 292036604999c5cddf83f59a659a1500fb42f401 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 7 Oct 2016 17:17:01 -0500 Subject: [PATCH 04/16] Script-land changes for BIT-1641. --- scripts/base/protocols/ssh/main.bro | 36 +++++++++++------------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 9eeb892f3f..eee7a4cea7 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -170,9 +170,8 @@ event ssh_client_version(c: connection, version: string) c$ssh$version = 2; } -event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=5 +event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5 { - # TODO - what to do here? if ( !c?$ssh || ( c$ssh?$auth_success && c$ssh$auth_success ) ) return; @@ -180,41 +179,31 @@ event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=5 if ( c$ssh?$compression_alg && ( c$ssh$compression_alg in compression_algorithms ) ) return; - c$ssh$auth_success = T; + c$ssh$auth_success = authenticated; + if ( c$ssh?$auth_attempts ) c$ssh$auth_attempts += 1; else + { c$ssh$auth_attempts = 1; + if ( !authenticated ) + event ssh_auth_failed(c); + } - if ( disable_analyzer_after_detection ) + if ( authenticated && disable_analyzer_after_detection ) disable_analyzer(c$id, c$ssh$analyzer_id); } -event ssh_auth_successful(c: connection, auth_method_none: bool) &priority=-5 +event ssh_auth_attempted(c: connection, authenticated: bool) &priority=-5 { - if ( c?$ssh && !c$ssh$logged ) + if ( authenticated && c?$ssh && !c$ssh$logged ) { + event ssh_auth_result(c, authenticated, c$ssh$auth_attempts); c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); } } -event ssh_auth_failed(c: connection) &priority=5 - { - if ( !c?$ssh || ( c$ssh?$auth_success && !c$ssh$auth_success ) ) - return; - - # We can't accurately tell for compressed streams - if ( c$ssh?$compression_alg && ( c$ssh$compression_alg in compression_algorithms ) ) - return; - - c$ssh$auth_success = F; - if ( c$ssh?$auth_attempts ) - c$ssh$auth_attempts += 1; - else - c$ssh$auth_attempts = 1; - } - # Determine the negotiated algorithm function find_alg(client_algorithms: vector of string, server_algorithms: vector of string): string { @@ -265,6 +254,9 @@ event connection_state_remove(c: connection) &priority=-5 { if ( c?$ssh && !c$ssh$logged && c$ssh?$client && c$ssh?$server ) { + if ( c$ssh?$auth_success ) + event ssh_auth_result(c, c$ssh$auth_success, c$ssh$auth_attempts); + c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); } From 3e7d143e3113616342900a827b8d413945bc4d98 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 13 Oct 2016 14:58:14 -0500 Subject: [PATCH 05/16] Update baselines for adding a field to ssh.log as part of BIT-1641 --- .../btest/Baseline/core.tunnels.gre/ssh.log | 10 ++-- .../scripts.base.protocols.ssh.basic/ssh.log | 52 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/testing/btest/Baseline/core.tunnels.gre/ssh.log b/testing/btest/Baseline/core.tunnels.gre/ssh.log index 62b19cfd16..a3f6d0d738 100644 --- a/testing/btest/Baseline/core.tunnels.gre/ssh.log +++ b/testing/btest/Baseline/core.tunnels.gre/ssh.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssh -#open 2016-07-13-16-13-04 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version auth_success direction client server cipher_alg mac_alg compression_alg kex_alg host_key_alg host_key -#types time string addr port addr port count bool enum string string string string string string string string -1055289978.855137 CtPZjS20MLrsMUOJi2 66.59.111.190 40264 172.28.2.3 22 2 - - SSH-2.0-OpenSSH_3.6.1p1 SSH-1.99-OpenSSH_3.1p1 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 20:7c:e5:96:b0:4e:ce:a4:db:e4:aa:29:e8:90:98:07 -#close 2016-07-13-16-13-05 +#open 2016-10-13-19-54-38 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version auth_success auth_attempts direction client server cipher_alg mac_alg compression_alg kex_alg host_key_alg host_key +#types time string addr port addr port count bool count enum string string string string string string string string +1055289978.855137 CtPZjS20MLrsMUOJi2 66.59.111.190 40264 172.28.2.3 22 2 - - - SSH-2.0-OpenSSH_3.6.1p1 SSH-1.99-OpenSSH_3.1p1 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 20:7c:e5:96:b0:4e:ce:a4:db:e4:aa:29:e8:90:98:07 +#close 2016-10-13-19-54-38 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.basic/ssh.log b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/ssh.log index 7daa4ef910..6af991f2fd 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssh.basic/ssh.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.basic/ssh.log @@ -3,29 +3,29 @@ #empty_field (empty) #unset_field - #path ssh -#open 2016-07-13-16-16-57 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version auth_success direction client server cipher_alg mac_alg compression_alg kex_alg host_key_alg host_key -#types time string addr port addr port count bool enum string string string string string string string string -1324071333.792887 CHhAvVGS1DHFjwGM9 192.168.1.79 51880 131.159.21.1 22 2 F - SSH-2.0-OpenSSH_5.9 SSH-2.0-OpenSSH_5.8 aes128-ctr hmac-md5 none ecdh-sha2-nistp256 ssh-rsa a7:26:62:3f:75:1f:33:8a:f3:32:90:8b:73:fd:2c:83 -1409516196.413240 ClEkJM2Vm5giqnMf4h 10.0.0.18 40184 128.2.6.88 41644 2 T - SSH-2.0-OpenSSH_6.6 SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.1 aes128-ctr hmac-md5 none ecdh-sha2-nistp256 ssh-rsa 8a:8d:55:28:1e:71:04:99:94:43:22:89:e5:ff:e9:03 -1419870189.489202 C4J4Th3PJpwUYZZ6gc 192.168.2.1 57189 192.168.2.158 22 2 T - SSH-2.0-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 aes128-ctr hmac-md5-etm@openssh.com none diffie-hellman-group-exchange-sha256 ssh-rsa 28:78:65:c1:c3:26:f7:1b:65:6a:44:14:d0:04:8f:b3 -1419870206.111841 CtPZjS20MLrsMUOJi2 192.168.2.1 57191 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1419996264.344957 CUM0KZ3MLUfNB0cl11 192.168.2.1 55179 192.168.2.158 2200 2 T - SSH-2.0-OpenSSH_6.2 SSH-2.0-paramiko_1.15.2 aes128-ctr hmac-sha1 none diffie-hellman-group14-sha1 ssh-rsa 60:73:38:44:cb:51:86:65:7f:de:da:a2:2b:5a:57:d5 -1420588548.729561 CmES5u32sYpV7JYN 192.168.2.1 56594 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_5.3 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420590124.885826 CP5puj4I8PtEU4qzYg 192.168.2.1 56821 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420590308.781231 C37jN32gN3y3AZzyf6 192.168.2.1 56837 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420590322.682536 C3eiCBGOLw3VtHfOj 192.168.2.1 56845 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420590636.482711 CwjjYJ2WqgTbAqiHl6 192.168.2.1 56875 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420590659.429570 C0LAHyvtKSQHyJxIl 192.168.2.1 56878 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420591379.658705 CFLRIC3zaTU1loLGxh 192.168.2.1 56940 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420599430.828441 C9rXSW3KSpTYvPrlI1 192.168.2.1 57831 192.168.2.158 22 1 - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 -1420851448.310534 Ck51lg1bScffFj34Ri 192.168.2.1 59246 192.168.2.158 22 2 T - SSH-2.0-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 arcfour256 hmac-md5-etm@openssh.com none diffie-hellman-group-exchange-sha256 ssh-rsa 28:78:65:c1:c3:26:f7:1b:65:6a:44:14:d0:04:8f:b3 -1420860283.057451 C9mvWx3ezztgzcexV7 192.168.1.32 41164 128.2.10.238 22 2 T - SSH-2.0-OpenSSH_6.6p1-hpn14v4 SSH-1.99-OpenSSH_3.4+p1+gssapi+OpenSSH_3.7.1buf_fix+2006100301 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 7f:e5:81:92:26:77:05:44:c4:60:fb:cd:89:c8:81:ee -1420860616.428738 CNnMIj2QSd84NKf7U3 192.168.1.32 33910 128.2.13.133 22 2 T - SSH-2.0-OpenSSH_6.6p1-hpn14v4 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 93:d8:4c:0d:b2:c3:2e:da:b9:c0:67:db:e4:8f:95:04 -1420868281.665872 C7fIlMZDuRiqjpYbb 192.168.1.32 41268 128.2.10.238 22 2 F - SSH-2.0-OpenSSH_6.6 SSH-1.99-OpenSSH_3.4+p1+gssapi+OpenSSH_3.7.1buf_fix+2006100301 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 7f:e5:81:92:26:77:05:44:c4:60:fb:cd:89:c8:81:ee -1420917487.227035 CpmdRlaUoJLN3uIRa 192.168.1.31 52294 192.168.1.32 22 2 T - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_6.7 chacha20-poly1305@openssh.com hmac-sha2-512-etm@openssh.com none curve25519-sha256@libssh.org ssh-ed25519 e4:b1:8e:ca:6e:0e:e5:3c:7e:a4:0e:70:34:9d:b2:b1 -1421006072.224828 C1Xkzz2MaGtLrc1Tla 192.168.1.31 51489 192.168.1.32 22 2 T - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_6.7 chacha20-poly1305@openssh.com hmac-sha2-512-etm@openssh.com none curve25519-sha256@libssh.org ssh-ed25519 e4:b1:8e:ca:6e:0e:e5:3c:7e:a4:0e:70:34:9d:b2:b1 -1421041177.031508 CLNN1k2QMum1aexUK7 192.168.1.32 58641 131.103.20.168 22 2 F - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 -1421041299.777962 CBA8792iHmnhPLksKa 192.168.1.32 58646 131.103.20.168 22 2 T - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 -1421041526.353524 CGLPPc35OzDQij1XX8 192.168.1.32 58649 131.103.20.168 22 2 T - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 -#close 2016-07-13-16-16-57 +#open 2016-10-13-19-57-11 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version auth_success auth_attempts direction client server cipher_alg mac_alg compression_alg kex_alg host_key_alg host_key +#types time string addr port addr port count bool count enum string string string string string string string string +1324071333.792887 CHhAvVGS1DHFjwGM9 192.168.1.79 51880 131.159.21.1 22 2 F 2 - SSH-2.0-OpenSSH_5.9 SSH-2.0-OpenSSH_5.8 aes128-ctr hmac-md5 none ecdh-sha2-nistp256 ssh-rsa a7:26:62:3f:75:1f:33:8a:f3:32:90:8b:73:fd:2c:83 +1409516196.413240 ClEkJM2Vm5giqnMf4h 10.0.0.18 40184 128.2.6.88 41644 2 T 1 - SSH-2.0-OpenSSH_6.6 SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.1 aes128-ctr hmac-md5 none ecdh-sha2-nistp256 ssh-rsa 8a:8d:55:28:1e:71:04:99:94:43:22:89:e5:ff:e9:03 +1419870189.489202 C4J4Th3PJpwUYZZ6gc 192.168.2.1 57189 192.168.2.158 22 2 T 3 - SSH-2.0-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 aes128-ctr hmac-md5-etm@openssh.com none diffie-hellman-group-exchange-sha256 ssh-rsa 28:78:65:c1:c3:26:f7:1b:65:6a:44:14:d0:04:8f:b3 +1419870206.111841 CtPZjS20MLrsMUOJi2 192.168.2.1 57191 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1419996264.344957 CUM0KZ3MLUfNB0cl11 192.168.2.1 55179 192.168.2.158 2200 2 - - - SSH-2.0-OpenSSH_6.2 SSH-2.0-paramiko_1.15.2 aes128-ctr hmac-sha1 none diffie-hellman-group14-sha1 ssh-rsa 60:73:38:44:cb:51:86:65:7f:de:da:a2:2b:5a:57:d5 +1420588548.729561 CmES5u32sYpV7JYN 192.168.2.1 56594 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_5.3 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420590124.885826 CP5puj4I8PtEU4qzYg 192.168.2.1 56821 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420590308.781231 C37jN32gN3y3AZzyf6 192.168.2.1 56837 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420590322.682536 C3eiCBGOLw3VtHfOj 192.168.2.1 56845 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420590636.482711 CwjjYJ2WqgTbAqiHl6 192.168.2.1 56875 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420590659.429570 C0LAHyvtKSQHyJxIl 192.168.2.1 56878 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420591379.658705 CFLRIC3zaTU1loLGxh 192.168.2.1 56940 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420599430.828441 C9rXSW3KSpTYvPrlI1 192.168.2.1 57831 192.168.2.158 22 1 - - - SSH-1.5-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 - - - - - a1:73:d1:e1:25:72:79:71:56:56:65:ed:81:bf:67:98 +1420851448.310534 Ck51lg1bScffFj34Ri 192.168.2.1 59246 192.168.2.158 22 2 T 2 - SSH-2.0-OpenSSH_6.2 SSH-1.99-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 arcfour256 hmac-md5-etm@openssh.com none diffie-hellman-group-exchange-sha256 ssh-rsa 28:78:65:c1:c3:26:f7:1b:65:6a:44:14:d0:04:8f:b3 +1420860283.057451 C9mvWx3ezztgzcexV7 192.168.1.32 41164 128.2.10.238 22 2 T 5 - SSH-2.0-OpenSSH_6.6p1-hpn14v4 SSH-1.99-OpenSSH_3.4+p1+gssapi+OpenSSH_3.7.1buf_fix+2006100301 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 7f:e5:81:92:26:77:05:44:c4:60:fb:cd:89:c8:81:ee +1420860616.428738 CNnMIj2QSd84NKf7U3 192.168.1.32 33910 128.2.13.133 22 2 T 1 - SSH-2.0-OpenSSH_6.6p1-hpn14v4 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 93:d8:4c:0d:b2:c3:2e:da:b9:c0:67:db:e4:8f:95:04 +1420868281.665872 C7fIlMZDuRiqjpYbb 192.168.1.32 41268 128.2.10.238 22 2 F 6 - SSH-2.0-OpenSSH_6.6 SSH-1.99-OpenSSH_3.4+p1+gssapi+OpenSSH_3.7.1buf_fix+2006100301 aes128-cbc hmac-md5 none diffie-hellman-group-exchange-sha1 ssh-rsa 7f:e5:81:92:26:77:05:44:c4:60:fb:cd:89:c8:81:ee +1420917487.227035 CpmdRlaUoJLN3uIRa 192.168.1.31 52294 192.168.1.32 22 2 T 2 - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_6.7 chacha20-poly1305@openssh.com hmac-sha2-512-etm@openssh.com none curve25519-sha256@libssh.org ssh-ed25519 e4:b1:8e:ca:6e:0e:e5:3c:7e:a4:0e:70:34:9d:b2:b1 +1421006072.224828 C1Xkzz2MaGtLrc1Tla 192.168.1.31 51489 192.168.1.32 22 2 T 3 - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_6.7 chacha20-poly1305@openssh.com hmac-sha2-512-etm@openssh.com none curve25519-sha256@libssh.org ssh-ed25519 e4:b1:8e:ca:6e:0e:e5:3c:7e:a4:0e:70:34:9d:b2:b1 +1421041177.031508 CLNN1k2QMum1aexUK7 192.168.1.32 58641 131.103.20.168 22 2 F 1 - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 +1421041299.777962 CBA8792iHmnhPLksKa 192.168.1.32 58646 131.103.20.168 22 2 T 1 - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 +1421041526.353524 CGLPPc35OzDQij1XX8 192.168.1.32 58649 131.103.20.168 22 2 T 1 - SSH-2.0-OpenSSH_6.7 SSH-2.0-OpenSSH_5.3 aes128-ctr hmac-md5 none diffie-hellman-group-exchange-sha256 ssh-rsa 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 +#close 2016-10-13-19-57-11 From 7caf2d0356db026eb781a3e4c067d31bf90fe14c Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 13 Oct 2016 15:24:38 -0500 Subject: [PATCH 06/16] Clean up the logic for ssh_auth_failed. Addresses BIT-1641 --- scripts/base/protocols/ssh/main.bro | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index eee7a4cea7..d0ad9a8b73 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -77,7 +77,7 @@ export { ## ssh_capabilities ssh2_server_host_key ssh1_server_host_key ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key - global ssh_auth_failed: event (c: connection); + global ssh_auth_failed: event(c: connection); ## This event is generated when a determination has been made about ## the final authentication result of an :abbr:`SSH (Secure Shell)` @@ -100,7 +100,7 @@ export { ## ssh_capabilities ssh2_server_host_key ssh1_server_host_key ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key - global ssh_auth_result: event (c: connection, result: bool, auth_attempts: count); + global ssh_auth_result: event(c: connection, result: bool, auth_attempts: count); ## Event that can be handled when the analyzer sees an SSH server host ## key. This abstracts :bro:id:`ssh1_server_host_key` and @@ -186,8 +186,6 @@ event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5 else { c$ssh$auth_attempts = 1; - if ( !authenticated ) - event ssh_auth_failed(c); } if ( authenticated && disable_analyzer_after_detection ) @@ -252,13 +250,18 @@ event ssh_capabilities(c: connection, cookie: string, capabilities: Capabilities event connection_state_remove(c: connection) &priority=-5 { - if ( c?$ssh && !c$ssh$logged && c$ssh?$client && c$ssh?$server ) + if ( c?$ssh && !c$ssh$logged && c$ssh?$client && c$ssh?$server && c$ssh?$auth_success ) { - if ( c$ssh?$auth_success ) - event ssh_auth_result(c, c$ssh$auth_success, c$ssh$auth_attempts); + # Success get logged immediately. To protect against a race condition, we'll double check: + if ( c$ssh$auth_success ) + return; - c$ssh$logged = T; - Log::write(SSH::LOG, c$ssh); + # Now that we know it's a failure, we'll set the field, raise the event, and log it. + c$ssh$auth_success = F; + event SSH::ssh_auth_failed(c); + + c$ssh$logged = T; + Log::write(SSH::LOG, c$ssh); } } @@ -284,7 +287,7 @@ event ssh2_server_host_key(c: connection, key: string) &priority=5 event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=20 { - if ( atype == Analyzer::ANALYZER_SSH ) + if ( atype == Analyzer::ANALYZER_SSH ) { set_session(c); c$ssh$analyzer_id = aid; From 70aaffbaacaaf4cbef1ad0a15081f9bca23545a1 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 13 Oct 2016 16:33:48 -0500 Subject: [PATCH 07/16] Logic fix for ssh/main.bro when the auth status is indeterminate, and fix a test. Addresses BIT-1641. --- scripts/base/protocols/ssh/main.bro | 32 +++++++++++++------ .../protocols/ssh/one-auth-fail-only.test | 2 +- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index d0ad9a8b73..7b51b1b525 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -248,23 +248,37 @@ event ssh_capabilities(c: connection, cookie: string, capabilities: Capabilities server_caps$server_host_key_algorithms); } -event connection_state_remove(c: connection) &priority=-5 +event connection_state_remove(c: connection) { - if ( c?$ssh && !c$ssh$logged && c$ssh?$client && c$ssh?$server && c$ssh?$auth_success ) + if ( c?$ssh && !c$ssh$logged ) { - # Success get logged immediately. To protect against a race condition, we'll double check: - if ( c$ssh$auth_success ) - return; - - # Now that we know it's a failure, we'll set the field, raise the event, and log it. - c$ssh$auth_success = F; - event SSH::ssh_auth_failed(c); + # Do we have enough information to make a determination about auth success? + if ( c$ssh?$client && c$ssh?$server && c$ssh?$auth_success ) + { + # Success get logged immediately. To protect against a race condition, we'll double check: + if ( c$ssh$auth_success ) + return; + # Now that we know it's a failure, we'll set the field, and raise the event. + c$ssh$auth_success = F; + event SSH::ssh_auth_failed(c); + } + # If not, we'll just log what we have + else + { c$ssh$logged = T; Log::write(SSH::LOG, c$ssh); + } } } +event ssh_auth_failed(c: connection) &priority=-5 + { + c$ssh$logged = T; + Log::write(SSH::LOG, c$ssh); + } + + function generate_fingerprint(c: connection, key: string) { if ( !c?$ssh ) diff --git a/testing/btest/scripts/base/protocols/ssh/one-auth-fail-only.test b/testing/btest/scripts/base/protocols/ssh/one-auth-fail-only.test index fc39683a16..f6751c2a03 100644 --- a/testing/btest/scripts/base/protocols/ssh/one-auth-fail-only.test +++ b/testing/btest/scripts/base/protocols/ssh/one-auth-fail-only.test @@ -1,7 +1,7 @@ # @TEST-EXEC: bro -C -r $TRACES/ssh/sshguess.pcap %INPUT | sort >output # @TEST-EXEC: btest-diff output -event ssh_auth_failed(c: connection) +event SSH::ssh_auth_failed(c: connection) { print c$uid; } From 6fa9540e47f91d0e494371140f6ba3cf4f2cf891 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 14 Oct 2016 14:10:40 -0500 Subject: [PATCH 08/16] Fix istate.pybroccoli test on systems using Python 3 Filter out the python 2 "L" suffix on long integers (not valid in Python 3), and change python 3 "object at" to "instance at" when printing class instances. --- testing/btest/istate/pybroccoli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/btest/istate/pybroccoli.py b/testing/btest/istate/pybroccoli.py index 9f26efca31..7600c2b7d4 100644 --- a/testing/btest/istate/pybroccoli.py +++ b/testing/btest/istate/pybroccoli.py @@ -8,8 +8,8 @@ # @TEST-EXEC: btest-bg-wait -k 20 # @TEST-EXEC: btest-diff bro/.stdout # -# @TEST-EXEC: sed 's/instance at [^>]*>/instance at >/' python/.stdout.filtered -# @TEST-EXEC: btest-diff python/.stdout.filtered +# @TEST-EXEC: sed -e 's/instance at [^>]*>/instance at >/' -e 's/object at [^>]*>/instance at >/' python/.stdout.filtered +# @TEST-EXEC: TEST_DIFF_CANONIFIER="sed -e 's/^\([-]*[0-9][0-9]*\)L/\1/' | $SCRIPTS/diff-remove-timestamps" btest-diff python/.stdout.filtered event remote_connection_closed(p: event_peer) { From 24f74cb52e4020703f47cd35769e08dd54098a1c Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 14 Oct 2016 15:33:43 -0700 Subject: [PATCH 09/16] Fix alignment issue of ones_complement_checksum The ones_complement_checksum function assumes that the bytes passed into it are aligned on 16 bit boundaries. When using gcc (GCC) 6.2.1 20160916 (Red Hat 6.2.1-2) with -O2, this does not seem to hold true anymore; assuming 16 bit alignment will lead to accesses to uninitialized memory and wrong checksums. This commit adds a minimally invasive change that does not assume alignment anymore. This might have a small performance impact for every single packet we process. This error occured reproducibly when called from icmp6_checksum. --- src/net_util.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/net_util.cc b/src/net_util.cc index 677a869cc5..0f1493e190 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -18,13 +18,16 @@ // Returns the ones-complement checksum of a chunk of b short-aligned bytes. int ones_complement_checksum(const void* p, int b, uint32 sum) { - const u_short* sp = (u_short*) p; // better be aligned! + const unsigned char* sp = (unsigned char*) p; b /= 2; // convert to count of short's /* No need for endian conversions. */ while ( --b >= 0 ) - sum += *sp++; + { + sum += *sp + ( *(sp+1) << 8 ); + sp += 2; + } while ( sum > 0xffff ) sum = (sum & 0xffff) + (sum >> 16); From 303985e7dbef9c378dc24d2844206ba95fb1a0c6 Mon Sep 17 00:00:00 2001 From: balintm Date: Mon, 17 Oct 2016 10:18:09 +0100 Subject: [PATCH 10/16] Update smb1-com-open-andx.pac # of bytes in reserved field of request is 4 & response is 6B long. --- src/analyzer/protocol/smb/smb1-com-open-andx.pac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/smb/smb1-com-open-andx.pac b/src/analyzer/protocol/smb/smb1-com-open-andx.pac index 8f19f6f3a4..c7e7bea03a 100644 --- a/src/analyzer/protocol/smb/smb1-com-open-andx.pac +++ b/src/analyzer/protocol/smb/smb1-com-open-andx.pac @@ -52,7 +52,7 @@ type SMB1_open_andx_request(header: SMB_Header, offset: uint16) = record { open_mode : uint16; allocation_size : uint32; timeout : uint32; - reserved : padding[2]; + reserved : padding[4]; byte_count : uint16; filename : SMB_string(header.unicode, offsetof(filename); @@ -74,7 +74,7 @@ type SMB1_open_andx_response(header: SMB_Header, offset: uint16) = record { resource_type : uint16; nm_pipe_status : uint16; open_results : uint16; - reserved : padding[3]; + 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))); From c5696821c830f9a03df05024e221bd6158d1f5fc Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 18 Oct 2016 13:53:13 -0400 Subject: [PATCH 11/16] Update submodule [nomail] --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index 45f7dc6243..39510b5fb2 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 45f7dc6243aa7cbeeab9acbcf5d623e5ce991b2a +Subproject commit 39510b5fb2351d7aac85da0d335a128402db3bbc From 5cf2320fbc3ebb0d53e431829d2c9c56fdf6f08b Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 19 Oct 2016 13:48:17 -0700 Subject: [PATCH 12/16] Fix a couple of problems with signature matching. - IPv4 CIDR specifications didn't work with dst-ip/src-ip. - The "payload-size" condition was unreliable with UDP traffic. --- src/RuleCondition.cc | 4 +++ src/RuleMatcher.cc | 6 ++--- src/RuleMatcher.h | 1 + src/rule-parse.y | 6 ++--- .../Baseline/signatures.dst-ip-cidr-v4/output | 6 +++++ .../signatures.udp-payload-size/output | 6 +++++ testing/btest/Traces/ntp.pcap | Bin 0 -> 1296 bytes testing/btest/signatures/dst-ip-cidr-v4.bro | 17 +++++++++++++ testing/btest/signatures/udp-payload-size.bro | 23 ++++++++++++++++++ 9 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/signatures.dst-ip-cidr-v4/output create mode 100644 testing/btest/Baseline/signatures.udp-payload-size/output create mode 100644 testing/btest/Traces/ntp.pcap create mode 100644 testing/btest/signatures/dst-ip-cidr-v4.bro create mode 100644 testing/btest/signatures/udp-payload-size.bro diff --git a/src/RuleCondition.cc b/src/RuleCondition.cc index 40ef5f0ad1..9df70f118b 100644 --- a/src/RuleCondition.cc +++ b/src/RuleCondition.cc @@ -89,6 +89,10 @@ bool RuleConditionPayloadSize::DoMatch(Rule* rule, RuleEndpointState* state, // on the pure rules now. return false; + if ( state->PayloadSize() == 0 ) + // We are interested in the first non-empty chunk. + return false; + uint32 payload_size = uint32(state->PayloadSize()); switch ( comp ) { diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index c88bb77a4f..3ee7306fb5 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -144,7 +144,7 @@ bool RuleHdrTest::operator==(const RuleHdrTest& h) void RuleHdrTest::PrintDebug() { static const char* str_comp[] = { "<=", ">=", "<", ">", "==", "!=" }; - static const char* str_prot[] = { "", "ip", "icmp", "tcp", "udp" }; + static const char* str_prot[] = { "", "ip", "ipv6", "icmp", "icmpv6", "tcp", "udp", "next", "ipsrc", "ipdst" }; fprintf(stderr, " RuleHdrTest %s[%d:%d] %s", str_prot[prot], offset, size, str_comp[comp]); @@ -1095,10 +1095,10 @@ void RuleMatcher::ExecRule(Rule* rule, RuleEndpointState* state, bool eos) void RuleMatcher::ClearEndpointState(RuleEndpointState* state) { - state->payload_size = -1; - ExecPureRules(state, 1); + state->payload_size = -1; + loop_over_list(state->matchers, j) state->matchers[j]->state->Clear(); } diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index b16a1556f9..23b7e6d731 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -72,6 +72,7 @@ extern uint32 id_to_uint(const char* id); class RuleHdrTest { public: + // Note: Adapt RuleHdrTest::PrintDebug() when changing these enums. enum Comp { LE, GE, LT, GT, EQ, NE }; enum Prot { NOPROT, IP, IPv6, ICMP, ICMPv6, TCP, UDP, NEXT, IPSrc, IPDst }; diff --git a/src/rule-parse.y b/src/rule-parse.y index 32ada02cb3..3e9c8d7ddf 100644 --- a/src/rule-parse.y +++ b/src/rule-parse.y @@ -14,7 +14,7 @@ extern void end_PS(); Rule* current_rule = 0; const char* current_rule_file = 0; -static uint8_t mask_to_len(uint32_t mask) +static uint8_t ip4_mask_to_len(uint32_t mask) { if ( mask == 0xffffffff ) return 32; @@ -23,7 +23,7 @@ static uint8_t mask_to_len(uint32_t mask) uint8_t len; for ( len = 0; len < 32 && (! (x & (1 << len))); ++len ); - return len; + return 32 - len; } %} @@ -315,7 +315,7 @@ prefix_value: TOK_IP { $$ = new IPPrefix(IPAddr(IPv4, &($1.val), IPAddr::Host), - mask_to_len($1.mask)); + ip4_mask_to_len($1.mask)); } | TOK_IP6 ; diff --git a/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output b/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output new file mode 100644 index 0000000000..eb07f77921 --- /dev/null +++ b/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output @@ -0,0 +1,6 @@ +match, foo +match, foo +match, foo +match, foo +match, foo +match, foo diff --git a/testing/btest/Baseline/signatures.udp-payload-size/output b/testing/btest/Baseline/signatures.udp-payload-size/output new file mode 100644 index 0000000000..2ae3bbde9f --- /dev/null +++ b/testing/btest/Baseline/signatures.udp-payload-size/output @@ -0,0 +1,6 @@ +match, foo2 +match, foo2 +match, foo2 +match, foo2 +match, foo2 +match, foo2 diff --git a/testing/btest/Traces/ntp.pcap b/testing/btest/Traces/ntp.pcap new file mode 100644 index 0000000000000000000000000000000000000000..cc80d04afdd329b9a8ed2b0bf10ea4e3e7345196 GIT binary patch literal 1296 zcmca|c+)~A1{MYcU}0bcaxzqzBHGH>8KQt}5N1$vG#1*#A{xXhC(gm(%D~{G_LqUd zL9lA^ffbDLf`3{5GE@Vhg;m321`d#Vg5dU=#V^W_aI68@G*OfTZWF`~hBm%%pH_B3{ZtFF$?FLzeris9s|B*@*AawGn0}h74)W8bA3#6VBK-991{OcPkg~`r z0QmuAGKlV-F!K3s2csP$Q$fkWB zOmLep{q+7W$WMuf1pi7Q#gpeNBtJR9;%Q@Ytt-$EV3R?#qIBm8FfH?tWf#zoutput +# @TEST-EXEC: btest-diff output + +@TEST-START-FILE a.sig +signature foo { + dst-ip == 17.0.0.0/8 + ip-proto == udp + event "match" +} +@TEST-END-FILE + +event signature_match(state: signature_state, msg: string, data: string) + { + print "match", state$sig_id; + } + +@load-sigs ./a.sig diff --git a/testing/btest/signatures/udp-payload-size.bro b/testing/btest/signatures/udp-payload-size.bro new file mode 100644 index 0000000000..efc5411feb --- /dev/null +++ b/testing/btest/signatures/udp-payload-size.bro @@ -0,0 +1,23 @@ +# @TEST-EXEC: bro -r $TRACES/ntp.pcap %INPUT >output +# @TEST-EXEC: btest-diff output + +@TEST-START-FILE a.sig +signature foo1 { + ip-proto == udp + payload-size < 1 + event "match" +} + +signature foo2 { + ip-proto == udp + payload-size > 0 + event "match" +} +@TEST-END-FILE + +event signature_match(state: signature_state, msg: string, data: string) + { + print "match", state$sig_id; + } + +@load-sigs ./a.sig From 3d1f35f85b71bdcb528ced0e0d40945c6337d0ec Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 20 Oct 2016 11:53:34 -0400 Subject: [PATCH 13/16] Update submodule [nomail] --- aux/broctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broctl b/aux/broctl index f944471bec..741f6aefce 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit f944471bec062876aa18317f51b6fbe5325ca166 +Subproject commit 741f6aefce5758d7a62ac5be05f4c750afb5e463 From 99cd34f57d2fe2c86bfd831096a7d4ddcbf05d2d Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 21 Oct 2016 09:33:04 -0500 Subject: [PATCH 14/16] Python 3 compatibility fix for coverage-calc script --- testing/scripts/coverage-calc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/scripts/coverage-calc b/testing/scripts/coverage-calc index cc5253c75c..df12e0c86f 100755 --- a/testing/scripts/coverage-calc +++ b/testing/scripts/coverage-calc @@ -56,4 +56,4 @@ for k in stats: num_covered += 1 if len(stats) > 0: - print "%s/%s (%.1f%%) Bro script statements covered." % (num_covered, len(stats), float(num_covered)/len(stats)*100) + print("%s/%s (%.1f%%) Bro script statements covered." % (num_covered, len(stats), float(num_covered)/len(stats)*100)) From 860cfa7002bdf6f72cf9de5604a4f74c18c92299 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 25 Oct 2016 09:32:11 -0700 Subject: [PATCH 15/16] Update submodule [nomail] --- aux/btest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/btest b/aux/btest index 625dbecfd6..17d1c15476 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 625dbecfd63022d79a144b9651085e68cdf99ce4 +Subproject commit 17d1c1547678bfd54ef1202db5415bc85c7ae794 From 3284e92677e7c3266d6cf350702009c618e5b2f9 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 25 Oct 2016 10:21:57 -0700 Subject: [PATCH 16/16] NEWS file tweaks: input error events & OpenFlow. These were pointed out by Daniel. --- NEWS | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 34d942a7db..c4aeb6133a 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,9 @@ New Functionality New log files: net_control.log, netcontrol_catch_release.log, netcontrol_drop.log, and netcontrol_shunt.log. +- Bro now includes the OpenFlow framework which exposes the datastructures + necessary to interface to OpenFlow capable hardware. + - Bro's Intelligence Framework was refactored and new functionality has been added: @@ -154,8 +157,10 @@ New Functionality - The pcap buffer size can be set through the new option Pcap::bufsize. -- Input framework readers Table and Event can now define a custom - event to receive logging messages. +- Input framework readers stream types Table and Event can now define a custom + event (specified by the new "error_ev" field) to receive error messages + emitted by the input stream. This can, e.g., be used to raise notices in + case errors occur when reading an important input source. - The logging framework now supports user-defined record separators, renaming of column names, as well as extension data columns that can