diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index 5b452d432c..fd0abad67d 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -107,10 +107,10 @@ function check_ssh_connection(c: connection, done: bool) # this matches the conditions for a failed login. Failed # logins are only detected at connection state removal. - if ( # Require originators to have sent at least 50 bytes. - c$orig$size > 50 && + if ( # Require originators and responders to have sent at least 50 bytes. + c$orig$size > 50 && c$resp$size > 50 && # Responders must be below 4000 bytes. - c$resp$size < 4000 && + c$resp$size < authentication_data_size && # Responder must have sent fewer than 40 packets. c$resp$num_pkts < 40 && # If there was a content gap we can't reliably do this heuristic. @@ -122,7 +122,7 @@ function check_ssh_connection(c: connection, done: bool) event SSH::heuristic_failed_login(c); } - if ( c$resp$size > authentication_data_size ) + if ( c$resp$size >= authentication_data_size ) { c$ssh$status = "success"; event SSH::heuristic_successful_login(c); @@ -132,7 +132,7 @@ function check_ssh_connection(c: connection, done: bool) { # If this connection is still being tracked, then it's possible # to watch for it to be a successful connection. - if ( c$resp$size > authentication_data_size ) + if ( c$resp$size >= authentication_data_size ) { c$ssh$status = "success"; event SSH::heuristic_successful_login(c); @@ -150,8 +150,6 @@ function check_ssh_connection(c: connection, done: bool) # after detection is done. c$ssh$done=T; - Log::write(SSH::LOG, c$ssh); - if ( skip_processing_after_detection ) { # Stop watching this connection, we don't care about it anymore. @@ -164,7 +162,11 @@ function check_ssh_connection(c: connection, done: bool) event connection_state_remove(c: connection) &priority=-5 { if ( c?$ssh ) + { check_ssh_connection(c, T); + c$ssh$resp_size = c$resp$size; + Log::write(SSH::LOG, c$ssh); + } } event ssh_watcher(c: connection) diff --git a/scripts/policy/protocols/ssh/geo-data.bro b/scripts/policy/protocols/ssh/geo-data.bro index 3abc19d337..a5fed986ef 100644 --- a/scripts/policy/protocols/ssh/geo-data.bro +++ b/scripts/policy/protocols/ssh/geo-data.bro @@ -24,21 +24,29 @@ export { const watched_countries: set[string] = {"RO"} &redef; } +function get_location(c: connection): geo_location + { + local lookup_ip = (c$ssh$direction == OUTBOUND) ? c$id$resp_h : c$id$orig_h; + return lookup_location(lookup_ip); + } + event SSH::heuristic_successful_login(c: connection) &priority=5 { - local location: geo_location; - location = (c$ssh$direction == OUTBOUND) ? - lookup_location(c$id$resp_h) : lookup_location(c$id$orig_h); - # Add the location data to the SSH record. - c$ssh$remote_location = location; + c$ssh$remote_location = get_location(c); - if ( location?$country_code && location$country_code in watched_countries ) + if ( c$ssh$remote_location?$country_code && c$ssh$remote_location$country_code in watched_countries ) { NOTICE([$note=Watched_Country_Login, $conn=c, $msg=fmt("SSH login %s watched country: %s", (c$ssh$direction == OUTBOUND) ? "to" : "from", - location$country_code)]); + c$ssh$remote_location$country_code)]); } } + +event SSH::heuristic_failed_login(c: connection) &priority=5 + { + # Add the location data to the SSH record. + c$ssh$remote_location = get_location(c); + }