Introduction
In this lab, you will explore an advanced feature of Hashcat: custom charsets in mask attacks. While Hashcat's built-in charsets (?l, ?u, ?d, ?s) are powerful, they can be inefficient if you have specific information about the characters used in a password. For example, if you know a password only contains the characters 'a', 'b', 'c', '1', '2', '3', using the standard ?l and ?d charsets would test many unnecessary characters.
Custom charsets allow you to define a precise set of characters, dramatically reducing the search space and speeding up the cracking process. You will learn how to define a custom charset, create a mask that uses it, and execute a targeted attack to crack a password hash that follows a unique pattern.
Understand the Limitations of Built-in Charsets
In this step, you will learn about Hashcat's built-in charsets and why they are not always the most efficient tool for the job.
Hashcat uses placeholders, called charsets, to represent different types of characters in a mask attack:
?l= abcdefghijklmnopqrstuvwxyz?u= ABCDEFGHIJKLMNOPQRSTUVWXYZ?d= 0123456789?s= !"#$%&'()*+,-./:;<=>?@[]^_`{|}~?a= All of the above combined
These are useful for general cases, but if we know the password is composed of a very specific, limited set of characters, using these broad charsets is inefficient.
First, let's inspect the target hash we need to crack. The setup script has already created a file named hash.txt in your current directory (~/project).
View its content:
cat hash.txt
You should see the following MD5 hash:
2a5c3a657a73613391a8e58f1a43161e
This hash corresponds to an 8-character password composed only of the characters l, a, b, e, x, 1, 2, 3. If we were to use the built-in ?l and ?d charsets, Hashcat would waste time trying all 26 lowercase letters and 10 digits, instead of just the 8 known characters. In the next step, we will create a custom charset to solve this problem.
Define a Custom Charset with --custom-charset1
In this step, you will define a custom charset that precisely matches the characters known to be in the password.
Hashcat allows you to define up to four custom charsets using the command-line options --custom-charset1, --custom-charset2, --custom-charset3, and --custom-charset4.
For our scenario, the password is known to contain only characters from the set labex123. We can define this as our first custom charset.
Let's construct a command to see how this works. We will use the --stdout option to print the generated password candidates to the screen instead of performing a real attack. We'll also use head to only see the first few results.
Run the following command to generate 3-character passwords using our custom charset:
hashcat --stdout -a 3 --custom-charset1 labex123 ?1?1?1 | head -n 5
Let's break down this command:
--stdout: Prints the generated candidates to the console.-a 3: Specifies a mask attack.--custom-charset1 labex123: Defines?1as our custom set of characters.?1?1?1: The mask, which tells Hashcat to generate 3-character candidates where each character is from the set defined in?1.
You will see output like this, showing that only our specified characters are being used:
lll
lla
llb
lle
llx
Now you understand how to define a custom charset for a targeted attack.
Create a Mask that Utilizes the Custom Charset ?1
In this step, you will construct a mask that uses the custom charset you defined in the previous step.
Custom charsets are referenced in a mask using the placeholders ?1, ?2, ?3, and ?4, corresponding to the --custom-charset<N> option used. Since we used --custom-charset1, we will use ?1 in our mask.
We know our target password is 8 characters long, and every character is from our custom set. Therefore, the correct mask is ?1 repeated eight times.
For clarity and reusability, it's good practice to save your mask in a file. Let's create a file named mask.txt and put our mask inside it.
Execute the following command to create the file:
echo "?1?1?1?1?1?1?1?1" > mask.txt
Now, verify the content of the file to make sure it's correct:
cat mask.txt
The output should be exactly what you entered:
?1?1?1?1?1?1?1?1
With the mask file ready, you are now prepared to launch the attack.
Execute a Mask Attack with the Custom Charset
Now you will combine everything to launch the mask attack using your custom charset and mask file.
You have the hash in hash.txt, the custom charset defined, and the mask in mask.txt. Let's assemble the final Hashcat command.
Run the following command in your terminal to start the attack:
hashcat -m 0 -a 3 hash.txt --custom-charset1 labex123 mask.txt
Here is a breakdown of the full command:
-m 0: Specifies the hash type is MD5.-a 3: Selects mask attack mode.hash.txt: The input file containing our target hash.--custom-charset1 labex123: Defines our custom charset?1.mask.txt: The file containing the mask?1?1?1?1?1?1?1?1.
Hashcat will start the attack. Because our custom charset is very specific, the keyspace is small, and the attack should finish very quickly. You will see output indicating the progress, and finally, a status of Cracked.
...
Session..........: hashcat
Status...........: Cracked
Hash.Name........: MD5
Hash.Target......: 2a5c3a657a73613391a8e58f1a43161e
Time.Started.....: ...
Time.Estimated...: 0 secs (0.00ms)
Guess.Mask.......: ?1?1?1?1?1?1?1?1 [8]
Guess.Charset....: Custom Charset 1: 'labex123', len=8
Speed.#1.........: ... H/s (0.00ms) @ Accel:1 Loops:1 Thr:1 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 16777216/16777216 (100.00%)
Rejected.........: 0/16777216 (0.00%)
Restore.Point....: 1/1 (100.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: labex123 -> labex123
Hardware.Mon.#1..: Util: 0%
Started: ...
Stopped: ...
The attack is complete and successful. In the next step, you'll verify the cracked password.
Verify the Cracked Password Matches the Custom Pattern
In this final step, you will view the cracked password and confirm that it matches the expected pattern.
Hashcat automatically saves successfully cracked passwords to a file called a "potfile" (because it "pots" the hash and password). This prevents re-cracking the same hash in the future. The easiest way to see the cracked password for a given hash file is to use the --show option.
Execute the following command to display the cracked password for the hash in hash.txt:
hashcat -m 0 --show hash.txt
This command tells Hashcat to look up the hash from hash.txt in its potfile and display the corresponding plaintext password.
The output will be clear and simple:
2a5c3a657a73613391a8e58f1a43161e:labex123
As you can see, the cracked password is labex123. Notice that it is 8 characters long and contains only characters from the custom charset labex123 that you defined. This confirms that your targeted mask attack was successful and highly efficient.
Summary
In this lab, you have learned a powerful and efficient password cracking technique using Hashcat.
You started by understanding the limitations of Hashcat's built-in charsets for passwords with specific, known character sets. You then learned how to define your own character set using the --custom-charset1 option and reference it in a mask with ?1. By creating a mask file and launching a targeted attack, you were able to crack an MD5 hash in seconds.
This method of using custom charsets is essential for efficient password auditing and recovery when you have intelligence about the password's structure, significantly reducing the time and computational resources required for an attack.


