đź§ Offline Cracking of Password-Protected Files (-2john)
What is it?
- Concept: A huge range of unrelated-looking formats — encrypted ZIPs, PKCS#12/
.pfxcertificate bundles, Ansible Vault files, Password Safe databases, KeePass databases, SSH private keys, Office documents — all share the same underlying shape: a single passphrase runs through a KDF to derive a key, and the file itself carries enough salt/iteration/verification data to check a candidate passphrase without needing anything external. John the Ripper’s*2johnfamily is one script per format that reaches into that structure and re-emits it as a single generic hash line, so every one of these formats ends up cracked with the exact same offline dictionary-attack workflow. This note is the umbrella for all of them — individual formats don’t get their own separate technique note, since the pattern (and the fix) is identical regardless of which specific file is involved. - Impact: Turns “I have a file/vault I can’t open” into a completely offline, rate-limit-free dictionary/brute-force attack, with no interaction with the file’s origin system required — and because these passphrases are almost always chosen by a human for convenience (deployment automation, a personal database, a backup archive), a plain
rockyou.txtrun is frequently enough regardless of which format is involved.
How it works
- A protected file format stores everything needed to verify a password (a salt, a KDF iteration count, and a checksum/MAC computed from the correctly-derived key) directly inside the file — that’s how the legitimate application checks a password without needing to “phone home.”
- Cracking it offline just means recomputing that same verification step for every candidate password from a wordlist, entirely locally — but each format packs those verification fields differently, so a generic cracker needs a per-format parser to find them.
- Each
*2johnscript is exactly that parser: it reads the target file’s specific structure and re-emits the salt/iterations/verification value as one line in John’s own generic hash syntax (which Hashcat can frequently also consume, format-dependent) — the only real distinction between formats was ever extracting the right fields in the first place. - From there it’s an ordinary dictionary attack, no different in principle from cracking an NTLM hash. Once cracked, the recovered passphrase decrypts the file with that format’s own native tool (
unzip,openssl pkcs12,ansible-vault,pwsafe, …) —*2johnonly ever gets you the passphrase, not the plaintext directly.
Exploitation
Prerequisites
- Read access to a password/passphrase-protected file (ZIP, PFX, Ansible Vault, Password Safe database, etc.)
Attack Vectors
Every format below follows the same <format>2john '<input>' > <format>.hash naming — one consistent .hash extension for every extracted hash regardless of which script produced it, so the follow-up john <format>.hash ... command is always predictable instead of needing to remember a different suffix per format.
Encrypted ZIP Archives
zip2john '<file>.zip' > zip.hashjohn zip.hash --wordlist=/usr/share/wordlists/rockyou.txtunzip -P '<cracked_password>' '<file>.zip'PKCS#12 (.pfx) Certificate Bundles
A .pfx found bundled inside an archive is protected by its own password, independent of whatever unlocked the archive around it — always re-crack rather than reusing the outer password:
pfx2john '<file>.pfx' > pfx.hashjohn pfx.hash --wordlist=/usr/share/wordlists/rockyou.txtAnsible Vault
Targets a $ANSIBLE_VAULT;1.1;AES256-headered file, or an inline !vault | YAML block copied out into its own file first:
ansible2john '<vault_file>' > vault.hashjohn vault.hash --wordlist=/usr/share/wordlists/rockyou.txt
# hashcat -m 16900 --username vault.hash /usr/share/wordlists/rockyou.txtOnce cracked, decrypt with Ansible’s own tool rather than John/Hashcat — they only ever recover the passphrase, not the plaintext:
ansible-vault view '<vault_file>' --vault-password-file <(echo '<cracked_password>')Password Safe (.psafe3) Databases
See Password Safe (pwsafe) for the full command set once a hash is extracted:
pwsafe2john '<file>.psafe3' > psafe.hashjohn --format=pwsafe psafe.hash --wordlist=/usr/share/wordlists/rockyou.txtNotes
- The full
*2johnfamily (documented on John’s wiki) covers far more than the four formats above —ssh2john,office2john,keepass2john,rar2john,bitlocker2john, and dozens more. If a proprietary format shows up that isn’t obviously covered, check there before assuming it needs a custom cracker. - Layered protection is common and each layer needs its own crack — an outer ZIP’s password almost never also unlocks a
.pfx/vault sitting inside it; re-run the matching*2johnscript and crack again rather than assuming reuse. - One passphrase, many secrets: unlike a per-account password, an Ansible Vault (or similar) passphrase protects every secret encrypted under it — cracking one vault string is often enough to decrypt an entire playbook tree’s worth of credentials in one shot. Plain-text Ansible inventory/config files sitting next to the vaulted ones are also worth checking — not everything gets vaulted consistently.
- Every
*2johnscript (zip2john,pfx2john,ansible2john,pwsafe2john, …) is callable by its bare name oncejohnis installed — most are symlinks into/usr/share/john/under the hood, but that detail doesn’t matter day-to-day;which <format>2johnconfirms one exists before assuming a format isn’t covered. *2johnoutput isn’t always exclusive to John — several formats’ hash syntax (Ansible Vault being a common one) is also directly consumable by Hashcat with the right-mmode, worth trying if John’s default cracking speed for that format is slow.
Mitigation
- Fix: The strength of every attack in this family is entirely a function of passphrase strength — the file-format-level verification data being crackable at all is inherent to the format, not a bug. Use long, high-entropy passphrases for anything protecting a sensitive file or vault, and rotate any credential that was ever protected by a passphrase of uncertain strength — offline cracking is undetectable until it’s too late.
Related Usage
| File | Created |
|---|---|
| HTB - Administrator | Wednesday, July 22nd 2026, 5:00:00 am |
| HTB - Authority | July 23, 2026 |
| HTB - Timelapse | Friday, July 24th 2026, 12:47:06 am |
References: