diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2016-07-20 12:56:11 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2016-07-20 12:56:11 +0000 |
commit | 685ffe83039b198cd8f173421c6be85aedcb07f6 (patch) | |
tree | 9798b16f061c8f1e2b3cb55ce3e393acb65ecc93 /main/openssh | |
parent | 9740a41188bb15081b4fca6af1205c0316299100 (diff) | |
download | aports-685ffe83039b198cd8f173421c6be85aedcb07f6.tar.bz2 aports-685ffe83039b198cd8f173421c6be85aedcb07f6.tar.xz |
main/openssh: security fix for CVE-2016-6210
Diffstat (limited to 'main/openssh')
-rw-r--r-- | main/openssh/APKBUILD | 12 | ||||
-rw-r--r-- | main/openssh/CVE-2016-6210.patch | 219 |
2 files changed, 227 insertions, 4 deletions
diff --git a/main/openssh/APKBUILD b/main/openssh/APKBUILD index 93977fbe77..ee7f675779 100644 --- a/main/openssh/APKBUILD +++ b/main/openssh/APKBUILD @@ -3,7 +3,7 @@ pkgname=openssh pkgver=7.2_p2 _myver=${pkgver%_*}${pkgver#*_} -pkgrel=0 +pkgrel=1 pkgdesc="Port of OpenBSD's free SSH release" url="http://www.openssh.org/portable.html" arch="all" @@ -23,6 +23,7 @@ source="http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/$pkgname-$_myver.tar sshd.initd sshd.confd openssh-sftp-interactive.diff + CVE-2016-6210.patch " # HPN patches are from: http://www.psc.edu/index.php/hpn-ssh @@ -116,7 +117,8 @@ cd52fe99cb4b7d0d847bf5d710d93564 openssh6.5-peaktput.diff e21243d6ddff1bb929eed3676b4b9a2a bsd-compatible-realpath.patch 8590e08286f47a777725655873dd318f sshd.initd b35e9f3829f4cfca07168fcba98749c7 sshd.confd -2dd7e366607e95f9762273067309fd6e openssh-sftp-interactive.diff" +2dd7e366607e95f9762273067309fd6e openssh-sftp-interactive.diff +baccdaf19767102c91343742cc09ebc9 CVE-2016-6210.patch" sha256sums="a72781d1a043876a224ff1b0032daa4094d87565a68528759c1c2cab5482548c openssh-7.2p2.tar.gz bf49212e47a86d10650f739532cea514a310925e6445b4f8011031b6b55f3249 openssh6.5-peaktput.diff 861132af07c18f5e0ac7b64f389a929e61a051887bf44bda770a97e3afd9bfb6 openssh7.1-dynwindows.diff @@ -124,7 +126,8 @@ bf49212e47a86d10650f739532cea514a310925e6445b4f8011031b6b55f3249 openssh6.5-pea a843cacd7002a68e9d09b5d8ea1466c9980fa35fa3ccd8d9357ac793017de2a6 bsd-compatible-realpath.patch c31a116bba900c6c4795b061766169e6455d6e1b7cf9aa2ee5ba4eaa1afa76b0 sshd.initd 29c6d57ac3ec6018cadc6ba6cd9b90c9ed46e20049b970fdcc68ee2481a2ee41 sshd.confd -4ce1ad5f767c0f4e854a0cfeef0e2e400f333c649e552df1ecc317e6a6557376 openssh-sftp-interactive.diff" +4ce1ad5f767c0f4e854a0cfeef0e2e400f333c649e552df1ecc317e6a6557376 openssh-sftp-interactive.diff +53ee8c957e9dd3bb51fe629d04e6373c6e4b62026352463bad916a4e66c00f37 CVE-2016-6210.patch" sha512sums="44f62b3a7bc50a0735d496a5aedeefb71550d8c10ad8f22b94e29fcc8084842db96e8c4ca41fced17af69e1aab09ed1182a12ad8650d9a46fd8743a0344df95b openssh-7.2p2.tar.gz e041398e177674f698480e23be037160bd07b751c754956a3ddf1b964da24c85e826fb75e7c23c9826d36761da73d08db9583c047d58a08dc7b2149a949075b1 openssh6.5-peaktput.diff 72a7dc21d18388c635d14dda762ac50caeefd38f0153d8ea36d18e9d7c982e104f7b7a3af8c18fd479c31201fbdee1639f3a1ec60d035d4ca8721a8563fa11a0 openssh7.1-dynwindows.diff @@ -132,4 +135,5 @@ f35fffcd26635249ce5d820e7b3e406e586f2d2d7f6a045f221e2f9fb53aebc1ab1dd1e603b33894 f2b8daa537ea3f32754a4485492cc6eb3f40133ed46c0a5a29a89e4bcf8583d82d891d94bf2e5eb1c916fa68ec094abf4e6cd641e9737a6c05053808012b3a73 bsd-compatible-realpath.patch 7e4378daebd8f5df0cd2f0709af806a0d4a78c948b8fc3baaf3585e5f5ec5d0793f7e4d0a450bc43bbcb92daa09bfab482cbceb396b993c0545adfe56573cd44 sshd.initd b9ae816af54a55e134a9307e376f05367b815f1b3fd545c2a2c312d18aedcf907f413e8bad8db980cdd9aad4011a72a79e1e94594f69500939a9cb46287f2f81 sshd.confd -c1d09c65dbc347f0904edc30f91aa9a24b0baee50309536182455b544f1e3f85a8cecfa959e32be8b101d8282ef06dde3febbbc3f315489339dcf04155c859a9 openssh-sftp-interactive.diff" +c1d09c65dbc347f0904edc30f91aa9a24b0baee50309536182455b544f1e3f85a8cecfa959e32be8b101d8282ef06dde3febbbc3f315489339dcf04155c859a9 openssh-sftp-interactive.diff +202ae2ca83c0caeb0099ca22e7a248053d29cc7751c5b5865004108e4b998d7bf738df8cc0aa138a2b770748e5f90835e707434acd4719ce388181db1dc81ccd CVE-2016-6210.patch" diff --git a/main/openssh/CVE-2016-6210.patch b/main/openssh/CVE-2016-6210.patch new file mode 100644 index 0000000000..c543af3e3a --- /dev/null +++ b/main/openssh/CVE-2016-6210.patch @@ -0,0 +1,219 @@ +From 9286875a73b2de7736b5e50692739d314cd8d9dc 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@ +--- + 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); +-- +cgit v0.12 + +From 283b97ff33ea2c641161950849931bd578de6946 Mon Sep 17 00:00:00 2001 +From: Darren Tucker <dtucker@zip.com.au> +Date: Fri, 15 Jul 2016 13:49:44 +1000 +Subject: Mitigate timing of disallowed users PAM logins. + +When sshd decides to not allow a login (eg PermitRootLogin=no) and +it's using PAM, it sends a fake password to PAM so that the timing for +the failure is not noticeably different whether or not the password +is correct. This behaviour can be detected by sending a very long +password string which is slower to hash than the fake password. + +Mitigate by constructing an invalid password that is the same length +as the one from the client and thus takes the same time to hash. +Diff from djm@ +--- + auth-pam.c | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/auth-pam.c b/auth-pam.c +index 451de78..465b5a7 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -232,7 +232,6 @@ static int sshpam_account_status = -1; + static char **sshpam_env = NULL; + static Authctxt *sshpam_authctxt = NULL; + static const char *sshpam_password = NULL; +-static char badpw[] = "\b\n\r\177INCORRECT"; + + /* Some PAM implementations don't implement this */ + #ifndef HAVE_PAM_GETENVLIST +@@ -795,12 +794,35 @@ sshpam_query(void *ctx, char **name, char **info, + return (-1); + } + ++/* ++ * Returns a junk password of identical length to that the user supplied. ++ * Used to mitigate timing attacks against crypt(3)/PAM stacks that ++ * vary processing time in proportion to password length. ++ */ ++static char * ++fake_password(const char *wire_password) ++{ ++ const char junk[] = "\b\n\r\177INCORRECT"; ++ char *ret = NULL; ++ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; ++ ++ if (l >= INT_MAX) ++ fatal("%s: password length too long: %zu", __func__, l); ++ ++ ret = malloc(l + 1); ++ for (i = 0; i < l; i++) ++ ret[i] = junk[i % (sizeof(junk) - 1)]; ++ ret[i] = '\0'; ++ return ret; ++} ++ + /* XXX - see also comment in auth-chall.c:verify_response */ + static int + sshpam_respond(void *ctx, u_int num, char **resp) + { + Buffer buffer; + struct pam_ctxt *ctxt = ctx; ++ char *fake; + + debug2("PAM: %s entering, %u responses", __func__, num); + switch (ctxt->pam_done) { +@@ -821,8 +843,11 @@ sshpam_respond(void *ctx, u_int num, char **resp) + (sshpam_authctxt->pw->pw_uid != 0 || + options.permit_root_login == PERMIT_YES)) + buffer_put_cstring(&buffer, *resp); +- else +- buffer_put_cstring(&buffer, badpw); ++ else { ++ fake = fake_password(*resp); ++ buffer_put_cstring(&buffer, fake); ++ free(fake); ++ } + if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { + buffer_free(&buffer); + return (-1); +@@ -1166,6 +1191,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + { + int flags = (options.permit_empty_passwd == 0 ? + PAM_DISALLOW_NULL_AUTHTOK : 0); ++ char *fake = NULL; + + if (!options.use_pam || sshpam_handle == NULL) + fatal("PAM: %s called when PAM disabled or failed to " +@@ -1181,7 +1207,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + */ + if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && + options.permit_root_login != PERMIT_YES)) +- sshpam_password = badpw; ++ sshpam_password = fake = fake_password(password); + + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&passwd_conv); +@@ -1191,6 +1217,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) + + sshpam_err = pam_authenticate(sshpam_handle, flags); + sshpam_password = NULL; ++ free(fake); + if (sshpam_err == PAM_SUCCESS && authctxt->valid) { + debug("PAM: password authentication accepted for %.100s", + authctxt->user); +-- +cgit v0.12 + |