Skip to content

ESE-Datenbank-Forensik: Grundlagen für Ermittler

Wie eine ESE-Datenbank (JET Blue) wie Windows.edb aufgebaut ist: Header, Seiten, B+-Bäume, Katalog, Tagged Columns, Long Values und gelöschte Datensätze.

Veröffentlicht am 6 Min. Lesezeit

Kurz gesagt. ESE, auch JET Blue genannt, ist die eingebettete Datenbank-Engine hinter Windows.edb, SRUDB.dat, WebCacheV01.dat, der ntds.dit von Active Directory und Exchange. Eine ESE-Datei besteht aus einem Header (mit Schattenkopie), gefolgt von Seiten fester Größe, organisiert in B+-Bäumen. Der Katalog MSysObjects beschreibt jede Tabelle und Spalte. Zeilen mischen feste, variable und Tagged Columns (dünn besetzt). Große Werte liegen in einem separaten Long-Value-Baum. Text ist oft komprimiert. Änderungen gehen zuerst in Transaktionsprotokolle, deshalb ist eine Live-Kopie „dirty“. Gelöschte Zeilen werden als defunct markiert und später bereinigt, und in dieser Lücke findet Carving Spuren. Wer das weiß, kann die Ausgabe jedes ESE-Parsers beurteilen, auch dieses hier.

Warum Forensiker das interessieren sollte

Niemand muss einen ESE-Parser schreiben. Man muss aber genug wissen, um Fragen wie diese zu beantworten: Warum zeigt Tool A 41.000 Zeilen und Tool B 40.212? Warum ist diese Spalte in einem Viewer leer und im anderen nicht? Darf man über eine „dirty“ Datenbank berichten? Die Antworten liegen im Format.

Microsoft beschreibt ESE als ISAM-Engine (indexsequenzielle Zugriffsmethode) mit Transaktionen, Absturzwiederherstellung über ein Write-Ahead-Log und Unterstützung breiter Tabellen mit vielen dünn besetzten und mehrwertigen Spalten. Genau das braucht Windows Search: Hunderte mögliche Eigenschaften, pro Element eine Handvoll gesetzt. Microsoft hat den Quellcode der Engine 2021 unter MIT-Lizenz veröffentlicht. Die nützlichste Referenz für forensische Zwecke bleibt die Formatdokumentation von libesedb von Joachim Metz.

Weitere ESE-Datenbanken, die im selben Fall auftauchen können:

DateiInhaltSchwester-Tool
Windows.edbWindows-Search-Index (Windows 10 und älter)Windows Search Index Parser
SRUDB.datSystem Resource Usage MonitorSRUM-Parser
WebCacheV01.datVerlauf, Cookies und Cache von IE / altem EdgeBrowser-Forensik
ntds.ditActive-Directory-Datenbank—

Der Datei-Header

Die erste Seite der Datei ist der Header. Eine zweite Kopie, der Schatten-Header, folgt ihm. Die relevanten Felder:

Feld (laut libesedb)OffsetWarum es zählt
Signatur 0x89ABCDEF4Erkennt eine ESE-Datei unabhängig von der Erweiterung
Formatversion / -revision8 / 232Engine-Generation. Neuere Revisionen bringen das Layout für große Seiten.
Datenbankzustand522 = Dirty Shutdown, 3 = Clean Shutdown
Seitengröße2362 bis 32 KiB. Seiten mit 16 und 32 KiB nutzen ein anderes Seitenlayout.

Der Datenbankzustand ist das Erste, was man prüft. esentutl /mh Windows.edb gibt ihn aus (State: Dirty Shutdown), wie Microsofts archivierter Beitrag zu esentutl und VSS zeigt. Ein Dirty Shutdown bedeutet, dass bestätigte Änderungen möglicherweise nur in den Protokollen stehen. Siehe Windows.edb nach Dirty Shutdown reparieren.

Ist der primäre Header beschädigt, kann ein Parser auf die Schattenkopie ausweichen. Der Windows Search Index Parser tut das und meldet es in seinen Warnungen.

Seiten und B+-Bäume

Nach den beiden Header-Seiten ist die Datei ein Array von Seiten der angegebenen Größe. Jede Seite hat einen Header (40 Bytes; 80 Bytes im erweiterten Layout, das Seiten mit 16 und 32 KiB seit Windows 7 verwenden) und am Seitenende ein Array von Tags, die auf die enthaltenen Einträge zeigen.

Die Seiten bilden B+-Bäume. Die Daten einer Tabelle sind ein Baum, jeder Index ein weiterer, Long Values ein dritter. Zweigseiten zeigen auf Kindseiten; Blattseiten enthalten die Datensätze. Einträge einer Seite können ein gemeinsames Schlüsselpräfix mit dem ersten Eintrag der Seite teilen, ein kleiner Kompressionstrick, den Parser rückgängig machen müssen, um Schlüssel zu rekonstruieren.

Zwei Details auf Seitenebene zählen in der Forensik:

  • Defunct-Einträge. Ein gelöschter Datensatz wird zunächst in seinem Tag markiert und bleibt stehen. Er verschwindet, wenn die Seite bereinigt oder reorganisiert wird.
  • Freier Speicher. Durch Löschungen und Seitenzusammenführungen frei gewordener Platz wird später wiederverwendet, nicht sofort überschrieben. Alte Datensätze können dort überleben.

Der Katalog: MSysObjects

MSysObjects ist eine Tabelle wie jede andere, an bekannter Stelle (ihre Wurzel ist Seite 4). Sie listet jede Tabelle, Spalte, jeden Index und Long-Value-Baum mit IDs, Typen, Codepages und Wurzelseiten. Ein Parser liest zuerst den Katalog und durchläuft dann den Baum jeder Tabelle. Zu den Windows-Search-Tabellen darin gehören SystemIndex_PropertyStore, SystemIndex_Gthr und SystemIndex_GthrPth.

Datensätze: feste, variable und Tagged Columns

Ein ESE-Datensatz hat drei Teile:

TeilSpalten-IDsVerwendet für
Feste Spalten1–127Ganzzahlen, Datumswerte, GUIDs fester Größe
Variable Spalten128–255Kurzer Text und Binärdaten variabler Größe
Tagged Columns256+Dünn besetzte Werte: nur vorhanden, wenn gesetzt; können mehrwertig sein

SystemIndex_PropertyStore stützt sich stark auf Tagged Columns: Das Element hat eine WorkID und nur die tatsächlich gesetzten Eigenschaften. Mehrwertige Tagged Columns enthalten Listen, etwa System.Kind = program; executable. Ein Parser, der Mehrfachwerte ignoriert, verliert stillschweigend Daten.

Long Values

Ein Wert, der zu groß für den Datensatz ist, etwa ein langer Inhaltsauszug oder eine große Binäreigenschaft, liegt im Long-Value-Baum der Tabelle, und der Datensatz behält nur eine Referenz (eine Long-Value-ID mit 4 oder 8 Bytes, je nach Engine-Version). Ein Parser, der diesen Referenzen nicht folgt, zeigt die Eigenschaft leer oder als kurzen Binärblob. Wenn sich zwei Tools uneinig sind, ob ein Auszug existiert, ist das der erste Verdächtige.

Kompression

ESE kann Spaltendaten komprimieren. Die libesedb-Dokumentation beschreibt:

  • 7-Bit-Kompression für kurzen ASCII- oder Unicode-Text: Zeichen werden in 7 Bits gepackt.
  • XPRESS (LZ77) für größere Werte, erkennbar an einem führenden Byte.
  • Neuere Verfahren in aktuellen Engine-Versionen, die nicht jeder Parser implementiert.

Ein Parser, der ein Verfahren nicht beherrscht, zeigt Datenmüll oder nichts. Der Windows Search Index Parser unterstützt 7-Bit und XPRESS (einfaches LZ77) und meldet Werte, die er nicht dekodieren konnte, statt sie zu verbergen. XPRESS9 / XPRESS10 / LZ4 werden noch nicht unterstützt.

Transaktionsprotokolle und Checkpoint

ESE schreibt Änderungen in sequenzielle Protokolldateien (bei Windows Search: MSS.log, MSS00001.log…), und MSS.chk hält fest, wie weit sie angewendet sind. Die Datenbankdatei wird später aktualisiert. Die Folgen:

  • Eine Kopie einer laufenden Datenbank enthält nur, was bereits geschrieben wurde. Der Rest steht in den Protokollen.
  • esentutl /r MSS spielt die Protokolle in die Datenbank nach (Soft Recovery). Immer auf einer Kopie.
  • Die Protokolle selbst sind Spuren jüngster Änderungen. Spezialisierte Tools können sie auswerten; das geht über das hinaus, was die meisten Parser tun.

Wo sich gelöschte Windows-Search-Datensätze in ESE verstecken

OrtWiederherstellbar mit
Defunct-Einträge, die noch in Blattseiten stehenEinem Parser, der defunct-Tags liest, oder einem Carving-Tool
Freie / ungenutzte SeitenEinem Datensatz-Carver (etwa WinSearchDBAnalyzer oder dem wdsCarve-Ansatz von Chivers und Hargreaves, 2011)
Noch nicht nachgespielte TransaktionsprotokolleNachspielen auf einer Kopie, dann parsen; oder einem Protokoll-Parser

Der Windows Search Index Parser zählt derzeit die defunct-Einträge in den durchlaufenen Tabellen und meldet die Anzahl, ohne sie wiederherzustellen. Mehr zu dem, was überlebt, in Spuren gelöschter Dateien im Windows-Search-Index.

Ein Wort zur Validierung

ESE ist umfangreich, und die Details unterscheiden sich zwischen Engine-Versionen. Der ESE-Leser des Windows Search Index Parser folgt der libesedb-Dokumentation und Microsofts Quellcode und wird gegen einen synthetischen ESE-Writer getestet. Das belegt Selbstkonsistenz, nicht Korrektheit für jede echte Windows.edb. Bislang wurde er nicht an echten Datenbanken validiert, und die Oberfläche sagt das. Wenn ein Befund zählt, mit esedbexport, ESEDatabaseView oder SIDR vergleichen, wie im Parser-Vergleich beschrieben.

Verwandte Artikel

Verwandte Artikel