Skip to content

Forensique des bases ESE : les bases pour enquêteurs

Comment est construite une base ESE (JET Blue) comme Windows.edb : en-tête, pages, arbres B+, catalogue, colonnes tagged, valeurs longues et suppressions.

Publié le 8 min de lecture

En bref. ESE, aussi appelé JET Blue, est le moteur de base de données embarqué derrière Windows.edb, SRUDB.dat, WebCacheV01.dat, le ntds.dit d'Active Directory et Exchange. Un fichier ESE, c'est un en-tête (avec sa copie de secours), puis des pages de taille fixe organisées en arbres B+. Le catalogue MSysObjects décrit chaque table et chaque colonne. Les lignes mélangent colonnes fixes, variables et « tagged » (éparses). Les grosses valeurs vivent dans un arbre de valeurs longues séparé. Le texte est souvent compressé. Les modifications passent d'abord par des journaux de transactions, d'où l'état « dirty » d'une copie à chaud. Les lignes supprimées sont marquées « defunct » et nettoyées plus tard : c'est dans cet intervalle que le carving trouve des preuves. Connaître tout cela vous aide à juger la sortie de n'importe quel parseur ESE, y compris celui-ci.

Pourquoi un analyste forensique devrait s'y intéresser

Vous n'avez pas besoin d'écrire un parseur ESE. Vous devez en savoir assez pour répondre à des questions comme : pourquoi l'outil A affiche-t-il 41 000 lignes et l'outil B 40 212 ? Pourquoi cette colonne est-elle vide dans une visionneuse et pas dans l'autre ? Peut-on rapporter sur une base « dirty » ? Les réponses viennent du format.

