Registry Parser
Tous les articles

Récupérer des clés de registre supprimées et survivre au rejeu des journaux

9 min de lecture

La première fois que vous rejouez le journal de transactions d'une ruche et que vous regardez se matérialiser une valeur de registre qui ne devrait pas exister, vous comprenez pourquoi c'est une étape non optionnelle. Le registre vivant tel que Windows vous le montre est une vue des données. Le fichier de ruche en est une autre. Rejouer les journaux en donne une troisième. Comparer avec VSS en donne une quatrième. Les attaquants anti-forensiques comptent sur le fait que la plupart des analystes ne regardent que la première.

Cet article est le flux de récupération qui attrape le reste.

Ce que « supprimé » signifie en termes de registre

Le registre est un arbre copy-on-write à l'intérieur d'un fichier regf. Quand une clé ou une valeur est "supprimée", Windows ne met pas les octets à zéro. Il bascule le signe du champ taille de la cellule de négatif à positif, la marquant libre. Le bloc HBIN continue de contenir les anciens octets jusqu'à ce qu'une allocation ultérieure réutilise l'espace.

Cela s'applique aux valeurs supprimées, aux clés supprimées (dont les cellules nk et enfants sont toutes marquées libres), et aux cellules libérées pendant une réallocation quand une valeur dépasse sa taille d'origine. Un analyseur regf qui parcourt les cellules libres de la même façon que les cellules allouées fera remonter les enregistrements supprimés avec leurs noms, types et données intacts.

La passe de récupération sur cellules non allouées

Les analyseurs matures font cela automatiquement :

  1. Parcourir chaque bloc HBIN.
  2. Pour chaque cellule libre, tenter de l'analyser comme un enregistrement typé (nk, vk, sk, lh, db, ...).
  3. Valider contre les contraintes de format : longueur de nom sensée, comptes d'enfants raisonnables, horodatages plausibles, décalages embarqués pointant vers des cibles du type attendu.
  4. Faire remonter tout enregistrement qui valide.

La validation sépare une passe utile d'une passe qui crache des détritus. Des octets aléatoires passent occasionnellement la vérification du magique. Implémentations à connaître : yarp (stricte, conservative), regipy (plus lâche, faux positifs occasionnels, plus facile à scripter), et le plugin del de RegRipper (parcourt la ruche et reconstruit les chemins quand possible).

La sortie inclut typiquement les valeurs récupérées avec leurs noms, types et données ; les clés récupérées avec leurs LastWrite ; et les cellules "orphelines" qui valident mais ne peuvent pas être rattachées à un chemin parce que le nk parent a disparu. Les orphelins ne sont pas inutiles : une cellule vk pour une valeur nommée Debugger contenant C:\Windows\Temp\evil.exe est informative même sans savoir sous quelle sous-clé IFEO elle se trouvait.

Rejeu de journaux de transactions, fait correctement

Chaque ruche primaire sur Windows moderne est livrée avec .LOG1 et .LOG2. Le schéma à double journal protège contre une perte de courant pendant les écritures. Les rejouer n'est pas optionnel.

Les journaux contiennent des entrées de pages sales décrivant les modifications validées dans le journal mais pas encore flushées dans la ruche primaire. Chaque entrée dit "au décalage N, écrire ces M octets". Le rejeu les applique dans l'ordre.

Ce que le rejeu fait remonter :

Écritures en cours. Changements journalisés mais jamais persistés dans le fichier primaire. Ils apparaissent dans la ruche rejouée et nulle part ailleurs.

Séquences récemment validées. Même quand la primaire a été flushée, le journal peut encore contenir les écritures les plus récentes. Comparer la ruche post-rejeu à la primaire non rejouée vous dit ce qui a changé dans la dernière fenêtre de synchro.

Résidus de crash. Si le système a planté entre l'écriture du journal et le flush de la primaire, les journaux peuvent contenir des enregistrements que le registre vivant n'a jamais vus. Exactement les enregistrements que les attaquants ne s'attendent pas à ce que vous trouviez.

Numéros de séquence, bitmaps de pages sales, validation par entrée : faites le rejeu correctement ou utilisez une bibliothèque qui le fait déjà. Outils qui le gèrent automatiquement : yarp (--recover), regipy (--apply_transaction_logs), RegRipper quand les journaux sont dans le même répertoire, et l'analyseur de ce site. Vérifiez que l'outil signale réellement avoir rejoué les journaux. Certains sautent silencieusement le rejeu si les journaux semblent propres.

Snapshots VSS : diffs de registre dans le temps

Volume Shadow Copy Service stocke des snapshots périodiques du volume entier, ruches incluses. Une installation par défaut en garde quelques-uns ; un système bien géré en garde une à deux semaines. Le mouvement : extraire chaque snapshot, extraire les ruches, lancer la récupération sur chaque, comparer.

Ce que le diff fait remonter :

Persistance qui apparaît dans la ruche vivante mais pas dans le snapshot d'hier. Si le SOFTWARE d'hier n'avait pas de valeur à Run\evil et celui d'aujourd'hui en a une, la persistance a été installée entre ces deux moments.

Persistance qui apparaît et disparaît. Un snapshot d'il y a trois jours a une valeur Run ; celui d'hier non ; la ruche vivante non. L'attaquant a ajouté la persistance, exécuté la charge utile et nettoyé. Le snapshot s'en souvient.

Modifications à des valeurs existantes. Valeurs ImagePath de services modifiées. Valeurs IFEO Debugger ajoutées et retirées.

Changements de permissions. Descripteurs de sécurité modifiés pour cacher du contenu. Le descripteur pré-modification vit dans le snapshot.

VSS est la meilleure défense unique contre le schéma anti-forensique "éditer et annuler". vssadmin list shadows et Copy-Item contre le chemin GLOBALROOT de chaque snapshot vous donneront les ruches. shadowcopyview de NirSoft offre une interface plus conviviale pour la même chose.

Ce que les attaquants peuvent et ne peuvent pas nettoyer

La réponse honnête : un attaquant déterminé avec droits admin peut nettoyer presque n'importe quoi. La réponse malhonnête est celle qui rassure. Restons honnêtes.

Ce que les attaquants font couramment :

Supprimer la valeur, espérer pour le mieux. La plupart font cela. La récupération depuis les cellules non allouées la ramène.

Supprimer la valeur et forcer un flush. reg flush ou RegFlushKey. Les écritures suivantes dans le même HBIN peuvent écraser la cellule libérée. Le taux de récupération chute mais n'est pas nul.

Supprimer la valeur, flusher, et désactiver VSS. vssadmin delete shadows /all. Efface les snapshots qui tiennent l'état d'origine. La désactivation elle-même apparaît dans le journal système EVTX (event ID 8224). Le signal est "VSS a été effacé à l'heure T", et ce qui s'est passé juste avant T est maintenant votre investigation.

Écraser le contenu de la cellule délibérément. Écrire une grosse valeur de détritus, forçant la réallocation, puis la supprimer. Nettoie la cellule libérée. Rare parce que cela nécessite de comprendre le format regf.

Effacement en mode noyau. Possible mais exotique. Si votre attaquant a cette capacité, vous avez de plus gros problèmes.

Ce que les attaquants ne peuvent pas nettoyer facilement : les snapshots VSS pris avant qu'ils n'aient obtenu admin, les journaux de transactions déjà flushés et intacts, les enregistrements Sysmon/EVTX des éditions registre, l'entrée MFT du fichier de ruche, le contenu d'une image RAM prise entre l'édition et le nettoyage, et les pages de registre qui ont basculé dans le swap dans le pagefile.

Un flux de récupération pratique

Pour toute question "l'attaquant a-t-il modifié et annulé" :

  1. Tout acquérir. Ruche primaire, .LOG1, .LOG2, chaque copie VSS des mêmes, ruches de chaque profil disponible (y compris ceux périmés).
  2. Rejouer les journaux sur chaque ruche. Utilisez un outil qui rapporte explicitement le statut de rejeu. Si l'outil dit qu'il a sauté le rejeu parce que les numéros de séquence correspondent, vérifiez en essayant un autre outil avec des vérifications plus lâches.
  3. Lancer la récupération sur cellules non allouées sur chaque. yarp, regipy, del de RegRipper. Capturez les enregistrements orphelins aussi bien que ceux dont le chemin est reconstructible.
  4. Comparer entre VSS. Comparez les clés de persistance, services, IFEO, tâches planifiées entre chaque snapshot. Des outils comme regdiff d'Eric Zimmerman fonctionnent ; un script personnalisé qui hashe le contenu de chaque sous-clé aussi.
  5. Recouper avec EVTX. Cherchez les événements Registry value set (Sysmon event 13) et Registry object added or deleted (Sysmon event 12). Si Sysmon enregistrait le registre, vous obtenez les événements de changement avec horodatages.
  6. Recouper avec les horodatages du fichier ruche. L'enregistrement MFT du fichier ruche a l'horodatage de modification du fichier. Des clusters soudains de modifications dans la chronologie sont des pistes.
  7. Pivoter vers mémoire et pagefile. Si vous avez une image mémoire de la fenêtre pertinente, les pages registre en mémoire peuvent porter l'état pré-nettoyage. Les plugins registry de Volatility extraient cela. Le parseur pagefile gère les pages de ruches swappées.

La combinaison rejeu de journaux + diff VSS + récupération sur cellules non allouées attrape la vaste majorité des tentatives de nettoyage. Tout ce qui survit aux trois est un adversaire sophistiqué, et votre investigation doit escalader en conséquence.

Un piège courant

Les outils qui "récupèrent" des clés supprimées montrent parfois le même enregistrement depuis plusieurs sources sans vous le dire. Une valeur présente dans la ruche vivante, dans le rejeu de journal de transactions, et dans le snapshot VSS est une valeur, pas trois conclusions. Triez avec la déduplication en tête.

L'inverse compte aussi. Une conclusion qui apparaît dans exactement une source est parfois la conclusion la plus intéressante précisément parce qu'elle n'apparaît que dans une source. Une valeur IFEO Debugger supprimée visible uniquement dans le rejeu LOG1 est le genre de preuve qui clôt une affaire.

Pour aller plus loin

Le registre est un artefact indulgent pour les analystes qui le traitent comme un ensemble à quatre sources (ruche vivante + journaux

  • cellules non allouées + VSS) et impitoyable pour les analystes qui le traitent comme un fichier unique. L'approche à quatre sources prend plus de temps sur le premier dossier. Après cela, c'est la seule que vous utiliserez.