Índices de directorios ($I30)¶
Qué es $I30¶
Cada directorio NTFS mantiene un índice de los archivos que contiene, llamado $I30. Un directorio
pequeño lo guarda en su registro de la $MFT ($INDEX_ROOT); uno más grande tiene además
registros INDX, normalmente de 4096 bytes cada uno, en un flujo $INDEX_ALLOCATION:$I30. Cada
entrada del índice contiene una copia del $FILE_NAME del archivo: su nombre, la referencia de la
MFT, el directorio principal, cuatro marcas de tiempo y dos tamaños, tal como estaban la última vez
que NTFS actualizó la entrada.
Cuando un archivo se elimina o se renombra fuera de un directorio, NTFS quita su entrada y desplaza
las entradas que la siguen. Los bytes antiguos permanecen en el espacio residual (slack) del
registro INDX, más allá de las entradas en uso, hasta que las entradas posteriores los
sobrescriben. El espacio residual del índice puede conservar el nombre, las horas y el tamaño de un
archivo cuyo registro de la $MFT se reutilizó y cuyos registros del Diario USN ya se han
sobrescrito.
Mejor conclusión: un nombre encontrado en el espacio
residual del índice estuvo, en algún momento, en el índice de este directorio con las horas y los
tamaños de $FILE_NAME indicados. Una entrada del espacio residual no indica cuándo se quitó, ni si
se eliminó, se renombró o se desplazó por un reequilibrio.
Ubicación y recopilación¶
$I30 son metadatos de NTFS: recopílelo con una herramienta forense con acceso sin procesar (raw)
que pueda exportar el flujo $I30 de un directorio (los archivos exportados suelen llamarse
$I30). Juntei también puede buscar registros INDX en una imagen de disco o en el espacio no
asignado. Recopile además la $MFT y el $J del mismo volumen para determinar qué eran las
entradas del espacio residual.
Precauciones para el analista¶
- El espacio residual del índice es parcial y desordenado. Las entradas se sobrescriben a medida que cambia el directorio; la ausencia de un nombre no prueba nada.
- Muchas entradas del espacio residual son copias de entradas aún en uso, que quedan cuando las
entradas se desplazan.
CopyOfEntryInUselas marca. El mismo nombre eliminado también puede aparecer varias veces en el espacio residual. - Las horas de una entrada del índice son las horas de
$FILE_NAMEen la última actualización de la entrada. Pueden diferir tanto de las horas de$STANDARD_INFORMATIONcomo de las de$FILE_NAMEdel registro de la$MFTdel archivo. AllocatedSizeyRealSizetambién corresponden a la última actualización de la entrada y pueden estar obsoletos.- El
FileEntry(o elParentEntry) de una entrada del espacio residual puede faltar si bytes posteriores lo sobrescribieron. Cuando está presente, el registro de la MFT al que apunta puede haberse reutilizado desde entonces: compare el número de secuencia. parse-ntfs i30lee registros INDX. El índice de un directorio pequeño solo está en su registro de la$MFT($INDEX_ROOT); sus archivos están en la$MFT.
Análisis con 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
El resumen enumera los registros INDX (y cuántos se escribieron parcialmente), las entradas en uso y en el espacio residual, y los nombres de las entradas del espacio residual que no son copias exactas de entradas en uso. Esos nombres son candidatos a archivos eliminados o renombrados, no un veredicto por sí mismos.
Campos de salida CSV¶
| Campo | Interpretación |
|---|---|
SourcePath |
Archivo de entrada; distingue hosts y directorios. |
RecordOffset, EntryOffset |
Desplazamientos en bytes del registro INDX y de la entrada dentro de la entrada de datos. Esenciales para la validación y para los registros encontrados en imágenes de disco. |
RecordVCN, RecordLSN |
La posición del registro en el flujo del índice y su número de secuencia de $LogFile. |
FromSlack |
True para una entrada encontrada más allá de las entradas en uso. |
CopyOfEntryInUse |
Entrada del espacio residual con el mismo nombre, espacio de nombres, archivo (cuando se conoce), directorio principal y horas que una entrada en uso del mismo índice de directorio. Normalmente es un resto del desplazamiento de entradas, no un archivo eliminado. |
Filename |
El nombre en el directorio. |
Namespace |
win32, dos (nombre corto 8.3), win32_and_dos o posix. |
FileEntry, FileSequence |
La referencia de la MFT del archivo. Vacío para una entrada del espacio residual cuyo encabezado se sobrescribió. |
ParentEntry, ParentSequence |
La referencia de la MFT del directorio. Vacío cuando otros bytes la sobrescribieron. |
CreatedUTC, ModifiedUTC, MFT-ModifiedUTC, AccessedUTC |
Horas de $FILE_NAME, con precisión de 100 ns, a fecha de la última actualización de la entrada. |
AllocatedSize, RealSize |
Tamaños que NTFS copió en la entrada; consulte las precauciones anteriores. |
FileAttributes |
Nombres de atributos unidos por | (hidden|archive); is_directory para un subdirectorio. Los bits que esta versión de Juntei no nombra se conservan en hexadecimal (0x00800000). |
ReparseValue |
Etiqueta de punto de reanálisis o tamaño de atributos extendidos de $FILE_NAME. |
Problems |
Daños en el registro, como sectores escritos parcialmente. Las entradas de un registro dañado siguen mereciendo revisión, con precaución. |
JSON/JSONL tienen los mismos campos en snake_case, con problems como lista y null para los
valores desconocidos.
Cómo se encuentran las entradas del espacio residual¶
El espacio residual se examina en cada límite de 8 bytes, donde empiezan las entradas, en busca de
entradas completas, de atributos $FILE_NAME cuyo encabezado de entrada se sobrescribió y, al
principio del espacio residual, de un $FILE_NAME cuya referencia al directorio principal quedó
sobrescrita por el final de las entradas en uso. Un candidato debe parecerse a lo que escribe
Windows: un nombre UTF-16 válido sin caracteres de control ni separadores de ruta, cuatro horas
entre 1980 y 2100, un espacio de nombres conocido e indicadores de atributo conocidos. Una
referencia al directorio principal que supera los 32 bits corresponde a bytes que la
sobrescribieron y se deja vacía.
Se aplica la matriz de secuencia de actualización (update sequence array) de cada registro. Un
sector que no termina con el valor de secuencia de actualización se escribió parcialmente; Juntei
lee el registro tal como está e indica los sectores en Problems.
Estrategia de investigación¶
- Empiece por los nombres del espacio residual que no son copias, indicados en el resumen, y
después filtre con
--slack-only --no-copies. - Busque el
FileEntryen la$MFT. El mismoFileSequencesignifica el mismo archivo; uno mayor significa que el registro se liberó desde entonces y quizá se reutilizó. - Busque el nombre en el Diario USN para saber cuándo se eliminó o se renombró.
- Compare las horas de
$FILE_NAMEcon las horas de$STANDARD_INFORMATIONde la$MFTpara detectar timestomping. - Correlacione con Prefetch, LNK, Jump Lists y los registros de eventos para saber cómo se usó el archivo.
Más información¶
- Microsoft: Master File Table
- libfsntfs: documentación del formato NTFS
- dfir_ntfs
- INDXRipper
- ys-ntfs-parser (el módulo
i30de su cratemft)