Bugtraq mailing list archives
recovering ssh passwords from memory
From: Matt Power <mhpower () MIT EDU>
Date: Thu, 3 Aug 2000 18:04:54 -0400
If you use the ssh-1.2.30 ssh client on Solaris 8, a password typed for password authentication can often be partially recovered from the client process memory long afterwards, using pcat (from the TCT distribution). As far as I know, the problem is that ssh reads the password using fgets, and the program happens to not subsequently overwrite the relevant memory locations used by that stdio buffer. (It overwrites the main password buffer, but not the stdio buffer.) Here's a workaround that appears to address the issue for Solaris 8: *** ssh-1.2.30/readpass.c.old Wed Jul 5 11:26:50 2000 --- ssh-1.2.30/readpass.c Thu Aug 3 15:46:11 2000 *************** *** 94,96 **** { ! char buf[1024], *cp; unsigned char quoted_prompt[512]; --- 94,96 ---- { ! char buf[1024], *cp, *fs; unsigned char quoted_prompt[512]; *************** *** 223,225 **** /* Read the passphrase from the terminal. */ ! if (fgets(buf, sizeof(buf), f) == NULL) { --- 223,228 ---- /* Read the passphrase from the terminal. */ ! buf[0] = '\0'; ! fs = fgets(buf, sizeof(buf), f); ! memset(f->_base, 0, strlen(buf)); ! if (fs == NULL) { Note that this is not portable. If you wanted to use a similar approach on other systems, you might need to use f->_IO_read_base rather than f->_base. Also, you could instead modify the code so that read(2) is used for password input, avoiding stdio completely. Here are the results I have so far: on Solaris 8, if this password data is recoverable at all, the pcat output file will apparently always have at least the first four characters of the password. (It's easy to determine which four characters come from the password, so I don't think I need to outline that here.) Knowing four characters will sometimes help a lot with manual guessing of the full password, and provide a significant "workfactor reduction" if you're able to launch an exhaustive search attack. I don't have a general model of process memory use/reuse that explains why only four characters are present. On Red Hat Linux 6.2 i386, in many tries I've never seen any obvious part of a login password in the ssh process memory. This does not, however, mean that Linux keeps you safe from someone who gains root access and wants to find out what login or encryption passwords you typed in the past. They can instead sometimes recover passwords from the portions of /dev/mem corresponding to kernel tty->read_buf's long after the password was typed (there might be a similar level of tty-buffer risks with the kernel on Solaris or other systems; I haven't checked). To prevent this, you can modify the kernel -- I happen to put a "memset(tty->read_buf, 0, N_TTY_BUF_SIZE);" before the "return retval;" line in the function read_chan in linux/drivers/char/n_tty.c, along with some heuristic conditional logic for when that memset statement will be executed. Also, nothing is present in a tty->read_buf for passwords entered using a non-tty X application such as ssh-askpass, and in many tries I've not been able to recover ssh-askpass passwords from /dev/mem after the ssh-askpass process exits. You can use ssh-askpass for non-ssh tasks, e.g., "ssh-askpass | gpg --passphrase-fd 0 -aest -r mhpower () mit edu file" (this is not a good idea if your X setup provides any possible way for an unauthorized person to grab your keystrokes). Matt Power mhpower () mit edu
Current thread:
- recovering ssh passwords from memory Matt Power (Aug 04)
- Re: recovering ssh passwords from memory Theo de Raadt (Aug 06)
- <Possible follow-ups>
- Re: recovering ssh passwords from memory Scott Long (Aug 14)