Package: libpam-modules Version: 1.1.3-7.1 Severity: normal Tags: security, patch
After hashing the user's password with crypt(), pam_userdb compares the result to the stored hash case-insensitively with strncasecmp(). Hashes are case-sensitive and must be compared in this way. Comparing a hash case-insensitively leads to accepting hashes for completely different passwords which shouldn't be accepted. Traditional crypt() produces a 13-character string, and with each character allowed to be one of two cases (roughly), the number of passwords that need to be tried in a brute-force attack could be reduced by a factor of as much as 2^13 = 8192.
Additionally, using data.dsize as the length parameter for strncasecmp() means that crypt() results that are longer than data.dsize but whose first data.dsize characters are a match will pass, yet they shouldn't. This problem is less important while pam_userdb supports only traditional 13-character crypt() but it would become important if bug#671740 were fixed, so it may as well be solved at the same time.
-kv
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c index 11b0d6b..37af682 100644 --- a/modules/pam_userdb/pam_userdb.c +++ b/modules/pam_userdb/pam_userdb.c @@ -227,7 +227,11 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, cryptpw = crypt (pass, salt); if (cryptpw) { - compare = strncasecmp (data.dptr, cryptpw, data.dsize); + if (strlen(cryptpw) != data.dsize) { + compare = -1; + } else { + compare = memcmp (data.dptr, cryptpw, data.dsize); + } } else { compare = -2; if (ctrl & PAM_DEBUG_ARG) {