Cracking Password - Statistics will break your Password & Policy

The first two articles in our Password Cracking series have dealt with the Password cracking basics and some cool tricks deals. Although the approaches shown are important for understanding, they have so far tended to move within a theoretical framework.

Now we are confronting what we have learned with reality and thus demonstrating its practical applicability: In this article we present two cases in which we have successfully operated password cracking in real pen tests.

Table of Contents

Password cracking in the reality check

Case presentation: Company A without, company B with a password policy

The two case studies discussed here have some things in common: In both cases, the tested companies worked with classic Active Directory. Our pentesters took over the DC and then downloaded the NTDS.dit using DC Sync.

Company A is a larger company that did not have a password policy in place. Company B is a medium-sized company with different password policies for administrators and users. The respective password policies were configured sensibly.

It is probably not surprising that we were able to recover around 80% of the passwords at company A after a short time using password cracking. But we were also able to recover about 60% of the passwords (of users and administrators) at company B. How was that possible?

Do you want to get started as a penetration tester?
Qualify for your dream job with our practice-oriented intensive course!
To the Junior Penetration Tester certificate course

A look at the password policies

Company A had no password policy and the minimum length of 8 characters made password cracking very easy for us. In addition, some passwords were not set at all or were used several times. These requirements explain the high success rate of recovering the passwords.

Company B's password policy looks very secure at first glance: it enforced password updates after 30 days, stored a history of 24 previous passwords, and required three out of four complexity characteristics. However, the admin network still allowed LM hashes for password storage. The minimum length for passwords was 4 characters. Company B had thus fully met the old requirements of "NIST Special Publication 14 - 800. Appendix A".

Sounds really safe, doesn't it?

In reality, well-intentioned password policies unfortunately often lead to insecure passwords.

In the following sections, we examine each requirement and identify weaknesses in Company B's policy. (Spoiler Alert: The biggest vulnerability is usually the human.)

complexity requirements

In theory, complexity requirements should make it more difficult to crack passwords by increasing the number of possible character combinations. In practice, however, users often meet the requirements using typical schemes and, on the contrary, make cracking easier:

Capitalized first letters, followed by lower case letters and then numbers or special characters. Do your “secure” passwords happen to look like this too?

With the knowledge of such patterns, masks, rules and dictionaries can be created that are aimed precisely at such patterns.



Password history

The password history in AD is intended to prevent password reuse after password changes, but by storing expired passwords it can reveal extensive information about user behavior. The forced regular changes do not increase security, but ensure weaker passwords that are created once and then changed minimally each time. This weakens security in that a single cracked password from Password History can reveal all other passwords. A user's password history can be easily cracked with rules and masks.

The password history is not downloaded with the “normal” NTDS dump. Even frameworks like Crackmapexec can't do this at the moment. However, Secretsdump offers a suitable option with -history.


 example.local/Administrator:password123@ -history


Password reuse

So are you on the safer side if you don't force users to renew their passwords regularly? Not really, because passwords that have been created once are often used several times. Thanks to the missing salts in NTLM, Password Reuse is already recognizable from the hashes.

Due to Password Reuse, up to 30% of systems can have the same password.

This high number is partly due to the default administrator-assigned passwords for machine accounts in Active Directory. In addition, typical passwords are used several times by different people.

The password summer+year is an inglorious example.



weak ciphers

It sometimes still happens today that LM hashes were not deactivated in older systems or for reasons of backwards compatibility. The LM hash is the predecessor of the NT hash and has numerous cryptographic weaknesses, which means that it can be cracked without any problems today.

LM_Hashes should be disabled by default these days.


					LM deaktivert bzw. leerer LM Hash
example.local\user01:aad3b435b51404eeaad3b435b51404ee :9b1b37b966345526850732e17aed49f8:Sommer2022!

LM nicht deaktiviert
example.local\user02:628eddc897eb8d8cfb12c634df37c04f :9b1b37b966345526850732e17aed49f8:Sommer2022!

It's cracking time

A close look at the password policies of the two companies A and B revealed some weaknesses and points of attack. This section now deals with the methods with which these vulnerabilities can be exploited.

Step 1: Dictionary, Hybrid, and Mask/Bruteforce Attacks

First, I used a few methods against the passwords you're familiar with from the first articles: dictionary, hybrid, and mask/bruteforce attacks. My first approach to both NTDS dumps consisted of:

					1. LM-Hashes vorhanden?
    Wenn ja:
    hashcat -a3 -m3000 a?a?a?a?a?a?a?

2. Bruteforce bis 8 Zeichen:
    hashcat -a3 -m1000 -O -w4 ntds.txt "?a?a?a?a?a?a?a?a"

3. Wörterbuchangriffe mit Regeln und Loopback:
    hashcat -a0 -m1000 -O -w4 ntds.txt wörterbuch.txt -r rule.rule --loopback

4. OSINT & Cewl 
 Erstellung von gezielten Wörterbüchern mittels Cewl
 Suche nach weiteren Informationen über das Ziel

5. Gezieltere Wörterbuchangriffe mit Regeln und Loopback
    hashcat -a0 -m1000 -O -w4 ntds.txt eigenes_Wörterbuch.txt -r --loopback rule.rule


In this way, I cracked about 60% (company A) and 40% (company B) of the hashes in the first step. I then carried out a password analysis to determine and exploit statistical peculiarities.

Step 2: Analyze cracked passwords manually

The cracked passwords showed some abnormalities:

  • word repetitions
  • keyboard walk
  • Sätze
  • Similar suffixes or prefixes





Ähnliche Suffixe bzw. Präfixe:


These are all typical password combinations that can be easily cracked with the right rules and dictionaries.

The knowledge for this is publicly available, so an attacker could easily crack about 50% of the passwords.

However, in order to crack more than 50%, knowledge about the optimization of Hashcat and the attacks used is necessary. The next step deals with that.

Run through attack scenarios under realistic conditions?
You can do it legally in our holistic hacking lab!
To the Junior Penetration Tester course

Step 3: Use tools for analysis, statistics, rules and masks

Analyzing the cracked passwords further, tools like Pack and Pipal come into play to find common ground. Based on this analysis, statistics, rules and masks are then created to crack passwords with similar schemes. If information about the password policy is available, as in this case, you can use Pack to generate masks. This section introduces Pack and its included programs, as well as Pipal as an alternative, and gives tips on how to use them.


Peter Kacherginsky has Pack (Password Analysis and Cracking Kit) developed several years ago. Nowadays there is a rewrite in Python3 from Hydraze. With Pack you can analyze and evaluate passwords and design your own masks, rules and statistics. Pack consists of several programs: Statsgen, Maskgen, Policygen, Rulegen. All functions of Pack are mapped with these subprograms.


					git clone

Für RuleGen benötigt
sudo apt install python3-enchant



The basis of Pack is StatsGen, which is used to analyze passwords. Statsgen creates statistics about passwords, length distribution, character sets, password complexity and possible masks. Pack needs this information for its further use.

Another possibility with Statsgen is the -hiderare parameter, so that the statistics are not falsified by rare passwords. Filters can also be used to examine certain passwords more closely. To do this, use the -charset,-simplemask,-maxlength,-minlength options. Created masks can be saved with -O and used by Hashcat.



Pack is the Password Analysis and Cracking Kit

Syntax examples:

					Analyse von Passwörtern:
python3 cracked_hashes.txt

Analyse und Ausschluss von seltenen Passwörtern:
python3 cracked_hashes.txt --hiderare

Analyse und Speicherung als Maske:
python3 cracked_hashes.txt -o 

Analyse und Filterung  + alles vorherige:
python3 cracked_hashes.txt --simplemask=stringdigit --hidereare -o 


MaskGen optimizes the masks generated by StatsGen by sorting and analyzing masks. This allows better hash cracking results to be achieved.

You can sort masks by complexity, frequency or OptIndex (mixture of complexity and frequency). Most of the time -optindex is a good method for sorting, but for Password Policies -Complexity might also be worth a look. In my opinion, the parameter for sorting –occurrence can be neglected, since only a few meaningful masks are generated with it.

Often not all attacks can be carried out in pen tests. This is always a timing problem, especially with masks or brute force attacks. The maximum permitted time for all masks can be specified with –targettime. With —targettime, the entire duration of the engagement can be specified, i.e. the maximum possible time. Individual masks can be displayed with –showmasks and evaluated for their length, frequency and duration. This can be useful to find temporal outliers or masks that do not fit into the scheme for other reasons.

