From e517a32cdc3de7f84d4371584971dbdf2eca8e9b Mon Sep 17 00:00:00 2001 From: Laurence Date: Wed, 21 Jan 2026 12:41:24 +0000 Subject: [PATCH] refactor(sshd-logs): split ssh_failed-auth into distinct log_types The ssh-time-based-bf scenario was incorrectly triggering because a single SSH login attempt generates multiple log lines (Invalid user, pam_unix auth failure, Failed password, Connection closed), all previously tagged as ssh_failed-auth. This caused 1 real attempt to be counted as 3-4 events, inflating the count and skewing the MedianInterval calculation. Split ssh_failed-auth into distinct log_types per event category: - ssh_password_fail: actual auth failures (Failed password for) - ssh_invalid_user: username probing (Invalid user from) - ssh_pam_failure: PAM notification (duplicate signal, unused) - ssh_preauth_close: connection lifecycle (Connection closed [preauth]) - ssh_not_allowed: AllowUsers blocks - ssh_bad_banner, ssh_bad_keyexchange, ssh_magic_failed: protocol anomalies Added new scenarios for complete coverage (one per bucket): - ssh-invalid-user: detect username probing - ssh-preauth-scan: detect preauth disconnect scanning - ssh-not-allowed: detect blocked user attempts - ssh-scanner: detect protocol anomalies Updated existing scenarios (ssh-bf, ssh-slow-bf, ssh-time-based-bf) to use ssh_password_fail for accurate 1:1 counting of actual auth attempts. Co-Authored-By: Claude Opus 4.5 --- .tests/ssh-bf/scenario.assert | 24 ++-- .tests/ssh-bf/ssh-bf.log | 13 +- .tests/ssh-generic-test/scenario.assert | 4 +- .tests/ssh-generic-test/ssh-generic-test.log | 2 +- .tests/ssh-invalid-user/config.yaml | 12 ++ .tests/ssh-invalid-user/scenario.assert | 113 ++++++++++++++++ .tests/ssh-invalid-user/ssh-invalid-user.log | 6 + .tests/ssh-not-allowed/config.yaml | 12 ++ .tests/ssh-not-allowed/scenario.assert | 41 ++++++ .tests/ssh-not-allowed/ssh-not-allowed.log | 5 + .tests/ssh-preauth-scan/config.yaml | 12 ++ .tests/ssh-preauth-scan/scenario.assert | 57 ++++++++ .tests/ssh-preauth-scan/ssh-preauth-scan.log | 11 ++ .tests/ssh-scanner/config.yaml | 12 ++ .tests/ssh-scanner/scenario.assert | 109 +++++++++++++++ .tests/ssh-scanner/ssh-scanner.log | 12 ++ .tests/ssh-slow-bf/scenario.assert | 22 ++-- .tests/ssh-slow-bf/ssh-slow-bf.log | 44 +++---- .tests/ssh-time-based-bf/scenario.assert | 124 ++++++++++++++---- .../ssh-time-based-bf/ssh-time-based-bf.log | 25 ++-- .tests/sshd-invalid-bf/scenario.assert | 12 +- .tests/sshd-invalid-bf/sshd-invalid-bf.log | 12 +- .tests/sshd-logs/parser.assert | 32 ++--- .tests/sshd_banner_exchange/config.yaml | 4 +- .tests/sshd_banner_exchange/scenario.assert | 32 +---- .../s01-parse/crowdsecurity/sshd-logs.yaml | 79 +++++++---- scenarios/crowdsecurity/ssh-bf.yaml | 4 +- scenarios/crowdsecurity/ssh-generic-test.yaml | 2 +- scenarios/crowdsecurity/ssh-invalid-user.yaml | 40 ++++++ scenarios/crowdsecurity/ssh-not-allowed.yaml | 19 +++ scenarios/crowdsecurity/ssh-preauth-scan.yaml | 19 +++ scenarios/crowdsecurity/ssh-scanner.yaml | 19 +++ scenarios/crowdsecurity/ssh-slow-bf.yaml | 4 +- .../crowdsecurity/ssh-time-based-bf.yaml | 8 +- 34 files changed, 766 insertions(+), 180 deletions(-) create mode 100644 .tests/ssh-invalid-user/config.yaml create mode 100644 .tests/ssh-invalid-user/scenario.assert create mode 100644 .tests/ssh-invalid-user/ssh-invalid-user.log create mode 100644 .tests/ssh-not-allowed/config.yaml create mode 100644 .tests/ssh-not-allowed/scenario.assert create mode 100644 .tests/ssh-not-allowed/ssh-not-allowed.log create mode 100644 .tests/ssh-preauth-scan/config.yaml create mode 100644 .tests/ssh-preauth-scan/scenario.assert create mode 100644 .tests/ssh-preauth-scan/ssh-preauth-scan.log create mode 100644 .tests/ssh-scanner/config.yaml create mode 100644 .tests/ssh-scanner/scenario.assert create mode 100644 .tests/ssh-scanner/ssh-scanner.log create mode 100644 scenarios/crowdsecurity/ssh-invalid-user.yaml create mode 100644 scenarios/crowdsecurity/ssh-not-allowed.yaml create mode 100644 scenarios/crowdsecurity/ssh-preauth-scan.yaml create mode 100644 scenarios/crowdsecurity/ssh-scanner.yaml diff --git a/.tests/ssh-bf/scenario.assert b/.tests/ssh-bf/scenario.assert index ae58dc7535c..6ccd3d06626 100644 --- a/.tests/ssh-bf/scenario.assert +++ b/.tests/ssh-bf/scenario.assert @@ -6,7 +6,7 @@ results[0].Overflow.Sources["35.188.49.176"].GetScope() == "Ip" results[0].Overflow.Sources["35.188.49.176"].GetValue() == "35.188.49.176" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "35.188.49.176" @@ -14,7 +14,7 @@ results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "pascal" results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-02-12T14:10:21Z" basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[1].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "35.188.49.176" @@ -22,7 +22,7 @@ results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "pascal1" results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-02-12T14:10:21Z" basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[2].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "35.188.49.176" @@ -30,7 +30,7 @@ results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "pascal2" results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-02-12T14:10:22Z" basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[3].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "35.188.49.176" @@ -38,7 +38,7 @@ results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "pascal3" results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-02-12T14:10:22Z" basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[4].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "35.188.49.176" @@ -46,7 +46,7 @@ results[0].Overflow.Alert.Events[4].GetMeta("target_user") == "pascal4" results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-02-12T14:10:23Z" basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-bf.log" results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[5].GetMeta("machine") == "sd-126005" results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "35.188.49.176" @@ -62,7 +62,7 @@ results[1].Overflow.Sources["35.188.49.176"].GetScope() == "Ip" results[1].Overflow.Sources["35.188.49.176"].GetValue() == "35.188.49.176" basename(results[1].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[0].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[0].GetMeta("source_ip") == "35.188.49.176" @@ -70,7 +70,7 @@ results[1].Overflow.Alert.Events[0].GetMeta("target_user") == "pascal" results[1].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-02-12T14:10:21Z" basename(results[1].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[1].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[1].GetMeta("source_ip") == "35.188.49.176" @@ -78,7 +78,7 @@ results[1].Overflow.Alert.Events[1].GetMeta("target_user") == "pascal1" results[1].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-02-12T14:10:21Z" basename(results[1].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[2].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[2].GetMeta("source_ip") == "35.188.49.176" @@ -86,7 +86,7 @@ results[1].Overflow.Alert.Events[2].GetMeta("target_user") == "pascal2" results[1].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-02-12T14:10:22Z" basename(results[1].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[3].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[3].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[3].GetMeta("source_ip") == "35.188.49.176" @@ -94,7 +94,7 @@ results[1].Overflow.Alert.Events[3].GetMeta("target_user") == "pascal3" results[1].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-02-12T14:10:22Z" basename(results[1].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[4].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[4].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[4].GetMeta("source_ip") == "35.188.49.176" @@ -102,7 +102,7 @@ results[1].Overflow.Alert.Events[4].GetMeta("target_user") == "pascal4" results[1].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-02-12T14:10:23Z" basename(results[1].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-bf.log" results[1].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[5].GetMeta("machine") == "sd-126005" results[1].Overflow.Alert.Events[5].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[5].GetMeta("source_ip") == "35.188.49.176" diff --git a/.tests/ssh-bf/ssh-bf.log b/.tests/ssh-bf/ssh-bf.log index 90a22b7f6cf..bda3723f9e3 100644 --- a/.tests/ssh-bf/ssh-bf.log +++ b/.tests/ssh-bf/ssh-bf.log @@ -1,7 +1,6 @@ -Feb 12 14:10:21 sd-126005 sshd[16378]: Invalid user pascal from 35.188.49.176 port 53502 -Feb 12 14:10:21 sd-126005 sshd[16378]: Invalid user pascal1 from 35.188.49.176 port 53502 -Feb 12 14:10:22 sd-126005 sshd[16378]: Invalid user pascal2 from 35.188.49.176 port 53502 -Feb 12 14:10:22 sd-126005 sshd[16378]: Invalid user pascal3 from 35.188.49.176 port 53502 -Feb 12 14:10:23 sd-126005 sshd[16378]: Invalid user pascal4 from 35.188.49.176 port 53502 -Feb 12 14:10:24 sd-126005 sshd-session[16379]: Invalid user pascal5 from 35.188.49.176 port 53502 - +Feb 12 14:10:21 sd-126005 sshd[16378]: Failed password for invalid user pascal from 35.188.49.176 port 53502 ssh2 +Feb 12 14:10:21 sd-126005 sshd[16378]: Failed password for invalid user pascal1 from 35.188.49.176 port 53503 ssh2 +Feb 12 14:10:22 sd-126005 sshd[16378]: Failed password for invalid user pascal2 from 35.188.49.176 port 53504 ssh2 +Feb 12 14:10:22 sd-126005 sshd[16378]: Failed password for invalid user pascal3 from 35.188.49.176 port 53505 ssh2 +Feb 12 14:10:23 sd-126005 sshd[16378]: Failed password for invalid user pascal4 from 35.188.49.176 port 53506 ssh2 +Feb 12 14:10:24 sd-126005 sshd[16379]: Failed password for invalid user pascal5 from 35.188.49.176 port 53507 ssh2 diff --git a/.tests/ssh-generic-test/scenario.assert b/.tests/ssh-generic-test/scenario.assert index 9e354e60ca7..6782769c134 100644 --- a/.tests/ssh-generic-test/scenario.assert +++ b/.tests/ssh-generic-test/scenario.assert @@ -6,12 +6,12 @@ results[0].Overflow.Sources["127.0.0.1"].GetScope() == "Ip" results[0].Overflow.Sources["127.0.0.1"].GetValue() == "127.0.0.1" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-generic-test.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "leto" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "127.0.0.1" results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl" -results[0].Overflow.Alert.Events[0].GetMeta("timestamp")[4:] == "-06-12T16:20:12Z" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-06-12T16:20:12Z" results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-generic-test" results[0].Overflow.Alert.Remediation == false results[0].Overflow.Alert.GetEventsCount() == 1 diff --git a/.tests/ssh-generic-test/ssh-generic-test.log b/.tests/ssh-generic-test/ssh-generic-test.log index 9190b1330b6..bb5218c9f6a 100644 --- a/.tests/ssh-generic-test/ssh-generic-test.log +++ b/.tests/ssh-generic-test/ssh-generic-test.log @@ -1 +1 @@ -Jun 12 16:20:12 leto sshd-session[406147]: Invalid user crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl from 127.0.0.1 port 49916 +Jun 12 16:20:12 leto sshd-session[406147]: Failed password for invalid user crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl from 127.0.0.1 port 49916 ssh2 diff --git a/.tests/ssh-invalid-user/config.yaml b/.tests/ssh-invalid-user/config.yaml new file mode 100644 index 00000000000..3712dcc9929 --- /dev/null +++ b/.tests/ssh-invalid-user/config.yaml @@ -0,0 +1,12 @@ +parsers: +- crowdsecurity/syslog-logs +- crowdsecurity/dateparse-enrich +- ./parsers/s01-parse/crowdsecurity/sshd-logs.yaml +scenarios: +- ./scenarios/crowdsecurity/ssh-invalid-user.yaml +postoverflows: +- "" +log_file: ssh-invalid-user.log +log_type: syslog +labels: {} +ignore_parsers: true diff --git a/.tests/ssh-invalid-user/scenario.assert b/.tests/ssh-invalid-user/scenario.assert new file mode 100644 index 00000000000..bd82b195e72 --- /dev/null +++ b/.tests/ssh-invalid-user/scenario.assert @@ -0,0 +1,113 @@ +len(results) == 2 +"192.168.1.100" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["192.168.1.100"].IP == "192.168.1.100" +results[0].Overflow.Sources["192.168.1.100"].Range == "" +results[0].Overflow.Sources["192.168.1.100"].GetScope() == "Ip" +results[0].Overflow.Sources["192.168.1.100"].GetValue() == "192.168.1.100" +basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[0].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "admin" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-02-12T14:10:21Z" +basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[1].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "root" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-02-12T14:10:22Z" +basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[2].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "test" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-02-12T14:10:23Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[3].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "guest" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-02-12T14:10:24Z" +basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[4].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[4].GetMeta("target_user") == "mysql" +results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-02-12T14:10:25Z" +basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_invalid_user" +results[0].Overflow.Alert.Events[5].GetMeta("machine") == "sd-126005" +results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[5].GetMeta("target_user") == "oracle" +results[0].Overflow.Alert.Events[5].GetMeta("timestamp") == "2026-02-12T14:10:26Z" +results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-invalid-user_user-enum" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 6 +"192.168.1.100" in results[1].Overflow.GetSources() +results[1].Overflow.Sources["192.168.1.100"].IP == "192.168.1.100" +results[1].Overflow.Sources["192.168.1.100"].Range == "" +results[1].Overflow.Sources["192.168.1.100"].GetScope() == "Ip" +results[1].Overflow.Sources["192.168.1.100"].GetValue() == "192.168.1.100" +basename(results[1].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[0].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[0].GetMeta("target_user") == "admin" +results[1].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-02-12T14:10:21Z" +basename(results[1].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[1].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[1].GetMeta("target_user") == "root" +results[1].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-02-12T14:10:22Z" +basename(results[1].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[2].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[2].GetMeta("target_user") == "test" +results[1].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-02-12T14:10:23Z" +basename(results[1].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[3].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[3].GetMeta("target_user") == "guest" +results[1].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-02-12T14:10:24Z" +basename(results[1].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[4].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[4].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[4].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[4].GetMeta("target_user") == "mysql" +results[1].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-02-12T14:10:25Z" +basename(results[1].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-invalid-user.log" +results[1].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_invalid_user" +results[1].Overflow.Alert.Events[5].GetMeta("machine") == "sd-126005" +results[1].Overflow.Alert.Events[5].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[5].GetMeta("source_ip") == "192.168.1.100" +results[1].Overflow.Alert.Events[5].GetMeta("target_user") == "oracle" +results[1].Overflow.Alert.Events[5].GetMeta("timestamp") == "2026-02-12T14:10:26Z" +results[1].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-invalid-user" +results[1].Overflow.Alert.Remediation == true +results[1].Overflow.Alert.GetEventsCount() == 6 diff --git a/.tests/ssh-invalid-user/ssh-invalid-user.log b/.tests/ssh-invalid-user/ssh-invalid-user.log new file mode 100644 index 00000000000..239728c2ca8 --- /dev/null +++ b/.tests/ssh-invalid-user/ssh-invalid-user.log @@ -0,0 +1,6 @@ +Feb 12 14:10:21 sd-126005 sshd[16378]: Invalid user admin from 192.168.1.100 port 53502 +Feb 12 14:10:22 sd-126005 sshd[16379]: Invalid user root from 192.168.1.100 port 53503 +Feb 12 14:10:23 sd-126005 sshd[16380]: Invalid user test from 192.168.1.100 port 53504 +Feb 12 14:10:24 sd-126005 sshd[16381]: Invalid user guest from 192.168.1.100 port 53505 +Feb 12 14:10:25 sd-126005 sshd[16382]: Invalid user mysql from 192.168.1.100 port 53506 +Feb 12 14:10:26 sd-126005 sshd[16383]: Invalid user oracle from 192.168.1.100 port 53507 diff --git a/.tests/ssh-not-allowed/config.yaml b/.tests/ssh-not-allowed/config.yaml new file mode 100644 index 00000000000..fd6b4af61b7 --- /dev/null +++ b/.tests/ssh-not-allowed/config.yaml @@ -0,0 +1,12 @@ +parsers: +- crowdsecurity/syslog-logs +- crowdsecurity/dateparse-enrich +- ./parsers/s01-parse/crowdsecurity/sshd-logs.yaml +scenarios: +- ./scenarios/crowdsecurity/ssh-not-allowed.yaml +postoverflows: +- "" +log_file: ssh-not-allowed.log +log_type: syslog +labels: {} +ignore_parsers: true diff --git a/.tests/ssh-not-allowed/scenario.assert b/.tests/ssh-not-allowed/scenario.assert new file mode 100644 index 00000000000..f7c15d27565 --- /dev/null +++ b/.tests/ssh-not-allowed/scenario.assert @@ -0,0 +1,41 @@ +len(results) == 1 +"192.168.1.100" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["192.168.1.100"].IP == "192.168.1.100" +results[0].Overflow.Sources["192.168.1.100"].Range == "" +results[0].Overflow.Sources["192.168.1.100"].GetScope() == "Ip" +results[0].Overflow.Sources["192.168.1.100"].GetValue() == "192.168.1.100" +basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-not-allowed.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_not_allowed" +results[0].Overflow.Alert.Events[0].GetMeta("machine") == "myserver" +results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "root" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-11-14T00:20:42Z" +basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-not-allowed.log" +results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_not_allowed" +results[0].Overflow.Alert.Events[1].GetMeta("machine") == "myserver" +results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "admin" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-11-14T00:20:44Z" +basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-not-allowed.log" +results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_not_allowed" +results[0].Overflow.Alert.Events[2].GetMeta("machine") == "myserver" +results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "test" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-11-14T00:20:46Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-not-allowed.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_not_allowed" +results[0].Overflow.Alert.Events[3].GetMeta("machine") == "myserver" +results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "guest" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-11-14T00:20:48Z" +results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-not-allowed" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 4 diff --git a/.tests/ssh-not-allowed/ssh-not-allowed.log b/.tests/ssh-not-allowed/ssh-not-allowed.log new file mode 100644 index 00000000000..a225822dca8 --- /dev/null +++ b/.tests/ssh-not-allowed/ssh-not-allowed.log @@ -0,0 +1,5 @@ +Nov 14 00:20:42 myserver sshd[1112652]: User root from 192.168.1.100 port 22 not allowed because not listed in AllowUsers +Nov 14 00:20:44 myserver sshd[1112653]: User admin from 192.168.1.100 port 22 not allowed because not listed in AllowUsers +Nov 14 00:20:46 myserver sshd[1112654]: User test from 192.168.1.100 port 22 not allowed because not listed in AllowUsers +Nov 14 00:20:48 myserver sshd[1112655]: User guest from 192.168.1.100 port 22 not allowed because not listed in AllowUsers +Nov 14 00:20:50 myserver sshd[1112656]: User oracle from 192.168.1.100 port 22 not allowed because not listed in AllowUsers diff --git a/.tests/ssh-preauth-scan/config.yaml b/.tests/ssh-preauth-scan/config.yaml new file mode 100644 index 00000000000..639fff88ee8 --- /dev/null +++ b/.tests/ssh-preauth-scan/config.yaml @@ -0,0 +1,12 @@ +parsers: +- crowdsecurity/syslog-logs +- crowdsecurity/dateparse-enrich +- ./parsers/s01-parse/crowdsecurity/sshd-logs.yaml +scenarios: +- ./scenarios/crowdsecurity/ssh-preauth-scan.yaml +postoverflows: +- "" +log_file: ssh-preauth-scan.log +log_type: syslog +labels: {} +ignore_parsers: true diff --git a/.tests/ssh-preauth-scan/scenario.assert b/.tests/ssh-preauth-scan/scenario.assert new file mode 100644 index 00000000000..419b997c6b6 --- /dev/null +++ b/.tests/ssh-preauth-scan/scenario.assert @@ -0,0 +1,57 @@ +len(results) == 1 +"192.168.1.100" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["192.168.1.100"].IP == "192.168.1.100" +results[0].Overflow.Sources["192.168.1.100"].Range == "" +results[0].Overflow.Sources["192.168.1.100"].GetScope() == "Ip" +results[0].Overflow.Sources["192.168.1.100"].GetValue() == "192.168.1.100" +basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[0].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "root" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-01-24T15:32:31Z" +basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[1].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "root" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-01-24T15:32:32Z" +basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[2].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "admin" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-01-24T15:32:33Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[3].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "test" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-01-24T15:32:34Z" +basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[4].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[4].GetMeta("target_user") == "guest" +results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-01-24T15:32:35Z" +basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-preauth-scan.log" +results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_preauth_close" +results[0].Overflow.Alert.Events[5].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "192.168.1.100" +results[0].Overflow.Alert.Events[5].GetMeta("target_user") == "mysql" +results[0].Overflow.Alert.Events[5].GetMeta("timestamp") == "2026-01-24T15:32:36Z" +results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-preauth-scan" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 6 diff --git a/.tests/ssh-preauth-scan/ssh-preauth-scan.log b/.tests/ssh-preauth-scan/ssh-preauth-scan.log new file mode 100644 index 00000000000..58df8bef6d9 --- /dev/null +++ b/.tests/ssh-preauth-scan/ssh-preauth-scan.log @@ -0,0 +1,11 @@ +Jan 24 15:32:31 server sshd[2651912]: Connection closed by authenticating user root 192.168.1.100 port 59402 [preauth] +Jan 24 15:32:32 server sshd[2654543]: Connection closed by authenticating user root 192.168.1.100 port 38260 [preauth] +Jan 24 15:32:33 server sshd[2657307]: Disconnected from invalid user admin 192.168.1.100 port 45326 [preauth] +Jan 24 15:32:34 server sshd[2660116]: Disconnected from authenticating user test 192.168.1.100 port 52414 [preauth] +Jan 24 15:32:35 server sshd[2662890]: Connection reset by authenticating user guest 192.168.1.100 port 59502 [preauth] +Jan 24 15:32:36 server sshd[2665707]: Connection closed by invalid user mysql 192.168.1.100 port 38346 [preauth] +Jan 24 15:32:37 server sshd[2665708]: Connection closed by authenticating user oracle 192.168.1.100 port 38347 [preauth] +Jan 24 15:32:38 server sshd[2665709]: Connection closed by invalid user postgres 192.168.1.100 port 38348 [preauth] +Jan 24 15:32:39 server sshd[2665710]: Disconnected from invalid user jenkins 192.168.1.100 port 38349 [preauth] +Jan 24 15:32:40 server sshd[2665711]: Connection closed by authenticating user hadoop 192.168.1.100 port 38350 [preauth] +Jan 24 15:32:41 server sshd[2665712]: Connection reset by invalid user tomcat 192.168.1.100 port 38351 [preauth] diff --git a/.tests/ssh-scanner/config.yaml b/.tests/ssh-scanner/config.yaml new file mode 100644 index 00000000000..f9fcbe5a0f0 --- /dev/null +++ b/.tests/ssh-scanner/config.yaml @@ -0,0 +1,12 @@ +parsers: +- crowdsecurity/syslog-logs +- crowdsecurity/dateparse-enrich +- ./parsers/s01-parse/crowdsecurity/sshd-logs.yaml +scenarios: +- ./scenarios/crowdsecurity/ssh-scanner.yaml +postoverflows: +- "" +log_file: ssh-scanner.log +log_type: syslog +labels: {} +ignore_parsers: true diff --git a/.tests/ssh-scanner/scenario.assert b/.tests/ssh-scanner/scenario.assert new file mode 100644 index 00000000000..d1867ffc855 --- /dev/null +++ b/.tests/ssh-scanner/scenario.assert @@ -0,0 +1,109 @@ +len(results) == 3 +"192.168.1.102" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["192.168.1.102"].IP == "192.168.1.102" +results[0].Overflow.Sources["192.168.1.102"].Range == "" +results[0].Overflow.Sources["192.168.1.102"].GetScope() == "Ip" +results[0].Overflow.Sources["192.168.1.102"].GetValue() == "192.168.1.102" +basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-scanner.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_magic_failed" +results[0].Overflow.Alert.Events[0].GetMeta("machine") == "username" +results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.102" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-10-10T01:48:14Z" +basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-scanner.log" +results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_magic_failed" +results[0].Overflow.Alert.Events[1].GetMeta("machine") == "username" +results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.102" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-10-10T01:48:15Z" +basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-scanner.log" +results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_magic_failed" +results[0].Overflow.Alert.Events[2].GetMeta("machine") == "username" +results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.102" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-10-10T01:48:16Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-scanner.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_magic_failed" +results[0].Overflow.Alert.Events[3].GetMeta("machine") == "username" +results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.102" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-10-10T01:48:17Z" +results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-scanner" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 4 +"192.168.1.101" in results[1].Overflow.GetSources() +results[1].Overflow.Sources["192.168.1.101"].IP == "192.168.1.101" +results[1].Overflow.Sources["192.168.1.101"].Range == "" +results[1].Overflow.Sources["192.168.1.101"].GetScope() == "Ip" +results[1].Overflow.Sources["192.168.1.101"].GetValue() == "192.168.1.101" +basename(results[1].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-scanner.log" +results[1].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_bad_keyexchange" +results[1].Overflow.Alert.Events[0].GetMeta("machine") == "server" +results[1].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.101" +results[1].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-06-08T10:44:36Z" +basename(results[1].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-scanner.log" +results[1].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_bad_keyexchange" +results[1].Overflow.Alert.Events[1].GetMeta("machine") == "server" +results[1].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.101" +results[1].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-06-08T10:44:37Z" +basename(results[1].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-scanner.log" +results[1].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_bad_keyexchange" +results[1].Overflow.Alert.Events[2].GetMeta("machine") == "server" +results[1].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.101" +results[1].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-06-08T10:44:38Z" +basename(results[1].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-scanner.log" +results[1].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_bad_keyexchange" +results[1].Overflow.Alert.Events[3].GetMeta("machine") == "server" +results[1].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[1].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.101" +results[1].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-06-08T10:44:39Z" +results[1].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-scanner" +results[1].Overflow.Alert.Remediation == true +results[1].Overflow.Alert.GetEventsCount() == 4 +"192.168.1.100" in results[2].Overflow.GetSources() +results[2].Overflow.Sources["192.168.1.100"].IP == "192.168.1.100" +results[2].Overflow.Sources["192.168.1.100"].Range == "" +results[2].Overflow.Sources["192.168.1.100"].GetScope() == "Ip" +results[2].Overflow.Sources["192.168.1.100"].GetValue() == "192.168.1.100" +basename(results[2].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-scanner.log" +results[2].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_bad_banner" +results[2].Overflow.Alert.Events[0].GetMeta("machine") == "hostname" +results[2].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[0].GetMeta("source_ip") == "192.168.1.100" +results[2].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-12-01T18:59:33Z" +basename(results[2].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-scanner.log" +results[2].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_bad_banner" +results[2].Overflow.Alert.Events[1].GetMeta("machine") == "hostname" +results[2].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[1].GetMeta("source_ip") == "192.168.1.100" +results[2].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-12-01T18:59:34Z" +basename(results[2].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-scanner.log" +results[2].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_bad_banner" +results[2].Overflow.Alert.Events[2].GetMeta("machine") == "hostname" +results[2].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[2].GetMeta("source_ip") == "192.168.1.100" +results[2].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-12-01T18:59:35Z" +basename(results[2].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-scanner.log" +results[2].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_bad_banner" +results[2].Overflow.Alert.Events[3].GetMeta("machine") == "hostname" +results[2].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[3].GetMeta("source_ip") == "192.168.1.100" +results[2].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-12-01T18:59:36Z" +results[2].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-scanner" +results[2].Overflow.Alert.Remediation == true +results[2].Overflow.Alert.GetEventsCount() == 4 diff --git a/.tests/ssh-scanner/ssh-scanner.log b/.tests/ssh-scanner/ssh-scanner.log new file mode 100644 index 00000000000..29f79cf4714 --- /dev/null +++ b/.tests/ssh-scanner/ssh-scanner.log @@ -0,0 +1,12 @@ +Dec 1 18:59:33 hostname sshd[1189573]: banner exchange: Connection from 192.168.1.100 port 34388: invalid format +Dec 1 18:59:34 hostname sshd[1189575]: banner exchange: Connection from 192.168.1.100 port 44105: invalid format +Dec 1 18:59:35 hostname sshd[1189580]: banner exchange: Connection from 192.168.1.100 port 45164: invalid format +Dec 1 18:59:36 hostname sshd[1189581]: banner exchange: Connection from 192.168.1.100 port 37374: invalid format +Jun 8 10:44:36 server sshd[3204729]: Unable to negotiate with 192.168.1.101 port 45626: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth] +Jun 8 10:44:37 server sshd[3204730]: Unable to negotiate with 192.168.1.101 port 45627: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1 [preauth] +Jun 8 10:44:38 server sshd[3204731]: Unable to negotiate with 192.168.1.101 port 45628: no matching host key type found. Their offer: ssh-rsa,ssh-dss [preauth] +Jun 8 10:44:39 server sshd[3204732]: Unable to negotiate with 192.168.1.101 port 45629: no matching MAC found. Their offer: hmac-sha1 [preauth] +Oct 10 01:48:14 username sshd[386400]: Magic value check failed (4289475479) on obfuscated handshake from 192.168.1.102 port 62730 +Oct 10 01:48:15 username sshd[386401]: Magic value check failed (4289475480) on obfuscated handshake from 192.168.1.102 port 62731 +Oct 10 01:48:16 username sshd[386402]: Magic value check failed (4289475481) on obfuscated handshake from 192.168.1.102 port 62732 +Oct 10 01:48:17 username sshd[386403]: Magic value check failed (4289475482) on obfuscated handshake from 192.168.1.102 port 62733 diff --git a/.tests/ssh-slow-bf/scenario.assert b/.tests/ssh-slow-bf/scenario.assert index ba215e11fb7..9b5c9646af6 100644 --- a/.tests/ssh-slow-bf/scenario.assert +++ b/.tests/ssh-slow-bf/scenario.assert @@ -6,7 +6,7 @@ results[0].Overflow.Sources["103.100.210.198"].GetScope() == "Ip" results[0].Overflow.Sources["103.100.210.198"].GetValue() == "103.100.210.198" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "103.100.210.198" @@ -14,7 +14,7 @@ results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T12:16:00Z" basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[1].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "103.100.210.198" @@ -22,7 +22,7 @@ results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T12:16:33Z" basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[2].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "103.100.210.198" @@ -30,7 +30,7 @@ results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T12:17:00Z" basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[3].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "103.100.210.198" @@ -38,7 +38,7 @@ results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-09-30T12:17:33Z" basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[4].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "103.100.210.198" @@ -46,7 +46,7 @@ results[0].Overflow.Alert.Events[4].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-09-30T12:18:00Z" basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[5].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "103.100.210.198" @@ -54,7 +54,7 @@ results[0].Overflow.Alert.Events[5].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[5].GetMeta("timestamp") == "2026-09-30T12:18:33Z" basename(results[0].Overflow.Alert.Events[6].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[6].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[6].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[6].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[6].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[6].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[6].GetMeta("source_ip") == "103.100.210.198" @@ -62,7 +62,7 @@ results[0].Overflow.Alert.Events[6].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[6].GetMeta("timestamp") == "2026-09-30T12:19:00Z" basename(results[0].Overflow.Alert.Events[7].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[7].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[7].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[7].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[7].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[7].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[7].GetMeta("source_ip") == "103.100.210.198" @@ -70,7 +70,7 @@ results[0].Overflow.Alert.Events[7].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[7].GetMeta("timestamp") == "2026-09-30T12:19:33Z" basename(results[0].Overflow.Alert.Events[8].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[8].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[8].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[8].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[8].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[8].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[8].GetMeta("source_ip") == "103.100.210.198" @@ -78,7 +78,7 @@ results[0].Overflow.Alert.Events[8].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[8].GetMeta("timestamp") == "2026-09-30T12:20:00Z" basename(results[0].Overflow.Alert.Events[9].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[9].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[9].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[9].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[9].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[9].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[9].GetMeta("source_ip") == "103.100.210.198" @@ -86,7 +86,7 @@ results[0].Overflow.Alert.Events[9].GetMeta("target_user") == "hadoop" results[0].Overflow.Alert.Events[9].GetMeta("timestamp") == "2026-09-30T12:20:33Z" basename(results[0].Overflow.Alert.Events[10].GetMeta("datasource_path")) == "ssh-slow-bf.log" results[0].Overflow.Alert.Events[10].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[10].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[10].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[10].GetMeta("machine") == "ip-172-31-43-28" results[0].Overflow.Alert.Events[10].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[10].GetMeta("source_ip") == "103.100.210.198" diff --git a/.tests/ssh-slow-bf/ssh-slow-bf.log b/.tests/ssh-slow-bf/ssh-slow-bf.log index 1f4c8a64c62..d2a9d3ab758 100644 --- a/.tests/ssh-slow-bf/ssh-slow-bf.log +++ b/.tests/ssh-slow-bf/ssh-slow-bf.log @@ -1,22 +1,22 @@ -Sep 30 12:11:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:12:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:12:30 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:13:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:13:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:14:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:14:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:15:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:15:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:16:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:16:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:17:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:17:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:18:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:18:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:19:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:19:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:20:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:20:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:21:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:21:33 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 -Sep 30 12:22:00 ip-172-31-43-28 sshd[22789]: Invalid user hadoop from 103.100.210.198 port 56762 +Sep 30 12:11:33 ip-172-31-43-28 sshd[22789]: Failed password for invalid user hadoop from 103.100.210.198 port 56762 ssh2 +Sep 30 12:12:00 ip-172-31-43-28 sshd[22790]: Failed password for invalid user hadoop from 103.100.210.198 port 56763 ssh2 +Sep 30 12:12:30 ip-172-31-43-28 sshd[22791]: Failed password for invalid user hadoop from 103.100.210.198 port 56764 ssh2 +Sep 30 12:13:00 ip-172-31-43-28 sshd[22792]: Failed password for invalid user hadoop from 103.100.210.198 port 56765 ssh2 +Sep 30 12:13:33 ip-172-31-43-28 sshd[22793]: Failed password for invalid user hadoop from 103.100.210.198 port 56766 ssh2 +Sep 30 12:14:00 ip-172-31-43-28 sshd[22794]: Failed password for invalid user hadoop from 103.100.210.198 port 56767 ssh2 +Sep 30 12:14:33 ip-172-31-43-28 sshd[22795]: Failed password for invalid user hadoop from 103.100.210.198 port 56768 ssh2 +Sep 30 12:15:00 ip-172-31-43-28 sshd[22796]: Failed password for invalid user hadoop from 103.100.210.198 port 56769 ssh2 +Sep 30 12:15:33 ip-172-31-43-28 sshd[22797]: Failed password for invalid user hadoop from 103.100.210.198 port 56770 ssh2 +Sep 30 12:16:00 ip-172-31-43-28 sshd[22798]: Failed password for invalid user hadoop from 103.100.210.198 port 56771 ssh2 +Sep 30 12:16:33 ip-172-31-43-28 sshd[22799]: Failed password for invalid user hadoop from 103.100.210.198 port 56772 ssh2 +Sep 30 12:17:00 ip-172-31-43-28 sshd[22800]: Failed password for invalid user hadoop from 103.100.210.198 port 56773 ssh2 +Sep 30 12:17:33 ip-172-31-43-28 sshd[22801]: Failed password for invalid user hadoop from 103.100.210.198 port 56774 ssh2 +Sep 30 12:18:00 ip-172-31-43-28 sshd[22802]: Failed password for invalid user hadoop from 103.100.210.198 port 56775 ssh2 +Sep 30 12:18:33 ip-172-31-43-28 sshd[22803]: Failed password for invalid user hadoop from 103.100.210.198 port 56776 ssh2 +Sep 30 12:19:00 ip-172-31-43-28 sshd[22804]: Failed password for invalid user hadoop from 103.100.210.198 port 56777 ssh2 +Sep 30 12:19:33 ip-172-31-43-28 sshd[22805]: Failed password for invalid user hadoop from 103.100.210.198 port 56778 ssh2 +Sep 30 12:20:00 ip-172-31-43-28 sshd[22806]: Failed password for invalid user hadoop from 103.100.210.198 port 56779 ssh2 +Sep 30 12:20:33 ip-172-31-43-28 sshd[22807]: Failed password for invalid user hadoop from 103.100.210.198 port 56780 ssh2 +Sep 30 12:21:00 ip-172-31-43-28 sshd[22808]: Failed password for invalid user hadoop from 103.100.210.198 port 56781 ssh2 +Sep 30 12:21:33 ip-172-31-43-28 sshd[22809]: Failed password for invalid user hadoop from 103.100.210.198 port 56782 ssh2 +Sep 30 12:22:00 ip-172-31-43-28 sshd[22810]: Failed password for invalid user hadoop from 103.100.210.198 port 56783 ssh2 diff --git a/.tests/ssh-time-based-bf/scenario.assert b/.tests/ssh-time-based-bf/scenario.assert index b07bce53ebb..bc9e581761e 100644 --- a/.tests/ssh-time-based-bf/scenario.assert +++ b/.tests/ssh-time-based-bf/scenario.assert @@ -1,36 +1,44 @@ -len(results) == 2 -"10.0.0.101" in results[0].Overflow.GetSources() -results[0].Overflow.Sources["10.0.0.101"].IP == "10.0.0.101" -results[0].Overflow.Sources["10.0.0.101"].Range == "" -results[0].Overflow.Sources["10.0.0.101"].GetScope() == "Ip" -results[0].Overflow.Sources["10.0.0.101"].GetValue() == "10.0.0.101" +len(results) == 4 +"10.0.0.103" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["10.0.0.103"].IP == "10.0.0.103" +results[0].Overflow.Sources["10.0.0.103"].Range == "" +results[0].Overflow.Sources["10.0.0.103"].GetScope() == "Ip" +results[0].Overflow.Sources["10.0.0.103"].GetValue() == "10.0.0.103" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" -results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.101" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.103" results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "root" -results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T11:00:00Z" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T13:00:00Z" basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[1].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" -results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.101" -results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "mysql" -results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T11:20:00Z" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.103" +results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "admin" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T13:00:02Z" basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[2].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" -results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.101" -results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "oracle" -results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T11:40:00Z" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.103" +results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "test" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T13:00:04Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" +results[0].Overflow.Alert.Events[3].GetMeta("machine") == "server" +results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "10.0.0.103" +results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "guest" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-09-30T14:00:04Z" results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-time-based-bf_user-enum" results[0].Overflow.Alert.Remediation == false -results[0].Overflow.Alert.GetEventsCount() == 3 +results[0].Overflow.Alert.GetEventsCount() == 4 "10.0.0.101" in results[1].Overflow.GetSources() results[1].Overflow.Sources["10.0.0.101"].IP == "10.0.0.101" results[1].Overflow.Sources["10.0.0.101"].Range == "" @@ -38,7 +46,7 @@ results[1].Overflow.Sources["10.0.0.101"].GetScope() == "Ip" results[1].Overflow.Sources["10.0.0.101"].GetValue() == "10.0.0.101" basename(results[1].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[1].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[0].GetMeta("machine") == "server" results[1].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.101" @@ -46,7 +54,7 @@ results[1].Overflow.Alert.Events[0].GetMeta("target_user") == "root" results[1].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T11:00:00Z" basename(results[1].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[1].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[1].GetMeta("machine") == "server" results[1].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.101" @@ -54,12 +62,84 @@ results[1].Overflow.Alert.Events[1].GetMeta("target_user") == "mysql" results[1].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T11:20:00Z" basename(results[1].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-time-based-bf.log" results[1].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[1].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[1].Overflow.Alert.Events[2].GetMeta("machine") == "server" results[1].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[1].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.101" results[1].Overflow.Alert.Events[2].GetMeta("target_user") == "oracle" results[1].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T11:40:00Z" -results[1].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-time-based-bf" +results[1].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-time-based-bf_user-enum" results[1].Overflow.Alert.Remediation == false results[1].Overflow.Alert.GetEventsCount() == 3 +"10.0.0.103" in results[2].Overflow.GetSources() +results[2].Overflow.Sources["10.0.0.103"].IP == "10.0.0.103" +results[2].Overflow.Sources["10.0.0.103"].Range == "" +results[2].Overflow.Sources["10.0.0.103"].GetScope() == "Ip" +results[2].Overflow.Sources["10.0.0.103"].GetValue() == "10.0.0.103" +basename(results[2].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[2].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" +results[2].Overflow.Alert.Events[0].GetMeta("machine") == "server" +results[2].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.103" +results[2].Overflow.Alert.Events[0].GetMeta("target_user") == "root" +results[2].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T13:00:00Z" +basename(results[2].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[2].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" +results[2].Overflow.Alert.Events[1].GetMeta("machine") == "server" +results[2].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.103" +results[2].Overflow.Alert.Events[1].GetMeta("target_user") == "admin" +results[2].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T13:00:02Z" +basename(results[2].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[2].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" +results[2].Overflow.Alert.Events[2].GetMeta("machine") == "server" +results[2].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.103" +results[2].Overflow.Alert.Events[2].GetMeta("target_user") == "test" +results[2].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T13:00:04Z" +basename(results[2].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[2].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[2].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" +results[2].Overflow.Alert.Events[3].GetMeta("machine") == "server" +results[2].Overflow.Alert.Events[3].GetMeta("service") == "ssh" +results[2].Overflow.Alert.Events[3].GetMeta("source_ip") == "10.0.0.103" +results[2].Overflow.Alert.Events[3].GetMeta("target_user") == "guest" +results[2].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-09-30T14:00:04Z" +results[2].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-time-based-bf" +results[2].Overflow.Alert.Remediation == false +results[2].Overflow.Alert.GetEventsCount() == 4 +"10.0.0.101" in results[3].Overflow.GetSources() +results[3].Overflow.Sources["10.0.0.101"].IP == "10.0.0.101" +results[3].Overflow.Sources["10.0.0.101"].Range == "" +results[3].Overflow.Sources["10.0.0.101"].GetScope() == "Ip" +results[3].Overflow.Sources["10.0.0.101"].GetValue() == "10.0.0.101" +basename(results[3].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[3].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[3].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" +results[3].Overflow.Alert.Events[0].GetMeta("machine") == "server" +results[3].Overflow.Alert.Events[0].GetMeta("service") == "ssh" +results[3].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.101" +results[3].Overflow.Alert.Events[0].GetMeta("target_user") == "root" +results[3].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-09-30T11:00:00Z" +basename(results[3].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[3].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[3].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" +results[3].Overflow.Alert.Events[1].GetMeta("machine") == "server" +results[3].Overflow.Alert.Events[1].GetMeta("service") == "ssh" +results[3].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.101" +results[3].Overflow.Alert.Events[1].GetMeta("target_user") == "mysql" +results[3].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-09-30T11:20:00Z" +basename(results[3].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "ssh-time-based-bf.log" +results[3].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[3].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" +results[3].Overflow.Alert.Events[2].GetMeta("machine") == "server" +results[3].Overflow.Alert.Events[2].GetMeta("service") == "ssh" +results[3].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.101" +results[3].Overflow.Alert.Events[2].GetMeta("target_user") == "oracle" +results[3].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-09-30T11:40:00Z" +results[3].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-time-based-bf" +results[3].Overflow.Alert.Remediation == false +results[3].Overflow.Alert.GetEventsCount() == 3 diff --git a/.tests/ssh-time-based-bf/ssh-time-based-bf.log b/.tests/ssh-time-based-bf/ssh-time-based-bf.log index d705380659d..c5d792f49bf 100644 --- a/.tests/ssh-time-based-bf/ssh-time-based-bf.log +++ b/.tests/ssh-time-based-bf/ssh-time-based-bf.log @@ -1,10 +1,15 @@ -Sep 30 10:00:00 server sshd[12345]: Invalid user admin from 10.0.0.100 port 56762 -Sep 30 10:06:00 server sshd[12346]: Invalid user test from 10.0.0.100 port 56763 -Sep 30 10:12:00 server sshd[12347]: Invalid user guest from 10.0.0.100 port 56764 -Sep 30 11:00:00 server sshd[12348]: Invalid user root from 10.0.0.101 port 56765 -Sep 30 11:20:00 server sshd[12349]: Invalid user mysql from 10.0.0.101 port 56766 -Sep 30 11:40:00 server sshd[12350]: Invalid user oracle from 10.0.0.101 port 56767 -Sep 30 12:00:00 server sshd[12351]: Invalid user postgres from 10.0.0.102 port 56768 -Sep 30 12:10:00 server sshd[12352]: Invalid user jenkins from 10.0.0.102 port 56769 -Sep 30 12:15:00 server sshd[12353]: Accepted password for jenkins from 10.0.0.102 port 56770 ssh2 -Sep 30 12:20:00 server sshd[12354]: Invalid user admin from 10.0.0.102 port 56771 +Sep 30 10:00:00 server sshd[12345]: Failed password for invalid user admin from 10.0.0.100 port 56762 ssh2 +Sep 30 10:06:00 server sshd[12346]: Failed password for invalid user test from 10.0.0.100 port 56763 ssh2 +Sep 30 10:12:00 server sshd[12347]: Failed password for invalid user guest from 10.0.0.100 port 56764 ssh2 +Sep 30 11:00:00 server sshd[12348]: Failed password for invalid user root from 10.0.0.101 port 56765 ssh2 +Sep 30 11:20:00 server sshd[12349]: Failed password for invalid user mysql from 10.0.0.101 port 56766 ssh2 +Sep 30 11:40:00 server sshd[12350]: Failed password for invalid user oracle from 10.0.0.101 port 56767 ssh2 +Sep 30 12:00:00 server sshd[12351]: Failed password for invalid user postgres from 10.0.0.101 port 56768 ssh2 +Sep 30 12:30:00 server sshd[12352]: Failed password for invalid user admin from 10.0.0.102 port 56769 ssh2 +Sep 30 12:40:00 server sshd[12353]: Failed password for invalid user test from 10.0.0.102 port 56770 ssh2 +Sep 30 12:45:00 server sshd[12354]: Accepted password for test from 10.0.0.102 port 56771 ssh2 +Sep 30 12:50:00 server sshd[12355]: Failed password for invalid user guest from 10.0.0.102 port 56772 ssh2 +Sep 30 13:00:00 server sshd[12356]: Failed password for invalid user root from 10.0.0.103 port 56773 ssh2 +Sep 30 13:00:02 server sshd[12357]: Failed password for invalid user admin from 10.0.0.103 port 56774 ssh2 +Sep 30 13:00:04 server sshd[12358]: Failed password for invalid user test from 10.0.0.103 port 56775 ssh2 +Sep 30 14:00:04 server sshd[12359]: Failed password for invalid user guest from 10.0.0.103 port 56776 ssh2 diff --git a/.tests/sshd-invalid-bf/scenario.assert b/.tests/sshd-invalid-bf/scenario.assert index e9d8b7622bd..64b9b176f16 100644 --- a/.tests/sshd-invalid-bf/scenario.assert +++ b/.tests/sshd-invalid-bf/scenario.assert @@ -6,7 +6,7 @@ results[0].Overflow.Sources["179.43.183.98"].GetScope() == "Ip" results[0].Overflow.Sources["179.43.183.98"].GetValue() == "179.43.183.98" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "179.43.183.98" @@ -14,7 +14,7 @@ results[0].Overflow.Alert.Events[0].GetMeta("target_user") == "root" results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-01-24T15:32:31Z" basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[1].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "179.43.183.98" @@ -22,7 +22,7 @@ results[0].Overflow.Alert.Events[1].GetMeta("target_user") == "root" results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-01-24T15:32:32Z" basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[2].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "179.43.183.98" @@ -30,7 +30,7 @@ results[0].Overflow.Alert.Events[2].GetMeta("target_user") == "root" results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-01-24T15:32:33Z" basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[3].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "179.43.183.98" @@ -38,7 +38,7 @@ results[0].Overflow.Alert.Events[3].GetMeta("target_user") == "root" results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-01-24T15:32:34Z" basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[4].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "179.43.183.98" @@ -46,7 +46,7 @@ results[0].Overflow.Alert.Events[4].GetMeta("target_user") == "root" results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-01-24T15:32:35Z" basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "sshd-invalid-bf.log" results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_password_fail" results[0].Overflow.Alert.Events[5].GetMeta("machine") == "server" results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "179.43.183.98" diff --git a/.tests/sshd-invalid-bf/sshd-invalid-bf.log b/.tests/sshd-invalid-bf/sshd-invalid-bf.log index 30b5631f4e2..8c14cf454a8 100644 --- a/.tests/sshd-invalid-bf/sshd-invalid-bf.log +++ b/.tests/sshd-invalid-bf/sshd-invalid-bf.log @@ -1,6 +1,6 @@ -Jan 24 15:32:31 server sshd[2651912]: Disconnected from authenticating user root 179.43.183.98 port 59402 [preauth] -Jan 24 15:32:32 server sshd[2654543]: Disconnected from authenticating user root 179.43.183.98 port 38260 [preauth] -Jan 24 15:32:33 server sshd[2657307]: Disconnected from authenticating user root 179.43.183.98 port 45326 [preauth] -Jan 24 15:32:34 server sshd[2660116]: Disconnected from authenticating user root 179.43.183.98 port 52414 [preauth] -Jan 24 15:32:35 server sshd[2662890]: Disconnected from authenticating user root 179.43.183.98 port 59502 [preauth] -Jan 24 15:32:36 server sshd[2665707]: Disconnected from authenticating user root 179.43.183.98 port 38346 [preauth] +Jan 24 15:32:31 server sshd[2651912]: Failed password for invalid user root from 179.43.183.98 port 59402 ssh2 +Jan 24 15:32:32 server sshd[2654543]: Failed password for invalid user root from 179.43.183.98 port 38260 ssh2 +Jan 24 15:32:33 server sshd[2657307]: Failed password for invalid user root from 179.43.183.98 port 45326 ssh2 +Jan 24 15:32:34 server sshd[2660116]: Failed password for invalid user root from 179.43.183.98 port 52414 ssh2 +Jan 24 15:32:35 server sshd[2662890]: Failed password for invalid user root from 179.43.183.98 port 59502 ssh2 +Jan 24 15:32:36 server sshd[2665707]: Failed password for invalid user root from 179.43.183.98 port 38346 ssh2 diff --git a/.tests/sshd-logs/parser.assert b/.tests/sshd-logs/parser.assert index 5f42fad3dd9..fe0b5eb389a 100644 --- a/.tests/sshd-logs/parser.assert +++ b/.tests/sshd-logs/parser.assert @@ -251,7 +251,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Parsed["timestamp"] == "Feb 12 14:10:21" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["log_type"] == "ssh_invalid_user" results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["machine"] == "sd-126005" results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][0].Evt.Meta["source_ip"] == "35.188.49.176" @@ -267,7 +267,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Parsed["timestamp"] == "Feb 12 14:10:21" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["log_type"] == "ssh_invalid_user" results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["machine"] == "sd-126005" results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][1].Evt.Meta["source_ip"] == "35.188.49.176" @@ -283,7 +283,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Parsed["timestamp"] == "Feb 12 14:10:21" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["log_type"] == "ssh_invalid_user" results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["machine"] == "sd-126005" results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][2].Evt.Meta["source_ip"] == "35.188.49.176" @@ -302,7 +302,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Parsed["timestamp"] == "N results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Parsed["uid"] == "0" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["log_type"] == "ssh_pam_failure" results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["machine"] == "workshop" results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][3].Evt.Meta["source_ip"] == "5.33.63.160" @@ -320,7 +320,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Parsed["timestamp"] == "N results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Parsed["uid"] == "0" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["log_type"] == "ssh_pam_failure" results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["machine"] == "workshop" results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][4].Evt.Meta["source_ip"] == "5.33.63.161" @@ -335,7 +335,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Parsed["timestamp"] == "Dec 22 14:53:37" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["machine"] == "ip-172-31-20-90" results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][5].Evt.Meta["source_ip"] == "206.81.24.125" @@ -351,7 +351,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Parsed["timestamp"] == "Feb 19 10:38:14" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["machine"] == "myhost" results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][6].Evt.Meta["source_ip"] == "92.255.85.135" @@ -367,7 +367,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Parsed["sshd_invalid_user results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Parsed["timestamp"] == "Feb 19 10:38:14" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["machine"] == "myhost" results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][7].Evt.Meta["source_ip"] == "92.255.85.135" @@ -383,7 +383,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Parsed["sshd_client_ip"] results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Parsed["timestamp"] == "Oct 10 01:48:14" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["log_type"] == "ssh_magic_failed" results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["machine"] == "username" results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][9].Evt.Meta["source_ip"] == "94.232.46.213" @@ -397,7 +397,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Parsed["sshd_client_ip"] results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Parsed["timestamp"] == "Oct 10 01:48:14" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["log_type"] == "ssh_magic_failed" results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["machine"] == "username" results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][10].Evt.Meta["source_ip"] == "94.232.46.213" @@ -412,7 +412,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Parsed["sshd_invalid_use results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Parsed["timestamp"] == "Aug 03 21:39:20" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["machine"] == "hostname" results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][11].Evt.Meta["source_ip"] == "206.81.24.125" @@ -470,7 +470,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Parsed["sshd_invalid_use results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Parsed["timestamp"] == "Feb 8 17:15:01" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["machine"] == "hostname" results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][15].Evt.Meta["source_ip"] == "80.94.92.63" @@ -486,7 +486,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Parsed["sshd_invalid_use results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Parsed["timestamp8601"] == "2023-11-14T00:20:42.738197+01:00" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["log_type"] == "ssh_not_allowed" results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["machine"] == "myserver" results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][16].Evt.Meta["source_ip"] == "192.168.1.1" @@ -504,7 +504,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Parsed["sshd_protocol"] results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Parsed["timestamp"] == "Apr 6 18:51:41" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["log_type"] == "ssh_password_fail" results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["machine"] == "eve" results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][17].Evt.Meta["source_ip"] == "192.168.1.2" @@ -548,7 +548,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Parsed["sshd_invalid_use results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Parsed["timestamp"] == "Feb 12 14:10:24" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["log_type"] == "ssh_invalid_user" results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["machine"] == "sd-126005" results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][20].Evt.Meta["source_ip"] == "192.168.1.3" @@ -563,7 +563,7 @@ results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Parsed["sshd_client_ip"] results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Parsed["timestamp"] == "Nov 19 11:28:15" basename(results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["datasource_path"]) == "sshd-logs.log" results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["datasource_type"] == "file" -results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["log_type"] == "ssh_failed-auth" +results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["log_type"] == "ssh_preauth_close" results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["machine"] == "myhost" results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["service"] == "ssh" results["s01-parse"]["crowdsecurity/sshd-logs"][21].Evt.Meta["source_ip"] == "118.27.24.104" diff --git a/.tests/sshd_banner_exchange/config.yaml b/.tests/sshd_banner_exchange/config.yaml index 3caeef89d75..aa658ca4011 100644 --- a/.tests/sshd_banner_exchange/config.yaml +++ b/.tests/sshd_banner_exchange/config.yaml @@ -1,9 +1,9 @@ parsers: - crowdsecurity/syslog-logs - crowdsecurity/dateparse-enrich -- crowdsecurity/sshd-logs +- ./parsers/s01-parse/crowdsecurity/sshd-logs.yaml scenarios: -- crowdsecurity/ssh-bf +- ./scenarios/crowdsecurity/ssh-scanner.yaml postoverflows: - "" log_file: sshd_banner_exchange.log diff --git a/.tests/sshd_banner_exchange/scenario.assert b/.tests/sshd_banner_exchange/scenario.assert index 0d0efae1a5e..2307d6c23b2 100644 --- a/.tests/sshd_banner_exchange/scenario.assert +++ b/.tests/sshd_banner_exchange/scenario.assert @@ -6,52 +6,32 @@ results[0].Overflow.Sources["59.91.122.57"].GetScope() == "Ip" results[0].Overflow.Sources["59.91.122.57"].GetValue() == "59.91.122.57" basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "sshd_banner_exchange.log" results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[0].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "ssh_bad_banner" results[0].Overflow.Alert.Events[0].GetMeta("machine") == "hostname" results[0].Overflow.Alert.Events[0].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "59.91.122.57" results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-12-01T18:59:33Z" basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "sshd_banner_exchange.log" results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[1].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "ssh_bad_banner" results[0].Overflow.Alert.Events[1].GetMeta("machine") == "hostname" results[0].Overflow.Alert.Events[1].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "59.91.122.57" results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-12-01T18:59:33Z" basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "sshd_banner_exchange.log" results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[2].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "ssh_bad_banner" results[0].Overflow.Alert.Events[2].GetMeta("machine") == "hostname" results[0].Overflow.Alert.Events[2].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "59.91.122.57" results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-12-01T18:59:33Z" basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "sshd_banner_exchange.log" results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[3].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_failed-auth" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "ssh_bad_banner" results[0].Overflow.Alert.Events[3].GetMeta("machine") == "hostname" results[0].Overflow.Alert.Events[3].GetMeta("service") == "ssh" results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "59.91.122.57" results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-12-01T18:59:33Z" -basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "sshd_banner_exchange.log" -results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[4].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "ssh_failed-auth" -results[0].Overflow.Alert.Events[4].GetMeta("machine") == "hostname" -results[0].Overflow.Alert.Events[4].GetMeta("service") == "ssh" -results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "59.91.122.57" -results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-12-01T18:59:33Z" -basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "sshd_banner_exchange.log" -results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" -results[0].Overflow.Alert.Events[5].GetMeta("extra_log_type") == "ssh_bad_banner" -results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "ssh_failed-auth" -results[0].Overflow.Alert.Events[5].GetMeta("machine") == "hostname" -results[0].Overflow.Alert.Events[5].GetMeta("service") == "ssh" -results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "59.91.122.57" -results[0].Overflow.Alert.Events[5].GetMeta("timestamp") == "2026-12-01T18:59:33Z" -results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-bf" +results[0].Overflow.Alert.GetScenario() == "crowdsecurity/ssh-scanner" results[0].Overflow.Alert.Remediation == true -results[0].Overflow.Alert.GetEventsCount() == 6 +results[0].Overflow.Alert.GetEventsCount() == 4 diff --git a/parsers/s01-parse/crowdsecurity/sshd-logs.yaml b/parsers/s01-parse/crowdsecurity/sshd-logs.yaml index 986a7b58563..8e97adad14e 100644 --- a/parsers/s01-parse/crowdsecurity/sshd-logs.yaml +++ b/parsers/s01-parse/crowdsecurity/sshd-logs.yaml @@ -23,90 +23,104 @@ pattern_syntax: SSHD_DISPATCH_FATAL: 'ssh_dispatch_run_fatal: Connection from %{IP_WORKAROUND:sshd_client_ip}( port \d+)?: message authentication code incorrect \[preauth\]' SSHD_REFUSED_CONN: 'refused connect from.*\((::ffff:)?%{IP_WORKAROUND:sshd_client_ip}\)' nodes: + # + # Primary authentication failures - use for brute force detection + # These represent actual password/auth attempts + # - grok: name: "SSHD_FAIL" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_password_fail - meta: target_user expression: "evt.Parsed.sshd_invalid_user" - grok: - name: "SSHD_PREAUTH_AUTHENTICATING_USER_ALT" + name: "SSHD_USER_FAIL" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_password_fail - meta: target_user expression: "evt.Parsed.sshd_invalid_user" + # + # User enumeration - invalid username detection + # Useful for detecting username guessing/enumeration attacks + # - grok: - name: "SSHD_PREAUTH_AUTHENTICATING_USER" + name: "SSHD_INVALID_USER" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_invalid_user - meta: target_user expression: "evt.Parsed.sshd_invalid_user" - grok: - name: "SSHD_DISC_PREAUTH" - apply_on: message - - grok: - name: "SSHD_BAD_VERSION" - apply_on: message - - grok: - name: "SSHD_INVALID_USER" + name: "SSHD_INVALID_USER_ALT" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_invalid_user - meta: target_user expression: "evt.Parsed.sshd_invalid_user" + # + # PAM authentication failure notification + # This is a duplicate notification from PAM, not a separate auth attempt + # - grok: - name: "SSHD_INVALID_USER_ALT" + name: "SSHD_AUTH_FAIL" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_pam_failure - meta: target_user expression: "evt.Parsed.sshd_invalid_user" + # + # Pre-auth connection lifecycle events + # Connection closed/disconnected during authentication phase + # - grok: - name: "SSHD_NOT_ALLOWED_USER" + name: "SSHD_PREAUTH_AUTHENTICATING_USER" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_preauth_close - meta: target_user expression: "evt.Parsed.sshd_invalid_user" - grok: - name: "SSHD_INVALID_BANNER" + name: "SSHD_PREAUTH_AUTHENTICATING_USER_ALT" apply_on: message statics: - meta: log_type - value: ssh_failed-auth - - meta: extra_log_type - value: ssh_bad_banner + value: ssh_preauth_close + - meta: target_user + expression: "evt.Parsed.sshd_invalid_user" + # + # Access control - user not in AllowUsers + # - grok: - name: "SSHD_USER_FAIL" + name: "SSHD_NOT_ALLOWED_USER" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_not_allowed - meta: target_user expression: "evt.Parsed.sshd_invalid_user" + # + # Protocol/scanner detection events + # - grok: - name: "SSHD_AUTH_FAIL" + name: "SSHD_INVALID_BANNER" apply_on: message statics: - meta: log_type - value: ssh_failed-auth - - meta: target_user - expression: "evt.Parsed.sshd_invalid_user" + value: ssh_bad_banner - grok: name: "SSHD_MAGIC_VALUE_FAILED" apply_on: message statics: - meta: log_type - value: ssh_failed-auth + value: ssh_magic_failed - meta: target_user expression: "evt.Parsed.sshd_invalid_user" - grok: @@ -115,6 +129,15 @@ nodes: statics: - meta: log_type value: ssh_bad_keyexchange + # + # Other events (non-auth related) + # + - grok: + name: "SSHD_DISC_PREAUTH" + apply_on: message + - grok: + name: "SSHD_BAD_VERSION" + apply_on: message - grok: name: "SSHD_AUTH_TIMEOUT" apply_on: message diff --git a/scenarios/crowdsecurity/ssh-bf.yaml b/scenarios/crowdsecurity/ssh-bf.yaml index 0cb67f37573..e7731428822 100644 --- a/scenarios/crowdsecurity/ssh-bf.yaml +++ b/scenarios/crowdsecurity/ssh-bf.yaml @@ -2,7 +2,7 @@ type: leaky name: crowdsecurity/ssh-bf description: "Detect ssh bruteforce" -filter: "evt.Meta.log_type == 'ssh_failed-auth'" +filter: "evt.Meta.log_type == 'ssh_password_fail'" leakspeed: "10s" references: - http://wikipedia.com/ssh-bf-is-bad @@ -24,7 +24,7 @@ labels: type: leaky name: crowdsecurity/ssh-bf_user-enum description: "Detect ssh user enum bruteforce" -filter: evt.Meta.log_type == 'ssh_failed-auth' +filter: evt.Meta.log_type == 'ssh_password_fail' groupby: evt.Meta.source_ip distinct: evt.Meta.target_user leakspeed: 10s diff --git a/scenarios/crowdsecurity/ssh-generic-test.yaml b/scenarios/crowdsecurity/ssh-generic-test.yaml index 1a37052d06b..978429c2baf 100644 --- a/scenarios/crowdsecurity/ssh-generic-test.yaml +++ b/scenarios/crowdsecurity/ssh-generic-test.yaml @@ -2,7 +2,7 @@ type: trigger name: crowdsecurity/ssh-generic-test description: "Crowdsec Generic Test Scenario: SSH brute force trigger" -filter: "evt.Meta.log_type == 'ssh_failed-auth' && evt.Meta.target_user == 'crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl'" +filter: "evt.Meta.log_type == 'ssh_password_fail' && evt.Meta.target_user == 'crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl'" groupby: evt.Meta.source_ip blackhole: 1m labels: diff --git a/scenarios/crowdsecurity/ssh-invalid-user.yaml b/scenarios/crowdsecurity/ssh-invalid-user.yaml new file mode 100644 index 00000000000..3000d038032 --- /dev/null +++ b/scenarios/crowdsecurity/ssh-invalid-user.yaml @@ -0,0 +1,40 @@ +# SSH invalid user probing - username enumeration before password stage +type: leaky +name: crowdsecurity/ssh-invalid-user +description: "Detect SSH username probing (invalid user attempts)" +filter: "evt.Meta.log_type == 'ssh_invalid_user'" +leakspeed: "10s" +capacity: 5 +groupby: evt.Meta.source_ip +blackhole: 1m +reprocess: true +labels: + service: ssh + confidence: 2 + spoofable: 0 + classification: + - attack.T1589 + label: "SSH Invalid User Probing" + behavior: "ssh:probe" + remediation: true +--- +# SSH invalid user probing - user enumeration variant +type: leaky +name: crowdsecurity/ssh-invalid-user_user-enum +description: "Detect SSH username enumeration (multiple invalid usernames)" +filter: "evt.Meta.log_type == 'ssh_invalid_user'" +groupby: evt.Meta.source_ip +distinct: evt.Meta.target_user +leakspeed: 10s +capacity: 5 +blackhole: 1m +reprocess: true +labels: + service: ssh + confidence: 3 + spoofable: 0 + classification: + - attack.T1589 + behavior: "ssh:bruteforce" + label: "SSH Username Enumeration" + remediation: true diff --git a/scenarios/crowdsecurity/ssh-not-allowed.yaml b/scenarios/crowdsecurity/ssh-not-allowed.yaml new file mode 100644 index 00000000000..8fbbd39cbc3 --- /dev/null +++ b/scenarios/crowdsecurity/ssh-not-allowed.yaml @@ -0,0 +1,19 @@ +# SSH not allowed - user blocked by AllowUsers directive +type: leaky +name: crowdsecurity/ssh-not-allowed +description: "Detect repeated attempts by users blocked via AllowUsers directive" +filter: "evt.Meta.log_type == 'ssh_not_allowed'" +leakspeed: "30s" +capacity: 3 +groupby: evt.Meta.source_ip +blackhole: 5m +reprocess: true +labels: + service: ssh + confidence: 2 + spoofable: 0 + classification: + - attack.T1110 + label: "SSH Access Denied (AllowUsers)" + behavior: "ssh:bruteforce" + remediation: true diff --git a/scenarios/crowdsecurity/ssh-preauth-scan.yaml b/scenarios/crowdsecurity/ssh-preauth-scan.yaml new file mode 100644 index 00000000000..09cac5b605f --- /dev/null +++ b/scenarios/crowdsecurity/ssh-preauth-scan.yaml @@ -0,0 +1,19 @@ +# SSH preauth disconnect - connection closed before completing auth +type: leaky +name: crowdsecurity/ssh-preauth-scan +description: "Detect SSH scanning via preauth disconnects (connections closed before completing authentication)" +filter: "evt.Meta.log_type == 'ssh_preauth_close'" +leakspeed: "10s" +capacity: 5 +groupby: evt.Meta.source_ip +blackhole: 1m +reprocess: true +labels: + service: ssh + confidence: 2 + spoofable: 0 + classification: + - attack.T1595 + label: "SSH Preauth Scan" + behavior: "ssh:scan" + remediation: true diff --git a/scenarios/crowdsecurity/ssh-scanner.yaml b/scenarios/crowdsecurity/ssh-scanner.yaml new file mode 100644 index 00000000000..64554624a26 --- /dev/null +++ b/scenarios/crowdsecurity/ssh-scanner.yaml @@ -0,0 +1,19 @@ +# SSH scanner detection - protocol anomalies +type: leaky +name: crowdsecurity/ssh-scanner +description: "Detect SSH scanners via protocol anomalies (bad banners, key negotiation failures, obfuscation attempts)" +filter: "evt.Meta.log_type in ['ssh_bad_banner', 'ssh_bad_keyexchange', 'ssh_magic_failed']" +leakspeed: "30s" +capacity: 3 +groupby: evt.Meta.source_ip +blackhole: 5m +reprocess: true +labels: + service: ssh + confidence: 2 + spoofable: 0 + classification: + - attack.T1595 + label: "SSH Scanner" + behavior: "ssh:scan" + remediation: true diff --git a/scenarios/crowdsecurity/ssh-slow-bf.yaml b/scenarios/crowdsecurity/ssh-slow-bf.yaml index 53c8967f550..f55a91087e8 100644 --- a/scenarios/crowdsecurity/ssh-slow-bf.yaml +++ b/scenarios/crowdsecurity/ssh-slow-bf.yaml @@ -2,7 +2,7 @@ type: leaky name: crowdsecurity/ssh-slow-bf description: "Detect slow ssh bruteforce" -filter: "evt.Meta.log_type == 'ssh_failed-auth'" +filter: "evt.Meta.log_type == 'ssh_password_fail'" leakspeed: "60s" references: - http://wikipedia.com/ssh-bf-is-bad @@ -24,7 +24,7 @@ labels: type: leaky name: crowdsecurity/ssh-slow-bf_user-enum description: "Detect slow ssh user enum bruteforce" -filter: evt.Meta.log_type == 'ssh_failed-auth' +filter: evt.Meta.log_type == 'ssh_password_fail' groupby: evt.Meta.source_ip distinct: evt.Meta.target_user leakspeed: 60s diff --git a/scenarios/crowdsecurity/ssh-time-based-bf.yaml b/scenarios/crowdsecurity/ssh-time-based-bf.yaml index c1c798b6296..c117efebe5a 100644 --- a/scenarios/crowdsecurity/ssh-time-based-bf.yaml +++ b/scenarios/crowdsecurity/ssh-time-based-bf.yaml @@ -2,12 +2,12 @@ type: conditional name: crowdsecurity/ssh-time-based-bf description: "Detect time-based ssh bruteforce attempts that evade rate limiting (with false positive reduction)" -filter: "evt.Meta.service == 'ssh' && evt.Meta.log_type in ['ssh_failed-auth', 'auth_success']" +filter: "evt.Meta.service == 'ssh' && evt.Meta.log_type in ['ssh_password_fail', 'auth_success']" groupby: evt.Meta.source_ip capacity: -1 cancel_on: "evt.Meta.log_type == 'auth_success'" condition: | - let failedAuths = filter(queue.Queue, {#.Meta.log_type == 'ssh_failed-auth'}); + let failedAuths = filter(queue.Queue, {#.Meta.log_type == 'ssh_password_fail'}); len(failedAuths) >= 3 && MedianInterval(map(failedAuths[-3:], {#.Time})) > duration("10m") leakspeed: 2h @@ -27,13 +27,13 @@ labels: type: conditional name: crowdsecurity/ssh-time-based-bf_user-enum description: "Detect time-based ssh user enum bruteforce attempts (with false positive reduction)" -filter: "evt.Meta.service == 'ssh' && evt.Meta.log_type in ['ssh_failed-auth', 'auth_success']" +filter: "evt.Meta.service == 'ssh' && evt.Meta.log_type in ['ssh_password_fail', 'auth_success']" groupby: evt.Meta.source_ip distinct: evt.Meta.target_user capacity: -1 cancel_on: "evt.Meta.log_type == 'auth_success'" condition: | - let failedAuths = filter(queue.Queue, {#.Meta.log_type == 'ssh_failed-auth'}); + let failedAuths = filter(queue.Queue, {#.Meta.log_type == 'ssh_password_fail'}); len(failedAuths) >= 3 && MedianInterval(map(failedAuths[-3:], {#.Time})) > duration("10m") leakspeed: 2h