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: