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.
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
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.
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).
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
.
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.
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.