diff --git a/.tests/matrix-wellknown-probing/config.yaml b/.tests/matrix-wellknown-probing/config.yaml new file mode 100644 index 00000000000..697c7486c50 --- /dev/null +++ b/.tests/matrix-wellknown-probing/config.yaml @@ -0,0 +1,12 @@ +parsers: +- crowdsecurity/syslog-logs +- crowdsecurity/nginx-logs +- crowdsecurity/http-logs +- crowdsecurity/dateparse-enrich +scenarios: +- ./scenarios/adrianrudnik/matrix-wellknown-probing.yaml +postoverflows: +- "" +log_file: matrix-wellknown-probing.log +log_type: nginx +ignore_parsers: true diff --git a/.tests/matrix-wellknown-probing/matrix-wellknown-probing.log b/.tests/matrix-wellknown-probing/matrix-wellknown-probing.log new file mode 100644 index 00000000000..f899fd07ee9 --- /dev/null +++ b/.tests/matrix-wellknown-probing/matrix-wellknown-probing.log @@ -0,0 +1,6 @@ +127.0.0.1 - - [29/Dec/2024:17:11:38 +0000] "GET /.well-known/matrix/server HTTP/2.0" 404 48 "-" "Conduwuit/0.5.0 (e123456 🥴🦴🏳️⚧️)" +127.0.0.2 - - [29/Dec/2024:17:11:39 +0200] "GET /.well-known/matrix/client HTTP/1.0" 404 48 "-" "Go-http-client/2.0" +127.0.0.3 - - [29/Dec/2024:17:11:41 +0000] "GET /.well-known/something HTTP/1.0" 404 48 "-" "Go-http-client/2.0" +127.0.0.4 - - [29/Dec/2024:17:11:42 +0000] "GET /index.html HTTP/1.0" 404 48 "-" "Conduwuit/0.5.0 (e123456 🥴🦴🏳️⚧️)" +127.0.0.5 - - [29/Dec/2024:17:11:43 +0000] "GET / HTTP/2.0" 404 48 "-" "Conduwuit/0.5.0 (e897654 🥴🦴🏳️⚧️)" +127.0.0.6 - - [29/Dec/2024:17:11:40 +0000] "GET /.well-known/matrix/server HTTP/3.0" 404 48 "-" "Conduwuit/0.5.0 (f000000 🥴🦴🏳️⚧️)" \ No newline at end of file diff --git a/.tests/matrix-wellknown-probing/scenario.assert b/.tests/matrix-wellknown-probing/scenario.assert new file mode 100644 index 00000000000..44a8afc8db7 --- /dev/null +++ b/.tests/matrix-wellknown-probing/scenario.assert @@ -0,0 +1,42 @@ +len(results) == 2 + +"127.0.0.6" in results[0].Overflow.GetSources() +results[0].Overflow.Sources["127.0.0.6"].IP == "127.0.0.6" +results[0].Overflow.Sources["127.0.0.6"].Range == "" +results[0].Overflow.Sources["127.0.0.6"].GetScope() == "Ip" +results[0].Overflow.Sources["127.0.0.6"].GetValue() == "127.0.0.6" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_path") == "matrix-wellknown-probing.log" +results[0].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[0].Overflow.Alert.Events[0].GetMeta("http_args_len") == "0" +results[0].Overflow.Alert.Events[0].GetMeta("http_path") == "/.well-known/matrix/server" +results[0].Overflow.Alert.Events[0].GetMeta("http_status") == "404" +results[0].Overflow.Alert.Events[0].GetMeta("http_user_agent") == "Conduwuit/0.5.0 (f000000 🥴🦴🏳️⚧️)" +results[0].Overflow.Alert.Events[0].GetMeta("http_verb") == "GET" +results[0].Overflow.Alert.Events[0].GetMeta("log_type") == "http_access-log" +results[0].Overflow.Alert.Events[0].GetMeta("service") == "http" +results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "127.0.0.6" +results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2024-12-29T17:11:40Z" +results[0].Overflow.Alert.GetScenario() == "adrianrudnik/matrix-wellknown-probing" +results[0].Overflow.Alert.Remediation == true +results[0].Overflow.Alert.GetEventsCount() == 1 + +"127.0.0.1" in results[1].Overflow.GetSources() +results[1].Overflow.Sources["127.0.0.1"].IP == "127.0.0.1" +results[1].Overflow.Sources["127.0.0.1"].Range == "" +results[1].Overflow.Sources["127.0.0.1"].GetScope() == "Ip" +results[1].Overflow.Sources["127.0.0.1"].GetValue() == "127.0.0.1" +results[1].Overflow.Alert.Events[0].GetMeta("datasource_path") == "matrix-wellknown-probing.log" +results[1].Overflow.Alert.Events[0].GetMeta("datasource_type") == "file" +results[1].Overflow.Alert.Events[0].GetMeta("http_args_len") == "0" +results[1].Overflow.Alert.Events[0].GetMeta("http_path") == "/.well-known/matrix/server" +results[1].Overflow.Alert.Events[0].GetMeta("http_status") == "404" +results[1].Overflow.Alert.Events[0].GetMeta("http_user_agent") == "Conduwuit/0.5.0 (e123456 🥴🦴🏳️⚧️)" +results[1].Overflow.Alert.Events[0].GetMeta("http_verb") == "GET" +results[1].Overflow.Alert.Events[0].GetMeta("log_type") == "http_access-log" +results[1].Overflow.Alert.Events[0].GetMeta("service") == "http" +results[1].Overflow.Alert.Events[0].GetMeta("source_ip") == "127.0.0.1" +results[1].Overflow.Alert.Events[0].GetMeta("timestamp") == "2024-12-29T17:11:38Z" +results[1].Overflow.Alert.GetScenario() == "adrianrudnik/matrix-wellknown-probing" +results[1].Overflow.Alert.Remediation == true +results[1].Overflow.Alert.GetEventsCount() == 1 + diff --git a/scenarios/adrianrudnik/matrix-wellknown-probing.md b/scenarios/adrianrudnik/matrix-wellknown-probing.md new file mode 100644 index 00000000000..b0eb2ba4d86 --- /dev/null +++ b/scenarios/adrianrudnik/matrix-wellknown-probing.md @@ -0,0 +1,13 @@ +## Synapse Matrix Servers: Known/Server Requests + +Prohibit Matrix servers from sending requests to the current server endpoints, even if the server no longer exists (decommissioned) or never existed (inherited/re-registered domain). + +More details at + +- https://github.com/element-hq/synapse/issues/3765 +- https://github.com/element-hq/synapse/issues/5442 +- https://github.com/element-hq/synapse/issues/17739 + +There does not seem to be a viable way to tell matrix network servers to stop sending these queries, hence this scenario to ban IP sources making these endless queries. Depending on the number of channels/servers the old server was connected to, this can be a significant number of requests per day. + +There does not seem to be a viable way to tell matrix network servers to stop sending these queries, hence this scenario to ban IP sources making these endless queries. diff --git a/scenarios/adrianrudnik/matrix-wellknown-probing.yaml b/scenarios/adrianrudnik/matrix-wellknown-probing.yaml new file mode 100644 index 00000000000..ae2ba8e2ec4 --- /dev/null +++ b/scenarios/adrianrudnik/matrix-wellknown-probing.yaml @@ -0,0 +1,19 @@ +type: trigger +#debug: true +name: adrianrudnik/matrix-wellknown-probing +description: "Detect matrix .well-known probing" +filter: | + evt.Meta.log_type in ['http_access-log', 'http_error-log'] and + evt.Meta.http_status == '404' and + Upper(evt.Meta.http_path) contains Upper('/.well-known/matrix/server') +groupby: evt.Meta.source_ip +blackhole: 5m +labels: + service: http + remediation: true + confidence: 3 + spoofable: 0 + classification: + - attack.T1498 + behavior: "http:dos" + label: "HTTP DOS by matrix servers inquiring about possible server"