Table of Contents

How to retrieve and audit password hashes from remote Linux servers

The following instructions were originally written in response to a specific John the Ripper Pro support request. Retrieving all of your servers' password hashes for audits on a single system and automating this setup (presumably to repeat the audits on a regular basis) is not always the right thing to do. This poses a lot of extra risk to your servers' security. You could want to opt to deploy pam_passwdqc and do “manual” audits with JtR infrequently instead. On some systems, you may also switch to stronger password hashes, which will further reduce the typically low percentage of passwords that pass pam_passwdqc's checks yet are reasonably crackable with JtR.

Setup of the auditor's system

Let's assume that you want to audit all of your Linux servers' passwords on a single “secure” Linux system - a workstation or server that is preferably not used for “risky” purposes (does not run services, is not reachable from the Internet, etc.)

Create a dedicated pseudo-user account for accessing the remote servers and running JtR. As root, run:

useradd -m john
su - john
chmod 700 .
umask 077
echo 'umask 077' >> .bashrc

The exact commands may differ depending on your Linux distribution.

Generate an SSH key pair. Under the newly created john account, invoke:

ssh-keygen -t rsa -b 2048

This will prompt you for a passphrase to protect the private key. You may opt to have no passphrase (just press Enter) to allow for unattended runs (e.g., on cron) and to avoid typing the passphrase many times (once per remote server), or you may choose a strong passphrase if greater security is desired.

Create a script to access the remote servers:

cat > unshadow-remote.sh << EOF
#!/bin/sh

while read host; do
        ssh -2nxT -i .ssh/id_rsa root@$host false > passwd-$host
done < hosts
EOF
chmod 700 unshadow-remote.sh

The above places the script into a file called unshadow-remote.sh.

Create a file called hosts with the remote server list in it. For example, to include the auditor's system itself place the line localhost into the file:

echo localhost > hosts

Setup of remote servers

On each remote server (or on the auditor's system itself if you use the above example with localhost), create a script to dump the password hashes (as root and while in root's home directory):

cat > unshadow.pl << EOF
#!/usr/bin/perl

print "$n:$p:$u:$g:$f:$d:$s\n" while ($n,$p,$u,$g,$q,$c,$f,$d,$s) = getpwent();
EOF
chmod 700 unshadow.pl

The above places the script into a file called unshadow.pl. This script requires Perl to be installed, and it eliminates the need for using JtR's unshadow program.

Create the /root/.ssh/authorized_keys file or add a line to it if the file already exists:

cat >> .ssh/authorized_keys << EOF
from="AAA.BBB.CCC.DDD",command="exec ./unshadow.pl",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty PLACE-YOUR-SSH-PUBLIC-KEY-HERE
EOF

Substitute the auditor system's outbound IP address for AAA.BBB.CCC.DDD and the SSH public key from ~john/.ssh/id_rsa.pub (one very long line) for PLACE-YOUR-SSH-PUBLIC-KEY-HERE. It is important that you place everything on one line - starting with from= and ending with the SSH public key.

Since this line will be identical across your remote servers, you may as well prepare it on the auditor's system:

echo 'from="AAA.BBB.CCC.DDD",command="exec ./unshadow.pl",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty '`cat .ssh/id_rsa.pub` > authorized_keys-for-remote-servers
cat !$

and then copy&paste it into the remote servers' /root/.ssh/authorized_keys files. This avoids the need for fully logging in to those servers from the auditor's system - good for security.

Retrieving the password hashes

To retrieve the remote servers' password hashes from the auditor's system, run:

./unshadow-remote.sh

It will ask you to confirm the remote servers' SSH host keys. You need to verify the key fingerprints (to ensure that you're not being deceived with a man-in-the-middle attack), then enter “yes”. You may view a server's SSH host key fingerprint with (under a trusted non-root account on the server):

ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub

You will only need to go through this verification procedure the first time you run the script (or the first time you run it after having added a new server). On subsequent invocations, there should be no prompts.

The script will create a file per “remote” server - e.g., it will create a file called passwd-localhost for the auditor's system itself (if you use the example given above).

Running John the Ripper to audit the hashes

It is preferable to run John the Ripper on all of your password hash files at once. (This is easy to do and it provides a performance improvement over running JtR against the files one-by-one.) To do so, run:

john passwd-*

under the john account on the auditor's system. This assumes that you have the john program somewhere in your PATH - e.g., that you have installed the JtR Pro RPM package. If you built JtR from source on your own, then you will likely need to specify the path to the john program binary in this command (and in subsequent commands invoking john as well).

Please note that if the servers use more than one hash type, you will need to run john on each hash type individually, e.g.:

john --format=descrypt --session=descrypt passwd-*

and:

john --format=md5crypt --session=md5crypt passwd-*

The –session option lets you run multiple instances of JtR at once - e.g., in different “windows” under GNU screen.

To display the cracked passwords for an individual server, run:

john --show passwd-SERVER-NAME

substituting the actual server name for SERVER-NAME.

Avoiding the need for Perl on the servers

If the dependency on Perl is a problem for you (although it probably won't be), it may be avoided by having the servers output /etc/passwd and /etc/shadow individually, and by having the auditor's system run JtR's unshadow program on the two files. To have the servers output the two files, two separate SSH keypairs may be used, or you may introduce a “protocol” where the files would be sent over a single SSH connection but separated with a “magic line”. The tools to use here are cat on the servers (e.g., command=“exec cat /etc/passwd” in an authorized_keys file) and maybe sed on the auditor's system (to split the data on the “magic line” into two files before running unshadow on them).

Alternatively, you may install JtR on each server and use command=“exec unshadow /etc/passwd /etc/shadow” in the authorized_keys files. This is easier to do (no further scripting is needed), but “unnecessarily” installing JtR on each server is not so neat.

Setting up proactive password strength checking

Last but not least, please note that auditing the password hashes should be secondary to proactively preventing weak passwords from being set. You may implement the latter by deploying pam_passwdqc. Once you have done so, you might want to reconsider the need for or the frequency of password hash audits with John the Ripper.

If you choose to no longer do the audits with John the Ripper or to do them very infrequently (just to verify that pam_passwdqc with its specific settings does the job for you and to catch those hopefully very few non-obvious weak passwords that would pass pam_passwdqc's checks), you may want to (temporarily) deactivate the authorized_keys files on the servers (by renaming them) and to shred -u any passwd-* files and john.pot on the auditor's system. Please don't forget that the password hash retrieval setup and the password hashes (and cracked passwords) stored on the auditor's system do pose a lot of extra risk to your servers' security, so this risk better be justified.

Back to John the Ripper tutorials.