Discussion:
Openssh use enumeration
(too old to reply)
C0r3dump3d
2016-07-19 13:10:48 UTC
Permalink
Hi, sorry I don't know if I send this to the correct channel.

I have notice that OpenSSH has recognized the presence of the user
enumeration as a vulnerability,
http://seclists.org/fulldisclosure/2016/Jul/51 (CVE-2016-6210).

I want to make an appreciation, this is a old vulnerability
already announced three years ago.

https://blog.curesec.com/article/blog/OpenSSH-User-Enumeration-Time-Based-Attack-20.html


http://seclists.org/fulldisclosure/2013/Jul/88

http://www.behindthefirewalls.com/2014/07/openssh-user-enumeration-time-based.html

I would like to point out that there is another vulnerability present in
the bug, it's possible in certain circumstances to provoke a DOS
condition in the access to the ssh server, I made a brief study of this
possibility here:

https://www.devconsole.info/?p=382

and included this attack in my tool that exploit this vulnerability:

https://github.com/c0r3dump3d/osueta

It's necessary to request another CVE-ID for the DOS attack?

At least, I think it should be clarified in the announce of the
vulnerability.

Regards.
Darren Tucker
2016-07-21 01:45:38 UTC
Permalink
Post by C0r3dump3d
Hi, sorry I don't know if I send this to the correct channel.
It is.

[..]
Post by C0r3dump3d
it's possible in certain circumstances to provoke a DOS
condition in the access to the ssh server.
We have been discussing this a bit, and what we have just added is a
simple hard limit on the allowed size of a password string at 1k,
above which the password is immediately refused. There's other
possible embellishments (eg, add a possibly variable delay) but we
haven't decided on any yet.

