diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index f1f8857e03..55f424344b 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_made = false; + auth_decision = AUTH_UNKNOWN; 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_made ) + if ( auth_decision != AUTH_SUCCESS ) ProcessEncrypted(len, orig); return; @@ -105,9 +105,10 @@ 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; } @@ -131,17 +132,20 @@ void SSH_Analyzer::ProcessEncrypted(int len, bool orig) // another packet of the same size. if ( len == userauth_failure_size ) { - if ( ssh_auth_failed ) + if ( ssh_auth_failed && auth_decision != AUTH_FAILURE ) 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 dc3a7c5e39..89668f93d1 100644 --- a/src/analyzer/protocol/ssh/SSH.h +++ b/src/analyzer/protocol/ssh/SSH.h @@ -35,12 +35,14 @@ 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; + }; } diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.one-auth-fail-only/output b/testing/btest/Baseline/scripts.base.protocols.ssh.one-auth-fail-only/output new file mode 100644 index 0000000000..1a210e7b10 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.one-auth-fail-only/output @@ -0,0 +1,11 @@ +C0LAHyvtKSQHyJxIl +C37jN32gN3y3AZzyf6 +C3eiCBGOLw3VtHfOj +C4J4Th3PJpwUYZZ6gc +CHhAvVGS1DHFjwGM9 +CP5puj4I8PtEU4qzYg +CUM0KZ3MLUfNB0cl11 +ClEkJM2Vm5giqnMf4h +CmES5u32sYpV7JYN +CtPZjS20MLrsMUOJi2 +CwjjYJ2WqgTbAqiHl6 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 new file mode 100644 index 0000000000..fc39683a16 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssh/one-auth-fail-only.test @@ -0,0 +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) + { + print c$uid; + }