Artefactos de Windows · Lección 4 de 9
Acceso a archivos y carpetas: archivos LNK, Jump Lists, RecentDocs y listas MRU
12 min de lectura
Los artefactos de ejecución de programas (lección 2.3) muestran que se ejecutó un programa. Esta lección muestra qué archivos y carpetas abrió un usuario con él: los accesos directos automáticos de la carpeta Recent, las Jump Lists y las listas de elementos usados más recientemente (MRU) del NTUSER.DAT del usuario. En conjunto, responden a las preguntas más frecuentes del examen práctico: qué archivo, desde qué volumen, con qué programa y cuándo se abrió por última vez.
Archivos LNK
Un archivo Shell Link (LNK) es un acceso directo de Windows. Además de los accesos directos que crean los usuarios, Windows los crea automáticamente: cuando una aplicación registra un archivo como usado recientemente (el Explorador de archivos y los cuadros de diálogo estándar de apertura y guardado lo hacen), se escribe un enlace en %APPDATA%\Microsoft\Windows\Recent, es decir, C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Recent. Al abrir E:\Clients\budget-q3.xlsx, se crea budget-q3.xlsx.lnk y también Clients.lnk para la carpeta contenedora.
Hay un LNK automático por cada nombre de destino. Volver a abrir el mismo archivo actualiza el enlace existente, y abrir un archivo diferente con el mismo nombre en otra carpeta lo sobrescribe, por lo que la carpeta Recent conserva solo el destino más reciente para cada nombre. Windows también elimina las entradas antiguas. Una configuración de privacidad o una directiva de grupo que desactive los elementos recientes puede impedir que se escriban tanto la carpeta Recent como las Jump Lists, por lo que una carpeta vacía no es, por sí sola, prueba de una limpieza.
Estructura
Todos los enteros están en formato little-endian. Microsoft documenta el formato como [MS-SHLLINK].
| Parte | Contenido |
|---|---|
| ShellLinkHeader (0x4C bytes) | HeaderSize 0x0000004C en 0x00; LinkCLSID 00021401-0000-0000-C000-000000000046 en 0x04; LinkFlags en 0x14; atributos del destino en 0x18; FILETIME de creación, acceso y escritura del destino en 0x1C, 0x24 y 0x2C; tamaño del archivo de destino (4 bytes) en 0x34 |
| LinkTargetIDList | Elementos del shell (el formato utilizado por Shellbags, lección 2.5) que describen la ruta de destino |
| LinkInfo | VolumeID: tipo de unidad (2 = extraíble, 3 = fija, 4 = de red, 5 = CD-ROM), número de serie de la unidad, etiqueta del volumen; después, la ruta base local o, para un recurso compartido, la ruta de red, como \\FS01\finance |
| StringData | Nombre opcional, ruta relativa, directorio de trabajo, argumentos, ubicación del icono |
| Bloques ExtraData | Cada uno con un tamaño y una firma, p. ej., TrackerDataBlock 0xA0000003, PropertyStoreDataBlock 0xA0000009 |
Por tanto, todos los archivos LNK comienzan con 4C 00 00 00 01 14 02 00 00 00 00 00 C0 00 00 00 00 00 00 46. Las marcas de tiempo y el tamaño de la cabecera describen el destino tal como era cuando se actualizó el enlace por última vez, no el propio enlace. Si el destino estaba en FAT32, su marca de tiempo de modificación tiene una resolución de 2 segundos (lección 1.5).
El TrackerDataBlock (0x60 bytes) contiene el nombre NetBIOS del equipo en el que se encontró el destino (16 bytes, con relleno NUL; para un archivo en un recurso compartido, suele ser el servidor de archivos) y los identificadores de seguimiento distribuido de enlaces (droids): un identificador de volumen y un identificador de objeto de archivo, tanto actuales como de origen. Cuando el identificador de objeto de archivo es un UUID de versión 1, sus últimos 6 bytes (el campo de nodo) suelen contener la dirección MAC del equipo que lo generó, aunque el nodo también puede ser aleatorio.
Marcas de tiempo del propio archivo LNK
El archivo .lnk tiene sus propias marcas de tiempo en la $MFT. Para los elementos recientes automáticos, la interpretación habitual es:
- Creación ≈ la primera vez que se abrió un archivo con ese nombre mediante el shell.
- Modificación ≈ la vez más reciente que se abrió.
Trate esto como una interpretación que debe corroborarse, no como una regla, porque otras actividades pueden actualizar el enlace. En una recopilación de triaje, es posible que la copia en su estación de trabajo no conserve las marcas de tiempo originales; léalas de la $MFT recopilada o del registro de la herramienta de recopilación si las registró.
Por qué son importantes los archivos LNK
El enlace persiste cuando el destino se elimina, se borra de forma segura o está en una unidad USB que ya no está conectada. Un LNK de Recent con tipo de unidad extraíble, un número de serie de volumen y una ruta en E:\ es una evidencia clave de que este usuario abrió ese archivo desde ese volumen. El número de serie es lo que vincula el enlace con un volumen formateado específico (lección 2.6). LECmd analiza archivos individuales o carpetas completas, por ejemplo, LECmd.exe -d <Recent folder> --csv <out>.
Jump Lists
Las Jump Lists son las listas de elementos recientes y anclados de cada aplicación que se muestran en la barra de tareas y en el menú Inicio. Se encuentran junto a los LNK de Recent:
Recent\AutomaticDestinations\<AppID>.automaticDestinations-ms: mantenidas por Windows. Cada una es un archivo compuesto OLE (firmaD0 CF 11 E0 A1 B1 1A E1) que contiene flujos numerados, cada uno de ellos un LNK completo, y un flujo denominado DestList.Recent\CustomDestinations\<AppID>.customDestinations-ms: escritas por aplicaciones que definen sus propias categorías o tareas; el contenido es una cabecera corta seguida principalmente de estructuras LNK, no un archivo compuesto.
El AppID es un hash de 16 dígitos hexadecimales calculado a partir de la identidad de la aplicación (su AppUserModelID o la ruta de su ejecutable), por lo que identifica el programa que mantuvo la lista. Las listas de referencia publicadas relacionan AppID conocidos con programas, y JLECmd resuelve muchos de ellos; para un AppID desconocido, los tipos de archivo de los destinos y otros artefactos de ejecución suelen revelar el programa.
DestList
El flujo DestList tiene una cabecera de 32 bytes seguida de una entrada por elemento. En Windows 10 y 11, cada entrada incluye:
| Campo | Significado |
|---|---|
| Droids | Identificadores de volumen y de objeto, como en el TrackerDataBlock |
| Nombre NetBIOS | Equipo en el que se encontró el destino |
| Número de entrada | Da nombre al flujo LNK: la entrada 26 corresponde al flujo 1a (hexadecimal) |
| Último acceso registrado | FILETIME (UTC) de la última vez que la aplicación usó el elemento |
| Estado de anclaje | Posición de anclaje, o -1 (0xFFFFFFFF) si no está anclado |
| Recuento de accesos | Cuántas veces se usó el elemento |
| Ruta | Ruta completa del destino, UTF-16 |
Los números de entrada se asignan en orden creciente, por lo que un número mayor se añadió a la lista más tarde; ordenar por la marca de tiempo del último acceso proporciona el orden MRU. El LNK integrado contiene el tipo de unidad, el número de serie del volumen y las marcas de tiempo del destino; la marca de tiempo de uso procede de DestList.
Las Jump Lists suelen persistir más tiempo que los LNK de Recent y registrar más historial. Utilizan la ruta completa como clave, por lo que dos archivos con el mismo nombre en carpetas diferentes conservan entradas independientes; un usuario que elimina elementos de la carpeta Recent rara vez modifica AutomaticDestinations; y cada aplicación mantiene su propia lista, que puede contener más elementos de los que muestra la barra de tareas. JLECmd analiza ambos tipos, por ejemplo, JLECmd.exe -d <Recent folder> --csv <out>.
Listas MRU del Registro
Estas claves están en el NTUSER.DAT del usuario, bajo Software\Microsoft\Windows\CurrentVersion\Explorer, salvo que se indique lo contrario. Muchas utilizan MRUListEx: números de valor de 4 bytes en formato little-endian, con el más reciente primero y terminados en 0xFFFFFFFF. La única marca de tiempo de uso que proporcionan es LastWrite de la clave (lección 2.1), que fecha el cambio en la primera posición de la lista.
| Clave | Qué registra |
|---|---|
RecentDocs | Nombres de archivos y carpetas abiertos recientemente; una subclave por extensión (.xlsx, Folder). Los valores contienen el nombre, no la ruta completa. LastWrite de una clave fecha únicamente su entrada más reciente |
ComDlg32\OpenSavePidlMRU\<ext> (y *) | Rutas completas, como elementos del shell, de archivos abiertos o guardados mediante cuadros de diálogo comunes, por extensión |
ComDlg32\LastVisitedPidlMRU | El nombre del ejecutable y la última carpeta que utilizó en un cuadro de diálogo de apertura o guardado |
RunMRU | Comandos escritos en Win+R; valores a, b, c… terminados en \1, ordenados mediante un valor de cadena MRUList |
TypedPaths | Rutas escritas en la barra de direcciones del Explorador de archivos; url1 es la más reciente |
WordWheelQuery | Términos de búsqueda escritos en el Explorador de archivos, UTF-16, ordenados mediante MRUListEx |
Microsoft Office y LibreOffice
Office 2016, 2019, 2021, 2024 y Microsoft 365 (todos de la versión 16.0) mantienen sus propias listas en Software\Microsoft\Office\16.0\<App>\User MRU\<account id>\File MRU, donde <App> es Word, Excel o PowerPoint y el identificador de cuenta identifica la cuenta con la sesión iniciada (por ejemplo, LiveId_… o ADAL_…). Cada valor Item n tiene un aspecto como [F00000000][T01DCE118009C9A00][O00000000]*C:\Users\ana\Documents\plan.docx. La parte [T…] es un FILETIME en hexadecimal: 0x01DCE118009C9A00 = 134.229.582.120.000.000, que corresponde a 2026-05-11T07:30:12Z. Es una marca de tiempo por archivo, algo que RecentDocs no puede proporcionar. Una clave del mismo nivel, Place MRU, enumera las carpetas.
LibreOffice no utiliza estas claves; mantiene los documentos recientes como URL file:/// en el archivo de su perfil de usuario registrymodifications.xcu (en %APPDATA%\LibreOffice\4\user).
Ejemplo resuelto: ¿cuándo se abrió budget-q3.xlsx por última vez?
La recopilación de triaje del equipo de ana, DESKTOP-7QK2M1F (Windows 11), contiene una Jump List de Excel en AutomaticDestinations y Recent\budget-q3.xlsx.lnk.
1. DestList. JLECmd muestra la entrada 26: ruta E:\Clients\budget-q3.xlsx, nombre NetBIOS DESKTOP-7QK2M1F, recuento de accesos 4, estado de anclaje -1, FILETIME del último acceso 0x01DCE76C17B033A0. Conviértalo: 0x01DCE76C17B033A0 = 134.236.540.354.180.000 intervalos de cien nanosegundos; ÷ 10.000.000 = 13.423.654.035,418 s desde 1601; − 11.644.473.600 = tiempo Unix 1.779.180.435,418 = 2026-05-19T08:47:15.418Z.
2. LNK integrado. Entrada 26 = 0x1A, por lo que se abre el flujo 1a: tipo de unidad 2 (extraíble), bytes del número de serie de la unidad 4D 3C 2B 1A, leídos en formato little-endian como 0x1A2B3C4D y mostrados como 1A2B-3C4D, etiqueta CLIENTS.
3. LNK de Recent. budget-q3.xlsx.lnk tiene la misma ruta, el mismo tipo de unidad y el mismo número de serie. Su cabecera contiene la marca de tiempo de modificación del destino 2026-05-12T13:02:40Z y un tamaño de 48.640 bytes. Según la $MFT recopilada, el propio .lnk se creó el 2026-05-11T07:30:12Z y se modificó el 2026-05-19T08:47:16Z.
4. Comparación. La modificación del LNK es 0,582 s posterior a la marca de tiempo de DestList. Distintos componentes escriben los dos artefactos durante la misma apertura, por lo que una diferencia de uno o dos segundos es normal. El número de serie del volumen en ambos coincide con el del sector de arranque de la imagen USB (lección 2.6). La creación del LNK sugiere una primera apertura el 2026-05-11, y el recuento muestra al menos cuatro usos.
Respuesta: se abrió por última vez a las 2026-05-19T08:47:15Z (en segundos, como solicita la tarea), según la Jump List de Excel, corroborada por el LNK de Recent. Escriba siempre UTC con Z; nunca copie una hora que una herramienta haya mostrado en hora local sin convertirla.
Selección y corroboración
| Pregunta | Mejor artefacto | Corroborar con |
|---|---|---|
| ¿Cuándo se abrió el archivo X por última vez? | Último acceso de DestList en la Jump List de la aplicación | Marca de tiempo de modificación del LNK de Recent; marca de tiempo [T…] de Office; LastWrite de RecentDocs si X encabeza la lista |
| ¿Cuándo se abrió X por primera vez? | Marca de tiempo de creación del LNK de Recent | Registro del diario USN que crea el .lnk (lección 1.4) |
| ¿Estaba X en una unidad extraíble y en cuál? | LinkInfo del LNK: tipo de unidad y número de serie del volumen | LNK integrado en la Jump List; VBR de la imagen USB (lección 2.6) |
| ¿Qué programa abrió X? | AppID de la Jump List que contiene X | LastVisitedPidlMRU; artefactos de ejecución (lección 2.3) |
| ¿Qué carpeta exploró el usuario o en cuál guardó archivos? | OpenSavePidlMRU, LastVisitedPidlMRU | Shellbags (lección 2.5) |
| ¿Qué escribió o buscó el usuario? | TypedPaths, RunMRU, WordWheelQuery | LastWrite de la clave; Shellbags |
Enfoque del examen: Espere una tarea que pregunte cuándo se abrió un archivo por última vez, desde qué volumen o con qué programa, y que requiera como respuesta una hora UTC exacta, una ruta completa o un número de serie de volumen. Sepa dónde se encuentra cada artefacto en una recopilación de triaje, cómo se corresponde un número de entrada de DestList con un nombre de flujo hexadecimal y que las marcas de tiempo de la cabecera LNK pertenecen al destino. Prepárese para explicar por qué RecentDocs fecha únicamente su entrada más reciente.
Puntos clave
- Los LNK automáticos de
%APPDATA%\Microsoft\Windows\Recentregistran la ruta, las marcas de tiempo, el tamaño, el tipo de unidad, el número de serie del volumen y el nombre del equipo del destino, y persisten tras la eliminación o retirada del destino. - Existe un LNK de Recent por cada nombre de destino; sus propias marcas de tiempo de creación y modificación suelen aproximarse a la primera y la última apertura, lo que debe corroborarse.
- Las Jump Lists de
AutomaticDestinationsson archivos compuestos con flujos LNK numerados y una DestList que contiene la marca de tiempo del último acceso, el recuento de accesos, el estado de anclaje y la ruta de cada elemento. - MRUListEx proporciona el orden; LastWrite de una clave fecha únicamente la entrada que encabeza la lista. Los valores
[T…]de File MRU de Office proporcionan FILETIME por archivo. - Responda a «cuándo se abrió por última vez» a partir de DestList, corrobore con el LNK e indique UTC con
Z.