Thanks.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Selphie Keller
2016-07-21 02:18:57 UTC
Permalink
I thought this was already addressed with the internal blowfish hash of
"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK" to where all
passwords were checked against this to prevent timing analysis for user
enumeration.
Post by Darren Tucker
Post by C0r3dump3d
Hi, sorry I don't know if I send this to the correct channel.
It is.
[..]
Post by C0r3dump3d
it's possible in certain circumstances to provoke a DOS
condition in the access to the ssh server.
We have been discussing this a bit, and what we have just added is a
simple hard limit on the allowed size of a password string at 1k,
above which the password is immediately refused. There's other
possible embellishments (eg, add a possibly variable delay) but we
haven't decided on any yet.
Thanks.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
_______________________________________________
openssh-unix-dev mailing list
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Selphie Keller
2016-07-21 02:31:34 UTC
Permalink
Ahh i see, just got up to speed on the issue, so seems like the issue is
related to blowfish being faster then sha family hashing for longer length
passwords, so there is a time lag difference between the blowfish internal
hash and the sha family hash, though this could be tricky to fix since some
systems may still use blowfish based hashing and changing the internal hash
from blowfish to sha to fix this for modern systems may invalidate it
inversely on older systems, where this attack can be done to find the
difference in the other direction of taking to long. Some sorta of hybrid
solution of computing hashes based on what the system is actively using
should resolve the timing issue. So if this is on a newer system using sha
family for hashing it would use a sha family hash to be the fall back for
accounts and blowfish if it's on a system using blowfish.
Post by Selphie Keller
I thought this was already addressed with the internal blowfish hash of
"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK" to where all
passwords were checked against this to prevent timing analysis for user
enumeration.
Post by Darren Tucker
Post by C0r3dump3d
Hi, sorry I don't know if I send this to the correct channel.
It is.
[..]
Post by C0r3dump3d
it's possible in certain circumstances to provoke a DOS
condition in the access to the ssh server.
We have been discussing this a bit, and what we have just added is a
simple hard limit on the allowed size of a password string at 1k,
above which the password is immediately refused. There's other
possible embellishments (eg, add a possibly variable delay) but we
haven't decided on any yet.
Thanks.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA
(new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
_______________________________________________
openssh-unix-dev mailing list
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Darren Tucker
2016-07-21 02:48:46 UTC
Permalink
On Thu, Jul 21, 2016 at 12:31 PM, Selphie Keller
Post by Selphie Keller
Ahh i see, just got up to speed on the issue, so seems like the issue is
related to blowfish being faster then sha family hashing for longer length
passwords,
or the system's crypt() not understanding $2a$ -style salts, which
most glibcs don't. On those, crypt fails immediately due to invalid
salt.
Post by Selphie Keller
so there is a time lag difference between the blowfish internal
hash and the sha family hash, though this could be tricky to fix since some
systems may still use blowfish based hashing and changing the internal hash
The best I could come up with (which is what I implemented[1]) was to
look the crypt method used for root's password and use that, falling
back to DES if that fails. That scheme won't help if you don't set a
root password (or set it to *LK* or similar), but short of surveying
all accounts on the system I'm not sure how to do much better.

[1] https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b5e50692739d314cd8d9dc
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Selphie Keller
2016-07-21 03:02:57 UTC
Permalink
I wonder if could be useful to set the fall back account to something user
defined to avoid suggesting people add passwords to root, though I do like
root since the account is always there, but I myself would do that invalid
pass before actually adding a real pass to root, however I think it would
be nice if there was a sshd_config option for fallback_timing_account to
let the user specify something other then root like some generic user they
already have that doesn't involve root. Or have ssh create an dummy account
on the system that has only a invalid password. The fall back to DES seems
ok, but not sure it would fully resolve the issue, since timing for DES and
sha family would be different, but does fix the instant fail for crypt not
understanding blowfish. The random delay idea is pretty good it would make
timing analysis difficult. I wonder if DES + random delay in event root has
no password could be an option.
Post by Darren Tucker
On Thu, Jul 21, 2016 at 12:31 PM, Selphie Keller
Post by Selphie Keller
Ahh i see, just got up to speed on the issue, so seems like the issue is
related to blowfish being faster then sha family hashing for longer
length
Post by Selphie Keller
passwords,
or the system's crypt() not understanding $2a$ -style salts, which
most glibcs don't. On those, crypt fails immediately due to invalid
salt.
Post by Selphie Keller
so there is a time lag difference between the blowfish internal
hash and the sha family hash, though this could be tricky to fix since
some
Post by Selphie Keller
systems may still use blowfish based hashing and changing the internal
hash
The best I could come up with (which is what I implemented[1]) was to
look the crypt method used for root's password and use that, falling
back to DES if that fails. That scheme won't help if you don't set a
root password (or set it to *LK* or similar), but short of surveying
all accounts on the system I'm not sure how to do much better.
[1]
https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b5e50692739d314cd8d9dc
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Darren Tucker
2016-07-21 03:18:00 UTC
Permalink
Post by Selphie Keller
I wonder if could be useful to set the fall back account to something user
defined to avoid suggesting people add passwords to root, though I do like
root since the account is always there,
Since committing that diff I've heard of people running in production
with no root password (ie *LK*, !! or similar).

It's about the same amount of code to search for the first account with
a valid salt, which would avoid this problem in the case where the root
account doesn't have a real password.

djm: what do you think?

diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
index 8913bb8..5385243 100644
--- a/openbsd-compat/xcrypt.c
+++ b/openbsd-compat/xcrypt.c
@@ -78,14 +78,18 @@ pick_salt(void)
if (salt[0] != '\0')
return salt;
strlcpy(salt, "xx", sizeof(salt));
- if ((pw = getpwuid(0)) == NULL)
- return salt;
- passwd = shadow_pw(pw);
- if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL)
- return salt; /* no $, DES */
- typelen = p - passwd + 1;
- strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
- explicit_bzero(passwd, strlen(passwd));
+ setpwent();
+ while ((pw = getpwent()) != NULL) {
+ passwd = shadow_pw(pw);
+ if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) {
+ typelen = p - passwd + 1;
+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
+ explicit_bzero(passwd, strlen(passwd));
+ goto out;
+ }
+ }
+ out:
+ endpwent();
return salt;
}
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Selphie Keller
2016-07-21 03:34:07 UTC
Permalink
yeah I like this idea, fixes the issue with blowfish hashes and non root
passwords, maybe random delay as the final fall back if no salts/passwords
are found. Seems rare, but I do have one box that I use ssh keys on and
none of the accounts have a hash set, but I also don't have password auth
enabled.
Post by Darren Tucker
Post by Selphie Keller
I wonder if could be useful to set the fall back account to something
user
Post by Selphie Keller
defined to avoid suggesting people add passwords to root, though I do
like
Post by Selphie Keller
root since the account is always there,
Since committing that diff I've heard of people running in production
with no root password (ie *LK*, !! or similar).
It's about the same amount of code to search for the first account with
a valid salt, which would avoid this problem in the case where the root
account doesn't have a real password.
djm: what do you think?
diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
index 8913bb8..5385243 100644
--- a/openbsd-compat/xcrypt.c
+++ b/openbsd-compat/xcrypt.c
@@ -78,14 +78,18 @@ pick_salt(void)
if (salt[0] != '\0')
return salt;
strlcpy(salt, "xx", sizeof(salt));
- if ((pw = getpwuid(0)) == NULL)
- return salt;
- passwd = shadow_pw(pw);
- if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL)
- return salt; /* no $, DES */
- typelen = p - passwd + 1;
- strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
- explicit_bzero(passwd, strlen(passwd));
+ setpwent();
+ while ((pw = getpwent()) != NULL) {
+ passwd = shadow_pw(pw);
+ if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) !=
NULL) {
+ typelen = p - passwd + 1;
+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
+ explicit_bzero(passwd, strlen(passwd));
+ goto out;
+ }
+ }
+ endpwent();
return salt;
}
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Darren Tucker
2016-07-21 03:48:03 UTC
Permalink
On Thu, Jul 21, 2016 at 1:34 PM, Selphie Keller
Post by Selphie Keller
yeah I like this idea, fixes the issue with blowfish hashes and non root
passwords, maybe random delay as the final fall back if no salts/passwords
are found.
Well if there are no accounts with a valid salt then there's also no
valid account to compare the timing of invalid accounts against.
Worst case that'd be DES crypt vs empty password and I'm not sure if
you'd be able to pick that out of the background crypto.
Post by Selphie Keller
Seems rare, but I do have one box that I use ssh keys on and none
of the accounts have a hash set, but I also don't have password auth
enabled.
IMO random delays are overrated for mitigating timing attacks; you can
look for inconsistent behaviour as the indicator of whatever you're
looking for.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Morham Anthelleron
2016-07-21 04:00:51 UTC
Permalink
Post by Darren Tucker
Since committing that diff I've heard of people running in production
with no root password (ie *LK*, !! or similar).
It's about the same amount of code to search for the first account with
a valid salt, which would avoid this problem in the case where the root
account doesn't have a real password.
djm: what do you think?
Since OpenSSH already makes use of an unprivileged user for privsep, why not
take the next step of setting a (long) random password for it using the
system's normal shadow password routines?

