Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9c5bef9
Applied 2to3 to each python file
Hydraze Jun 18, 2016
67ae930
deleted unused imports
Hydraze Jun 18, 2016
7b148df
fix statsgen.py's file opening mode and prints of masks
Hydraze Jun 18, 2016
39620d4
fix divisions in maskgen
Hydraze Jun 19, 2016
1f8243c
fix divisions in policygen
Hydraze Jun 19, 2016
3c93ef6
fix small spelling typo
Hydraze Jun 19, 2016
1d73c2a
first pass of cleanup: modified None comparisons to use the is keyword
Hydraze Jun 19, 2016
1c94727
Add an exception handler in case the provider dict does not exist
Hydraze Jun 21, 2016
602342d
Fix file opening to mimic old behaviour
Hydraze Jun 21, 2016
6fc2ad8
Use a python3 integer division instead of the floating one
Hydraze Jun 21, 2016
a208d84
PEP8 compliance for statsgen.py
Hydraze Jun 21, 2016
996fdf8
make analyze_password a static method
Hydraze Jun 21, 2016
8f7ccfc
remove an useless call to len()
Hydraze Jun 21, 2016
8abf9a2
cleanup of maskgen.py (PEP8 compliance)
Hydraze Jun 21, 2016
20e2136
fix a typo in loadmasks where the opened file was arg[0] instead of t…
Hydraze Jun 21, 2016
901ac05
add a static decorator to getcomplexity
Hydraze Jun 21, 2016
17f27f1
improved PEP8 compliance for policygen.py and code cleanup
Hydraze Jun 21, 2016
0b22917
add the staticmethod decorator for getcomplexity method
Hydraze Jun 21, 2016
15e77ef
clean up and PEP8 compliance for rulegen.py
Hydraze Jun 22, 2016
7492eb6
make some methods static in rulegen
Hydraze Jun 22, 2016
e3ed4a8
small style in statsgen.py
Hydraze Jun 22, 2016
5d3ace9
Delete an useless list() added by 2to3
Hydraze Aug 8, 2016
ef1c210
policygen.py now handles maxdigit directive correctly.
Hydraze Aug 8, 2016
92f073a
Fix bug when threads != cpu_count
matlink Mar 17, 2017
3134998
Merge pull request #1 from matlink/patch-2
Hydraze Mar 18, 2017
ba885da
shabang python3
Aug 17, 2017
9f63259
fix python3 env
matlink Aug 17, 2017
78c931f
Fixed 'x' and 'O' rules
Chick3nman Feb 5, 2018
5cd5f1b
Merge pull request #2 from matlink/master
Hydraze Feb 15, 2018
fd779b2
Merge pull request #3 from Chick3nman/master
Hydraze Nov 28, 2019
3d3a070
Modernize PACK toolkit for current Python 3
Jul 28, 2026
9f79c96
Fix StatsGen help output
Jul 28, 2026
cdd28b1
Merge current upstream master into modernize
Jul 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Byte-compiled / optimized files
__pycache__/
*.py[cod]
*$py.class

# Packaging / build artifacts
build/
dist/
*.egg-info/
.eggs/

# Virtual environments
.venv/
venv/
env/

# PACK output files
*.rule
*.word
*.masks
*.hcmask

# Editor / OS cruft
.idea/
.vscode/
*.swp
.DS_Store
677 changes: 0 additions & 677 deletions README

This file was deleted.

165 changes: 165 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# PACK — Password Analysis and Cracking Kit

PACK is a collection of utilities to analyze password lists and turn what you
learn into effective attacks for the [hashcat](https://hashcat.net/hashcat/)
family of password crackers. It detects the masks, character sets, rules and
policies that people actually use, so you can prioritize the cheapest, most
productive candidates first.

> PACK does **not** crack passwords itself. It produces input files (masks,
> rules and wordlists) that make a real cracker far more efficient.

Originally written by Peter Kacherginsky (iphelix). This fork modernizes the
toolkit for current Python 3.

## What's in the box

| Tool | Purpose |
| -------------- | ----------------------------------------------------------------------- |
| `statsgen.py` | Statistical analysis of a password list (length, charset, masks, …). |
| `maskgen.py` | Turn `statsgen` output into optimal, sorted hashcat masks (`.hcmask`). |
| `policygen.py` | Generate masks matching (or violating) a password-complexity policy. |
| `rulegen.py` | Reverse source words and hashcat rules from already-cracked passwords. |

## Requirements

- **Python 3.8+** (no third-party packages for `statsgen`, `maskgen` or
`policygen` — standard library only).
- **`rulegen` only** additionally needs [PyEnchant](https://pyenchant.github.io/pyenchant/)
plus the system `enchant` library and a dictionary.

On Debian/Ubuntu:

```bash
sudo apt install libenchant-2-2 aspell-en hunspell-en-us
```

## Installation

Clone and run the scripts directly:

```bash
git clone https://github.com/iphelix/pack.git
cd pack

# Optional: only needed for rulegen
pip install -r requirements.txt

python3 statsgen.py --help
```

Or install as a package to get the `statsgen`, `maskgen`, `policygen` and
`rulegen` commands on your `PATH`:

```bash
pip install . # core tools
pip install '.[rulegen]' # also pull in pyenchant for rulegen
```

## Usage

### StatsGen — analyze a password list

```bash
python3 statsgen.py rockyou.txt
```

Reports the most common lengths, character sets, password complexity, and both
"simple" masks (e.g. `stringdigit`) and hashcat "advanced" masks
(e.g. `?l?l?l?l?l?l?l?l`). Useful flags:

- `--minlength` / `--maxlength`, `--charset`, `--simplemask` — filter the sample.
- `--hiderare` — hide items covering less than 1% of the sample.
- `-o out.masks` — save advanced masks with occurrences (feed this to `maskgen`).

```bash
python3 statsgen.py rockyou.txt -o rockyou.masks --hiderare
```

### MaskGen — build optimal masks

Consumes the `.masks` file produced by `statsgen -o` and emits a `.hcmask`
sorted by the *optimal index* (coverage vs. cost), occurrence, or complexity:

```bash
python3 maskgen.py rockyou.masks --optindex --showmasks -o rockyou.hcmask
```

- `-t 86400` — stop once the accumulated masks would take longer than N seconds.
- `--pps 1000000000` — cracking speed used for time estimates.
- Filters: `--minlength/--maxlength`, `--min/maxtime`, `--min/maxcomplexity`,
`--min/maxoccurrence`.
- `--checkmasks '?u?l?l?l?l?l?d,...'` or `--checkmasksfile masks.hcmask` — report
how much of your sample a given set of masks would cover.

### PolicyGen — masks for a password policy

Generate only the masks that satisfy (or, with `--noncompliant`, violate) a
complexity policy, avoiding wasted work on impossible candidates:

```bash
python3 policygen.py --minlength 8 --maxlength 8 \
--minlower 1 --minupper 1 --mindigit 1 --minspecial 1 \
-o complexity.hcmask
```

Add `--showmasks` to print each mask with its strength breakdown and estimated
runtime. Maximum bounds (`--maxlower/--maxupper/--maxdigit/--maxspecial`) let you
model sites that forbid certain classes (e.g. `--maxspecial 0`).

### RuleGen — reverse words and hashcat rules

Given already-cracked passwords, `rulegen` finds a likely dictionary source word
and the hashcat rule that transforms it into the password, using the Levenshtein
reverse-path algorithm and Enchant spell-checking. See the paper
[Automatic Password Rule Analysis and Generation](http://thesprawl.org/research/automatic-password-rule-analysis-generation/)
for the theory, and the [hashcat rule reference](https://hashcat.net/wiki/doku.php?id=rule_based_attack)
for rule syntax.

Analyze a single password (prints the source word and rule):

```bash
python3 rulegen.py --password 'P@ssw0rd'
# [word] Password
# [rule] sa@ o50
```

Analyze a whole file — writes `analysis.rule` / `analysis.word` and their
frequency-sorted `-sorted` variants:

```bash
python3 rulegen.py rockyou.txt -b rockyou
```

Handy options:

- `-b BASENAME` — output base name.
- `-w wordlist.dict` — use a custom wordlist instead of the spell checker.
- `--providers aspell,hunspell` — choose enchant provider engines.
- `--maxwords` / `--maxworddist` and `--maxrules` / `--maxrulelen` — tune how many
candidate words/rules are considered and how large they may get.
- `--simplewords` / `--simplerules` — faster, less thorough generation.
- `--bruterules` — also try reversal/rotation pre-rules (slower).
- `-v` / `-d` — verbose / debug output.

## What changed in this modernized fork

- Ported the command-line interface of all four tools from the deprecated
`optparse` to `argparse`.
- Made `rulegen`'s `pyenchant` dependency optional with a clear install message
instead of a raw `ImportError`, and switched the default provider list from the
legacy `aspell,myspell` to `aspell,hunspell` (enchant-2).
- `rulegen --password` now prints the generated word and rule directly instead of
silently discarding them.
- Fixed several bugs: word-frequency percentages summed the wrong counter; the
extract (`x`) rule collided with the truncate (`'`) rule; a debug line was a
no-op string instead of a `print`.
- Guarded against division-by-zero and file-handle leaks on empty inputs, and
wrapped file access in context managers.
- Added packaging (`pyproject.toml`, `requirements.txt`) with console entry points
and a `.gitignore`.

## License

See [LICENSE](LICENSE). PACK is provided for authorized security testing,
password audits, and research.
Loading