The two philosophies of password cracking
You'll see two primary methodologies for password cracking: dictionary and brute-force. The distinction is somewhat of a misnomer; a hash function is a one-way function, so we can't actually defeat the algorithm to find an original text – we can only find collisions (one of which will be the original text). There is no way around this needle-in-a-haystack effort, so really, any tactic is technically a use of brute-force computing speed. So in this context:
- A dictionary attack employs a predefined list of values to hash; this list is often called a dictionary or a wordlist. Wordlists can be employed as defined, where every single entry is tried until the wordlist is exhausted, or it can be modified with rules, making the attack a hybrid attack. Rules apply specific modifications to the wordlist to search for variants of the original word. For example, imagine the wordlist entry is password. A rule may tell the cracker to try capitalizing the initial letter and then adding a number, 0-9, to the end. This will increase the actual wordlist being searched to include password1, password2, and so on. When we consider password-creating habits and human-friendly adaptations to corporate password policy, rule sets tend to be our golden ticket to success in cracking.
- A brute-force attack puts together the full list of all possible combinations of a given character set. By its nature, a plain brute-force attack can take a very long time to complete. We can modify the guesses, similarly to using rules to enhance dictionary attacks, with masking. Masking allows us to define different character sets for certain positions in the password, greatly narrowing down the search space. For example, let's say we want to search for any combination of letters, not just words that may be found in a wordlist; but, we assume the user capitalized the first letter, and then added a couple of numbers to the end. In this example, the mask would set a capital letters character set for the first character position, then both uppercase and lowercase for the remaining letters, and then only digits for the last two character positions. To get an idea of what this can do to a search, let's suppose we're looking for a 10-character password, and the available characters are a-z and A-Z, 0-9, and the 13 symbols along the top of the keyboard. Then, let's apply a mask that only searches for a capital initial letter, and only numbers for the last two characters:
- Without mask: ((26 * 2) + 10 + 13) ^ 10 = 5.6313515 * 10^18. (About 5.63 quintillion passwords.)
- With mask: 26 * (75^7) * (10^2) = 3.4705811 * 10^16. (About 34.7 quadrillion passwords.)
- You might be looking at that and thinking, those are both enormous numbers. But with a very simple mask – a single capital letter at the front, and two digits at the end – we reduced the search space by more than 99.3%. If we had the processing power that would crunch the unmasked space in four days, our mask reduces that to about 36 minutes. As you can see, masking is for brute-force cracking what rule sets are for dictionary attacks: a golden ticket to success when you dump hashes from a domain controller on your client's network.
The key point with both modification methods is to target the psychological factors of password selection. With known words, not many people will use a word without changing some character in a memorable way (and, in fact, corporate password policy simply won't allow unmodified dictionary words). With brute-force attacks, very few people will choose kQM6R#ah*p as a password, but our unmasked 10-character search described just now will check it as well as quadrillions of other unlikely choices.