Microsoft décrit ESE comme un moteur ISAM (méthode d'accès séquentielle indexée) avec transactions, récupération après incident via un journal d'écriture anticipée, et prise en charge de tables très larges avec de nombreuses colonnes éparses et multivaluées. Ce dernier point correspond exactement au besoin de Windows Search : des centaines de propriétés possibles, une poignée renseignées par élément. Microsoft a publié le code source du moteur sous licence MIT en 2021. La référence la plus utile pour la forensique reste la documentation du format libesedb de Joachim Metz.

Autres bases ESE que vous croiserez dans la même affaire :

FichierContenuOutil de la même famille
Windows.edbIndex Windows Search (Windows 10 et antérieurs)Windows Search Index Parser
SRUDB.datSystem Resource Usage Monitorparseur SRUM
WebCacheV01.datHistorique, cookies et cache d'IE / ancien Edgeforensique des navigateurs
ntds.ditBase Active Directory—

L'en-tête du fichier

La première page du fichier est l'en-tête. Une seconde copie, l'en-tête de secours (shadow header), la suit. Les champs qui comptent :

Champ (selon libesedb)OffsetPourquoi c'est utile
Signature 0x89ABCDEF4Identifie un fichier ESE quelle que soit son extension
Version / révision du format8 / 232Génération du moteur. Les révisions récentes ajoutent la structure des grandes pages.
État de la base522 = dirty shutdown, 3 = clean shutdown
Taille de page236De 2 à 32 Kio. Les pages de 16 et 32 Kio utilisent une structure de page différente.

L'état de la base est la première chose à vérifier. esentutl /mh Windows.edb l'affiche (State: Dirty Shutdown), comme le montre le billet archivé de Microsoft sur esentutl et VSS. Un dirty shutdown signifie que des modifications validées peuvent n'exister que dans les journaux. Voir réparer un Windows.edb en dirty shutdown.

Si l'en-tête principal est endommagé, un parseur peut se rabattre sur la copie de secours. Le Windows Search Index Parser le fait et l'indique dans ses avertissements.

Pages et arbres B+

Après les deux pages d'en-tête, le fichier est un tableau de pages de la taille déclarée. Chaque page a un en-tête (40 octets ; 80 octets dans la structure étendue utilisée par les pages de 16 et 32 Kio depuis Windows 7) et un tableau de tags en fin de page qui pointe vers les entrées qu'elle contient.

Les pages forment des arbres B+. Les données d'une table forment un arbre ; chaque index en est un autre ; les valeurs longues un troisième. Les pages de branche pointent vers des pages filles ; les pages feuilles contiennent les enregistrements. Les entrées d'une page peuvent partager un préfixe de clé commun avec la première entrée de la page, une petite astuce de compression que les parseurs doivent défaire pour reconstruire les clés.

Deux détails au niveau des pages comptent en forensique :

  • Les entrées « defunct ». Un enregistrement supprimé est d'abord marqué dans son tag et laissé en place. Il disparaît quand la page est nettoyée ou réorganisée.
  • L'espace libre. L'espace libéré par les suppressions et les fusions de pages est réutilisé plus tard, pas effacé immédiatement. D'anciens enregistrements peuvent y survivre.

Le catalogue : MSysObjects

MSysObjects est une table comme les autres, à un emplacement connu (sa racine est la page 4). Elle liste chaque table, colonne, index et arbre de valeurs longues, avec leurs identifiants, types, pages de code et pages racines. Un parseur lit d'abord le catalogue, puis parcourt l'arbre de chaque table. Parmi les tables Windows Search qu'on y trouve : SystemIndex_PropertyStore, SystemIndex_Gthr et SystemIndex_GthrPth.

Enregistrements : colonnes fixes, variables et tagged

Un enregistrement ESE a trois parties :

PartieIdentifiants de colonneUsage
Colonnes fixes1–127Entiers, dates, GUID de taille fixe
Colonnes variables128–255Texte court et binaire de taille variable
Colonnes tagged256+Valeurs éparses : présentes seulement si renseignées ; peuvent être multivaluées

SystemIndex_PropertyStore s'appuie massivement sur les colonnes tagged : l'élément a un WorkID et seulement les propriétés effectivement renseignées. Les colonnes tagged multivaluées contiennent des listes, comme System.Kind = program; executable. Un parseur qui ignore les valeurs multiples perd des données sans le dire.

Les valeurs longues

Une valeur trop grande pour l'enregistrement, comme un long extrait de contenu ou une grosse propriété binaire, est stockée dans l'arbre de valeurs longues de la table ; l'enregistrement ne garde qu'une référence (un identifiant de valeur longue sur 4 ou 8 octets selon la version du moteur). Un parseur qui ne suit pas ces références affiche la propriété vide ou sous forme d'un court blob binaire. Quand deux outils ne s'accordent pas sur l'existence d'un extrait, c'est le premier suspect.

La compression

ESE peut compresser les données des colonnes. La documentation libesedb décrit :

  • La compression 7 bits pour du texte ASCII ou Unicode court : les caractères sont empaquetés sur 7 bits.
  • XPRESS (LZ77) pour les valeurs plus grandes, identifiée par un octet de tête.
  • Des schémas plus récents dans les versions récentes du moteur, que tous les parseurs n'implémentent pas.

Un parseur qui ne gère pas un schéma donné affiche du charabia ou rien. Le Windows Search Index Parser gère la compression 7 bits et XPRESS (LZ77 simple) et signale les valeurs qu'il n'a pas pu décoder au lieu de les masquer. XPRESS9 / XPRESS10 / LZ4 ne sont pas encore pris en charge.

Journaux de transactions et checkpoint

ESE écrit les modifications dans des fichiers journaux séquentiels (pour Windows Search : MSS.log, MSS00001.log…), et MSS.chk enregistre jusqu'où ils ont été appliqués. Le fichier de base est mis à jour plus tard. Conséquences :

  • Une copie d'une base en fonctionnement ne contient que ce qui a été vidé sur disque. Le reste est dans les journaux.
  • esentutl /r MSS rejoue les journaux dans la base (récupération douce, « soft recovery »). Toujours sur une copie.
  • Les journaux sont eux-mêmes des traces de modifications récentes. Des outils spécialisés savent les parser, ce qui dépasse ce que font la plupart des parseurs.

Où se cachent les enregistrements Windows Search supprimés dans ESE

EmplacementRécupérable avec
Entrées « defunct » encore présentes dans les pages feuillesUn parseur qui lit les tags defunct, ou un outil de carving
Pages libres / inutiliséesUn outil de carving d'enregistrements (par exemple WinSearchDBAnalyzer, ou l'approche wdsCarve de Chivers et Hargreaves, 2011)
Journaux de transactions pas encore rejouésRejeu sur une copie, puis parsing ; ou un parseur de journaux

Le Windows Search Index Parser compte actuellement les entrées « defunct » des tables qu'il parcourt et en indique le nombre, sans les récupérer. Plus de détails dans les traces de fichiers supprimés dans l'index Windows Search.

Un mot sur la validation

ESE est un format vaste et les détails varient selon les versions du moteur. Le lecteur ESE du Windows Search Index Parser suit la documentation libesedb et le code source de Microsoft, et il est testé contre un écrivain ESE synthétique. Cela prouve la cohérence interne, pas l'exactitude sur chaque Windows.edb réel. À ce jour, il n'a pas été validé sur des bases réelles, et l'interface le dit. Quand une constatation compte, comparez avec esedbexport, ESEDatabaseView ou SIDR, comme expliqué dans la comparaison des parseurs.

Articles liés

Articles liés