Introduction to Password Hashing and Cracking
Password Hashing
Passwords are typically stored in a specialized encrypted format called
hashes. A hash function in an encryption algorithm (also called a cipher)
that easily converts a password into an encryption string, but it is
mathematically / computationally difficult to convert the encryption
string back into the password. This is a special type of encryption that is
called a "one-way" function. Regardless of the size of the password (input),
the hashes (output) produced by a specific hash function are the same size.
The hash function works as follows:
Password --> Hash function --> Hashed password (Store hash)Passwords also often have a random string called a "salt" attached to them. The salt is randomly generated for each password. It serves two purposes. If two users have the same password, the salt will likely be different for each of them, so they'll have different hashed passwords. It also makes an old attack, where common words are pre-hashed to make a list of hashed passwords, more difficult to run as each word will have thousands of possible hashes, depending on the salt. With salting, the password encryption process is:
Password+Salt --> Hash function --> Hashed password (Store hash+salt)There are many different hash functions, each of which uses a differnt technique to create the hash and each of which have different output lengths. Generalized hash functions are designed to be very fast, so they can be used for a variety of purposes. Specialized password hash functions are designed to be very slow so they can thwart the password cracking technique covered below. Common hash functions seen historically and currently to hash passwords:
- MD5 - Generalized, 16 byte output
- SHA1 - Generalized, 20 byte output
- SHA-256 - Generalized, 32 byte output
- SHA-512 - Generalized, 64 byte output
- bcrypt - Specialized for passwords, 16 byte salt, 24 byte output
- PBKDF2 - Specialized for passwords, Wraps around various ciphers so salt and output depend on cipher used
Creating Hashed Password on Linux Command-Line
Most Linux systems have command-line tools to call the generalized hash
functions to create a hash string. The tools on the Linux Mint systems
in Science III 315 are:
- md5sum
- sha1sum
- sha256sum
- sha512sum
echo "password" | md5sumTo create a salted hashed password, you have to create the binary string for the salt and add that to the password string. An example of the command for that is:
printf "\xa1\x43\x5e\x78password" | md5sumThe following shell script will call any of the above hashing algorithms with the given salt bytes and password to create the hash string:
#!/bin/bash if [ $# -lt 6 ] then echo "Usage: $0 <cipher> <saltByte1> <saltByte2> <saltByte3> <saltByte4> <password>" echo "" echo " Salt bytes should be given in hexadecimal" echo "" echo "Example: ./hash.sh sha1sum a3 5b ef 7a testing123" exit 1 fi RESULT=$(printf "\x$2\x$3\x$4\x$5$6" | $1 | cut -f 1 -d ' ') echo "$RESULT:$2$3$4$5"To create this script, use vi to edit a file called hash.sh with the following command:
vi hash.shType 'i' to go into Insert mode and type in the above script. Use the arrow keys to navigate within Insert mode. When you are done typing the script, hit the Esc key to go into Command mode, then type :wq and hit the Enter key to save and quit. To run your script, type the following:
chmod +x hash.sh ./hash.sh sha1sum a1 3e 45 a9 password
Password Cracking
Since hash functions are one-way functions, the only way to crack a password
is to generate a guess, hash the guess, see if it matches the password hash,
then repeat this until a match is found. The workflow is:
Start --> Generate Guess and Append Salt --> Hash function --> Hash for Guess /|\ | | | | \|/ Try Again <-- No <-- Match Password Hash? | | \|/ Yes --> DoneThe Hashcat tool is one way to crack passwords. It uses the massive parallelism of modern graphics cards (GPUs) to greatly increase the number of guesses per second, in order to find matches as quickly as possible. Hashcat also supports pattern matching, where guesses can be based on patterns such as dictionary words or modifications of dictionary words. Since most people follow similar behaviors when selecting passwords (a word with a number at the end for example), using pattern-based guessing can find matches more quickly than truly random brute-force guessing (although Hashcat also supports this mode). Go to the Hashcat page and download the Hashcat binaries. Open in Archive Manager and tell Archive Manager to extract the files. Then open a terminal and change to the extracted directory. To see the maximum guesses per second for different hashing algorithms, use the following command to run the benchmarks:
./hashcat64.bin -bTo see the help page for hashcat, run the following command:
./hashcat64.bin --help
Using Hashcat with Password Script
Redirect the output of your hash.sh script into a file to use it with Hashcat.
You can put multiple passwords into the file first. For example, the following
command will generate two SHA1 passwords and then run a dictionary attack
against them with Hashcat:
./hash.sh sha1sum a1 3e 45 a9 password >> test.hash ./hash.sh sha1sum 32 ae 72 ef password >> test.hash ./hashcat64.bin -m 120 --hex-salt test.hash example.dictYou must use the --hex-salt option since your script uses hexadecimal salts. If you forget that option, a match will not be found. The hash algorithm is given by the -m option. You must match the algorithm used by your script. The possible options are:
Algorithm | Option to Hashcat |
---|---|
md5sum | -m 20 |
sha1sum | -m 120 |
sha256sum | -m 1420 |
sha512sum | -m 1720 |
rm test.hash