diff --git a/.tests/mailu-front/config.yaml b/.tests/mailu-front/config.yaml new file mode 100644 index 00000000000..bfe74145a7d --- /dev/null +++ b/.tests/mailu-front/config.yaml @@ -0,0 +1,11 @@ +parsers: + - crowdsecurity/syslog-logs + - ./parsers/s01-parse/ruokki/mailu-front-logs.yaml + - crowdsecurity/dateparse-enrich + +scenarios: + - ./scenarios/ruokki/mailu-front.yaml +postoverflows: + - "" +log_file: mailu-front.log +log_type: mailu-front diff --git a/.tests/mailu-front/mailu-front.log b/.tests/mailu-front/mailu-front.log new file mode 100644 index 00000000000..e6f4b1c2ac5 --- /dev/null +++ b/.tests/mailu-front/mailu-front.log @@ -0,0 +1,11 @@ +2025/03/30 04:06:16 [info] 13#13: *282145 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "valerie@test.com" +2025/03/30 04:06:48 [info] 13#13: *282155 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "vanessa@test.com" +2025/03/30 04:07:24 [info] 13#13: *282165 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "verify@test.com" +2025/03/30 04:07:55 [info] 13#13: *282175 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "veronica@test.com" +2025/03/30 04:08:27 [info] 13#13: *282187 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "victor@test.com" +2025/03/30 04:08:59 [info] 13#13: *282197 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "victoria@test.com" +2025/03/30 04:09:28 [info] 13#13: *282207 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "video@test.com" +2025/03/30 04:10:02 [info] 13#13: *282217 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "videochat@test.com" +2025/03/30 04:10:35 [info] 13#13: *282227 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "vince@test.com" +2025/03/30 04:11:06 [info] 13#13: *282237 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "vincent@test.com" +2025/03/30 04:11:38 [info] 13#13: *282249 client login failed: "AUTH not supported" while in http auth state, client: 10.0.0.1, server: 0.0.0.0:25, login: "violeta@test.com" \ No newline at end of file diff --git a/.tests/mailu-front/parser.assert b/.tests/mailu-front/parser.assert new file mode 100644 index 00000000000..bb6a6243f25 --- /dev/null +++ b/.tests/mailu-front/parser.assert @@ -0,0 +1,16 @@ + + +len(results["s01-parse"]["ruokki/mailu-front"]) == 11 +results["s01-parse"]["ruokki/mailu-front"][0].Success == true +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Parsed["source_ip"] == "10.0.0.1" +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Parsed["time"] == "2025/03/30 04:06:16" +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Parsed["loglevel"] == "info" + +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Meta["source_ip"] == "10.0.0.1" +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Meta["log_type"] == "mailu-front" +results["s01-parse"]["ruokki/mailu-front"][0].Evt.Meta["sub_type"] == "auth_fail" + +results["s01-parse"]["ruokki/mailu-front"][0].Evt.StrTime == "2025/03/30 04:06:16" + +results["s02-enrich"]["crowdsecurity/dateparse-enrich"][0].Success == true +results["s02-enrich"]["crowdsecurity/dateparse-enrich"][0].Evt.Enriched["MarshaledTime"] == "2025-03-30T04:06:16Z" diff --git a/.tests/mailu-front/scenario.assert b/.tests/mailu-front/scenario.assert new file mode 100644 index 00000000000..3981f513395 --- /dev/null +++ b/.tests/mailu-front/scenario.assert @@ -0,0 +1,45 @@ +len(results) == 1 +"10.0.0.1" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["10.0.0.1"].IP == "10.0.0.1" +results[0].Overflow.Sources["10.0.0.1"].Range == "" +results[0].Overflow.Sources["10.0.0.1"].GetScope() == "Ip" +results[0].Overflow.Sources["10.0.0.1"].GetValue() == "10.0.0.1" +basename(results[0].Overflow.Alert.Events[0].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[0].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2025-03-30T04:06:48Z" +basename(results[0].Overflow.Alert.Events[1].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[1].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2025-03-30T04:07:24Z" +basename(results[0].Overflow.Alert.Events[2].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[2].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[2].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[2].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2025-03-30T04:07:55Z" +basename(results[0].Overflow.Alert.Events[3].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[3].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2025-03-30T04:08:27Z" +basename(results[0].Overflow.Alert.Events[4].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[4].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[4].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[4].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2025-03-30T04:08:59Z" +basename(results[0].Overflow.Alert.Events[5].GetMeta("datasource_path")) == "mailu-front.log" +results[0].Overflow.Alert.Events[5].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[5].GetMeta("log_type") == "mailu-front" +results[0].Overflow.Alert.Events[5].GetMeta("source_ip") == "10.0.0.1" +results[0].Overflow.Alert.Events[5].GetMeta("sub_type") == "auth_fail" +results[0].Overflow.Alert.Events[5].GetMeta("timestamp") == "2025-03-30T04:09:28Z" +results[0].Overflow.Alert.GetScenario() == "ruokki/mailu-front-bf" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 7 \ No newline at end of file diff --git a/collections/ruokki/mailu-front.md b/collections/ruokki/mailu-front.md new file mode 100755 index 00000000000..8179594728a --- /dev/null +++ b/collections/ruokki/mailu-front.md @@ -0,0 +1,14 @@ +A collection to defend your [Mailu-front](https://github.com/Mailu/Mailu) instance against common attacks: + - Mailu-front parser + - Mailu-front brute-force detection + +## Acquisition template + +Example acquisition for this collection: +```yaml +--- +source: file +labels: + type: mailu-front +``` +Depending on your installation method, you may need to change the acquisition template. diff --git a/collections/ruokki/mailu-front.yaml b/collections/ruokki/mailu-front.yaml new file mode 100755 index 00000000000..0a9c59584df --- /dev/null +++ b/collections/ruokki/mailu-front.yaml @@ -0,0 +1,6 @@ +parsers: +- ruokki/mailu-front +scenarios: +- ruokki/mailu-front +description: "Collection including parsers and scenarios mailu-front" +author: ruokki diff --git a/parsers/s01-parse/ruokki/mailu-front-logs.md b/parsers/s01-parse/ruokki/mailu-front-logs.md new file mode 100644 index 00000000000..94139ea7ea7 --- /dev/null +++ b/parsers/s01-parse/ruokki/mailu-front-logs.md @@ -0,0 +1,15 @@ +# Description + +A parser that will search for unauthorized access to mailu front. + +## Acquisition template + +Example acquisition for this collection: + +```yaml +--- +filenames: + - /var/log/mailu-front/*.log +labels: + type: mailu-front +``` diff --git a/parsers/s01-parse/ruokki/mailu-front-logs.yaml b/parsers/s01-parse/ruokki/mailu-front-logs.yaml new file mode 100644 index 00000000000..186fe7e15d0 --- /dev/null +++ b/parsers/s01-parse/ruokki/mailu-front-logs.yaml @@ -0,0 +1,19 @@ +filter: "evt.Parsed.program startsWith 'mailu-front'" +onsuccess: next_stage +name: ruokki/mailu-front +description: "Parse mailu-front service log" +grok: + #our grok pattern : capture .* + pattern: '^%{NGINXERRTIME:time} \[%{LOGLEVEL:loglevel}\] %{NONNEGINT:pid}#%{NONNEGINT:tid}: \*%{NONNEGINT:cid} client login failed: "AUTH not supported" while in http auth state, client: %{IP:source_ip}, server: %{IP:destination_ip}:%{POSINT:port_server}, login: "%{EMAILADDRESS:user_mail}"' + #pattern: ^%{DATA:some_data}$ + #the field to which we apply the grok pattern : the log message itself + apply_on: message +statics: + - meta: source_ip + expression: evt.Parsed.source_ip + - meta: log_type + value: mailu-front + - target: evt.StrTime + expression: evt.Parsed.time + - meta: sub_type + value: auth_fail diff --git a/scenarios/ruokki/mailu-front.md b/scenarios/ruokki/mailu-front.md new file mode 100755 index 00000000000..4921f80fd38 --- /dev/null +++ b/scenarios/ruokki/mailu-front.md @@ -0,0 +1,3 @@ +Detect failed authentications for Mailu front : + +leakspeed of 1m, capacity of 5, blackhole of 5m on source ip diff --git a/scenarios/ruokki/mailu-front.yaml b/scenarios/ruokki/mailu-front.yaml new file mode 100755 index 00000000000..fdd896d4f7d --- /dev/null +++ b/scenarios/ruokki/mailu-front.yaml @@ -0,0 +1,18 @@ +# Dockge Bruteforce +type: leaky +name: ruokki/mailu-front-bf +description: "Mailu Front Bruteforce" +filter: evt.Meta.log_type == 'mailu-front' && evt.Meta.sub_type== 'auth_fail' +groupby: evt.Meta.source_ip +leakspeed: 2m +capacity: 5 +labels: + service: mailu-front + classification: + - attack.T1110 + behavior: "pop3/imap:bruteforce" + confidence: 3 + spoofable: 0 + label: "Mailu-front Bruteforce" + remediation: true +