Housekeeping found a guest laptop after an early checkout. Room 214, registered to vera. IT pulled a full KAPE triage before wiping it. The room is Forensics / Hard, and the whole thing is one long credential ladder: a Windows login password unlocks DPAPI, DPAPI unlocks the browser key, the browser key hands you a saved password, and that password mounts an encrypted vault. No cracking the vault — just a good memory.
Two tracks
Same solve, two lenses. First the manual CLI chain you'd run in an IR workstation. Then the same chain with Claude (Cowork) driving — an offline forensics copilot that walked the whole ladder and left behind a reusable tool. Flag and passwords are abstracted to placeholders below.
Recon
Interesting artifacts in the KAPE dump:
C/Windows/System32/config/{SAM,SYSTEM} # local hashes
C/Users/vera/AppData/Roaming/Microsoft/Protect/<SID>/ # DPAPI master key
C/Users/vera/AppData/Local/Google/Chrome For Testing/User Data/
Local State # DPAPI-wrapped AES key
Default/Login Data # saved passwords (SQLite)
C/Users/vera/Documents/backup # 100 MiB, no magic
The backup file is the target:
$ file backup
backup: data
$ python3 -c "import math,collections as c; d=open('backup','rb').read(200000); \
print(-sum((n/len(d))*math.log2(n/len(d)) for n in c.Counter(d).values()))"
7.999
Fixed size, no header magic, entropy pegged at 8 bits/byte. That's a TrueCrypt/VeraCrypt container. The username vera is not subtle.
The 1.26.29 nudge
The in-room hint ("why did Patch tell me this version number 1.26.29") points at a Chromium-flavoured artifact. Translation: the secret you need was typed into a browser, not into a shell.
The chain — by hand
1. NT hash to login password
$ impacket-secretsdump -sam SAM -system SYSTEM LOCAL
vera:1000:aad3b435b51404eeaad3b435b51404ee:1241186a4aac4f34f4bf7ace71b396a8:::
$ echo '1241186a4aac4f34f4bf7ace71b396a8' > nt.hash
$ john --format=NT --wordlist=rockyou.txt nt.hash # → <login-pass>
# or, GPU: hashcat -m 1000 -a 0 nt.hash rockyou.txt
This is the only step that touches a wordlist — you need the plaintext to unwrap DPAPI, not to open the vault.
2. Login password to DPAPI master key
$ impacket-dpapi masterkey \
-file <SID>/<GUID> \
-sid S-1-5-21-2529683458-431225740-1723070931-1000 \
-password <login-pass>
Decrypted key with User Key (SHA1)
Decrypted key: 0x5e5715ec...9d40
3. Master key to the Chrome AES key, to the saved password
Chrome's Local State holds an AES-256-GCM key, itself DPAPI-wrapped (a DPAPI prefix on the blob). Unwrap it with the master key, then decrypt each v10 blob in Login Data (3-byte prefix | 12-byte nonce | ciphertext | 16-byte GCM tag).
URL : http://bytelotus.thm:8080/
USER: VeraSecretVault
PASS: <vault-pass>
4. That saved password is the VeraCrypt volume key
$ sudo cryptsetup open --type tcrypt --veracrypt backup vera
Enter passphrase: <vault-pass>
$ sudo mount -o ro /dev/mapper/vera /mnt/vera
$ ls /mnt/vera/secret_financial_documents/
important_invoice_byte_lotus.pdf transactions_q3.csv
The flag is rendered on the invoice: THM{<redacted>}. The line item reads like a confession — fitting, given who Vera turned out to be.
The chain — with Claude driving
Second track: I ran the same room inside a Cowork session, fully offline, pointed at the KAPE folder. The agent dumped the hashes, cracked the NT hash, walked the DPAPI master key, unwrapped the Chrome AES key and decrypted Login Data — then hit the one interesting wrinkle:
No kernel crypto in the sandbox
The cloud sandbox had no dm-crypt / AF_ALG, so cryptsetup --veracrypt was a dead end. Instead of stopping, it decrypted the VeraCrypt header (PBKDF2-HMAC-SHA512, 500000 iterations) and the AES-XTS data region in pure Python, carved the FAT32 image, pulled the PDF, and rendered it to confirm the flag.
Two things worth stealing from that run:
- The XTS data-unit numbering is absolute — the first data sector sits at
encryptedAreaStart / 512(here131072 / 512 = 256), not zero. Number from zero and your "decrypted" volume is still noise.cryptsetuphides this behind an IV offset; do it by hand and you meet it. impacket.dpapi.deriveKeysFromUser()returns three candidate keys (SHA1-, MD4/NTLM- and legacy-derived), not two. Loop over all of them until the master key decrypts, or the "obvious" key fails you on a real case.
The session also left behind a reusable tool — a self-contained chrome_dpapi_decrypt.py that takes the login password, SID and the three Chrome/Protect paths and prints every saved credential. Pure Python, no kext, runs the same on macOS as in a Linux VM.
Copilot, not oracle
An agent is a force multiplier, not an authority. Every step above is reproducible by hand — the payoff is speed and a clean tool at the end, not blind trust. Read the code it writes before you run it, especially in DFIR where the output is evidence.
Why this works
DPAPI is the hinge. Once you hold a user's login password (or their master key), the entire pile of "protected" per-user secrets falls over: browser passwords, saved RDP creds, Wi-Fi keys, cached credentials. That's exactly the Credential Access story a SOC watches for (MITRE T1555.003, T1552). The room just walks it end to end and parks a vault key at the bottom.
The container never needed brute force. The design flaw is human: a high-value passphrase saved into a browser turns a strong VeraCrypt volume into a one-hop pivot.