đź§  Offline Cracking of Password-Protected Files (-2john)

What is it?

  • Concept: A huge range of unrelated-looking formats — encrypted ZIPs, PKCS#12/.pfx certificate 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 *2john family 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.txt run is frequently enough regardless of which format is involved.

How it works

  1. 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.”
  2. 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.
  3. Each *2john script 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.
  4. 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, …) — *2john only 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.hash
john zip.hash --wordlist=/usr/share/wordlists/rockyou.txt
unzip -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.hash
john pfx.hash --wordlist=/usr/share/wordlists/rockyou.txt

Ansible 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.hash
john vault.hash --wordlist=/usr/share/wordlists/rockyou.txt
# hashcat -m 16900 --username vault.hash /usr/share/wordlists/rockyou.txt

Once 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.hash
john --format=pwsafe psafe.hash --wordlist=/usr/share/wordlists/rockyou.txt

Notes

  • The full *2john family (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 *2john script 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 *2john script (zip2john, pfx2john, ansible2john, pwsafe2john, …) is callable by its bare name once john is installed — most are symlinks into /usr/share/john/ under the hood, but that detail doesn’t matter day-to-day; which <format>2john confirms one exists before assuming a format isn’t covered.
  • *2john output 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 -m mode, 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.
FileCreated
HTB - AdministratorWednesday, July 22nd 2026, 5:00:00 am
HTB - AuthorityJuly 23, 2026
HTB - TimelapseFriday, July 24th 2026, 12:47:06 am

References: