Management Wants a Word — Forensics (Hacker Holidays, Day 14)

Management Wants a Word — Forensics (Hacker Holidays, Day 14) Link to heading

Room: TryHackMe — Hacker Holidays Catégorie: Forensics / Windows Registry / DPAPI Tags: KAPE NTUSER.DAT DPAPI impacket hashcat Chrome VeraCrypt steganography

TL;DR Link to heading

Un dump KAPE fournit une arborescence Windows. L’énoncé oriente vers le navigateur (“un navigateur va se souvenir de choses pour toi”). Les identifiants sauvegardés dans Chrome sont protégés par DPAPI ; pour les déchiffrer il faut casser le mot de passe Windows de l’utilisatrice via son hash NTLM (SAM), puis remonter toute la chaîne DPAPI jusqu’à la clé AES de Chrome. Les identifiants récupérés ne sont pas des creds web mais la passphrase d’un volume VeraCrypt déguisé en fichier backup. Le flag est caché dans un PDF présent dans ce volume.


1. Reconnaissance Link to heading

Arborescence fournie (extrait) :

./C/Users/vera/Documents/backup
./C/Users/vera/NTUSER.DAT (+ .LOG1/.LOG2)
./C/Windows/System32/config/{SAM,SYSTEM,SOFTWARE,SECURITY,DEFAULT} (+ LOGs)

Le fichier backup attire l’attention :

$ stat -c%s ./C/Users/vera/Documents/backup
104857600            # exactement 100 MiB

$ file ./C/Users/vera/Documents/backup
./C/Users/vera/Documents/backup: data   # entropie élevée, aucun magic number

Une taille aussi ronde et l’absence totale de header laissent penser à un conteneur chiffré créé volontairement (VeraCrypt/TrueCrypt ne posent pas de header en clair, par design, pour le déni plausible).

2. Fausse piste : artefacts registre classiques Link to heading

Première intuition : “dernières commandes” → RunMRU, TypedPaths, UserAssist, WordWheelQuery dans NTUSER.DAT.

hivexregedit --export "./C/Users/vera/NTUSER.DAT" '\' > ntuser.reg
rg -i "runmru|wordwheelquery|typedpaths" ntuser.reg

Toutes ces clés existent mais sont vides, y compris après rejeu des journaux de transaction (.LOG1/.LOG2) via regipy. Piste abandonnée — l’indice narratif de la room pointe explicitement ailleurs :

“ok so apparently a browser will remember things for you that you never told anyone else 💀 not every hidden file needs a password cracker, some of them just need a really good memory” — @0xMia

3. Artefacts navigateur Link to heading

Le profil de vera contient une installation Chrome for Testing (build sans App-Bound Encryption — DPAPI simple, pas la double couche introduite dans Chrome 127+) :

C:\Users\vera\AppData\Local\Google\Chrome For Testing\User Data\Local State
C:\Users\vera\AppData\Local\Google\Chrome For Testing\User Data\Default\Login Data

Chrome empile deux couches de chiffrement sur les mots de passe enregistrés :

  1. Local State → os_crypt.encrypted_key : une clé AES-256 aléatoire, chiffrée une fois via DPAPI (CryptProtectData).
  2. Login Data (SQLite) : chaque password_value chiffré en AES-256-GCM avec cette clé AES.

Il faut donc d’abord la masterkey DPAPI de l’utilisateur, stockée sous :

C:\Users\vera\AppData\Roaming\Microsoft\Protect\<SID>\<GUID>
$ find . -ipath "*Protect*" -type f
./C/Users/vera/AppData/Roaming/Microsoft/Protect/S-1-5-21-2529683458-431225740-1723070931-1000/c90719ef-5b98-474e-b934-136d606a702a
./C/Users/vera/AppData/Roaming/Microsoft/Protect/S-1-5-21-2529683458-431225740-1723070931-1000/Preferred

Le SID est directement le nom du dossier ; le fichier nommé par son GUID est la masterkey chiffrée.

SID  : S-1-5-21-2529683458-431225740-1723070931-1000
GUID : c90719ef-5b98-474e-b934-136d606a702a

4. Obtenir le mot de passe Windows de vera Link to heading

4.1 — Hash NTLM via secretsdump.py (impacket) Link to heading

secretsdump.py -sam ./C/Windows/System32/config/SAM \
               -system ./C/Windows/System32/config/SYSTEM LOCAL
vera:1000:aad3b435b51404eeaad3b435b51404ee:1241186a4aac4f34f4bf7ace71b396a8:::

Note d’environnement. Sur une machine avec plusieurs installations Python/impacket qui se chevauchent, secretsdump.py peut lever une TypeError interne (unexpected keyword argument). Le plus fiable est un venv isolé :

python3 -m venv /tmp/impvenv
/tmp/impvenv/bin/pip install "impacket==0.12.0" "setuptools<81"
/tmp/impvenv/bin/secretsdump.py -sam SAM -system SYSTEM LOCAL

4.2 — Crack du hash avec hashcat Link to heading

hashcat -m 1000 1241186a4aac4f34f4bf7ace71b396a8 /usr/share/wordlists/rockyou.txt
1241186a4aac4f34f4bf7ace71b396a8:minivera

