ansible-vault & ansible2john
Ansible Vault encrypts files or individual YAML values at rest. The report finds encrypted configuration fields, recovers a weak vault passphrase, then decrypts the stored service credential. The vault password and enclosed account password are different secrets.
Identify the container
head -n 1 encrypted-value.vault
python3 /usr/share/john/ansible2john.py encrypted-value.vault > vault.john
john --wordlist=lab-candidates.txt vault.john
john --show vault.john
A complete payload begins with an Ansible Vault header such as $ANSIBLE_VAULT;1.1;AES256. For an inline !vault | YAML value, copy only that block into a separate file, remove YAML indentation and retain the header and every hexadecimal line. Do not pass a whole mixed YAML document to the extractor and assume all values were processed.
Open after recovery
ansible-vault view encrypted-value.vault --ask-vault-pass
# When a separate plaintext evidence copy is required:
ansible-vault decrypt encrypted-value.vault --ask-vault-pass --output verified-value.txt
view avoids replacing the encrypted input; decrypt without a separate output can overwrite it. Success: the recovered vault password authenticates decryption of the original payload. Confirm the resulting value’s role before any login test. Keep the plaintext copy private and delete it when evidence retention ends. Use a strong vault password and keep vault-password files separate from the encrypted repository.
Whole files, inline values and vault IDs
| Form | Identification | Preparation |
|---|---|---|
| Encrypted file | Header on the first line | Extract a protected copy directly |
| Inline YAML value | !vault tag followed by an indented block | Save only the de-indented vault payload |
| Vault-ID-labelled payload | Header includes a label, commonly format 1.2 | Keep the complete header and choose the matching vault identity |
# Structure only: hexadecimal data omitted
service_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;lab
<COMPLETE_HEXADECIMAL_PAYLOAD>
The placeholder above is not crackable input. A label such as lab helps select a password source; it is not the encryption password. Different blocks in the same YAML file may use different vault passwords.
Preserve originals and extraction errors
umask 077
mkdir -p evidence/vault
cp encrypted-value.vault evidence/vault/input.vault
sha256sum evidence/vault/input.vault > evidence/vault/input.sha256
python3 /usr/share/john/ansible2john.py evidence/vault/input.vault \
> evidence/vault/input.john 2> evidence/vault/extract-errors.txt
wc -l evidence/vault/input.john
Check that a complete $ansible$ record exists before starting John. Keep each inline field in its own evidence file so a successful password can be associated with the correct configuration key.
Isolate the cracking session
john --session=lab-vault --wordlist=lab-candidates.txt evidence/vault/input.john
john --status=lab-vault
john --restore=lab-vault
john --show evidence/vault/input.john
--restore resumes an interrupted saved session; it is not a second simultaneous run against an active session. A previously recovered password can appear immediately because John retains a potfile. Verify it with Ansible rather than treating that line as proof of a new crack.
For a labelled payload, prompt for the correct identity:
ansible-vault view evidence/vault/input.vault --vault-id lab@prompt
Diagnose failure at the correct step
| Symptom | What to check |
|---|---|
| Extractor rejects header | Complete header, supported format and YAML indentation |
| Hex decoding fails | Truncated lines, added whitespace or copied YAML keys |
| John loads no hashes | Jumbo format support and extractor stderr |
| Candidate list exhausted | Format is correct; candidates did not match |
| Ansible cannot decrypt a potfile hit | Correct block, vault ID and exact password including punctuation |
| Decrypted value is another encrypted object | Identify that object’s format and validate it separately |
What a useful finding contains
Record the repository/file path, YAML key, vault label, original digest, extraction tool and local decryption result. Explain whether the weakness was a guessable passphrase, an exposed vault-password file, or both. A credential found inside the plaintext is a second disclosure; its current validity and permissions need separate validation. See John extractors for other file formats.
Related learning
How attacks work. Examples use fictional lab values; replace placeholders only with values from the system you are testing.