If one is concerned about an accidentally "successful" login, you could
perturb the supplied passphrase prior to passing it down to the authentication
library to ensure a successful entry is impossible.

Alternately, a second "dummy" account that's not used at all by the system
which is a chroot jail with nothing in it with a random password?

This way no bizarre system assumptions need be made, and it accommodates the
wide range of "policy" preferences for the bulk of the userbase.

=M=
Darren Tucker
2016-07-21 04:16:14 UTC
Permalink
On Thu, Jul 21, 2016 at 2:00 PM, Morham Anthelleron
<***@r.paypc.com> wrote:
[...]
Post by Morham Anthelleron
Since OpenSSH already makes use of an unprivileged user for privsep, why not
take the next step of setting a (long) random password for it using the
system's normal shadow password routines?
Assuming you mean putpwent(): that requires an encrypted string to put
in pw_passwd putting us right back where we started.
Post by Morham Anthelleron
If one is concerned about an accidentally "successful" login, you could
perturb the supplied passphrase prior to passing it down to the authentication
library to ensure a successful entry is impossible.
Alternately, a second "dummy" account that's not used at all by the system
which is a chroot jail with nothing in it with a random password?
If we could reliably come up with the encrypted string to put in that
dummy account we wouldn't need the dummy account.

Actually setting a password is quite system dependent. exec'ing
/bin/passwd in most cases needs a controlling terminal although some
have flags for reading form stdin. Using pam_chauthtok() would
require making assumptions about what the prompts were. Some systems
enforce complexity (as opposed to entropy) requirements. And then
you'd have an account with a password that you're not quite sure where
it came from.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Darren Tucker
2016-07-21 04:27:04 UTC
Permalink
On Thu, Jul 21, 2016 at 1:48 PM, Darren Tucker <***@zip.com.au> wrote:
[...]
Post by Darren Tucker
Well if there are no accounts with a valid salt then there's also no
valid account to compare the timing of invalid accounts against.
Worst case that'd be DES crypt vs empty password and I'm not sure if
you'd be able to pick that out of the background crypto.
I just measured the speed of DES crypt on a somewhat elderly 2.1GHz
Xeon X3210 at about 7 microseconds. Good luck picking that out of
Diffie-Hellman exchange over a network.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Selphie Keller
2016-07-21 04:36:58 UTC
Permalink
Darren, If you have time could you try the actual tool against the new
patch curious to see how it stands up https://github.com/c0r3dump3d/osueta
Post by Darren Tucker
[...]
Post by Darren Tucker
Well if there are no accounts with a valid salt then there's also no
valid account to compare the timing of invalid accounts against.
Worst case that'd be DES crypt vs empty password and I'm not sure if
you'd be able to pick that out of the background crypto.
I just measured the speed of DES crypt on a somewhat elderly 2.1GHz
Xeon X3210 at about 7 microseconds. Good luck picking that out of
Diffie-Hellman exchange over a network.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Fiedler Roman
2016-07-21 07:59:53 UTC
Permalink
From: openssh-unix-dev
I wonder if could be useful to set the fall back account to something user
defined to avoid suggesting people add passwords to root, though I do like
root since the account is always there, but I myself would do that invalid
pass before actually adding a real pass to root, however I think it would
be nice if there was a sshd_config option for fallback_timing_account to
let the user specify something other then root like some generic user they
already have that doesn't involve root. Or have ssh create an dummy
account
on the system that has only a invalid password. The fall back to DES seems
ok, but not sure it would fully resolve the issue, since timing for DES
and
sha family would be different, but does fix the instant fail for crypt not
understanding blowfish. The random delay idea is pretty good it would make
timing analysis difficult. I wonder if DES + random delay in event root
has
no password could be an option.
Why not use the settings from /etc/login.defs?

