How Passwords are Stored and Cracked — The Basics of Using Hashcat

Ismail Hakim
Cyberkarta
Published in
5 min readNov 23, 2020

Imagine that you are running a social media web service which handles thousands of logins every day. Not the busiest server in the world, but still your customer put their trust on you to handle these requests and store their credentials. There may also customer credit card numbers those are sitting behind the login page.

On the worst day of your company, data breach can still happen, even though your company put high effort to prevent this. As expert said, cybercriminal will merely need one gap to invade your system, while you must patch them all. If this event really occurs, there may only two things that the users think about, is my account affected this data breach? If it so, how far? The data breach itself surely will ruin company’s reputation, but it can be catastrophic if world knows that you store user data in a faulty way, such as storing plain text password. Hiding the truth will not make any better.

At this point, there may be a question, from the user, how do I know whether the web server store my plain text password or hashed one? In most of the case, the answer is you can not know except it is written explicitly in the web or user ask directly to website owner. However, if you forgot the password and the web can give the forgotten password to you, it is the greatest sign that your password is stored in plain. Almost all big company in 2020, store user’s password using its message digest or hash.

To understand better, there is a library in Python called hashlib or you can use online hashing tool, the latter is not recommended on production site because it is safer to compute and store hash with your own resources. Example below is a Python script to compute MD5 hash with any user input. The script contains f string, so it can only run on Python 3.6 or newer.

import hashlib

username = input(“username: “)

password = input(“password: “)

hash_text = hashlib.md5(password.encode()).hexdigest()

print (f’{username}:{hash_text}’)

Run it, and input these:

username: admin

password: admin123

admin:0192023a7bbd73250516f069df18b500

This python script takes 2 user input, username and password, and then compute MD5 hash (in hexadecimal). Finally, it prints username and hashed password. As a precaution, I use MD5 hash to fulfill this demo as it fast to be computed and cracked. Nowadays, MD5 should not be used in production environment, it is way safer to use SHA256 or SHA512.

The password changed in specific way, and it represented in hexadecimal form. If you try different username and password combination, notice that the length of the hash is not changed (that is one of the characteristics).

Example 1:

username: admin

password: 123

admin:202cb962ac59075b964b07152d234b70

Example 2:

username: myaccount

password: SuperLongPasswordThatIDontBothertoRememberIt

myaccount:b246fff4ac99ba02332598a8c6ef4a46

Another trait of hash message is that it one-way function or we can say the hash message cannot be reversed easily. Based on this trait, most server use username and password combination verification as diagram below.

The well-known method for authenticating user

As you can see, especially in password section, a server calculate hash from the user input and then match username and its hashed password in the user database. In this model, it is the only workflow available, as hashed password cannot be reversed to clear-text password.

Within same algorithm, calculating hash message always results in consistent value (if it is not consistent, how do server verify user in the first place). This nature can result in a poor outcome if user use weak or well-known password and reuse it on multiple accounts, however.

Cracking Password

Storing passwords in its hash is one-layer security itself, nevertheless cyber criminal will still hunt those because there are ways to recover clear-text password from its hash. The notorious tool today is hashcat.

Hashcat is an application that capable of cracking password by using CPU or GPU. If you decide to use GPU, hashcat can crack password several times faster. You can also differently allocate resource to hashcat in case you want to work with something else with your computer when cracking process is running. Before it begins, you must decide what kind attack you want to do with hashcat.

First of all, the dictionary attack. Dictionary attack is performed by using dictionary file that contains list of words. You may choose the famous rockyou.txt that contains thousands of commonly used passwords. If you are using Kali Linux, you can find it on “/usr/share/wordlists/rockyou.txt”. If you experience a slow speed, you may create customized wordlist for the purpose of testing, or even upgrade your GPU.

Command:

hashcat -O -m0 -a0 -w3 21232f297a57a5a743894a0e4a801fc3 /usr/share/wordlists/rockyou.txt

Result:

21232f297a57a5a743894a0e4a801fc3:admin

Explanation:

-O = optimized kernel option; it makes password cracking much faster, but it only works for short password entry.

-m0 = use module 0 (MD5); hashcat capable of cracking plenty of hash algorithm.

-a0 = use dictionary attack

-w3 = use high workload profile; you can use -w1 to -w4 (the lowest to highest resource consumption) to increase password cracking rates.

By using my RTX 2070, the 21232f297a57a5a743894a0e4a801fc3 hash is cracked instantly and giving admin as the result.

You are able to change hash value 21232f297a57a5a743894a0e4a801fc3 to a file that contains list of hashes to be cracked. The command will be:

hashcat -O -m0 -a0 -w3 password_md5.txt /usr/share/wordlists/rockyou.txt

Sometimes, password is strong, but not strong enough. You can specify a rule by giving -r <rule_location>. For this example, I use different hash and best64 rule (https://github.com/hashcat/hashcat/blob/master/rules/best64.rule) that already installed with hashcat and located inside rules folder.

Command:

hashcat -O -m0 -a0 -w3 2e6e5a2b38ba905790605c9b101497bc /usr/share/wordlists/rockyou.txt -r rules/best64.rule

Result:

2e6e5a2b38ba905790605c9b101497bc:Admin12

How disappointing if we actually skip that weak password by using merely rockyou.txt wordlist.

Secondly, the brute force attack. Brute force attack tries different character permutation. The more type and number of characters, the longer time is needed.

In this example, I will try to crack 6-digit PIN that stored in MD5, by using brute force attack.

Command:

hashcat -O -m0 -a3 -w3 30eebaf0235367a45abf1f9a106063dc ?d?d?d?d?d?d

Result:

30eebaf0235367a45abf1f9a106063dc:135798

Explanation:

-a3 = use brute force attack

?d = indicate a digit (0–9 number), you can use another character, such as:

?l = indicate a lowercase character (a-z)

?u = indicate an uppercase character (A-Z)

?s = indicate a sign character («space»!”#$%&’()*+,-./:;<=>?@[\]^_`{|}~)

?a = indicate all character (?l?u?d?s)

Six-digit PIN is just a dust for hashcat. It cracked in a matter of seconds.

That’s all for now, hopefully this article can tell the importance of using unique and strong password.

On final note, these mentioned are just two of thousand ways to crack password, there are advanced attacks out there, such as mask attack and rainbow attack that capable of cracking password much more effectively and quickly.

--

--