Mutating Wordlists
Password policies, which have grown in prevalence in recent years,
dictate a minimum password length and the use of character variation
including upper and lower case letters, special characters, and numerical values.
Most passwords in the commonly-used wordlists
will not fulfill these requirements.
We can address this by automating the process of changing (or mutating)
our wordlists before sending them to this target
in what is known as a rule-based attack.
In this type of attack, individual rules are implemented through rule functions,
which are used to modify existing passwords contained in a wordlist.
An individual rule consists of one or more rule functions.
We will often use multiple rule functions in each rule.
In order to leverage a rule-based attack, we’ll create a rule file
containing one or more rules and use it with a cracking tool.
In a simple example, we could create a rule function
that appends fixed characters to all passwords in a wordlist,
or modifies various characters in a password.
For the following example, we’ll assume that we face a password policy
requiring an upper case letter, a special character, and a numerical value.
Let’s check the first 10 passwords of rockyou
to determine if they fit this requirement.
We’ll use the head command to display the first 10 lines of the wordlist.
The listing shows that none of the first ten passwords of rockyou
fulfill the requirements of the password policy of this example.
We could now use rule functions to mutate the wordlist to fit the password policy.
But before we mutate a complex wordlist like rockyou,
let’s first familiarize ourselves with rule functions
and how to use them with a more basic example.
In order to demonstrate rule functions such as capitalization,
let’s copy the 10 passwords and save them to demo.txt in a newly-created directory.
Then, we’ll remove all number sequences (which don’t fit the password policy)
by using sed with ^1 referring to all lines starting with a “1”,
deleting them with d,
and doing the editing in place with -i.
We now have five passwords in our demo wordlist.
Let’s mutate these passwords to fit the password policy,
which must include a numerical value,
a special character, and an uppercase letter.
If we want to add a character, the simplest form is to prepend or append it.
We can use the $ function to append a character or caret to prepend a character.
Both of these functions expect one character after the function selector.
For example, if we want to prepend a “3” to every password in a file,
the corresponding rule function would be caret 3.
When generating a password with a numerical value,
many users simply add a “1” at the end of an existing password.
Therefore, let’s create a rule file containing $1
to append a “1” to all passwords in our wordlist.
We’ll create a demo.rule with this rule function.
We need to escape the special character “$” to echo it into the file correctly.
Now, we can use hashcat with our wordlist mutation, providing the rule file with -r,
and --stdout, which starts Hashcat in debugging mode.
In this mode, Hashcat will not attempt to crack any hashes,
but merely display the mutated passwords.
The listing shows that a “1” was appended to each password
due to the rule function $1.
Now, let’s address the upper case character of the password policy.
When forced to use an upper case character in a password,
many users tend to capitalize the first character.
Therefore, we’ll add the c rule function to our rule file,
which capitalizes the first character and converts the rest to lower case.
Let’s try an example using two rule files: demo1.rule and demo2.rule.
We will format these files differently.
In demo1.rule, the rule functions are on the same line separated by a space.
In this case, Hashcat will use them consecutively
on each password of the wordlist.
The result is that the first character of each password is capitalized
AND a “1” is appended to each password.
In demo2.rule the rule functions are on separate lines.
Hashcat interprets the second rule function, on the second line, as new rule.
In this case, each rule is used separately,
resulting in two mutated passwords for every password from the wordlist.
Good!
We have adapted the demo1.rule rule file to two of the three password policies.
Let’s work on the third and add a special character.
We’ll start with “!”, which is a very common special character.
Based on this assumption, we’ll add $! to our rule file.
Since we want all rule functions applied to every password,
we need to specify the functions on the same line.
Again, we will demonstrate this with two different rule files
to stress the concept of combining rule functions.
In the first rule file we’ll add $! to the end of the first rule.
In the second rule file we’ll add it at the beginning of the rule.
The output shows that demo1.rule mutates passwords
by appending first the “1” and then “!”.
The other rule file, demo2.rule, appends “!” first and then the “1”.
This shows us that the rule functions are applied from left to right in a rule.
The rule contained in demo1.rule mutates the passwords of our wordlist
to fulfill the requirements of the password policy.
Now that we have a basic understanding of rules and how to create them,
let’s crack a hash with a rule-based attack.
In this demonstration,
let’s assume that we retrieved an MD5 hash from a target system.
We’ll use the rockyou wordlist, and modify it for a password policy
requiring an upper case letter,
a numerical value, and a special character.
Let’s create a rule file to address this password policy.
As before, we’ll use the c rule function for the capitalization of the first letter
We’ll also use “!” again as special character.
For the numerical values we’ll append the (ever-popular) “1”, “2”, and “123”
followed by the special character.
Next, we can run Hashcat.
We will disable debugging by removing the standard out argument.
Instead, we’ll specify -m, which sets the hash type.
In this demonstration, we want to crack MD5, which is hash type 0,
which we retrieved from the Hashcat hash example page.
After the hash type,
we’ll provide the target MD5 hash file (crackme) and the rockyou wordlist.
Then, we’ll specify -r to provide our demo3.rule.
As our Kali VM doesn’t have access to a GPU,
we’ll also enter --force to ignore related warnings from Hashcat.
In this case, we cracked the password,
which was not included in the default rockyou file.
This only took Hashcat a few seconds despite running on the CPU.
When attempting to create rules to mutate an existing wordlist,
we should always consider human behavior and convenience with regard to passwords.
Most users use a main word and modify it to fit a password policy,
perhaps appending numbers and special characters.
When an upper case letter is required, most users capitalize the first letter.
When special characters are required
most users add the special character at the end of the password
and rely on characters on the left side of the keyboard
since these digits are easy to reach and type.
Instead of creating rules ourselves,
we can also use rules provided by Hashcat or other sources.
Hashcat includes a variety of effective rules in its rules directory.
These predefined rules cover a broad variety of mutations
and are most useful when we don’t have any information
about the target’s password policy.
We’ll use the predefined rules in the upcoming demonstrations and examples.
However, it’s always most efficient to discover information about existing
password policies,
or to look up typically-used default policies
for the target software environment.
Let’s briefly summarize what we did in this section.
We began by discussing rule-based attacks
and why they are preferred over dictionary attacks.
Then, we discussed rules and used them to mutate wordlists to crack an MD5 hash.
At the end of this section
we briefly introduced the predefined rule files provided by Hashcat.
In the next section we’ll discuss a basic methodology for cracking,
which we can use as an outline for demonstrations and exercises.