# If set to MD5 , MD5-based algorithm will be used for encrypting password
# If set to SHA256, SHA256-based algorithm will be used for encrypting
password
# If set to SHA512, SHA512-based algorithm will be used for encrypting
password
# If set to DES, DES-based algorithm will be used for encrypting password
(default)
# Overrides the MD5_CRYPT_ENAB option
#
# Note: It is recommended to use a value consistent with
# the PAM modules configuration.
#
ENCRYPT_METHOD SHA512

/usr/bin/passwd from "shadow" package goes down the same way when setting
passwords. So perhaps following code would be hard to do timing analysis
for:

* Get default hash method from login.def
* Get/create a fake crypted passwd for the method/salt being default.
* Get the pwent for the user name requested
* When user not found: get the entry for root and discard the result
* When user check succeeded: get the entry for the user "nonexisting:xxxx" -
I think ':' is forbidden, so name should never exist (TODO: check side
effects)
* Compare the supplied passwd with the fake or real hash
* Do what has to be done.

What do you think? Only easy timing attacks should be on systems where
DefaultMethod!=all password methods, which could be deemed a configuration
error.

Roman
Post by Darren Tucker
On Thu, Jul 21, 2016 at 12:31 PM, Selphie Keller
Post by Selphie Keller
Ahh i see, just got up to speed on the issue, so seems like the issue
is
Post by Darren Tucker
Post by Selphie Keller
related to blowfish being faster then sha family hashing for longer
length
Post by Selphie Keller
passwords,
or the system's crypt() not understanding $2a$ -style salts, which
most glibcs don't. On those, crypt fails immediately due to invalid
salt.
Post by Selphie Keller
so there is a time lag difference between the blowfish internal
hash and the sha family hash, though this could be tricky to fix since
some
Post by Selphie Keller
systems may still use blowfish based hashing and changing the internal
hash
The best I could come up with (which is what I implemented[1]) was to
look the crypt method used for root's password and use that, falling
back to DES if that fails. That scheme won't help if you don't set a
root password (or set it to *LK* or similar), but short of surveying
all accounts on the system I'm not sure how to do much better.
[1]
https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b
5e50692739d314cd8d9dc
Darren Tucker
2016-07-21 08:36:23 UTC
Permalink
Post by Fiedler Roman
Why not use the settings from /etc/login.defs?
That's (I think) Linux only. FreeBSD has /etc/login.conf which is a
different format. No idea what Solaris has but it doesn't seem to be
either of those. No idea about the other dozen or more platforms we
run on.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Loading...