[openssh-commits] [openssh] 01/01: Determine appropriate salt for invalid users.

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Jul 15 13:46:13 AEST 2016


This is an automated email from the git hooks/post-receive script.

dtucker pushed a commit to branch master
in repository openssh.

commit 9286875a73b2de7736b5e50692739d314cd8d9dc
Author: Darren Tucker <dtucker at zip.com.au>
Date:   Fri Jul 15 13:32:45 2016 +1000

    Determine appropriate salt for invalid users.
    
    When sshd is processing a non-PAM login for a non-existent user it uses
    the string from the fakepw structure as the salt for crypt(3)ing the
    password supplied by the client.  That string has a Blowfish prefix, so on
    systems that don't understand that crypt will fail fast due to an invalid
    salt, and even on those that do it may have significantly different timing
    from the hash methods used for real accounts (eg sha512).  This allows
    user enumeration by, eg, sending large password strings.  This was noted
    by EddieEzra.Harari at verint.com (CVE-2016-6210).
    
    To mitigate, use the same hash algorithm that root uses for hashing
    passwords for users that do not exist on the system.  ok djm@
---
 auth-passwd.c           | 12 ++++++++----
 openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/auth-passwd.c b/auth-passwd.c
index 63ccf3c..530b5d4 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -193,7 +193,7 @@ int
 sys_auth_passwd(Authctxt *authctxt, const char *password)
 {
 	struct passwd *pw = authctxt->pw;
-	char *encrypted_password;
+	char *encrypted_password, *salt = NULL;
 
 	/* Just use the supplied fake password if authctxt is invalid */
 	char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
@@ -202,9 +202,13 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
 	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
 		return (1);
 
-	/* Encrypt the candidate password using the proper salt. */
-	encrypted_password = xcrypt(password,
-	    (pw_password[0] && pw_password[1]) ? pw_password : "xx");
+	/*
+	 * Encrypt the candidate password using the proper salt, or pass a
+	 * NULL and let xcrypt pick one.
+	 */
+	if (authctxt->valid && pw_password[0] && pw_password[1])
+		salt = pw_password;
+	encrypted_password = xcrypt(password, salt);
 
 	/*
 	 * Authentication is accepted if the encrypted passwords
diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
index 8577cbd..8913bb8 100644
--- a/openbsd-compat/xcrypt.c
+++ b/openbsd-compat/xcrypt.c
@@ -25,6 +25,7 @@
 #include "includes.h"
 
 #include <sys/types.h>
+#include <string.h>
 #include <unistd.h>
 #include <pwd.h>
 
@@ -62,11 +63,44 @@
 #  define crypt DES_crypt
 # endif
 
+/*
+ * Pick an appropriate password encryption type and salt for the running
+ * system.
+ */
+static const char *
+pick_salt(void)
+{
+	struct passwd *pw;
+	char *passwd, *p;
+	size_t typelen;
+	static char salt[32];
+
+	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));
+	return salt;
+}
+
 char *
 xcrypt(const char *password, const char *salt)
 {
 	char *crypted;
 
+	/*
+	 * If we don't have a salt we are encrypting a fake password for
+	 * for timing purposes.  Pick an appropriate salt.
+	 */
+	if (salt == NULL)
+		salt = pick_salt();
+
 # ifdef HAVE_MD5_PASSWORDS
         if (is_md5_salt(salt))
                 crypted = md5_crypt(password, salt);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list