// Recovering Hashes without Dozens of GPUs - Root101 | Fundamentals of Linux Administration

Latest posts

Recovering Hashes without Dozens of GPUs

Cryptographic hash functions are the most used method for saving user passwords. A hash function is a one-way function that gets a string as input and translates it into another string that looks nothing like the original. Even though transforming a password into hash is easy, there is no way of turning a hashed string back to a password. That is the main reason almost all of the user passwords stored as hashes.

Let us imagine a public web service that allows users to store their valuable files. The system currently holds 10TB of data. A hacker finds a small problem with input sanitation and utilizes this to run a piece of malicious code and escalate privileges. Now the attacker can access all the information, but downloading 10TB from the backdoor can raise quite a few alarms. At this point, using a proper hashing algorithm can change everything. If passwords not hashed, the attacker can log in web service with credentials and pull all the information. Given how many people still use the same passwords for different sites, attackers could easily steal more data. If the passwords stored with a modern cryptographic hash function, the attacker needs to invest a lot more time in cracking this hash.

Linux and Windows store passwords as hashes, just like every system that has multi-user functionality. Slow hashing algorithms are better for credential storage; fast and old hash algorithms are still in use for verify file integrity.

1. Hash Cracking Theory

When creating a hash, most of the systems use CPU. Calculating a hash is not a small task. When we write down our credentials to any system and press enter, we have to wait a few seconds, even if the password is wrong. This is because the system can not validate a password without hashing it first, and hashing on a CPU can take a few seconds. hashcat uses GPU instead of CPU and uses it very efficiently. This provides us a much-needed performance advantage.

Since it is not possible to reverse hash functions, we need to try hashing different strings until we found a match for the given hash. It is effortless to try every combination for a four-digit PIN code. There are 100(10x10x10x10) combinations. What if these characters can also be letters as well as numbers? We can choose between 10 digits, 26 uppercase letters, and 26 lowercase letters. Now we have to try out 14,776,336(62x62x62x62) combinations. As the numbers show, trying out every combination in such ranges would take years, even with a weak hashing algorithm.

There are also specialized ways of recovering hashing like rainbow tables. Such methods are effective in only certain types of hashes.

Luckily, human beings are not very random when creating passwords. We can exploit this to make more educated password guesses instead of trying out every combination.

2. Preparation

Before making any attempt to recover the passwords, it is best to start by learning about the system that produced the hashes. First, we need to learn which hashing algorithm is used. Hash type can be MD5, SHA1, bcrypt, WPA. The full candidate list can be found on hashcat website. Hash mode needs to be set for hashcat to work. -m flag can be used for this.

If possible, it would be very useful to learn about the password policy. What is the minimum number of characters allowed, what kind of passwords are prohibited by the system for being weak. Such information saves precious processing time. It is impossible for the hashcat to know the password policy of the hash, so it can easily waste time with impossible candidates.

3. Maximize the Cracking Speed

There are few things to consider to reach max speed with your hardware. Most important thing is using correct drivers. Without a proper GPU driver, hashcat might function slower than it should be.

3.1 Create Enough Candidates for Fast Hashes

hashcat needs a steady supply of candidates to work on max performance. This problem usually happens with fast hashes. Brute force methods with large enough keyspace, max out resources instantly, but adding rules can speed up hash cracking if you are working with a wordlist.

3.2 Cooling

hashcat has a GPU temperature limit; when it reaches this limit, speed gets reduced to not damage the GPU. Most GPU don't max out fans unless it gets scalding. Disable automatic fan control and max out the fans manually. This can increase your hash cracking speed, and it will improve the life expectancy of the GPU. If you don't have many case fans, consider leaving the case door open while cracking hashes.

3.3 Track your attempts

There are many methods of cracking hashes, understand your attacks, and don't waste time on overlapping spaces. Merge wordlists and remove duplicates before scanning. Keep notes about your past scans and avoid the same spaces.

Test Hashes and Hardware

For this guide, we will use the infamous LinkedIn leak from 2012, which later resurfaced in 2016. The leak has 17,264,398 SHA1 hashes. To keep playfield even, we used a GTX 970 for our guide, a GPU from 2014.

Hashes get removed from the list when found. The goal is to show the effectiveness of methods as some methods use hashes cracked as older steps to improve attacks. While reading the steps, keep in mind, every step deals with hashes that survived at earlier stages.