With the -showmasks parameter, the individual masks can be output with their respective length, frequency and duration. The -pps parameter is important for keeping the calculation realistic: It includes the computing power in passwords per second. With higher computing power, more extensive masks can be searched more quickly and vice versa. With -o, the masks can be saved in the .hcmasks format, which Hashcat can work with without any problems. The maskgen headers can be hidden with -q.

Individual filters:
You can also sort masks by length, time, complexity or frequency using individual filters. The -minlength or -maxlength parameters are useful if e.g. B. up to 8 letters is cracked or you want to refrain from masks from a certain length. The duration of an individual mask can be specified with the parameters –mintime or –maxtime.

Personally, I would specify the duration of the available time with -targettime and the time for the respective individual mask with -mintime in order to avoid outliers. The masks can be fine-tuned with –min/maxcomplexity and –min/maxoccurrence, but the above parameters are usually sufficient to get started.

Your own masks generated with Maskgen can be tested on password lists for their functionality against real passwords. However, I would advise caution here, as most password leaks come from websites and/or from the English-speaking area. Therefore, many of these dumps are not comparable to the typical passwords from the "German" AD environment. It is still possible with the –checkmasksfile option, in which two masks are compared with each other.


Pack is the Password Analysis and Cracking Kit

Syntax examples:

					Analyse von Masken, Anzeige aller Masken und eigener Geschwindigkeit: 
python  --showmasks --pps 10000000
Analyse von Masken und Sortierung nach optindex:
python  --optindex 

Analyse von Masken und Filterung nach Länge:
python  --minlength=9 --maxlength=14

Analyse von Masken und Sortierung nach einzelner Maskenlaufzeit
python  --targettime 21600

Analyse von Masken und Filterung nach gesamter Maskenlaufzeit:
python  --maxtime=3600 



PolicyGen is the tool of choice when it comes to corporate password policies. In AD environments, password policies (link to Article 1) often enforce a minimum level of complexity. The use of upper and lower case letters, numbers and special characters is enforced here. PoliyGen generates masks that conform to this scheme.

PolicyGen can be used to perform a variety of tasks: check password policy compliance, support password cracking in pen tests, and check password policies.

As with MaskGen, the hashes per second can be specified using -pps. This also applies to other parameters such as -o to save, -showmasks and -q. The length of the password can be specified with the parameters –min/maxlength. It should be noted here that masks that are too large can no longer be cracked in an acceptable time. The individual policy parameters can be defined using -min/maxspecial, -min/maxdigit, -min/maxupper, -min/maxlower. If you are looking for passwords that violate the policy as part of an audit, you can do this with -noncompliant.

With Windows Password Policies, however, there is a special feature: only 3 of 4 complexity requirements are required natively, which is not intended in PolicyGen. The workaround consists of executing all 4 combinations manually, then merging them into one file and then deduplication. Also, –noncompliant would be a useful option here to find passwords that violate the policy.

					./ --minlength=9  --maxlength=10 --mindigit=1 --minspecial=1 --minlower=1 -o testing/mask01.hcmask
./ --minlength=9  --maxlength=10 --mindigit=1 --minspecial=1 --minupper=1 -o testing/mask02.hcmask
./ --minlength=9  --maxlength=10 --mindigit=1 --minlower=1 --minupper=1 -o testing/mask03.hcmask
./ --minlength=9  --maxlength=10 --minspecial=1 --minlower=1 --minupper=1 -o testing/mask04.hcmask

cat *.hcmask >> allmasks
sort allmasks | uniq -u > 9-10_chars_3_off_4.hcmask


Pack is the Password Analysis and Cracking Kit

Syntax examples:

					Passwort Policy zwischen 9 und 14 Zeichen
./ --minlength=9 --maxlength=14

Passwort Policy mit verschiedenen Zeichen als Mindestanforderung:
./ --minspecial=1 --minlower=1 --minupper=1 --mindigit=1

Passwort Policy mit verschiedenen Zeichen als Maximalanforderung:
./ --maxdigit=5 --maxlower=3 --maxupper=4 --maxspecial=2

Passwort Policy mit verschiedenen Zeichen und Filterung nach noncompliant
./ --minspecial=1 --minlower=1 --minupper=1 --mindigit=1 --noncompliant


