diff options
Diffstat (limited to 'debian/patches/CVE-2016-6210-1.patch')
-rw-r--r-- | debian/patches/CVE-2016-6210-1.patch | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/debian/patches/CVE-2016-6210-1.patch b/debian/patches/CVE-2016-6210-1.patch new file mode 100644 index 000000000..9b46ec12a --- /dev/null +++ b/debian/patches/CVE-2016-6210-1.patch | |||
@@ -0,0 +1,114 @@ | |||
1 | From e5ef9d3942cebda819a6fd81647b51c8d87d23df Mon Sep 17 00:00:00 2001 | ||
2 | From: Darren Tucker <dtucker@zip.com.au> | ||
3 | Date: Fri, 15 Jul 2016 13:32:45 +1000 | ||
4 | Subject: Determine appropriate salt for invalid users. | ||
5 | |||
6 | When sshd is processing a non-PAM login for a non-existent user it uses | ||
7 | the string from the fakepw structure as the salt for crypt(3)ing the | ||
8 | password supplied by the client. That string has a Blowfish prefix, so on | ||
9 | systems that don't understand that crypt will fail fast due to an invalid | ||
10 | salt, and even on those that do it may have significantly different timing | ||
11 | from the hash methods used for real accounts (eg sha512). This allows | ||
12 | user enumeration by, eg, sending large password strings. This was noted | ||
13 | by EddieEzra.Harari at verint.com (CVE-2016-6210). | ||
14 | |||
15 | To mitigate, use the same hash algorithm that root uses for hashing | ||
16 | passwords for users that do not exist on the system. ok djm@ | ||
17 | |||
18 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b5e50692739d314cd8d9dc | ||
19 | Bug-Debian: https://bugs.debian.org/831902 | ||
20 | Last-Update: 2016-07-22 | ||
21 | |||
22 | Patch-Name: CVE-2016-6210-1.patch | ||
23 | --- | ||
24 | auth-passwd.c | 12 ++++++++---- | ||
25 | openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++ | ||
26 | 2 files changed, 42 insertions(+), 4 deletions(-) | ||
27 | |||
28 | diff --git a/auth-passwd.c b/auth-passwd.c | ||
29 | index 63ccf3c..530b5d4 100644 | ||
30 | --- a/auth-passwd.c | ||
31 | +++ b/auth-passwd.c | ||
32 | @@ -193,7 +193,7 @@ int | ||
33 | sys_auth_passwd(Authctxt *authctxt, const char *password) | ||
34 | { | ||
35 | struct passwd *pw = authctxt->pw; | ||
36 | - char *encrypted_password; | ||
37 | + char *encrypted_password, *salt = NULL; | ||
38 | |||
39 | /* Just use the supplied fake password if authctxt is invalid */ | ||
40 | char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; | ||
41 | @@ -202,9 +202,13 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) | ||
42 | if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) | ||
43 | return (1); | ||
44 | |||
45 | - /* Encrypt the candidate password using the proper salt. */ | ||
46 | - encrypted_password = xcrypt(password, | ||
47 | - (pw_password[0] && pw_password[1]) ? pw_password : "xx"); | ||
48 | + /* | ||
49 | + * Encrypt the candidate password using the proper salt, or pass a | ||
50 | + * NULL and let xcrypt pick one. | ||
51 | + */ | ||
52 | + if (authctxt->valid && pw_password[0] && pw_password[1]) | ||
53 | + salt = pw_password; | ||
54 | + encrypted_password = xcrypt(password, salt); | ||
55 | |||
56 | /* | ||
57 | * Authentication is accepted if the encrypted passwords | ||
58 | diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c | ||
59 | index 8577cbd..8913bb8 100644 | ||
60 | --- a/openbsd-compat/xcrypt.c | ||
61 | +++ b/openbsd-compat/xcrypt.c | ||
62 | @@ -25,6 +25,7 @@ | ||
63 | #include "includes.h" | ||
64 | |||
65 | #include <sys/types.h> | ||
66 | +#include <string.h> | ||
67 | #include <unistd.h> | ||
68 | #include <pwd.h> | ||
69 | |||
70 | @@ -62,11 +63,44 @@ | ||
71 | # define crypt DES_crypt | ||
72 | # endif | ||
73 | |||
74 | +/* | ||
75 | + * Pick an appropriate password encryption type and salt for the running | ||
76 | + * system. | ||
77 | + */ | ||
78 | +static const char * | ||
79 | +pick_salt(void) | ||
80 | +{ | ||
81 | + struct passwd *pw; | ||
82 | + char *passwd, *p; | ||
83 | + size_t typelen; | ||
84 | + static char salt[32]; | ||
85 | + | ||
86 | + if (salt[0] != '\0') | ||
87 | + return salt; | ||
88 | + strlcpy(salt, "xx", sizeof(salt)); | ||
89 | + if ((pw = getpwuid(0)) == NULL) | ||
90 | + return salt; | ||
91 | + passwd = shadow_pw(pw); | ||
92 | + if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL) | ||
93 | + return salt; /* no $, DES */ | ||
94 | + typelen = p - passwd + 1; | ||
95 | + strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); | ||
96 | + explicit_bzero(passwd, strlen(passwd)); | ||
97 | + return salt; | ||
98 | +} | ||
99 | + | ||
100 | char * | ||
101 | xcrypt(const char *password, const char *salt) | ||
102 | { | ||
103 | char *crypted; | ||
104 | |||
105 | + /* | ||
106 | + * If we don't have a salt we are encrypting a fake password for | ||
107 | + * for timing purposes. Pick an appropriate salt. | ||
108 | + */ | ||
109 | + if (salt == NULL) | ||
110 | + salt = pick_salt(); | ||
111 | + | ||
112 | # ifdef HAVE_MD5_PASSWORDS | ||
113 | if (is_md5_salt(salt)) | ||
114 | crypted = md5_crypt(password, salt); | ||