Forense de descargas en macOS: un caso paso a paso
Una intrusión sintética en macOS analizada con Quarantine Parser: cronología, fila borrada recuperada, rechazo de Gatekeeper y AppleDouble en USB.
TL;DR. Este caso paso a paso usa la muestra sintética del sitio: el portátil macOS FIN-MBP-03, la usuaria dana.whitlock, el 14 de septiembre de 2026. En pocos minutos, los datos de cuarentena muestran un archivo de herramientas de un servicio de alojamiento cuya fila en la base de datos se borró y se recuperó, una descarga desde un sitio de paste, un LaunchAgent falso con el valor de cuarentena del archivo comprimido, un auxiliar al que se le quitó la cuarentena, una imagen de disco cuya app rechazó Gatekeeper y una hoja de cálculo financiera que llegó a un volumen USB. También muestra dónde terminan los datos de cuarentena.
Todo lo que sigue es ficticio: equipos, personas y archivos no existen, y todos los dominios terminan en .example.
El escenario
El caso continúa la intrusión ficticia FIN-WKS-07 / svc_backup. Un atacante con una sesión robada está activo en el portátil de dana.whitlock, del departamento financiero, entre aproximadamente las 10:05 y las 10:50 UTC. La pregunta: qué se descargó, qué se preparó y si salió algo.
1. Cargar la muestra
Abra la página de inicio en /es y pulse Probar un ejemplo. El análisis se ejecuta en su navegador; no se sube nada. La vista Fuentes enumera lo que se cargó y cómo se analizó cada archivo. La línea base abarca del 18 de agosto al 15 de septiembre: informes de la intranet y del servidor de documentos guardados con Safari, MeetClient-5.2.pkg y MeetClient-5.3.pkg desde downloads.meet.example con Chrome (la 5.3 aprobada por la usuaria, flags 00c3), adjuntos de Mail de ap@vendor.example y priya.raman@fin.example, adjuntos de Mensajes y un AirDrop recibido a través de sharingd.
2. Fijar la ventana del incidente
Fije el rango de tiempo en 10:00–10:55 UTC del 2026-09-14, escribiéndolo o arrastrando sobre la franja de densidad. El rango se aplica a todas las vistas y exportaciones y se guarda en el hash de la URL, así que el enlace reproduce su vista. La línea base desaparece y la vista Hallazgos solo enumera las pistas de esta ventana.
3. Leer la cronología
La Cronología muestra tres descargas dentro de la ventana:
- 10:07:12, Safari,
https://files.example/s/8f3k2/tools.zip, origenhttps://files.example/s/8f3k2; - 10:12:05, Chrome,
https://paste.example/raw/Zx81; - 10:26:30, Safari,
https://transfer.example/d/Qm7/sync-agent.dmg.
La vista Dominios no muestra ninguno de estos hosts en la línea base. Los hallazgos los señalan como servicios de alojamiento de archivos, de paste y de transferencia, y señalan archivos comprimidos e imágenes de disco de dominios poco vistos. Son pistas, no veredictos: el personal financiero sí usa servicios de transferencia.
4. La fila de files.example recuperada
La fila de tools.zip aparece marcada como recuperada. En el escenario, la fila se borró de la base de datos con sqlite3 hacia las 10:48. El lector SQLite propio de la herramienta encontró el registro en el espacio libre de la página de la tabla y lo reconstruyó. El hallazgo dice «posible borrado o limpieza». El artículo sobre recuperación explica el carving.
La fila de QuarantineEventsV2 recuperada sigue uniéndose por UUID: la vista Archivos muestra cinco archivos con su identificador, entre ellos los tres archivos que extrajo la Utilidad de Archivo (tools/README.txt, tools/updater.sh, tools/com.example.updater.plist) con el mismo valor de cuarentena. Borrar la fila no eliminó los atributos, y son los atributos los que devuelven la fila a su contexto.
5. El texto de paste.example
La descarga de Chrome se guarda como ~/Downloads/Zx81.txt. Un paste en bruto descargado durante una intrusión puede ser un script o una lista de comandos, pero los datos de cuarentena solo demuestran la descarga. Recopile y lea el archivo en sí.
6. La copia en LaunchAgents
Una copia de com.example.updater.plist está en ~/Library/LaunchAgents/. Sigue llevando el valor de cuarentena de tools.zip, UUID incluido, así que es uno de los cinco archivos unidos. El hallazgo «archivo descargado en una carpeta de inicio automático» apunta a ella. El valor de cuarentena indica de dónde vino el plist, no cuándo se copió a LaunchAgents; feche ese paso con otros artefactos.
7. El sync-helper sin cuarentena
~/Library/Caches/.sync/sync-helper tiene un WhereFroms que apunta a files.example, pero ningún atributo de cuarentena. La herramienta genera «WhereFroms sin atributo de cuarentena (posible xattr -d)». En el escenario, el atributo se eliminó. En un caso real, valore las alternativas explicadas en kMDItemWhereFroms frente a la cuarentena antes de calificarlo de antiforense.
8. La imagen de disco de transfer.example y el rechazo de Gatekeeper
Treinta y cinco segundos después de descargar la imagen de disco, un registro .LastGKReject muestra que Gatekeeper rechazó /Volumes/Sync Agent/SyncAgent.app a las 10:27:05, con XProtectMalwareType 2 (reportado como app/programa sin firmar; Apple no documenta la correspondencia). El nombre del volumen coincide con la imagen; el vínculo se basa en el nombre y la hora. Consulte .LastGKReject como evidencia para ver la cadena completa.
9. Q3_forecast.xlsx en el volumen EXFIL
Para este paso, amplíe el rango a todo el conjunto de datos. Q3_forecast.xlsx era un adjunto de Mail recibido el 28 de agosto. La muestra incluye su archivo AppleDouble ._Q3_forecast.xlsx del volumen USB exFAT EXFIL. Ese archivo aún contiene el valor de cuarentena de Mail y el WhereFroms, lo que vincula la copia de la memoria con el adjunto original.
Cronología (UTC, 2026-09-14)
| Hora | Fuente | Evento |
|---|---|---|
| 10:07:12 | Fila recuperada, cinco archivos unidos | Safari descarga tools.zip de files.example |
| 10:12:05 | Fila de la base, atributo | Chrome descarga Zx81.txt de paste.example |
| sin fecha | Atributo de la copia en LaunchAgents | com.example.updater.plist en ~/Library/LaunchAgents/ |
| sin fecha | WhereFroms, sin cuarentena | sync-helper bajo ~/Library/Caches/.sync/ |
| 10:26:30 | Fila de la base | Safari descarga sync-agent.dmg de transfer.example |
| 10:27:05 | .LastGKReject | Gatekeeper rechaza SyncAgent.app, tipo 2 |
| hacia 10:48 | Recuperación del espacio libre | Fila de files.example borrada con sqlite3 |
| sin fecha | AppleDouble en EXFIL | Q3_forecast.xlsx presente en el volumen USB |
Exporte la cronología y los archivos como CSV, JSON o CSV listo para Timesketch; las exportaciones siguen el rango seleccionado.
Lo que los datos de cuarentena no pueden mostrar
Tres pasos del escenario no dejan rastro de cuarentena:
- la apertura de Terminal usada para ejecutar comandos;
- la concesión de acceso total al disco en TCC;
- la copia al USB en sí.
Pase a otros artefactos: los registros unificados para la actividad de procesos y políticas, TCC.db para los permisos de privacidad y FSEvents para los cambios en el sistema de archivos, como la escritura en el volumen EXFIL. Recopile también los propios archivos: Zx81.txt, updater.sh, el plist del LaunchAgent y sync-helper.
Para los comandos de recopilación, consulte recopilar eventos de cuarentena, y para una referencia condensada, la ficha de eventos de cuarentena de nuestro sitio hermano.
Preguntas frecuentes
¿Es real el caso FIN-MBP-03?
No. Equipo, usuaria, dominios y archivos son ficticios y los datos son sintéticos. Todos los dominios usan el sufijo reservado .example. La muestra existe para mostrar cómo encajan los artefactos.
¿Pueden los datos de cuarentena demostrar que un archivo se copió a un USB?
No directamente. Muestran de dónde vino un archivo. En la muestra, el archivo AppleDouble del volumen EXFIL demuestra que Q3_forecast.xlsx llegó a ese volumen con sus atributos, pero la copia en sí debe fecharse con otros artefactos, como FSEvents.
¿Por qué faltaba la fila de files.example en la base de datos activa?
En el escenario se borró con sqlite3 hacia las 10:48 UTC. Quarantine Parser la recuperó analizando el espacio libre de la página de la tabla. La recuperación depende de la configuración de SQLite y de escrituras posteriores, así que no haberla recuperado no habría demostrado nada.