4. Hashcat

hashcat is the world's fastest password recovery utility. It supports five unique modes of attack.

For limiting hashcat to use only the second GPU -d 2 parameter was given to all examples.

4.1 Install Hashcat

Install process for hashcat is pretty simple. You can also use package managers, but pulling directly from the official site guarantees the latest version. The package is pretty good, and you don't have to deal with dependencies.

wget https://hashcat.net/files/hashcat-6.0.0.7z
7z x hashcat-6.0.0.7z
cat linkedin.txt | cut -d: -f2 | sort | uniq

5 Modes of Hashcat

hashcat offers different modes of attacks.

5.1 Straight Mode | 0

The straight attack is the most basic option we have. We need to provide the hashcat with a wordlist, and hashcat would try every line in this list on the given list of hashes.

When it comes to wordlists, there are many of them out there. Most of the wordlists include cracked from passwords from older hash leaks. Since we are working on a leaked hash list, using a wordlist like RockYou would be cheating. So we start with a simple English dictionary we found from google.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist --remove -d 2 ~/corncob_lowercase.txt

Session..........: hashcat
Status...........: Exhausted
Hash.Name........: SHA1
Hash.Target......: hashlist
Time.Started.....: Mon Jul  6 12:04:45 2020 (3 secs)
Time.Estimated...: Mon Jul  6 12:04:48 2020 (0 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.2..........: 13366.2 kH/s (1.06ms) @ Accel:1024 Loops:1 Thr:64 Vec:1
Recovered........: 25570/17264398 (0.15%) Digests
Remaining........: 17238828 (99.85%) Digests
Recovered/Time...: CUR:N/A,N/A,N/A AVG:623132,37387971,897311312 (Min,Hour,Day)
Progress.........: 58110/58110 (100.00%)
Rejected.........: 0/58110 (0.00%)
Restore.Point....: 58110/58110 (100.00%)
Restore.Sub..2...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates..2....: aardvark -> zulus
Hardware.Mon..2..: Temp: 38c Fan: 99% Util:  8% Core:1328MHz Mem:3004MHz Bus:4

GPU Time = 3s

Cracked = 25.570

Hash Cracked per Second = 8.523,33

Total Cracked So Far = 25.570

Remaining Hashes = %99,85

Twenty-five thousand five hundred seventy people used lowercase dictionary words for their passwords.

5.1.1 Wordlist with Rules

But what about people who used capitalization in the first letter(Fire)? What about the people who added a calendar year at the end of the word(fire2000)? Some people might do both(Fire2000).

To scan for such passwords, we can modify the wordlist. The thing about wordlists are, they are not just data; they are big data. Changing only the first letter in a large wordlist could take hours and a lot of free disk space. Luckily, hashcat has an option to make such modifications on the fly. It is called rule based attack.

To capitalize on the first letter, we need to use the operator "c". To add constants to the end of the candidate, we can use "$" operator. There are much more rules can do for us.

First, we need a file to store our rules. Our first rule is just "c"

cat myrules.rule
c

To use hashcat with rules, -r parameter is used.

./hashcat-6.0.0/hashcat.bin -m 100 --remove -d 2 hashlist -r myrules.rule /speed/corncob_lowercase.txt


Time.Started.....: Mon Jul  6 12:16:26 2020 (1 sec)
Time.Estimated...: Mon Jul  6 12:16:27 2020 (0 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt)
Guess.Mod........: Rules (myrules.rule)
Guess.Queue......: 1/1 (100.00%)
Speed2...........: 12304.0 kH/s (0.85ms) @ Accel:1024 Loops:1 Thr:64 Vec:1
Recovered........: 9009/17238828 (0.05%) Digests

GPU Time = 1s

Cracked = 9.009

Hash Cracked per Second = 9.009

Total Cracked So Far = 34.579

Remaining Hashes = %99,80

Now, let's add "2000" to the end of every candidate and capitalize first letters. Notice there are now two rules in the file.

cat myrules.rule
c
c$2$0$0$0
./hashcat-6.0.0/hashcat.bin -m 100 --remove -d 2 hashlist -r myrules.rule /speed/corncob_lowercase.txt

Time.Started.....: Mon Jul  6 12:18:32 2020 (0 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt)
Guess.Mod........: Rules (myrules.rule)
Guess.Queue......: 1/1 (100.00%)
Speed2...........: 14466.4 kH/s (0.72ms) @ Accel:1024 Loops:1 Thr:64 Vec:1
Recovered........: 624/17229819 (0.00%) Digests
Candidates..2....: Aardvark2000 -> Zulus2000

GPU Time = 1s

Cracked = 624

Hash Cracked per Second = 624

Total Cracked So Far = 35.203

Remaining Hashes = %99,80

Six hundred twenty-four people used a dictionary word, but they made the first character uppercase and added the year 2000 to the end.

There are infinite rule combinations, but some of the best rule lists come with the latest hashcat.

ls hashcat-6.0.0/rules/
best64.rule      Incisive-leetspeak.rule      T0XlC-insert_00-99_1950-2050_toprules_0_F.rule  toggles3.rule
combinator.rule  InsidePro-HashManager.rule   T0XlC-insert_space_and_special_0_F.rule         toggles4.rule
d3ad0ne.rule     InsidePro-PasswordsPro.rule  T0XlC-insert_top_100_passwords_1_G.rule         toggles5.rule
dive.rule        leetspeak.rule               T0XlC.rule                                      unix-ninja-leetspeak.rule
generated2.rule  oscommerce.rule              T0XlCv1.rule
generated.rule   rockyou-30000.rule           toggles1.rule
hybrid           specific.rule                toggles2.rule

Let's try best64 rule set with our wordlist.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist -r hashcat-6.0.0/rules/best64.rule  /speed/corncob_lowercase.txt --remove


Time.Started.....: Mon Jul  6 12:21:11 2020 (23 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt)
Guess.Mod........: Rules (hashcat-6.0.0/rules/best64.rule)
Guess.Queue......: 1/1 (100.00%)
Speed2...........: 84501.0 kH/s (17.70ms) @ Accel:32 Loops:77 Thr:64 Vec:1
Recovered........: 215845/17229195 (1.25%) Digests
Candidates..2....: foundation -> resres

GPU Time = 23s.

Cracked = 215.845

Hash Cracked Per Second = 9.384,57

Total Cracked So Far = 251.048

Remaining Hashes = %99,55

Rule lists are very good at increasing the number of candidates. Another thing to note here is the speed of operation. The very same GPU working on the same hash type started working faster:

Pure wordlist

Speed2...........: 13366.2 kH/s (1.06ms) @ Accel:1024 Loops:1 Thr:64 Vec:1

Wordlist with rule list

Speed2...........: 84501.0 kH/s (17.70ms) @ Accel:32 Loops:77 Thr:64 Vec:1

But what made GPU go six times faster? As mentioned in the speed section, this is a fast hash. It is not easy to provide enough candidates for such fast hashes. Ruleset simply provides more candidates for the process, and the process gets faster. We are yet to achieve the max hash cracking speed for our GPU.

We can specify multiple rule files to hashcat, but it runs them one by one, stopping and restarting sessions for every rule file. This is not very efficient. To create a single rule file that has all the rules in it:

find hashcat-6.0.0/rules/ -type f -exec cat "{}" \; | sort | uniq > allrules

As we can see, these rules are very optimized. Our wordlist found out 25570 passwords, but the same wordlist with rules:

./hashcat-6.0.0/hashcat.bin -m 100 hashlist -r allrules  ~/corncob_lowercase.txt --remove

Time.Started.....: Mon Jul  6 12:25:23 2020 (6 mins, 54 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt)
Guess.Mod........: Rules (allrules)
Guess.Queue......: 1/1 (100.00%)
Speed2...........: 61623.4 kH/s (18.91ms) @ Accel:192 Loops:32 Thr:64 Vec:1
Recovered........: 2416561/17013350 (14.20%) Digests
Candidates..2....: zzaardvarkark -> Zzzuluslus

GPU Time = 414 sec

Cracked = 2.416.561

Hash Cracked Per Second = 5.837,10

Total Cracked So Far = 2.667.609

Remaining Hashes = %84,55

We cracked more than %15 of the remaining passwords in this attack. In the earlier example, testing the same wordlist took 3 seconds. Now it took 6 minutes 54 seconds to recover two and a half million hashes.

Since we exhausted the most basic attack, now we need to move on to more advanced methods.

5.2 Combination | 1

A combination attack is pretty similar to the straight attack. Instead of one dictionary, this attack uses two dictionaries and adds the words side by side. Let's check for users who just added two lowercase dictionary words together.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist --remove -d 2 -a 1  /speed/corncob_lowercase.txt  /speed/corncob_lowercase.txt

Time.Started.....: Mon Jul  6 12:35:22 2020 (31 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: File (/speed/corncob_lowercase.txt), Right Side
Speed2...........:   110.8 MH/s (3.73ms) @ Accel:2 Loops:128 Thr:1024 Vec:1
Recovered........: 63299/14596789 (0.43%) Digests
Candidates..2....: trussesyoke -> zuluszulus

GPU Time = 31 secs

Cracked = 63.299

Hash Cracked Per Second = 2.041,90

Total Cracked So Far = 2.730.908

Remaining Hashes = %84,18

What about the users who added two dictionary words with capitalizing only the first letter?

In this mode, -j applies rules to the left wordlist, -k applies rules to the right wordlist. We need to specify individual rules instead of rule lists.

Time.Started.....: Mon Jul  6 12:43:54 2020 (23 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: File (/speed/corncob_lowercase.txt), Right Side
Speed2...........:   147.1 MH/s (3.70ms) @ Accel:2 Loops:128 Thr:1024 Vec:1
Recovered........: 14890/14533490 (0.10%) Digests
Candidates..2....: Trussesyoke -> Zuluszulus

GPU Time = 23secs

Cracked = 14.890

Hash Cracked Per Second = 647,39

Total Cracked So Far = 2.745.798

Remaining Hashes = %84,10

Notice the speed. Two wordlists have exponentially more candidates that one.

Pure wordlist

Speed2...........: 13366.2 kH/s (1.06ms) @ Accel:1024 Loops:1 Thr:64 Vec:1

Wordlist with rule list

Speed2...........: 84501.0 kH/s (17.70ms) @ Accel:32 Loops:77 Thr:64 Vec:1

Combinator with single rule

Speed2...........: 147.1 MH/s (3.70ms) @ Accel:2 Loops:128 Thr:1024 Vec:1

5.3 Brute-force | 3

As the most popular form of password cracking, we try out every possible combination on the list without a guiding wordlist. This attack is often very time-consuming, even for GPUs. Official guide explains the details, We need to write masks to attack certain keyspaces. -i parameters increase password length one by one.

We start by clearing lower lengths with a full brute force. This will crack recover every possible password between length one and five.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist --remove -d 2 -a 3 ?a?a?a?a?a -i

Recovered........: 0/12325824 (0.00%) Digests
Time.Started.....: Mon Jul  6 13:44:05 2020 (36 secs)

GPU Time = 36 secs

Cracked = 0

Hash Cracked Per Second = 0

It seems like, passwords shorter than five characters were not allowed by the system back than.

We can smoothly go for longer passwords with this attack, and it could clear a lot of hashes from our list given than SHA1 is an ancient and weak hash function. This tutorial is not cracking hashes with GPU power. It is about using patterns and statistics to break down hashes. The same methods are applicable for stronger and newer hashes.

Let us start with scanning for all digit passwords:

Time.Started.....: Mon Jul  6 12:55:34 2020 (4 secs)
Guess.Mask.......: ?d?d?d?d?d?d [6]
Speed2...........: 81918.2 kH/s (11.50ms) @ Accel:2 Loops:100 Thr:1024 Vec:1
Recovered........: 341872/14518600 (2.35%) Digests

Time.Started.....: Mon Jul  6 12:57:43 2020 (3 secs)
Guess.Mask.......: ?d?d?d?d?d?d?d [7]
Speed2...........:  4022.1 kH/s (7.88ms) @ Accel:2 Loops:125 Thr:1024 Vec:1
Recovered........: 209534/14176728 (1.48%) Digests

Time.Started.....: Mon Jul  6 12:58:56 2020 (6 secs)
Guess.Mask.......: ?d?d?d?d?d?d?d?d [8]
Speed2...........: 17219.4 kH/s (18.15ms) @ Accel:2 Loops:125 Thr:1024 Vec:1
Recovered........: 401539/13967194 (2.87%) Digests

Time.Started.....: Mon Jul  6 13:13:26 2020 (11 secs)
Guess.Mask.......: ?d?d?d?d?d?d?d?d?d [9]
Speed2...........: 86920.6 kH/s (23.35ms) @ Accel:4 Loops:62 Thr:1024 Vec:1
Recovered........: 71985/17264398 (0.42%) Digests

Time.Started.....: Mon Jul  6 13:02:23 2020 (1 min, 4 secs)
Guess.Mask.......: ?d?d?d?d?d?d?d?d?d?d [10]
Speed2...........:   155.9 MH/s (16.98ms) @ Accel:2 Loops:125 Thr:1024 Vec:1
Recovered........: 260366/13493670 (1.93%) Digests

GPU Time = 4 + 3 + 11 + 64 secs

Cracked = 341872 + 209534 + 401539 + 71985 + 260366 = 1.285.296

Hash Cracked Per Second = 15.674,34

Total Cracked So Far = 4.031.094

Remaining Hashes = %76,65

Now we will scan for all lowercase letters passwords. From the earlier attack, we know there can't be any password shorter than five characters.

Time.Started.....: Mon Jul  6 13:18:37 2020 (5 secs)
Guess.Mask.......: ?l?l?l?l?l?l [6]
Speed2...........: 59496.7 kH/s (9.51ms) @ Accel:2 Loops:84 Thr:1024 Vec:1
Recovered........: 132666/13233304 (1.00%) Digests

Time.Started.....: Mon Jul  6 13:19:50 2020 (46 secs)
Guess.Mask.......: ?l?l?l?l?l?l?l [7]
Speed2...........:   174.3 MH/s (9.41ms) @ Accel:4 Loops:64 Thr:1024 Vec:1
Recovered........: 240316/13100638 (1.83%) Digests

Time.Started.....: Mon Jul  6 13:21:31 2020 (17 mins, 54 secs)
Guess.Mask.......: ?l?l?l?l?l?l?l?l [8]
Speed2...........:   191.6 MH/s (4.43ms) @ Accel:2 Loops:128 Thr:1024 Vec:1
Recovered........: 534498/12860322 (4.16%) Digests

GPU Time = 5 + 46 + 17*60 + 54 secs

Cracked = 132666 + 240316 + 534498 = 907.480

Hash Cracked Per Second = 806,65

Total Cracked So Far = 4.938.574

Remaining Hashes = %71,39

If you are sitting near your GPU, you might have felt an increase in room temperature. Unlike wordlist based attacks, this method generates candidates instead of reading them from a file. This method can easily to max out your GPU and use every bit of resource. If you are using a single GPU, you might see flickers and tears on your screens while such an attack is running. When we compare the speeds with earlier attacks:

Pure wordlist

Speed2...........: 13366.2 kH/s (1.06ms) @ Accel:1024 Loops:1 Thr:64 Vec:1

Wordlist with rule list

Speed2...........: 84501.0 kH/s (17.70ms) @ Accel:32 Loops:77 Thr:64 Vec:1

Combinator with single rule

Speed2...........: 147.1 MH/s (3.70ms) @ Accel:2 Loops:128 Thr:1024 Vec:1

Mask attack with large space

Speed2...........: 191.6 MH/s (4.43ms) @ Accel:2 Loops:128 Thr:1024 Vec:1

The last one is the most extended attack we used. Not all LinkedIn members are native English speakers. As we can see, hash per second is not very high for this one. We have chosen to spend some time on eight characters to find new words for our later attacks.

Experts often say that passwords should contain more than letters and digits. Another powerful feature of hashcat is the ability to define custom character sets in rules. We already removed some of the only letter and only digit passwords with our earlier scans.

We need two custom character sets for our last mask attack.

  • -1 ?l*.$-_!

all lower letters, "*" , "." , "$" , "-" , "_", "!"

  • -2 ?u?l*.$-_!

all uppercase, all lower letters, "*" , "." , "$" , "-" , "_", "!"

Time.Started.....: Mon Jul  6 13:44:45 2020 (9 secs)
Guess.Mask.......: ?2?1?1?1?1?1 [6]
Guess.Charset....: -1 ?l*.$-_!, -2 ?u?l*.$-_!, -3 Undefined, -4 Undefined
Speed2...........:   205.1 MH/s (13.75ms) @ Accel:2 Loops:128 Thr:1024 Vec:1
Recovered........: 17904/12325824 (0.15%) Digests

Time.Started.....: Mon Jul  6 13:48:54 2020 (4 mins, 59 secs)
Guess.Mask.......: ?2?1?1?1?1?1?1 [7]
Guess.Charset....: -1 ?l*.$-_!, -2 ?u?l*.$-_!, -3 Undefined, -4 Undefined
Speed2...........:   210.7 MH/s (5.60ms) @ Accel:2 Loops:128 Thr:1024 Vec:1
Recovered........: 29119/12307920 (0.24%) Digests

GPU Time = 9 + 4 * 60 + 59 secs

Cracked = 17904 + 29119 = 47.023

Hash Cracked Per Second = 157,27

Total Cracked So Far = 4.985.597

Remaining Hashes = %71,12

These were the low hanging fruits. Bunch of ready to use mask lists come with hashcat. These masks were generated from earlier leaks, and using them would be cheating for us.

ls hashcat-6.0.0/masks/
8char-1l-1u-1d-1s-compliant.hcmask     rockyou-1-60.hcmask    rockyou-4-43200.hcmask   rockyou-7-2592000.hcmask
8char-1l-1u-1d-1s-noncompliant.hcmask  rockyou-2-1800.hcmask  rockyou-5-86400.hcmask
hashcat-default.hcmask                 rockyou-3-3600.hcmask  rockyou-6-864000.hcmask

5.4 Hybrid Wordlist + Mask | 6

While talking about rule attacks, we added 2000 to the end of all our words. What if we wanted to test every word with every possible past or future year in the end? Hybrid attacks help you scan this space.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist --remove -d 2 -a 6 /speed/corncob_lowercase.txt ?d?d?d?d

Time.Started.....: Mon Jul  6 13:58:17 2020 (15 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?d?d?d?d) [4], Right Side
Speed2...........: 38177.7 kH/s (12.81ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 127489/12278801 (1.04%) Digests

GPU Time =15 secs

Cracked = 127.489

Hash Cracked Per Second =8.499,27

Total Cracked So Far = 5.113.086

Remaining Hashes = %70,38

If we combine this new method with our custom rule set, we create an efficient attack.

  • -1 ?l*.$-_!

all digits, all lower letters, "*" , "." , "$" , "-" , "_", "!"

Time.Started.....: Mon Jul  6 14:03:07 2020 (0 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?1) [1], Right Side
Guess.Charset....: -1 ?d?l*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   178.0 MH/s (10.24ms) @ Accel:8 Loops:42 Thr:1024 Vec:1
Recovered........: 0/12151312 (0.00%) Digests

Time.Started.....: Mon Jul  6 14:04:12 2020 (1 sec)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?1?1) [2], Right Side
Guess.Charset....: -1 ?d?l*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   115.7 MH/s (15.62ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 2604/12151312 (0.02%) Digests

Time.Started.....: Mon Jul  6 14:04:56 2020 (31 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?1?1?1) [3], Right Side
Guess.Charset....: -1 ?d?l*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   137.7 MH/s (3.08ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 82217/12148708 (0.68%) Digests

Let us remove letters from our charset to speed up our scans.

Time.Started.....: Mon Jul  6 14:08:00 2020 (18 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?1?1?1?1) [4], Right Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   213.6 MH/s (3.07ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 3200/12062227 (0.03%) Digests
Remaining........: 12059027 (99.97%) Digests

Time.Started.....: Mon Jul  6 14:09:01 2020 (4 mins, 37 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Left Side
Guess.Mod........: Mask (?1?1?1?1?1) [5], Right Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   184.0 MH/s (3.07ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 29830/12059027 (0.25%) Digests

GPU Time = 0 + 1 + 31 + 18 + 4 * 60 + 37 sec

Cracked = 0 + 2604 + 82217 + 3200 + 29830 = 117.851

Hash Cracked Per Second = 360,40

Total Cracked So Far = 5.230.937

Remaining Hashes = %69,70

5.5 Hybrid Mask + wordlist | 7

This method is very similar to our last method. The difference is in the ordering. This attack puts masks before the wordlist.

Since putting numbers before passwords are not as common as putting them after the words, we go with the same character and digits-based mask.

./hashcat-6.0.0/hashcat.bin -m 100 hashlist --remove -d 2 -a 7 -1 ?d\*.\$-_! ?1 /speed/corncob_lowercase.txt

Time.Started.....: Mon Jul  6 14:15:28 2020 (1 sec)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Right Side
Guess.Mod........: Mask (?1) [1], Left Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   834.5 kH/s (1.65ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 0/12029197 (0.00%) Digests

Time.Started.....: Mon Jul  6 14:16:09 2020 (1 sec)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Right Side
Guess.Mod........: Mask (?1?1) [2], Left Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........: 11787.0 kH/s (1.91ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 37/12029197 (0.00%) Digests

Time.Started.....: Mon Jul  6 14:16:53 2020 (2 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Right Side
Guess.Mod........: Mask (?1?1?1) [3], Left Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   134.1 MH/s (2.82ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 413/12029160 (0.00%) Digests

Time.Started.....: Mon Jul  6 14:17:44 2020 (21 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Right Side
Guess.Mod........: Mask (?1?1?1?1) [4], Left Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   179.6 MH/s (6.74ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 34492/12028747 (0.29%) Digests

Time.Started.....: Mon Jul  6 14:18:52 2020 (4 mins, 19 secs)
Guess.Base.......: File (/speed/corncob_lowercase.txt), Right Side
Guess.Mod........: Mask (?1?1?1?1?1) [5], Left Side
Guess.Charset....: -1 ?d*.$-_!, -2 Undefined, -3 Undefined, -4 Undefined
Speed2...........:   231.6 MH/s (20.16ms) @ Accel:4 Loops:128 Thr:1024 Vec:1
Recovered........: 4425/11994255 (0.04%) Digests

GPU Time = 1 + 2 + 21 + 4 * 60 + 19 sec

Cracked =37 + 413 + 34492 + 4425 = 39.367

Hash Cracked Per Second = 139,11

Total Cracked So Far = 5.270.304

Remaining Hashes = %69,47

Now, we tried every different attack in hashcat and recovered only a certain percentage of hashes. Some might think we need more hardware or computation time to recover the rest of the hashes.

6. Using the Information

Nowadays, people often think hash cracking is about hardware power. Hash cracking is about processing information; it is about thinking about the keyspace and statistics and finding patterns.

If you were to toss a perfect coin, both sides have a fifty percent chance. If you toss six coins, can you expect three heads and three tails? Not very likely. During WWII, a mathematician named John Kerrich was imprisoned in a prison camp. During this time, he tossed a coin 100 times and got 5067 heads. Statistics gets its power from numbers, this is called the law of large numbers.

Basicly for statistics to work accurately, you need a large number of samples. Since we are working with a pretty large dataset, this law applies for us.

All we did so far was about extracting information from our hashes. Now we know some of them, and we need to use this information to gather more information. By recovering some hashes from our list, we unknowingly created a very optimized wordlist. How many of the recovered hashes have some form of similarity with the unrecovered hashed?

Hashcat saved recovered hashes in a file called "hashcat.potfile", which currently holds all the recovered hashes. Let's transform this file into a wordlist.

cat hashcat-6.0.0/hashcat.potfile  | cut -d: -f2 > ourlist

Let us run our wordlist with all the rules; this would take a while.

Time.Started.....: Mon Jul  6 14:34:39 2020 (2 hour, 13 mins)
Time.Estimated...: Mon Jul  6 15:48:35 2020 (0 secs)
Guess.Base.......: File (ourlist)
Guess.Mod........: Rules (allrules)
Guess.Queue......: 1/1 (100.00%)
Speed.2.........:   122.5 MH/s (3.57ms) @ Accel:64 Loops:16 Thr:64 Vec:1
Recovered........: 4909894/11799033 (41.61%) Digests

GPU Time = 2 hour, 13 mins

Cracked = 4.909.894

Hash Cracked Per Second = 615,27

Total Cracked So Far = 10.180.198

Remaining Hashes = %41,03

As we can see, this new wordlist is exceptionally optimized for our hash list; even with a fundamental attack, we cracked almost 5 million new hashes!

We used three hours of GPU time for the all steps of this guide on a GPU from time period of the leak.

Using a smaller ruleset could yield faster results. But we wanted to exhaust all the known rules for the second part of this tutorial. In the second part, we will create our custom ruleset, custom mask lists, improve our custom dictionary, and even use statistical methods like Markov Chains to generate candidates for hash recovery. To properly evaluate the efficiency of our future custom methods, we allow this scan to run entirely.

Published under  on .

Root101

Open Source and Linux, Notes, Guides and Ideas