RuleGen offers tools and possibilities to analyse, generate and optimize rules. For this purpose, cracked passwords are analyzed using the Python library Enchant and language engines such as Aspell, Myspell and Hunspell. Rulegen can analyze both individual passwords and entire lists of words and create suitable rules. You can also analyze and further optimize rules that have been created.

In order for Rulegen to work properly, some dictionaries need to be used for the various spelling corrections. It is recommended to install as large a variety of dictionaries as possible: different languages, dialects, subject-specific dictionaries or also old/new orthography.


					Eine kleine Auswahl an Wörterbüchern:
sudo apt install aspell-de-1901
sudo apt install aspell-de
sudo apt install aspell-nl
sudo apt install aspell-fr
sudo apt install hunspell-de-de
sudo apt install hunspell-de-med
sudo apt install hunspell-de-at
sudo apt install hunspell-de-ch


Individual passwords:

Individual passwords can then be changed with the –password to be analyzed. Here it makes sense to use the verbose mode in order to be able to follow the creation of the rule.

Exotic words can be forced as root words using -word, as they are often not recognized by the language engine. A usage example would be the customer name in the pentest. For several such custom words, you can use –wordlist to specify your own dictionaries, which should also be taken into account. Own word lists are particularly useful if you already have cracked passwords or want to use special language/words.

The –morerules and –morewords parameters are suitable for creating more rules or word suggestions. These options allow the generation of suboptimal rules and words. Another option for adjusting RuleGen would be the —maxworddist=10 option, which adjusts the allowed Levenshtein distance. With these options it should be noted that more root words or rules can be generated, but the quality does not necessarily increase.

Comparison of different RuleGen options in terms of the amount of cracked hashes:
It can be seen that Aspell is the more efficient speech correction and the default settings are more than sufficient in most cases.

Note: The evaluation does not meet any scientific requirements and was only carried out with a limited number of different NTDS dumps.

					Standardeinstellungen mit Aspell
./ hash.txt --providers=aspell  -b test03
Recovered........: 3309/9061 (36.52%) Digests (total), 3309/9061 (36.52%) Digests (new)
Standart Einstelllungen mit hunspell
./ hash.txt --providers=hunspell  -b test02
Recovered........: 2963/9061 (32.70%) Digests (total), 2963/9061 (32.70%) Digests (new)

Einstellungen mit verschiedenen Parametern zusammen 
./ hash.txt  --maxworddist=15 --morewords --morerules --providers=aspell,myspell,hunspell  -b test01
Recovered........: 2656/9061 (29.31%) Digests (total), 2656/9061 (29.31%) Digests (new)

Password lists:

Password lists can simply be specified as a file and are interpreted directly by RuleGen. The passwords in the lists must be entered without the respective hash value or other additions. Passwords that do not provide sufficient patterns are skipped. The same applies to numbers and non-ASCII characters, which is a certain limitation with different languages.

With the -b option the results can be saved in a file. An unsorted rules and root words file is created.


Pack is the Password Analysis and Cracking Kit

Syntax examples:

					Rulegen Analyse einzelner Passwörter im Verbose Modus:
./ Hashlist --password WinterS8793! -verbose

Rulegen Analyse von Passwortlisten mit Speicherung der Regeln
./ Hashlist -b 

Rulegen Analyse von Passwortlisten mit verschiedenen Sprachprovidern:
./ Hashlist --providers=aspell,hunspell,myspell

Rulegen Analyse von Passwortlisten mit erzwungenen Stammwörtern:
./ Hashlist —word=  

Rulegen Analyse von Passwortlisten mit eigenen Wörterbüchern:
./ Hashlist -w /path/to/the/dict 

Rulegen Analyse von Passwortlisten mit Fine-Tuning der Regel/Wort Generierung:
./ Hashlist --maxworddist=10 --maxwords=7 --maxrulelen=15 --maxrules = 5



An alternative to Pack is Pipal, programmed by Robin Wood aka Digininja. Just like Pack, it analyzes passwords and offers a few special features, which I will discuss below.

The program has a modular structure so that all functions can be activated or deactivated. The modules are called Checkers and each offer individual specific functions. The modular design offers the great advantage that functions that are not required can be temporarily deactivated. This brings advantages in terms of time, especially with large password lists.

By default, Pipal only uses the Basic Checker, which analyzes the most common passwords and root words, password length and distribution, and letter/digit usage. Other checkers include methods for analyzing languages ​​such as German, English, French and Dutch. There are also checkers that (similar to StatsGen) generate masks for Hashcat or compare passwords with the default Windows password policy.

