Navegadores, correo y sincronización en la nube · Lección 1 de 6
Navegadores Chromium: historial, descargas, cookies y sesiones
12 min de lectura
La mayoría de los equipos Windows que examine ejecutan al menos un navegador basado en Chromium, y el navegador suele ser donde se hace visible la intención: qué buscó el usuario, qué página abrió, qué archivo descargó y desde dónde. Esta lección aborda el perfil de Chromium: dónde se encuentra, qué archivos SQLite y JSON contiene, cómo leer visitas, transiciones y descargas con horas UTC exactas, qué implica el cifrado de cookies y contraseñas para un examinador y cómo recopilar las bases de datos para no perder registros recientes y eliminados. La caché y la navegación privada se tratan en la lección 4.3.
Un formato de perfil, muchos navegadores
Google Chrome, Microsoft Edge, Brave, Opera y Vivaldi comparten el formato de perfil de Chromium, por lo que los mismos archivos, tablas y analizadores se aplican a todos ellos. Cada navegador mantiene una carpeta User Data y, dentro de ella, una carpeta por perfil: Default para el primer perfil, después Profile 1, Profile 2 y así sucesivamente.
| Navegador | Ubicación del perfil en Windows |
|---|---|
| Google Chrome | %LOCALAPPDATA%\Google\Chrome\User Data\<Profile> |
| Microsoft Edge | %LOCALAPPDATA%\Microsoft\Edge\User Data\<Profile> |
| Brave | %LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\<Profile> |
| Vivaldi | %LOCALAPPDATA%\Vivaldi\User Data\<Profile> |
| Opera | %APPDATA%\Opera Software\Opera Stable\Default (Roaming, no Local; las versiones anteriores usan la propia carpeta Opera Stable) |
%LOCALAPPDATA% es C:\Users\<user>\AppData\Local, de modo que la propia ruta vincula el perfil con una cuenta de Windows. Revise todas las carpetas de perfil, no solo Default: un segundo perfil es un lugar habitual para la actividad que el usuario quería mantener separada.
Local State, un nivel más arriba, en User Data, es un archivo JSON para todo el navegador. En profile.info_cache enumera cada carpeta de perfil con su name visible y, para un perfil con sesión iniciada, el correo electrónico de la cuenta en user_name. En os_crypt.encrypted_key contiene la clave codificada en Base64 que protege las cookies y las contraseñas guardadas. Una vez decodificado, ese valor comienza con el texto ASCII DPAPI, seguido de un bloque de datos protegido por la API de protección de datos de Windows (DPAPI) para ese usuario.
La base de datos History
History es una base de datos SQLite. Chromium almacena sus tiempos como tiempo WebKit: microsegundos desde 1601-01-01 UTC (lección 3.1). Chrome elimina las visitas de más de unos 90 días de antigüedad, por lo que un período inicial vacío puede deberse a la caducidad, no a la inactividad.
urls y visits
La tabla urls tiene una fila por cada URL distinta: id, url, title, visit_count, typed_count (la frecuencia con que se escribió la URL en el omnibox, la barra combinada de direcciones y búsqueda) y last_visit_time. Es un resumen. La tabla visits tiene una fila por visita, que es lo que necesita una línea de tiempo:
url: elurls.idde la página visitada (una clave foránea, no texto);visit_time: cuándo comenzó la visita (tiempo WebKit);from_visit: elvisits.idde la visita de origen, que permite reconstruir cadenas de navegación;transition: cómo llegó el usuario;visit_duration: cuánto tiempo permaneció cargada la página en su pestaña, en microsegundos, hasta que la pestaña navegó a otra página o se cerró.
Valores de transición
El byte menos significativo de transition (transition & 0xFF) es el tipo básico; los bits más significativos son calificadores.
| Valor básico | Tipo | Significado |
|---|---|---|
| 0 | LINK | Se siguió un enlace |
| 1 | TYPED | URL escrita en el omnibox o elegida entre sus sugerencias |
| 2 | AUTO_BOOKMARK | Se abrió desde un marcador |
| 5 | GENERATED | Búsqueda u otra URL generada a partir del texto del omnibox |
| 7 | FORM_SUBMIT | Resultado del envío de un formulario |
| 8 | RELOAD | Se volvió a cargar la página |
Los bits calificadores incluyen 0x01000000 (adelante/atrás), 0x02000000 (desde la barra de direcciones), 0x10000000 y 0x20000000 (inicio y fin de una cadena de redirecciones), 0x40000000 (redirección del cliente) y 0x80000000 (redirección del servidor). Así, 805.306.368 = 0x30000000 es un LINK que inició y finalizó una cadena, y 838.860.805 = 0x32000005 es GENERATED desde la barra de direcciones. Algunas herramientas muestran los valores cuyo bit más significativo está activado como enteros negativos; la máscara proporciona el mismo tipo básico en ambos casos. Una visita TYPED es una evidencia más sólida de la intención del usuario que una visita LINK, que puede desencadenar una página o un script.
downloads y downloads_url_chains
La tabla downloads tiene una fila por descarga: target_path (ruta final), current_path (ruta durante la descarga, normalmente igual a target_path cuando se completa), start_time, end_time, received_bytes, total_bytes, state (1 completada, 2 cancelada, 4 interrumpida), danger_type (0 significa que no se mostró ninguna advertencia), tab_url y referrer (la página desde la que se inició la descarga), mime_type, opened (1 si se abrió desde la interfaz de descargas del navegador) y last_access_time. downloads_url_chains se vincula con ella mediante id y contiene una fila por chain_index; el índice más alto es la URL de la que procedía realmente el archivo, y los índices inferiores muestran las redirecciones que llevaron hasta allí. El archivo en disco suele tener un flujo Zone.Identifier cuyo HostUrl debería coincidir con esa URL final (lección 1.4).
keyword_search_terms
keyword_search_terms almacena los términos de búsqueda escritos en el omnibox (term y normalized_term en minúsculas), con url_id apuntando a la fila de urls de la página de resultados. Al unirla con visits se obtiene la hora de cada búsqueda.
Otros archivos del perfil
| Archivo | Formato | Qué permite saber |
|---|---|---|
..\Local State | JSON | Qué perfiles existen, sus nombres y las cuentas con sesión iniciada; la clave de cifrado |
History | SQLite | Qué páginas se visitaron, cuándo y cómo; qué se descargó; qué se buscó |
Shortcuts | SQLite | Qué texto escribió el usuario en el omnibox y a qué URL se resolvió (omni_box_shortcuts) |
Top Sites | SQLite | Qué sitios visitó más el usuario |
Favicons | SQLite | Para qué URL de páginas se cargaron iconos; útil para comparar con History |
Bookmarks | JSON | Qué se añadió a marcadores y cuándo (date_added, tiempo WebKit almacenado como cadena) |
Preferences, Secure Preferences | JSON | Cuenta con sesión iniciada, directorio de descarga predeterminado, configuración de extensiones |
Login Data | SQLite | Qué sitios tenían nombres de usuario guardados (logins: origin_url, username_value, date_created, times_used) |
Web Data | SQLite | Qué se escribió en los formularios web (autofill: name, value, count, date_created, date_last_used) |
Network\Cookies | SQLite | Qué hosts establecieron cookies, cuándo se crearon, cuándo se usaron por última vez y cuándo caducan |
Sessions\ | SNSS | Qué pestañas y navegaciones estaban abiertas en la sesión actual o en la última |
Extensions\<id>\<version>\ | carpetas | Qué extensiones están instaladas (manifest.json proporciona el nombre y los permisos) |
No todos los tiempos de Chromium son tiempos WebKit: date_created y date_last_used en la tabla autofill son segundos Unix. Compruebe la magnitud de cada valor antes de convertirlo.
Sesiones
Las versiones recientes mantienen archivos Session_<n> y Tabs_<n> en la carpeta Sessions, donde <n> es una marca de tiempo WebKit; las versiones anteriores usaban Current Session, Last Session, Current Tabs y Last Tabs en la carpeta del perfil. Son archivos SNSS: la firma SNSS, una versión de 32 bits y, después, una serie de comandos que registran ventanas, pestañas y las entradas de navegación de cada pestaña con URL y títulos. Pueden mostrar páginas que estaban abiertas cuando se cerró el navegador, incluidas algunas que ya no figuran en History.
Cookies y cifrado
Desde Chrome 96, la base de datos de cookies es Network\Cookies (antes, Cookies en la carpeta del perfil). La tabla cookies contiene creation_utc, host_key, name, path, expires_utc, last_access_utc y el valor en encrypted_value, con todos los tiempos en formato WebKit. Desde Chrome 80, los valores llevan el prefijo v10 y se cifran con AES-256-GCM mediante la clave de Local State, que a su vez está protegida por DPAPI. Por tanto, descifrarlos sin conexión requiere la clave maestra DPAPI del usuario, que normalmente se recupera con la contraseña del usuario. Desde Chrome 127 en Windows, el cifrado vinculado a la aplicación protege las cookies nuevas (prefijo v20) con una clave adicional que solo entrega un servicio de Chrome que se ejecuta como SYSTEM, y únicamente a la aplicación Chrome. El descifrado sin conexión de valores v20 de una recopilación de triaje es mucho más difícil y, a menudo, inviable. Rara vez se necesitan los valores de las cookies: el host, el nombre y las tres marcas de tiempo suelen mostrar que una cuenta visitó un servicio o inició sesión en él, y cuándo. Las contraseñas guardadas en Login Data también están cifradas; la URL, el nombre de usuario y las fechas están en texto claro.
Recopilación y análisis seguros
Recopile cada base de datos junto con sus archivos complementarios. Un diario de reversión (History-journal) contiene copias de páginas anteriores a un cambio y puede contener registros sobrescritos posteriormente. Una base de datos en modo de registro de escritura anticipada tiene archivos -wal y -shm; el WAL contiene cambios recientes que aún no se han escrito en el archivo principal. Recopile todo lo que exista y trabaje sobre copias: abrir una base de datos con WAL puede integrar el registro en ella y modificar la evidencia. Chromium compila SQLite con la eliminación segura activada, de modo que las filas eliminadas normalmente se sobrescriben con ceros en el archivo principal; pueden sobrevivir copias anteriores en el diario o en el WAL, en las instantáneas de volumen o en el espacio no asignado, y recuperarlas mediante carving requiere una herramienta de recuperación de SQLite y verificación en hexadecimal.
DB Browser for SQLite (abierto en modo de solo lectura) basta para realizar consultas manuales. Hindsight (obsidianforensics) analiza un perfil completo de Chromium y lo convierte en una única línea de tiempo, BrowsingHistoryView de NirSoft lee varios navegadores a la vez y Plaso tiene complementos de Chrome como chrome_27_history (lección 3.3). Verifique cualquier valor analizado comparándolo con la tabla sin procesar.
Ejemplo resuelto: las visitas de ana y una descarga
La recopilación de triaje contiene C:\Users\ana\AppData\Local\Google\Chrome\User Data\Default\History y History-journal. En Local State, profile.info_cache solo enumera Default, con una dirección de correo electrónico en user_name. La consulta es SELECT v.id, u.url, datetime(v.visit_time/1000000 - 11644473600, 'unixepoch') AS utc, v.transition & 0xFF AS core, v.from_visit, v.visit_duration FROM visits v JOIN urls u ON v.url = u.id ORDER BY v.visit_time;. La división entera descarta los microsegundos; escriba el resultado en formato ISO 8601 con T y Z.
| id | url | UTC | core | from_visit | visit_duration |
|---|---|---|---|---|---|
| 4180 | https://www.google.com/search?q=send+large+files+free | 2026-03-14T14:08:52Z | 5 | 0 | 11.777.903 |
| 4181 | https://transfer.example.com/ | 2026-03-14T14:09:03Z | 0 | 4180 | 43.528.443 |
| 4182 | https://transfer.example.com/upload | 2026-03-14T14:09:47Z | 0 | 4181 | 1.275.384.220 |
Compruebe manualmente la fila clave. visit_time es 13.417.970.987.412.563. Dividido entre 1.000.000: 13.417.970.987 s desde 1601. Menos 11.644.473.600: Unix 1.773.497.387. Como 1.773.446.400 es 2026-03-14T00:00:00Z, los 50.987 s restantes = 14 h (50.400) + 9 min (540) + 47 s, lo que da 2026-03-14T14:09:47Z. La duración, 1.275.384.220 µs, es de 1.275 s o 21 min 15 s, por lo que la página permaneció cargada hasta aproximadamente las 14:31:02Z, lo que encaja con el intervalo de SRUM que termina a las 14:31:09Z (lecciones 2.8 y 3.4). keyword_search_terms contiene send large files free con url_id igual al urls.id de la visita 4180.
La tabla downloads tiene una fila con target_path C:\Users\ana\Downloads\xfer.exe, start_time 13.417.892.317.250.948 y end_time 13.417.892.320.031.776, received_bytes y total_bytes ambos con 1.482.752, state 1 y danger_type 0. Inicio: 13.417.892.317 − 11.644.473.600 = 1.773.418.717; menos 1.773.360.000 (2026-03-13T00:00:00Z) quedan 58.717 s = 16 h (57.600) + 18 min (1.080) + 37 s, por lo que es 2026-03-13T16:18:37Z. Fin: 3 s después, 2026-03-13T16:18:40Z. downloads_url_chains proporciona el índice 0 https://files.example.net/get/xfer-latest y el índice 1 https://cdn.files.example.net/b/7f3a/xfer.exe, el origen del archivo. La hora de finalización coincide con la hora de modificación de $SI y la hora de Shimcache de xfer.exe (lección 2.3), el tamaño coincide con Amcache y la primera ejecución a las 16:20:02Z se produjo 82 segundos después. El hallazgo: el perfil de Chrome de la cuenta de ana descargó xfer.exe desde cdn.files.example.net entre las 16:18:37Z y las 16:18:40Z.
Enfoque del examen: Deberá saber convertir tiempos WebKit devisits,downloadsocookiesa ISO 8601 UTC, unirvisits.urlconurls.idpara encontrar la página correspondiente a una visita y leer la URL final dedownloads_url_chains. Conozca los tipos básicos de transición tras aplicar la máscara 0xFF, quevisit_durationestá en microsegundos y qué archivo responde a cada pregunta, incluido Local State para perfiles y cuentas. Recuerde que los tiempos de autofill son segundos Unix, no tiempo WebKit.
Puntos clave
- Chrome, Edge, Brave, Opera y Vivaldi comparten un formato de perfil en
User Data\<Profile>; Local State enumera los perfiles y contiene la clave protegida por DPAPI. - History:
urlsresume cada URL;visitsregistra cada visita convisit_time,from_visit,transition(tipo básico = byte menos significativo) yvisit_durationen microsegundos. downloadsproporciona rutas, tiempos, tamaños y estado;downloads_url_chainsproporciona las redirecciones, con elchain_indexmás alto como URL final del archivo.- Los valores de las cookies están cifrados (v10 con la clave protegida por DPAPI, v20 vinculado a la aplicación desde Chrome 127), pero los hosts, los nombres y los tiempos están en texto claro y suelen ser suficientes.
- Recopile los archivos
-journal,-waly-shmcon cada base de datos y trabaje sobre copias; la eliminación segura rellena con ceros las filas eliminadas, por lo que debe buscar copias anteriores en diarios, archivos WAL e instantáneas de volumen.