Crack a password: techniques and hands-on exercise
Sometimes during security engagements, ethical hackers need to crack passwords. However, not all of them have the skills and the resources required to achieve it. Therefore, they might miss interesting attack surface that could make the difference between success and failure in the engagement.
In this article, we will explore many key concepts that revolve around password cracking. Hopefully, you will have the necessary knowledge to crack passwords during your own security assessments. Besides, you will put your knowledge to test in an exercise. If you grasp the different techniques in this article, you should be able to crack a password-protected ZIP archive that I prepared for you. Are you ready? Let’s get to it!
If you like watching educational videos, I prepared this one for you as well.
A quick note for experts in cryptography, this article tries to simplify concepts as much as possible. I might have overlooked or oversimplified some of them.
Password cracking and hashes
Password cracking and hashes go hand-in-hand. Otherwise, why would you even think of cracking a password if it is in plaintext? But wait! What is a hash?
Quick introduction to hashes
Simply put, it is a fixed-length string composed of random characters that ideally map to one unique string. There are many algorithms that use different mathematical operations and produce different lengths. The cool property of these algorithms is that you cannot go backwards. In other words, you cannot extract the plaintext input from the hash. This makes it the perfect candidate for storing passwords. For example, respectable web applications never store their users’ plaintext passwords, but rather the password hash (with a salt as well).
One simple hashing algorithm is called MD5. You have certainly heard of it before. Let’s take the example of the password “Password123” in plaintext. I know, it is a weak password, but just bear with me. We will use the md5
command that comes with zsh in mac, but feel free to use md5sum
if you are on Linux. The command is:
echo -n Password123 | md5
When you generate the MD5 hash, you get 42f749ade7f9e195bf475f37a44cafcb
. Now, let’s hash another password, for example “Password124”. Notice how we have changed only one character, but the resulting hash is 0da21eca396b1532f6cccf167234b441
. What a huge difference! Both hashes are totally different.
Plaintext, hash, salt
Serious developers never store plaintext passwords in the database. Instead, they append a random string to the end of the user’s password, generate the hash, then store the resulting hash with the salt in the database. When the user logs in, the application looks up the user identifier in the database, grabs the salt, appends it to the user’s password, generates the hash and compares it with the one stored. If they match, it means that the user’s password is correct.
Of course, not all developers apply a salt. Therefore, they leave their users open to password cracking since humans always come with predictable and weak passwords. Besides, if two users have the same password, the database would contain the same hash for both of them.
We won’t go into details, but a crucial property of a hashing algorithm is its ability to avoid hash collision, which happens when to different inputs produce the same hash. MD5 suffers from such problem, but that’s not our concern in this article.
Password cracking to the rescue
You may wonder how we are supposed to recover plaintext password from the hash. The answer does not require a lot of thinking, we are going to brute force … intelligently!
Since we cannot recover the plaintext password directly from the hash, we will use a list of password candidates, calculate the hash for every password, and compare it with the one we want to crack. We would find the right password as soon as the two hashes match. Therefore, we would have cracked the password.
In theory, that sounds straight-forward. But in practice, this require considerable computing resources, depending on the number of candidates and the hashing algorithm being used. Therefore, one needs to try to strike the right balance between efficiency and thoroughness. Hopefully, this is the goal of the article. But first, let’s get those hashes.
Before you crack a password, get those hashes!
It goes without saying that you can’t crack a password if you don’t have a hash, or a list of hashes. The question then is: How would you find those hashes?
There are so many places where hackers can find password hashes. We will explore some of them in this section.
Collect password hashes directly from vulnerable assets
When ethical hackers exploit a vulnerability or abuse a feature in a target, they may find hashes. For example, suppose that you find a SQL injection during a penetration testing engagement. If the application manages its users’ identities and your customer agrees to go further, you can dump the users’ table that contains the list of password hashes.
Another avenue where you typically deal with password hashes is Kerberos tickets. They are encrypted with the account’s password. One famous attack against such tickets is known as Kerberoasting, which consists of dumping service account credential hashes and cracking them offline.
Then, we have NetNTLMv2 hashes that you can collect during an internal penetration testing engagement. If LLMNR is enabled on the customer’s network, you can poison some broadcast requests and collect NetNTLMv2 hashes that you can attempt to crack offline.
Get password hashes from a data breach
Sometimes, luck is not in your favour and you don’t find a vulnerability or a security misconfiguration directly in the assets you are testing. In this case, you can turn your attention to leaked databases, which store passwords and hashes from previous data breaches. You can look at a terrifying list of breaches on the have I been pwned website.
As this is a gray area, I leave the task to find such databases as an exercise to the reader.
As a side note, many services exist to check if your password has been leaked. You may want to check that right now on haveibeenpwned. If it has been breached, then pause reading and reset your password to a stronger one, or maybe use a passphrase instead, something like: “I really like thehackerish website!”, I am just kidding!
Generate hashes from password-protected files
Sometimes during engagements, you find password-protected files, such as ZIP archives, Microsoft Office documents or Kerberos tickets. You can generate a hash of these files using known tools.
For example, you can use zip2john
for ZIP archives and office2john
for Office documents, they both ship with johntheripper. Regarding TGS Kerberos tickets, you can use kirbi2hashcat.
I uploaded a password-protected ZIP archive to Github. Feel free to download it and follow along. We will generate its hash using the following commands on Kali Linux.
#install john
sudo apt update && sudo apt install john
#Generate the hash
zip2john archive.zip > hash
#see the content of the hash
cat hash
You should get a result similar to this one.
The operation seems to have run successfully, but after some troubleshooting, I found that the hash was wrong. In fact, the part $1*2*2*0
of the hash should be $1*1*2*0
. Otherwise, you won’t be able to crack the hash. Go ahead and modify the hash file before proceeding.
Password cracking techniques
Before jumping right into password cracking tools, let’s explore the different techniques that you should know to increase your chances of cracking a password. Since cracking a password depends on the password candidates that you try, the right password should obviously exist in your list. This is where you invoke the artistic skill within you, with all the creativity and the intuition it brings with it.
Plain brute force
The most basic and naive approach would be to try every combination of every character, with arbitrary password lengths. For example, you might try all combinations from aaa
to ZZZZZZZZ
. This will eventually crack the password, but it will take forever! You don’t want to spend the rest of your life cracking a password, do you?
List of probable passwords
The second approach is located on the other side of the spectrum. In other words, you attempt to crack a password based on a list of probable passwords related to your target’s interests, let’s call it a wordlist. While this would run significantly faster, it does not cover a satisfying search space. This approach would only crack passwords that you think might be used.
Humans are humans
Another approach would be to use your previous wordlist and append the most known passwords. These are passwords from previous breaches and cracked passwords of real users. You would be surprised how many people still use these passwords!
This will certainly increase our chances because we are taking advantage of the fact that people tend to use predictable and known passwords. However, it won’t cover harder passwords that are not part of our wordlist so far.
Rules to the rescue
Our wordlist is good, but that’s not enough for us. We want the best! We want to cover weird combinations, permutations, alterations, mutations, everything that is based on our wordlist, but more complicated.
To give you an example, the password iloveyou
is a famous password in almost every wordlist. Yet, people might choose a harder password by uppercasing the the first letter, appending three digits and a symbol, and maybe transform o’s to 0’s. A potential password would be Il0vey0u123$
. You would argue that this is a strong password, but I don’t think so. Again, we are taking advantage of the predictable human nature when it comes to choosing a password, especially when they rush into creating an account while a password policy requires them to comply with a “strong” policy.
This approach would take every word from our wordlist and generate as many transformations as we define to mimic how users choose their passwords. With this, I think we can be sure that we will crack even more passwords.
Still can’t crack the password? Let’s bring masks to the party!
Sometimes, even our previous “smart” approach fail. This is where it is time to get dumb! Well not completely. You see, we can still bruteforce the password, but more intelligently, or less naively, however you’d like to see it.
We will once more take advantage of the predictable human nature I explained earlier and expand our search space even wider than the wordlist and rules. The idea is to define specific charsets for specific positions in the password. An example would be more descriptive.
Suppose that you enumerated the password policy and found that the minimum password length is 7 characters, with a combination of Uppercase, lowercase, digits and numbers. Sounds robust right? Not really! Once again, some human passwords tend to follow a predictable patterns. For example, some people start with a capital case, followed by a string of lowercase characters, followed by a digit and a symbol. Therefore, you can translate that pattern in a series of rules that tell the cracking tool what charset to use in what position. This reduces the search space, thus reducing the cracking time.
Of course, there are so many other techniques, but these are the ones I usually use. If you made it this far, congratulations! You are now ready to start cracking passwords.
Crack a password using john
Now that we have a hash and understand some cracking techniques, we can start exploring the tools. One of the famous tools for that purpose is JohnTheRipper. I guess it ships with Kali Linux by default. Otherwise, you can easily install it the same way that I did when generating the ZIP archive hash above.
Crack passwords using john and a wordlist
John supports so many formats, which you can list using john --list=formats
. Here is just an excerpt of the huge list. See if you recognize some!
Let’s load our previous hash and try to crack it using the default wordlist that ships with Kali under /usr/share/wordlist/rockyou.txt
. I like the fact that this tool auto-detects the hash type without manually specifying it. For example, it successfully detects that my hash has the format PKZIP. However, I found myself specifying the format in most cases to avoid any ambiguities.
Obviously, my password is not inside the wordlist, otherwise it would have been a piece of cake to crack. But notice that I used the time
command to show you that it took a blazing 2 seconds to exhaust the entire 14344391 rockyou wordlist password candidates!
Crack passwords using john and rules
Once again, we can use the option --list
, this time to show all the rules that ship with john.
These rules are defined under john’s config file john.conf
. On Kali for example, it is located under /usr/share/john/john.conf
. Same thing for Parrot OS. You can run the following command to locate the rule All
in that file.
grep "List.Rules:All" /usr/share/john/john.conf -A 5
You will notice that it includes other rules, such as Jumbo
and hashcat
, which themselves include yet other rules. All of them can be found in the same file as well.
Let’s use the rule all
to crack a password. First, let’s generate a MD5 hash for the seemingly strong, but predictable password Iloveyou123.
. To do that, run the following command on Linux: echo -n Iloveyou123. | md5sum | tee /tmp/hash
. Then, let’s create a wordlist with only one word, iloveyou
. The command to crack the password would be:
john --wordlist=/tmp/wordlist --format=raw-md5 --rules=All hash
We could also use our own rules file, you just have to point john to its path in the --rules
option. You can also write custom rules. Here is a documentation on how you can write your own.
In a few seconds, john successfully cracks the password. Notice how it transformed our word to apply the rule that matched our password.
Cracking passwords using john masks
Here, we will crack the same password as before, but using john’s ability to apply masks. The option --mask
exist just for that purpose. For example, we can instruct john to generate all possible combinations that start with an uppercase letter, then the word love
, followed by three lowercase letters, three digits and one symbol. In the screenshot below, ?u
, ?l
, ?d
, ?s
stand for uppercase, lowercase, digit and symbol, respectively.
For more information about masks, I invite you to read this issue.
Armed with this knowledge, I think you will be able to crack the ZIP archive. Can you give it a shot? Remember to take advantage of predictable patterns and include words that are related to the target in your wordlist, such as the username, first name, last name, interests, pet name, etc. If you still can’t crack the password, the last section of this article will give you the solution.
Show cracked passwords in john
If the crack was successful, you would see an output similar to the one below. Of course, I masked the password to give you a chance to find it yourself. I also added the password to my own rockyou.txt
wordlist, so yours won’t be successful at cracking the archive.
All the cracked passwords can be found in the file ~/.john/john.pot
. Besides, you can show the passwords you cracked using the --show
option.
You can also speed up the cracking time by forking multiple john processes using the option --fork=N
, where N is the number of processes you want to run in parallel.
Password cracking with hashcat
Hashcat is another famous tool that you can use to crack passwords. You can install it on various operating systems. For example, if you use a Debian-based Linux distributions, simply run sudo apt install hashcat
.
You can list hash formats that hashcat supports using the --help
option. Hashcat calls them modules.
Notice the module 0, which maps to raw MD5 hash. We will use it in the next examples.
Convert john hashes to hashcat
Sadly, hashcat does not come with binaries that help generate hashes from files, such as zip2john
and others that ship with John. However, you can refer to this documentation to construct a valid hash for hashcat. In most cases, you just have to apply a small modification to john’s hash.
From our previous ZIP archive hash, let’s run the following command to output just the parts that we are interested in. The command extracts only the part between pkzip2
or zip2
strings based on a regular expression, and stores the resulting hash in the file zip.hashcat
.
cat hash | grep -E -o '(\\$pkzip2\\$.*\\$/pkzip2\\$)|(\\$zip2\\$.*\\$/zip2\\$)' > zip.hashcat
Now, we can use the file zip.hashcat
to crack the password for the archive. But first, let’s explore how you can run the different cracking techniques using this tool.
Crack passwords using hashcat and a wordlist
This is straight-forward, let’s use the password !!!secret!!!
which exists in the rockyou wordlist towards the end. Like we did above, generate an MD5 hash, but make sure to escape the !
symbols using a backslash, like this: echo -n \\!\\!\\!secret\\!\\!\\! | md5sum
. Save the hash to a file.
Then, run the following command. We are using module 0, which maps to MD5, and we are passing the hash file, then the rockyou wordlist. We successfully crack the hash in less than a minute.
Crack a password with hashcat and rules
Like John, hashcat supports rules. They are typically located under /usr/share/hashcat/rules
, or under the rules
folder where you downloaded hashcat on Windows.
Unfortunately, hashcat does not come with a rule that includes all of the others. Since I don’t have time to investigate which rule will perform the right transformation, the following quick and dirty one-liner can do the job for us. It will put all the rules in one file that I called myrule
cd /usr/share/hashcat/rules/ && ls | xargs -n1 -I{} cat {} | sort -u | tee /tmp/myrule
Now, let’s run it with our one-word wordlist, like we did with john. This time, we specify the path to the rules file with the -r
option. Although we had some errors due to malformed rules, we successfully crack the password.
Password cracking with hashcat and masks
Like John, hashcat supports masks. Let’s use a mask to attempt to crack the same password. We need to tell hashcat that we are using masks by specifying the right attack mode with the option -a
, in this case 3. Make sure you specify the mask after the hash like you would when specifying a wordlist. Again, we successfully crack the password.
Show cracked passwords in hashcat
Similar to John, hashcat preserves a potfile of cracked passwords. It is located in your home directory, under ~/.hashcat/hashcat.potfile
. Besides, you can show only the cracked passwords of hashes in a particular file using the --show
option.
Crack passwords on the cloud
So far, we have been using our own workstation to perform password cracking. It does the job if you really fine-tune the techniques we have just explored. However, if you have a big list of hashes, or if you want to use large wordlists, a variety of rules and masks with huge search spaces, then you might want to purchase a Cloud instance from known Cloud providers. Every provider offers a brand dedicated to heavy calculations based on GPUs. Although they cost extra, you can spin them for a couple of hours and destroy them afterwards.
Microsoft Azure offers many GPU-optimized VMs, for which you can find a benchmark on GitHub. You can deploy a pre-configured VM from this repository. On AWS, have a look at this benchmark for various AWS EC2 instances.
Once you have your VM up and running, you need to install john, hashcat and the drivers for the Graphic cards. Finally, you would have to download some wordlists.
Solution for the password-protected ZIP archive
This section presents a solution to the password-protected ZIP archive that you are tasked to crack. If you haven’t practiced with the examples above, I strongly encourage you to do that first before looking at this solution.
Here we go!
We already generated the hash for both john and hashcat in previous sections. We now need a suitable wordlist. Since this is thehackerish website, we can hope that the password might contain words related to what it offers. Here is a potential custom wordlist from what we understand from the topics discussed in this website.
thehackerish
hacker
ethical
ethicalhacker
bugbounty
redteam
activedirectory
pentest
penetrationtesting
From there, we will use john with the rule all
.
As you can see, we cracked the password under 4 seconds! Now, we can unzip the archive to read the content of the secret.txt
file.