Index de répertoires ($I30)¶
Qu'est-ce que $I30 ?¶
Chaque répertoire NTFS conserve un index des fichiers qu'il contient, nommé $I30. Un petit répertoire le conserve dans
son enregistrement $MFT ($INDEX_ROOT) ; un répertoire plus grand possède également des enregistrements INDX, généralement de 4 096 octets chacun, dans
un flux $INDEX_ALLOCATION:$I30. Chaque entrée d'index contient une copie du $FILE_NAME du fichier : son
nom, sa référence MFT, son répertoire parent, quatre horodatages et deux tailles, tels qu'ils étaient lors de la dernière
mise à jour de l'entrée par NTFS.
Lorsqu'un fichier est supprimé d'un répertoire ou renommé hors de celui-ci, NTFS retire son entrée et déplace les entrées
qui la suivent. Les anciens octets restent dans le slack de l'enregistrement INDX, au-delà des entrées utilisées, jusqu'à ce que
des entrées ultérieures les écrasent. L'index slack peut conserver le nom, les horodatages et la taille d'un fichier dont
l'enregistrement $MFT a été réutilisé et dont les enregistrements du Journal USN ont été recyclés.
Meilleure conclusion : un nom trouvé dans l'index slack figurait, à un
moment donné, dans l'index de ce répertoire avec les horodatages et tailles $FILE_NAME indiqués. Une entrée de slack n'indique
pas quand elle a été retirée, ni si elle a été supprimée, renommée ou déplacée par un rééquilibrage.
Emplacement et collecte¶
$I30 est une métadonnée NTFS : collectez-le avec un outil forensique capable d'accès brut qui peut exporter le flux
$I30 d'un répertoire (les fichiers exportés sont souvent nommés $I30). Juntei peut également rechercher des enregistrements INDX dans une image disque ou
dans l'espace non alloué. Collectez aussi le $MFT et le $J du même volume, afin de déterminer à quoi
correspondaient les entrées de slack.
Précautions d'analyse¶
- L'index slack est partiel et non ordonné. Les entrées sont écrasées au fil des modifications du répertoire ; un nom absent ne prouve rien.
- De nombreuses entrées de slack sont des copies d'entrées encore utilisées, laissées lors du déplacement des entrées.
CopyOfEntryInUseles signale. Le même nom supprimé peut également figurer plusieurs fois dans le slack. - Les horodatages d'une entrée d'index sont des horodatages
$FILE_NAMEtels qu'ils étaient lors de la dernière mise à jour de l'entrée. Ils peuvent différer à la fois des horodatages$STANDARD_INFORMATIONet$FILE_NAMEde l'enregistrement$MFTdu fichier. AllocatedSizeetRealSizecorrespondent également à la dernière mise à jour de l'entrée et peuvent être obsolètes.- Le
FileEntry(ouParentEntry) d'une entrée de slack peut être absent lorsque des octets ultérieurs l'ont écrasé. Lorsqu'il est présent, l'enregistrement MFT qu'il désigne a pu être réutilisé depuis : comparez le numéro de séquence. parse-ntfs i30lit les enregistrements INDX. L'index d'un petit répertoire se trouve uniquement dans son enregistrement$MFT($INDEX_ROOT) ; ses fichiers figurent dans le$MFT.
Analyser avec Juntei¶
Usage: juntei parse-ntfs i30 <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find $I30 files (with $I30 in their name, or starting with an INDX record)
-f, --file <FILE> Parse one $I30 stream, or any file holding INDX records (a disk image, unallocated space)
Filtering:
--slack-only Only the entries found in slack
--no-copies Leave out the slack entries that copy an entry in use
Output:
-o, --output <FILE> Save every entry
-t, --output-type <TYPE> csv, json, or jsonl
juntei parse-ntfs i30 -f 'Users_$I30'
juntei parse-ntfs i30 -d evidence/ -o i30.csv
juntei parse-ntfs i30 -f 'Users_$I30' --slack-only --no-copies -t jsonl
juntei parse-ntfs i30 -f disk.raw -o carved-i30.csv
Le résumé répertorie les enregistrements INDX (et combien ont été partiellement écrits), les entrées utilisées et celles présentes dans le slack, ainsi que les noms des entrées de slack qui ne sont pas des copies exactes d'entrées utilisées. Ces noms sont des candidats de fichiers supprimés ou renommés, et non un verdict en soi.
Champs de sortie CSV¶
| Champ | Interprétation |
|---|---|
SourcePath |
Fichier d'entrée ; distingue les hôtes et les répertoires. |
RecordOffset, EntryOffset |
Décalages en octets de l'enregistrement INDX et de l'entrée dans l'entrée analysée. Essentiels pour la validation et pour les enregistrements trouvés dans des images disque. |
RecordVCN, RecordLSN |
La position de l'enregistrement dans le flux d'index et son numéro de séquence $LogFile. |
FromSlack |
True pour une entrée trouvée au-delà des entrées utilisées. |
CopyOfEntryInUse |
Entrée de slack ayant le même nom, le même espace de noms, le même fichier (lorsqu'il est connu), le même parent et les mêmes horodatages qu'une entrée utilisée du même index de répertoire. Généralement un reste du déplacement d'entrées, et non un fichier supprimé. |
Filename |
Le nom dans le répertoire. |
Namespace |
win32, dos (nom court 8.3), win32_and_dos ou posix. |
FileEntry, FileSequence |
La référence MFT du fichier. Vide pour une entrée de slack dont l'en-tête a été écrasé. |
ParentEntry, ParentSequence |
La référence MFT du répertoire. Vide lorsque d'autres octets l'ont écrasée. |
CreatedUTC, ModifiedUTC, MFT-ModifiedUTC, AccessedUTC |
Horodatages $FILE_NAME, à 100 ns près, tels qu'ils étaient lors de la dernière mise à jour de l'entrée. |
AllocatedSize, RealSize |
Tailles copiées par NTFS dans l'entrée ; voir les mises en garde ci-dessus. |
FileAttributes |
Noms d'attributs joints par | (hidden|archive) ; is_directory pour un sous-répertoire. Les bits que cette version de Juntei ne nomme pas sont conservés en hexadécimal (0x00800000). |
ReparseValue |
Balise d'analyse (reparse tag) ou taille des attributs étendus provenant de $FILE_NAME. |
Problems |
Dommages dans l'enregistrement, tels que des secteurs partiellement écrits. Les entrées d'un enregistrement endommagé méritent tout de même d'être examinées, avec prudence. |
Les formats JSON/JSONL contiennent les mêmes champs en snake_case, avec problems sous forme de liste et null pour les valeurs
inconnues.
Comment les entrées de slack sont trouvées¶
Le slack est parcouru à chaque limite de 8 octets, là où commencent les entrées, à la recherche d'entrées complètes, d'attributs
$FILE_NAME dont l'en-tête d'entrée a été écrasé et, au début du slack, d'un
$FILE_NAME dont la référence parente a été écrasée par la fin des entrées utilisées. Un candidat doit ressembler
à ce qu'écrit Windows : un nom UTF-16 valide sans caractères de contrôle ni séparateurs de chemin, quatre
horodatages compris entre 1980 et 2100, un espace de noms connu et des indicateurs d'attributs connus. Une référence parente dépassant
32 bits correspond à des octets qui l'ont écrasée et est laissée vide.
Le tableau de séquence de mise à jour (update sequence array) de chaque enregistrement est appliqué. Un secteur qui ne se termine pas par la valeur de séquence de mise à jour
a été partiellement écrit ; Juntei lit l'enregistrement tel quel et nomme les secteurs dans Problems.
Stratégie d'investigation¶
- Commencez par les noms du slack qui ne sont pas des copies, indiqués dans le résumé, puis filtrez avec
--slack-only --no-copies. - Recherchez le
FileEntrydans le$MFT. Un mêmeFileSequencesignifie le même fichier ; un numéro plus élevé signifie que l'enregistrement a été libéré depuis, et peut-être réutilisé. - Recherchez le nom dans le Journal USN pour savoir quand il a été supprimé ou renommé.
- Comparez les horodatages
$FILE_NAMEavec les horodatages$STANDARD_INFORMATIONdu$MFTpour détecter le timestomping. - Corrélez avec Prefetch, LNK, les Jump Lists et les journaux d'événements pour déterminer comment le fichier a été utilisé.
Plus de détails¶
- Microsoft : Master File Table
- libfsntfs : documentation du format NTFS
- dfir_ntfs
- INDXRipper
- ys-ntfs-parser (module
i30de sa cratemft)