In my opinion, the key difference to Pack and StatsGen is that Pipal is much more focused on purely analyzing and evaluating passwords. StatsGen, on the other hand, is more intended for creating masks in combination with MaskGen and shows its strengths there.


Für manche Module sollte auch noch das Gem "levenshtein-ffi" installiert sein:
gem install levenshtein-ffi

# Checkers:
Aktivieren des Basic Checkers:
ln -s ../checkers_available/basic.rb .

Aktiveren aller anderen Checker:
ln -s ../checkers_available/*rb .


Note that activating additional checkers can significantly increase the duration of the password analysis: the more checkers are used, the longer the process takes. Since these are symlinks, you can easily delete unnecessary checkers from the checkers_enabled file

Using different checkers can unlock different options, so I'm assuming the following setup:

					ls checkers_enabled/
01basic.rb            DE_emotion_checker.rb  DE_religion_checker.rb  DE_season_checker.rb  DE_vehicle_checker.rb      README
DE_colour_checker.rb  DE_family_checker.rb   DE_road_checker.rb      DE_sport_checker.rb   hashcat_mask_generator.rb  windows_complexity_checker.rb

For the analysis of passwords, Pipal needs a file with the respective passwords and the desired checker. The analysis then takes place automatically and is written to an output file with -o. Hashcat masks for all analyzed words can be output with the -hashcat.all option.


Pipal is the alternative to Pack Password Analysis and Cracking Kit

Syntax examples:

					Pipal Analyse einer Passwortliste:

Pipal Analyse einer Passwortliste und Speicherung:
./pipal.rb  -o 

Pipal Analyse einer Passwortliste und Anzeigen der Top Passwörter:
./pipal.rb  --top 

Pipal Analyse einer Passwortliste und Ausgabe aller Hashcat-Masken:
./pipal.rb  --hashcat.all


Learnings for penetration testers

With the tools, techniques and methods described in the text, we were able to significantly increase the amount of cracked hashes in both case studies with little effort.

With all analysis tools, however, you should always keep in mind that programs can do a lot, but humans can recognize more patterns than programs. My advice is therefore to carry out analyzes yourself and, if necessary, to write your own rules or masks for the respective case. Programming or scripting helps enormously to simplify this work.

Still, Pack & Pipal are two extremely valuable tools in advanced password cracking. In both cases, we were able to crack a significant amount of additional hashes using the Pack capabilities described above.

As a pentester (or attacker in general) I would use statistical methods to find patterns and exploit them. The topic still offers a lot of room for further research and own developments.

I will describe the further procedure in detail in the following articles, since there are a large number of methods, especially for cracking the last third of passwords. Password cracking is a very extensive topic if done correctly, so this article can only give an excerpt of the various options for password analysis.

Learnings for admins and users

Our first article on the topic of password cracking was about password policies, which, with the right settings, represent an important element of protection against attackers. In the case studies mentioned above, Company B's password policy meant that we were able to crack “only” 80% of the passwords instead of 60% using relatively simple means.

However, the still quite high percentage of cracked passwords also shows the weaknesses of the password policy instrument: users are “just human” and often look for the most convenient way to comply with guidelines. For example, a well-intentioned password history can actually mean that only minimally changed passwords can be cracked even more easily.

As a sysadmin (or defender in general), I would advise combining passwords with a lot of user awareness and MFA due to human weaknesses. Passwords generated by humans are always very vulnerable to statistical or even probabilistic attacks.

Don't want to waste time on your way to becoming a penetration tester?
In our courses, led by experienced penetration testers, you will learn everything you really need for this.
Go to the Junior Penetration Tester Intensive Course
Newsletter Form

Become a Cyber ​​Security Insider

Get early access and exclusive content!

By signing up, you agree to receive occasional marketing emails from us.
Please accept the cookies at the bottom of this page to be able to submit the form!

Table of Contents

NewsLetter Form Pop Up New

Become a Cyber ​​Security Insider

Subscribe to our knowledge base and get:

Early access to new blog posts
Exclusive content
Regular updates on industry trends and best practices

By signing up, you agree to receive occasional marketing emails from us.
Please accept the cookies at the bottom of this page to be able to submit the form!