115 lines
3.6 KiB
Diff
115 lines
3.6 KiB
Diff
From e5ef9d3942cebda819a6fd81647b51c8d87d23df Mon Sep 17 00:00:00 2001
|
|
From: Darren Tucker <dtucker@zip.com.au>
|
|
Date: Fri, 15 Jul 2016 13:32:45 +1000
|
|
Subject: 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@
|
|
|
|
Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b5e50692739d314cd8d9dc
|
|
Bug-Debian: https://bugs.debian.org/831902
|
|
Last-Update: 2016-07-22
|
|
|
|
Patch-Name: CVE-2016-6210-1.patch
|
|
---
|
|
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);
|