From abb012ae5c90c4bfc2b83512bc168f1ecaa0d10e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 10:00:37 -0800 Subject: [PATCH 1/3] BF: fixing injection for OpenSSH 6.3 -- making .* before non-greedy --- config/filter.d/sshd.conf | 2 +- testcases/files/logs/sshd | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index 08456177..be80b02f 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -14,7 +14,7 @@ _daemon = sshd failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from ( via \S+)?\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$ - ^%(__prefix_line)sFailed \S+ for .* from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ + ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM \s*$ ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from \s*$ ^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers\s*$ diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index 96338220..def0ebb5 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -94,3 +94,7 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 port 45785 ssh2: DSA 01:c0:79:41:91:31:9a:7d:95:23:91:ac:b1:6d:59:81, client user "dan", client host "localhost.localdomain" + +# Injecting into rhost for the format of OpenSSH >=6.3 +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } +Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 From 750e0c1e3dbce856437c115142d57f18b6c1fac7 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 10:06:24 -0800 Subject: [PATCH 2/3] BF: disallow exploiting of non-greedy .* in previous fix by providing too long rhost -- do not impose length limits for user-provided input since daemon might eventually change reported length and we would need to adjust anyways. So limiting in length does not provide additional security but allows for a possible injection vector --- ChangeLog | 2 +- config/filter.d/sshd.conf | 2 +- testcases/files/logs/sshd | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d9d1a96..5120c139 100644 --- a/ChangeLog +++ b/ChangeLog @@ -78,7 +78,7 @@ some obscure corner of the Internet. * filter.d/recidive -- support f2b syslog target and anchor regex at start * filter.d/mysqld-auth.conf - mysql can use syslog * filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian - bug #722970 + bug #722970. Thanks Colin Watson for the regex analysis. * filter.d/wuftpd - regex enhancements to support pam and wuftpd. Closes Debian bug #665925 Rolf Fokkens diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index be80b02f..d97fd675 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -14,7 +14,7 @@ _daemon = sshd failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from ( via \S+)?\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$ - ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ + ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$ ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM \s*$ ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from \s*$ ^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers\s*$ diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index def0ebb5..4f862d89 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -95,6 +95,8 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 port 45785 ssh2: DSA 01:c0:79:41:91:31:9a:7d:95:23:91:ac:b1:6d:59:81, client user "dan", client host "localhost.localdomain" -# Injecting into rhost for the format of OpenSSH >=6.3 -# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting into rhost for the format of OpenSSH >=6.3" } Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 + +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting while exhausting initially present {0,100} match length limits set for ruser etc" } +Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX from 1.2.3.4 From bf245f9640e3a957f1deb751f9eb28742f957107 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 14:34:31 -0800 Subject: [PATCH 3/3] DOC: adding DEV Notes for for non-greedy matchin within sshd.conf --- config/filter.d/sshd.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index d97fd675..a36b050c 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -26,4 +26,11 @@ failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|erro ignoreregex = +# DEV Notes: +# +# "Failed \S+ for .*? from ..." failregex uses non-greedy catch-all because +# it is coming before use of which is not hard-anchored at the end as well, +# and later catch-all's could contain user-provided input, which need to be greedily +# matched away first. +# # Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black