Mot de passe Windows de vera : minivera

Chemin alternatif. On peut éviter l’étape SAM/SYSTEM entièrement en extrayant un hash crackable directement depuis le fichier masterkey avec dpapimk2john.py (John the Ripper), puis en le cassant avec john/hashcat :

dpapimk2john.py --sid <SID> --masterkey <fichier_masterkey> > mkey.hash
john --wordlist=rockyou.txt mkey.hash

5. Déchiffrement DPAPI avec les outils impacket Link to heading

Plutôt qu’un script maison, impacket fournit dpapi.py (dans les exemples du dépôt) qui couvre tout le pipeline masterkey → blob :

curl -o dpapi.py https://raw.githubusercontent.com/fortra/impacket/master/examples/dpapi.py

5.1 — Déchiffrement de la masterkey utilisateur Link to heading

python3 dpapi.py masterkey \
  -file "AppData/Roaming/Microsoft/Protect/<SID>/<GUID>" \
  -sid S-1-5-21-2529683458-431225740-1723070931-1000 \
  -password minivera

→ affiche la masterkey déchiffrée (clé de session DPAPI de vera).

5.2 — Déchiffrement de la clé AES de Chrome (blob DPAPI) Link to heading

Le champ os_crypt.encrypted_key de Local State est un blob base64 préfixé DPAPI (5 octets) suivi de la structure DPAPI chiffrée avec la masterkey utilisateur :

python3 dpapi.py blob \
  -file local_state_encrypted_key.bin \
  -key <masterkey déchiffrée à l'étape 5.1>

→ clé AES-256 utilisée par Chrome pour chiffrer chaque mot de passe stocké.

6. Déchiffrement des identifiants Chrome Link to heading

Login Data est une base SQLite. Chaque password_value suit le format Chrome standard :

[v10 | v11]  (3 octets)  →  nonce GCM (12 octets)  →  ciphertext  →  tag GCM (16 derniers octets)

Avec la clé AES de l’étape 5.2, déchiffrement AES-256-GCM direct (pycryptodome) sur la table logins :

Champ Valeur
URL http://bytelotus.thm:8080/
Utilisateur VeraSecretVault
Mot de passe Wh4t1sV3raD0inG0nTh1sH0st

Point d’analyse. bytelotus.thm n’est résolvable nulle part dans le dump (pas d’entrée hosts, aucune trace DNS dans SYSTEM/SOFTWARE). Le nom d’utilisateur VeraSecretVault et l’absence de service réel à cette URL suggèrent que ces identifiants ne sont pas des creds web, mais servent de passphrase pour un conteneur chiffré local — confirmé ci-dessous.

7. backup est en fait un volume VeraCrypt Link to heading

Taille ronde (100 MiB), entropie maximale, aucun header identifiable — tout concorde avec un conteneur VeraCrypt (déni plausible = pas de magic number en clair).

sudo mkdir -p /mnt/veracrypt_test
sudo veracrypt --text --mount ./C/Users/vera/Documents/backup /mnt/veracrypt_test \
  --password="Wh4t1sV3raD0inG0nTh1sH0st" --pim=0 --keyfiles="" --protect-hidden=no

Montage réussi :

/mnt/veracrypt_test/
├── $RECYCLE.BIN/
├── System Volume Information/
└── secret_financial_documents/
    ├── important_invoice_byte_lotus.pdf
    └── transactions_q3.csv

8. Extraction du flag — stéganographie dans le PDF Link to heading

transactions_q3.csv contient une ligne suspecte au milieu de transactions plausibles :

2026-07-12,TXN-10531,Internal Adjustment,Image asset correction,0.00,Archived

→ indice explicite vers une image manipulée.

pdftotext sur le PDF ne renvoie rien : le document est composé uniquement d’une image scannée. Extraction de l’image embarquée :

pdfimages -list important_invoice_byte_lotus.pdf
pdfimages -all  important_invoice_byte_lotus.pdf /tmp/pdf_img

L’inspection de l’image extraite (stéganographie) révèle le flag de la room.

9. Synthèse de la chaîne complète Link to heading

Étape Outil / méthode
Extraction hash NTLM impacket secretsdump.py (SAM + SYSTEM)
Crack du hash hashcat -m 1000 + rockyou.txt → minivera
Localisation SID / masterkey AppData\Roaming\Microsoft\Protect\<SID>
Déchiffrement masterkey DPAPI impacket dpapi.py masterkey
Déchiffrement clé AES Chrome impacket dpapi.py blob (Local State)
Déchiffrement credentials AES-256-GCM sur Login Data (SQLite)
Identification du conteneur backup = volume VeraCrypt (100 MiB, sans header)
Montage du volume veracrypt --text --mount
Extraction du flag pdfimages + analyse stéganographique

Flag Link to heading

THM{________________________}

(volontairement masqué dans ce write-up public)


Outils utilisés Link to heading

  • KAPE — collecte des artefacts
  • impacketsecretsdump.py, dpapi.py
  • hashcat — crack NTLM
  • regipy — rejeu des transaction logs de registre
  • hivexregedit (libhivex) — export registre en .reg
  • VeraCrypt — montage du volume chiffré
  • pdfimages (Poppler) — extraction d’images de PDF