In many tests, we end up having to do some kind of password cracking, Kerberoasted hashes, hashes dumped from the SAM or ntds.dit, or some other kind of hash. When cracking, especially when we have a bunch of SPNs or we’ve got the ntds.dit, we aren’t focused on cracking every hash. We want to identify the most easily crackable passwords – passwords we can crack within a few days. I’ve been refining my password cracking workflow to help crack more passwords faster and wanted to share some of the things I’ve learned. DISCLAIMER: I am not a Hashcat expert. I’m certain there are more efficient ways to go about doing this.

If you’ve been doing password cracking for a while, you likely have a wordlist of passwords you’ve cracked in the past. The first step in the cracking process would be to run a wordlist attack against the hashes using your previously recovered passwords and your favorite ruleset.

Note: You’ll have to select your ruleset or mask based on the hash type. Remember, we’re not looking to crack everything. Sure, a bruteforce mask attack, or using a large ruleset like the dive rule might get you more results, but when you’re cracking a bunch of Kerberos TGS-REP hashes you got from Kerberoasting, it’s likely going to take quite a while. Similarly, it will take a long time with large masks or rulesets if you have limited hardware, say for instance a single GPU.

For this blog, we’re going to assume we’ve compromised the Nakatomi Corporation’s active directory. During the test, we observed that the password policy required 8-character passwords and complexity is enabled. I’ve prepared a list of hashes by selecting 100,000 random lines from the HaveIBeenPwnedv5 wordlist and eliminating any passwords that don’t match complexity requirements. I’ve combined that with some contrived passwords I created for this blog and the result is 25,738 hashes.

First attempt will be a wordlist attack using the rockyou wordlist and the best64 ruleset. We managed to crack 1298, or 5.04% of the passwords. Not too shabby for our first run.

We all know people are going to select memorable passwords. That’s why Password123 and Summer19! still work. Another thing employees are likely to remember is their username, so make a wordlist of usernames without the domain. In this example, I only have 3 employee names, but in a normal environment you’ll obviously have one username per hash.

cut -f1 -d : < hashfile |cut -f2 -d \\ > ntc.users

We’ll run a wordlist attack again, but this time we’ll use ntc.users as our wordlist. As you can see below, it looks like Joe Takagi and Harry Ellis used passwords based on their username.

I’ve also noticed that people frequently create passwords based on locations like city or state. Using some data from the SecLists project as well as searching Wikipedia and other sources, I created a wordlist of US cities and states as well as all of the world countries. As you can see here, that list with just the best64 rule got us another 31 passwords. We’d likely get many more with a larger ruleset.

People also like sports, and they like to use them in their passwords. I built a wordlist of various professional, minor league, and college team names. We know that Nakatomi Plaza is in LA, so it’s no surprise that there are a few Dodgers fans working at Nakatomi.

After working through a bunch of wordlists, I’ve cracked a respectable 42.38% percent of the hashes cracked. But can I do better? Another trick I’ve found to be very helpful is to parse out all recovered passwords, and make those into a wordlist, and run those back through the process. So, let’s see how that works here. In this case, not so great. Only an additional .07%. In practice, this generally yields a non-trivial increase in cracked passwords. This is true due to several factors:

  • Password patterns set by the helpdesk or used in service accounts
  • Passwords based on the company name
  • Passwords with regional significance – locations, teams, bands, etc.
  • Passwords taken from popular culture

If you’ve cracked passwords in the past, you’ve likely noticed that passwords within organizations tend to follow patterns. Mask attacks are effective technique for finding these similar passwords. If we’ve already done some password cracking, we can use Pipal to generate masks based on the recovered passwords. Note: You’ll need to edit the Pipal output so that only the Hashcat masks remain.

pipal -t 20 -o ntc.hcmask ntc.words

After running Hashcat with a -a 3 attack and our new set of masks, we can see a significant improvement. We’ve gone from 42.45% to 56.49%, a non-trivial 14% in just a few minutes.

You don’t necessarily need a powerful cracking rig to get good results. All of this was done with a single GeForce GTX 1050 Ti in my laptop. In fact, using this process on a recent assessment, I recovered 53% of the hashes from an organization with over 100,000 unique hashes in less than 8 hours of cracking time.

Takeaways

  • Create custom wordlists including the company name, usernames, and other company-relevant words
  • Take the time to build some custom wordlists with things like:
    • Cities, states, countries
    • Sports teams
    • Language dictionaries (at least English and Spanish)
    • Common first names and surnames taken from census data. The SecLists project will give you a good start.

Want to do some testing yourself?  You can practice your craft using some of the well known wordlists, such as the HaveIBeenPwned wordlists. You probably don’t want to use the entire wordlist, as they can be quite large. But you can create a smaller wordlist with the following code. This code will generate passwords that conform to complexity policies requiring 3 of 4 character types.

shuf -n 100000 /mnt/hgfs/wordlists/HaveIBeenPwnedv5.txt > base.txt
grep -x '.\{6,10\}' base.txt | \
   egrep -vx '[0-9]+' | \
   egrep -vx '[a-z]+'| \
   egrep -vx '[A-Z]+'| \
   egrep -vx '[[:punct:]]+' | \
   egrep -vx '[0-9a-z]+' | \
   egrep -vx '[0-9A-Z]+' | \
   egrep -vx '[[:digit:]][[:punct:]]+' | \
   egrep -vx '[a-zA-Z]+' | \
   egrep -vx '[[:lower:]][[:punct:]]+' | \
   egrep -vx '[[:upper:]][[:punct:]]+' \
    > candidates.txt

You can add your own contrived passwords to the candidates file and use the following code to generate hashes for cracking.

#!/usr/bin/env python

import hashlib,binascii
hashfile = open("test.hash", "wb")
with open('candidates.txt') as f:
for password in f:
hash = hashlib.new('md4', password.rstrip('\n').encode('utf-16le')).digest()
hashfile.write(binascii.hexlify(hash) + '\n')
hashfile.close()