03 November 2012

shadow passwords with openssl

I once had to break in to a CentOS box, because I'd forgotten root's password and didn't know the passwords to any other users (I think it had been shut down for a while). So I booted with a rescue disc (I think it was a CentOS installation disk, and I typed "linux rescue" at the prompt). The rescue disc mounted the filesystems, and I tried running passwd in a chroot. I got some kind of error message, and it wouldn't reset the password for root in /etc/shadow on the filesystem. I ended up editing /etc/shadow by typing in a password I got out of /etc/shadow on another box.

As I'm writing this, it occurs to me that if I knew the password to some other user (at this point I don't remember if I did or not), I could have just edited /etc/sudoers to give root to that other user, rebooted, logged in as that user, and done "sudo passwd" to reset root's password.

But if you ever need to create /etc/shadow entries by hand for some weird situation, here are a few suggestions involving openssl's passwd utility.

Incidentally, if you have trouble finding the man page for openssl's passwd ("man passwd" is likely to get you the man page for thing that resets your login password), try "man 1ssl passwd" (Ubuntu) or "man sslpasswd" (Red Hat 5).

The hashed passwords in /etc/shadow look something like this:

$1$.oDCRZmb$mYZm6IzfMWVfe38Pr4fHt0

The shadow entry has three parts delimited by dollar signs. The 1 indicates that this shadow entry was computed with the MD5 password algorithm. The next section (".oDCRZmb") is the salt, and the final portion is the hashed password.

You can generate these yourself. If you type the following (the "-1" requests the MD5 algorithm)

echo password | openssl passwd -1 -stdin

you should get something resembling

$1$DcuakEM4$c4WDkEXKd6YXNYjAfN2Sh/

You can reproduce this by providing the salt:

carl@stilgar:~$ echo password | openssl passwd -1 -stdin -salt DcuakEM4
$1$DcuakEM4$c4WDkEXKd6YXNYjAfN2Sh/

And it looks like openssl is smart enough to strip the newline:

carl@stilgar:~$ echo -n password | openssl passwd -1 -stdin -salt DcuakEM4
$1$DcuakEM4$c4WDkEXKd6YXNYjAfN2Sh/

Without the "-1" argument, openssl uses the standard crypt algorithm. The first two characters from crypt output are the salt, and this is what the Apache webserver's htpasswd uses for making passwords (at least, crypt seems to be the default algorithm for the Ubuntu and Red Hat 5 packages):

carl@stilgar:~$ echo password | openssl passwd -stdin
BxZPctq22eZ4M
carl@stilgar:~$ echo password | openssl passwd -stdin -salt Bx
BxZPctq22eZ4M

passwd also knows the Apache variant of the MD5 algorithm:

carl@stilgar:~$ echo password | openssl passwd -apr1 -stdin
$apr1$z4cUIQjr$fXbDk6ypzyZIIIb/OIp0I.
carl@stilgar:~$ echo password | openssl passwd -apr1 -stdin -salt z4cUIQjr
$apr1$z4cUIQjr$fXbDk6ypzyZIIIb/OIp0I.

Looks like Ubuntu uses the sha-512 algorithm for hashing passwords, and openssl's passwd doesn't support this. If you want to try making /etc/shadow entries w/ sha-512, try saving the following file as passwd.c:

#define XOPEN_SOURCE
#include 
#include 

int main(int argc, char *argv[]) {
    if ( argc < 2 ) {
        printf("usage: %s password salt\n", argv[0]);
        return;
    }
    printf("%s\n", (char *)crypt(argv[1], argv[2]));
    return;
}


And then try this:

gcc -lcrypt -o passwd passwd.c
./passwd password '$6$salt$'

No comments: