[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#281595: timing attack allows attacker to determine valid usernames



Colin Watson wrote:
20040530
 [...]
 - (dtucker) [auth-pam.c] Use an invalid password for root if
   PermitRootLogin != yes or the login is invalid, to prevent leaking
   information.  Based on Openwall's owl-always-auth patch.  ok djm@

However, that's only PAM password authentication, and
keyboard-interactive is relevant too. Darren, do you happen to know if
kbdint has been fixed in the same way in 3.9p1? I don't see anything
obvious in CVS.

No, it's not fixed in 3.9p1.

The problem is not exactly the same, though. In this case, it's partly because the keyboard-interactive code doesn't call the kbdint driver at all in this case. The first attached patch ought to fix that.

With that fixed, a change to the PAM code is required because it will complete for a real user with their real password if, eg they are listed in DenyUsers. This will result in the PAM code getting out of sync with the kbdint code, resulting in the authentication hanging. The second patch ought to fix that.

I haven't done much testing of either patch, so please let me know how they go.

--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Index: auth2-chall.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth2-chall.c,v
retrieving revision 1.21
diff -u -p -r1.21 auth2-chall.c
--- auth2-chall.c	1 Jun 2004 14:20:45 -0000	1.21
+++ auth2-chall.c	6 Jul 2004 12:13:10 -0000
@@ -268,12 +268,9 @@ input_userauth_info_response(int type, u
 	}
 	packet_check_eom();
 
-	if (authctxt->valid) {
-		res = kbdintctxt->device->respond(kbdintctxt->ctxt,
-		    nresp, response);
-	} else {
-		res = -1;
-	}
+	res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
+	if (!authctxt->valid)
+		res = 1;	/* keep going if login invalid */
 
 	for (i = 0; i < nresp; i++) {
 		memset(response[i], 'r', strlen(response[i]));
@@ -285,7 +282,7 @@ input_userauth_info_response(int type, u
 	switch (res) {
 	case 0:
 		/* Success! */
-		authenticated = 1;
+		authenticated = authctxt->valid ? 1 : 0;
 		break;
 	case 1:
 		/* Authentication needs further interaction */
Index: auth-pam.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
retrieving revision 1.118
diff -u -p -r1.118 auth-pam.c
--- auth-pam.c	16 Oct 2004 08:52:44 -0000	1.118
+++ auth-pam.c	20 Nov 2004 02:40:58 -0000
@@ -186,6 +186,7 @@ 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
@@ -746,7 +747,10 @@ sshpam_respond(void *ctx, u_int num, cha
 		return (-1);
 	}
 	buffer_init(&buffer);
-	buffer_put_cstring(&buffer, *resp);
+	if (sshpam_authctxt->valid)
+		buffer_put_cstring(&buffer, *resp);
+	else
+		buffer_put_cstring(&buffer, badpw);
 	if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
 		buffer_free(&buffer);
 		return (-1);
@@ -1093,7 +1097,6 @@ sshpam_auth_passwd(Authctxt *authctxt, c
 {
 	int flags = (options.permit_empty_passwd == 0 ?
 	    PAM_DISALLOW_NULL_AUTHTOK : 0);
-	static char badpw[] = "\b\n\r\177INCORRECT";
 
 	if (!options.use_pam || sshpam_handle == NULL)
 		fatal("PAM: %s called when PAM disabled or failed to "

Reply to: