From 4d5c2775514cf60967f2d5976eae0bc9d4134a5f Mon Sep 17 00:00:00 2001 From: PrOOnOOb Date: Fri, 10 Apr 2026 13:19:13 +0200 Subject: [PATCH 1/2] feat: add OpenVPN parser and bruteforce scenario --- parsers/s01-parse/proonoob/openvpn.yaml | 35 +++++++++++++++++++++++++ scenarios/proonoob/openvpn-bf.yaml | 12 +++++++++ 2 files changed, 47 insertions(+) create mode 100644 parsers/s01-parse/proonoob/openvpn.yaml create mode 100644 scenarios/proonoob/openvpn-bf.yaml diff --git a/parsers/s01-parse/proonoob/openvpn.yaml b/parsers/s01-parse/proonoob/openvpn.yaml new file mode 100644 index 00000000000..1da3eea9b91 --- /dev/null +++ b/parsers/s01-parse/proonoob/openvpn.yaml @@ -0,0 +1,35 @@ +filter: "evt.Line.Labels.type == 'openvpn'" +onsuccess: next_stage +name: proonoob/openvpn +description: "Parse OpenVPN logs (supports both syslog and ISO8601 timestamp formats)" +pattern_syntax: + OPENVPN_TLS_CRYPT: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: TLS Error: tls-crypt unwrapping failed from \\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" + OPENVPN_AUTH_FAILED: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: AUTH: Received control message: AUTH_FAILED.*\\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" + OPENVPN_TLS_HANDSHAKE: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: TLS Error: TLS handshake failed" + OPENVPN_VERIFY_ERROR: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: VERIFY ERROR" + OPENVPN_CATCHALL: "%{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA}" +nodes: + - grok: + name: "OPENVPN_TLS_CRYPT" + apply_on: message + - grok: + name: "OPENVPN_AUTH_FAILED" + apply_on: message + - grok: + name: "OPENVPN_TLS_HANDSHAKE" + apply_on: message + - grok: + name: "OPENVPN_VERIFY_ERROR" + apply_on: message + - grok: + name: "OPENVPN_CATCHALL" + apply_on: message +statics: + - meta: service + value: openvpn + - meta: source_ip + expression: "evt.Parsed.source_ip" + - meta: log_type + value: auth_failed + - target: evt.StrTime + expression: "evt.Parsed.timestamp" diff --git a/scenarios/proonoob/openvpn-bf.yaml b/scenarios/proonoob/openvpn-bf.yaml new file mode 100644 index 00000000000..8ac1d2f4aba --- /dev/null +++ b/scenarios/proonoob/openvpn-bf.yaml @@ -0,0 +1,12 @@ +type: leaky +name: proonoob/openvpn-bf +description: "Detect OpenVPN probing and bruteforce attempts via TLS errors" +filter: "evt.Meta.service == 'openvpn' && evt.Meta.log_type == 'auth_failed'" +groupby: "evt.Meta.source_ip" +capacity: 2 +leakspeed: "5m" +blackhole: "1m" +labels: + service: openvpn + type: bruteforce + remediation: true From 1a9d6f2d373ee3d9aebda0340efa1e0e4cc658f8 Mon Sep 17 00:00:00 2001 From: PrOOnOOb Date: Fri, 10 Apr 2026 13:33:44 +0200 Subject: [PATCH 2/2] feat: add tests, docs, collection and fix parser for OpenVPN --- .tests/openvpn-logs/config.yaml | 9 ++ .tests/openvpn-logs/openvpn-logs.log | 5 + .tests/openvpn-logs/parser.assert | 128 ++++++++++++++++++++++++ .tests/openvpn-logs/scenario.assert | 1 + collections/proonoob/openvpn.yaml | 7 ++ parsers/s01-parse/proonoob/openvpn.md | 22 ++++ parsers/s01-parse/proonoob/openvpn.yaml | 14 ++- scenarios/proonoob/openvpn-bf.md | 14 +++ scenarios/proonoob/openvpn-bf.yaml | 6 ++ 9 files changed, 198 insertions(+), 8 deletions(-) create mode 100644 .tests/openvpn-logs/config.yaml create mode 100644 .tests/openvpn-logs/openvpn-logs.log create mode 100644 .tests/openvpn-logs/parser.assert create mode 100644 .tests/openvpn-logs/scenario.assert create mode 100644 collections/proonoob/openvpn.yaml create mode 100644 parsers/s01-parse/proonoob/openvpn.md create mode 100644 scenarios/proonoob/openvpn-bf.md diff --git a/.tests/openvpn-logs/config.yaml b/.tests/openvpn-logs/config.yaml new file mode 100644 index 00000000000..9c80466ea80 --- /dev/null +++ b/.tests/openvpn-logs/config.yaml @@ -0,0 +1,9 @@ +parsers: + - crowdsecurity/syslog-logs + - ./parsers/s01-parse/proonoob/openvpn.yaml +scenarios: + - ./scenarios/proonoob/openvpn-bf.yaml +postoverflows: + - "" +log_file: openvpn-logs.log +log_type: syslog diff --git a/.tests/openvpn-logs/openvpn-logs.log b/.tests/openvpn-logs/openvpn-logs.log new file mode 100644 index 00000000000..56a3a0c971f --- /dev/null +++ b/.tests/openvpn-logs/openvpn-logs.log @@ -0,0 +1,5 @@ +2026-04-10T12:00:01.000000+02:00 vpn ovpn-server[4892]: TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:11111 +2026-04-10T12:00:02.000000+02:00 vpn ovpn-server[4892]: TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:22222 +2026-04-10T12:00:03.000000+02:00 vpn ovpn-server[4892]: TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:33333 +2026-04-10T12:00:04.000000+02:00 vpn ovpn-server[4892]: TLS Error: tls-crypt unwrapping failed from [AF_INET]5.6.7.8:44444 +Apr 5 11:26:07 vpn ovpn-server[380]: TLS Error: tls-crypt unwrapping failed from [AF_INET]9.10.11.12:55555 diff --git a/.tests/openvpn-logs/parser.assert b/.tests/openvpn-logs/parser.assert new file mode 100644 index 00000000000..a13e9380dfe --- /dev/null +++ b/.tests/openvpn-logs/parser.assert @@ -0,0 +1,128 @@ +len(results["s00-raw"]["crowdsecurity/syslog-logs"]) == 5 +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Success == true +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Parsed["logsource"] == "syslog" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:11111" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Parsed["pid"] == "4892" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Parsed["program"] == "ovpn-server" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:01.000000+02:00" +basename(results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Meta["datasource_type"] == "file" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Meta["machine"] == "vpn" +results["s00-raw"]["crowdsecurity/syslog-logs"][0].Evt.Whitelisted == false +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Success == true +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Parsed["logsource"] == "syslog" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:22222" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Parsed["pid"] == "4892" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Parsed["program"] == "ovpn-server" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:02.000000+02:00" +basename(results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Meta["datasource_type"] == "file" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Meta["machine"] == "vpn" +results["s00-raw"]["crowdsecurity/syslog-logs"][1].Evt.Whitelisted == false +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Success == true +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Parsed["logsource"] == "syslog" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:33333" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Parsed["pid"] == "4892" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Parsed["program"] == "ovpn-server" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:03.000000+02:00" +basename(results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Meta["datasource_type"] == "file" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Meta["machine"] == "vpn" +results["s00-raw"]["crowdsecurity/syslog-logs"][2].Evt.Whitelisted == false +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Success == true +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Parsed["logsource"] == "syslog" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]5.6.7.8:44444" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Parsed["pid"] == "4892" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Parsed["program"] == "ovpn-server" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:04.000000+02:00" +basename(results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Meta["datasource_type"] == "file" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Meta["machine"] == "vpn" +results["s00-raw"]["crowdsecurity/syslog-logs"][3].Evt.Whitelisted == false +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Success == true +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Parsed["logsource"] == "syslog" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]9.10.11.12:55555" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Parsed["pid"] == "380" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Parsed["program"] == "ovpn-server" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Parsed["timestamp"] == "Apr 5 11:26:07" +basename(results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Meta["datasource_type"] == "file" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Meta["machine"] == "vpn" +results["s00-raw"]["crowdsecurity/syslog-logs"][4].Evt.Whitelisted == false +len(results["s01-parse"]["proonoob/openvpn"]) == 5 +results["s01-parse"]["proonoob/openvpn"][0].Success == true +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["logsource"] == "syslog" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:11111" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["pid"] == "4892" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["program"] == "ovpn-server" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["sport"] == "11111" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:01.000000+02:00" +basename(results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["datasource_type"] == "file" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["log_type"] == "auth_failed" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["machine"] == "vpn" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["service"] == "openvpn" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Meta["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][0].Evt.Whitelisted == false +results["s01-parse"]["proonoob/openvpn"][1].Success == true +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["logsource"] == "syslog" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:22222" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["pid"] == "4892" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["program"] == "ovpn-server" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["sport"] == "22222" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:02.000000+02:00" +basename(results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["datasource_type"] == "file" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["log_type"] == "auth_failed" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["machine"] == "vpn" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["service"] == "openvpn" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Meta["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][1].Evt.Whitelisted == false +results["s01-parse"]["proonoob/openvpn"][2].Success == true +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["logsource"] == "syslog" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]1.2.3.4:33333" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["pid"] == "4892" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["program"] == "ovpn-server" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["sport"] == "33333" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:03.000000+02:00" +basename(results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["datasource_type"] == "file" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["log_type"] == "auth_failed" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["machine"] == "vpn" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["service"] == "openvpn" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Meta["source_ip"] == "1.2.3.4" +results["s01-parse"]["proonoob/openvpn"][2].Evt.Whitelisted == false +results["s01-parse"]["proonoob/openvpn"][3].Success == true +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["logsource"] == "syslog" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]5.6.7.8:44444" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["pid"] == "4892" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["program"] == "ovpn-server" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["source_ip"] == "5.6.7.8" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["sport"] == "44444" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Parsed["timestamp8601"] == "2026-04-10T12:00:04.000000+02:00" +basename(results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["datasource_type"] == "file" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["log_type"] == "auth_failed" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["machine"] == "vpn" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["service"] == "openvpn" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Meta["source_ip"] == "5.6.7.8" +results["s01-parse"]["proonoob/openvpn"][3].Evt.Whitelisted == false +results["s01-parse"]["proonoob/openvpn"][4].Success == true +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["logsource"] == "syslog" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["message"] == "TLS Error: tls-crypt unwrapping failed from [AF_INET]9.10.11.12:55555" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["pid"] == "380" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["program"] == "ovpn-server" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["source_ip"] == "9.10.11.12" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["sport"] == "55555" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Parsed["timestamp"] == "Apr 5 11:26:07" +basename(results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["datasource_path"]) == "openvpn-logs.log" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["datasource_type"] == "file" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["log_type"] == "auth_failed" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["machine"] == "vpn" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["service"] == "openvpn" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Meta["source_ip"] == "9.10.11.12" +results["s01-parse"]["proonoob/openvpn"][4].Evt.Whitelisted == false +len(results["success"][""]) == 0 diff --git a/.tests/openvpn-logs/scenario.assert b/.tests/openvpn-logs/scenario.assert new file mode 100644 index 00000000000..03455618a29 --- /dev/null +++ b/.tests/openvpn-logs/scenario.assert @@ -0,0 +1 @@ +len(results) == 0 diff --git a/collections/proonoob/openvpn.yaml b/collections/proonoob/openvpn.yaml new file mode 100644 index 00000000000..b85276a27ab --- /dev/null +++ b/collections/proonoob/openvpn.yaml @@ -0,0 +1,7 @@ +name: proonoob/openvpn +description: "OpenVPN parser and bruteforce detection" +author: proonoob +parsers: + - proonoob/openvpn +scenarios: + - proonoob/openvpn-bf diff --git a/parsers/s01-parse/proonoob/openvpn.md b/parsers/s01-parse/proonoob/openvpn.md new file mode 100644 index 00000000000..f7a62afb071 --- /dev/null +++ b/parsers/s01-parse/proonoob/openvpn.md @@ -0,0 +1,22 @@ +## Overview + +Parser for OpenVPN server logs. Supports both legacy syslog and modern ISO8601 timestamp formats. + +## Configuration + +Add to /etc/crowdsec/acquis.d/openvpn.yaml + +## Detected Events + +- auth_failed: TLS tls-crypt unwrapping failed (scanner/probe without valid key) +- auth_failed: AUTH_FAILED (failed authentication) +- auth_failed: TLS handshake failed +- auth_failed: Certificate VERIFY ERROR + +## Log formats supported + +Legacy syslog: +Apr 5 11:26:07 vpn ovpn-server[380]: TLS Error: tls-crypt unwrapping failed from [AF_INET]182.200.116.38:38382 + +Modern ISO8601: +2026-04-10T12:17:48.771346+02:00 vpn ovpn-server[448]: TLS Error: tls-crypt unwrapping failed from [AF_INET]182.200.116.38:38382 diff --git a/parsers/s01-parse/proonoob/openvpn.yaml b/parsers/s01-parse/proonoob/openvpn.yaml index 1da3eea9b91..74f24018569 100644 --- a/parsers/s01-parse/proonoob/openvpn.yaml +++ b/parsers/s01-parse/proonoob/openvpn.yaml @@ -1,13 +1,13 @@ -filter: "evt.Line.Labels.type == 'openvpn'" +filter: "evt.Parsed.program == 'ovpn-server'" onsuccess: next_stage name: proonoob/openvpn description: "Parse OpenVPN logs (supports both syslog and ISO8601 timestamp formats)" pattern_syntax: - OPENVPN_TLS_CRYPT: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: TLS Error: tls-crypt unwrapping failed from \\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" - OPENVPN_AUTH_FAILED: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: AUTH: Received control message: AUTH_FAILED.*\\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" - OPENVPN_TLS_HANDSHAKE: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: TLS Error: TLS handshake failed" - OPENVPN_VERIFY_ERROR: "%{TIMESTAMP_ISO8601:timestamp} %{HOSTNAME} %{NOTSPACE}: VERIFY ERROR" - OPENVPN_CATCHALL: "%{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA}" + OPENVPN_TLS_CRYPT: "TLS Error: tls-crypt unwrapping failed from \\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" + OPENVPN_AUTH_FAILED: "AUTH: Received control message: AUTH_FAILED.*\\[AF_INET\\]%{IPV4:source_ip}:%{INT:sport}" + OPENVPN_TLS_HANDSHAKE: "TLS Error: TLS handshake failed" + OPENVPN_VERIFY_ERROR: "VERIFY ERROR" + OPENVPN_CATCHALL: "%{GREEDYDATA}" nodes: - grok: name: "OPENVPN_TLS_CRYPT" @@ -31,5 +31,3 @@ statics: expression: "evt.Parsed.source_ip" - meta: log_type value: auth_failed - - target: evt.StrTime - expression: "evt.Parsed.timestamp" diff --git a/scenarios/proonoob/openvpn-bf.md b/scenarios/proonoob/openvpn-bf.md new file mode 100644 index 00000000000..d93e47816c3 --- /dev/null +++ b/scenarios/proonoob/openvpn-bf.md @@ -0,0 +1,14 @@ +## Overview + +Detects IPs performing OpenVPN TLS bruteforce or probing attacks. +Bans IPs that trigger 3 or more TLS errors within 15 minutes. + +## Configuration + +Requires the proonoob/openvpn parser. + +## Behavior + +- Trigger: 3 TLS errors +- Time window: 15 minutes +- Remediation: ban diff --git a/scenarios/proonoob/openvpn-bf.yaml b/scenarios/proonoob/openvpn-bf.yaml index 8ac1d2f4aba..3174fc4771a 100644 --- a/scenarios/proonoob/openvpn-bf.yaml +++ b/scenarios/proonoob/openvpn-bf.yaml @@ -10,3 +10,9 @@ labels: service: openvpn type: bruteforce remediation: true + confidence: 3 + spoofable: 0 + behavior: "openvpn:bruteforce" + label: "OpenVPN TLS bruteforce/probing" + classification: + - attack.T1110