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) {

Reply via email to