From 2cf90d986e15e643fb7e4e86ca39833a0f245b54 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 5 Nov 2013 11:34:32 -0500 Subject: [PATCH 1/2] Fix resp_size in ssh.log, require a minimum resp_size for the heuristic. Some work on geodata, but still a WIP. --- scripts/base/protocols/ssh/main.bro | 16 +++++++++------- scripts/policy/protocols/ssh/geo-data.bro | 22 +++++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) 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); + } From d108481e730cd14140895f708722d6d0b55eb988 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 5 Nov 2013 11:58:00 -0500 Subject: [PATCH 2/2] Remove resp_size from the log. Refactor when we write out to the log a bit. Geodata now works reliably. --- scripts/base/protocols/ssh/main.bro | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/base/protocols/ssh/main.bro b/scripts/base/protocols/ssh/main.bro index fd0abad67d..33b0c84147 100644 --- a/scripts/base/protocols/ssh/main.bro +++ b/scripts/base/protocols/ssh/main.bro @@ -37,12 +37,6 @@ export { client: string &log &optional; ## Software string from the server. server: string &log &optional; - ## Amount of data returned from the server. This is currently - ## the only measure of the success heuristic and it is logged to - ## assist analysts looking at the logs to make their own - ## determination about the success on a case-by-case basis. - resp_size: count &log &default=0; - ## Indicate if the SSH session is done being watched. done: bool &default=F; }; @@ -159,13 +153,23 @@ function check_ssh_connection(c: connection, done: bool) } +event heuristic_successful_login(c: connection) &priority=-5 + { + Log::write(SSH::LOG, c$ssh); + } + +event heuristic_failed_login(c: connection) &priority=-5 + { + Log::write(SSH::LOG, c$ssh); + } + 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); + if ( c$ssh$status == "undetermined" ) + Log::write(SSH::LOG, c$ssh); } }