Saltar al contenido

RegistrosEjecuciónActividad del usuario

Unified Logs: registro del sistema tracev3 en macOS

Los Unified Logs de macOS (tracev3 y uuidtext) registran inicios de sesión, sudo, TCC, Gatekeeper, instalaciones y dispositivos con precisión de subsegundo.

Ubicación
/private/var/db/diagnostics/
Prueba
Qué procesos y subsistemas informaron de algo y cuándo: inicios de sesión, uso de privilegios, controles de seguridad, dispositivos
Marcas de tiempo
Mach time convertido mediante los registros timesync; log show imprime ISO 8601 con desfase respecto a UTC
Acceso
root (el grupo admin puede leer el almacén); log collect requiere sudo
Retención
Rotación por tamaño, normalmente de días a unas pocas semanas
Adquisición
log collect, sysdiagnose, mac_apt, UAC, Aftermath

Qué es

El sistema Unified Logging (introducido en macOS 10.12 Sierra) es el registro central del kernel, de los daemons de Apple y del código de terceros que usa os_log. logd escribe archivos binarios comprimidos .tracev3; las cadenas de formato legibles no se guardan en cada entrada, sino en archivos uuidtext y de caché compartida (dsc) separados, indexados por el UUID del binario que generó el mensaje.

Para un investigador es el registro cronológico más completo de un Mac: autenticación, sudo, decisiones de TCC, actividad de Gatekeeper y XProtect, instalaciones, montajes de discos y cambios de red acaban aquí. Sus límites son igual de importantes: rotación por cuota, niveles que nunca se persisten y la redacción <private>.

Dónde se encuentra

RutaContenidoNotas
/private/var/db/diagnostics/Persist/Almacén principal .tracev3Hasta unos 10,5 MB por archivo (observación de Mandiant)
/private/var/db/diagnostics/Special/Entradas de menor volumen con su propio tiempo de vidaA menudo más antiguas que las de Persist
/private/var/db/diagnostics/Signpost/Signposts de rendimientoSolo se muestran con --signpost
/private/var/db/diagnostics/HighVolume/Datos de alto volumen, cuando se usanA menudo vacío
/private/var/db/diagnostics/timesync/Registros de arranque y de correlación de relojNecesarios para convertir las marcas de tiempo
/private/var/db/uuidtext/00 a FF, dsc/Cadenas de formato y rutas de imagen, cadenas de la caché compartidaNecesarios para mostrar los mensajes
*.logarchivePaquete portátil generado por log collect o sysdiagnoseAutocontenido

En las versiones actuales, el directorio diagnostics pertenece a root:admin con modo 750; recopílalo como root y concede Full Disk Access al terminal si la misma ejecución copia también datos de usuario protegidos por TCC. Las entradas que solo existen en memoria (la mayoría de los mensajes info y debug) se pierden al apagar el equipo.

Qué prueba

  • Qué proceso (processImagePath) y qué biblioteca (senderImagePath) emitieron un mensaje, con PID, hilo e ID de usuario.
  • Secuencias de eventos de seguridad: uso de sudo, inicios de sesión SSH y locales, solicitudes y resultados de TCC, evaluaciones de Gatekeeper, análisis de XProtect Remediator, instalación de perfiles de configuración.
  • Actividad de dispositivos y volúmenes (almacenamiento masivo USB, montajes de DiskArbitration), cambios de red y de Wi-Fi.
  • Sesiones de arranque (bootUUID) y la ventana temporal que cubre realmente el almacén.

No prueba una ausencia. Que falte una entrada puede significar que el nivel no se persistía, que el valor se redactó, que el texto del mensaje cambió entre versiones o que el archivo se eliminó por rotación.

Campos clave

Nombres de campo tal como los emite log show --style json o ndjson:

CampoSignificado
timestampHora de reloj con desfase respecto a UTC, precisión de microsegundos
machTimestampMach time bruto de la entrada
bootUUIDSesión de arranque a la que pertenece la entrada
processImagePath, processIDProceso que generó el registro
senderImagePath, senderImageUUIDBinario o biblioteca que emitió el mensaje
subsystem, categorySubsistema en notación DNS inversa y categoría, p. ej. com.apple.TCC
messageTypeDefault, Info, Debug, Error, Fault
eventTypep. ej. logEvent, activityCreateEvent, signpostEvent
eventMessage, formatStringTexto final y la plantilla de la que procede
userID, threadID, activityIdentifier, traceIDContexto para correlacionar
timezoneNameZona horaria registrada con la entrada

formatString resulta útil cuando los valores aparecen como <private>: la plantilla sigue mostrando qué tipo de evento se produjo.

Marcas de tiempo

Las entradas guardan valores de Mach time, no una época. Los registros timesync asocian el Mach time de cada arranque con la hora de reloj; en Apple silicon el valor bruto está en ticks de la base de tiempo y no en nanosegundos, por eso los parsers de terceros necesitan la carpeta timesync. El resultado es un instante UTC.

En macOS actual, log show no respeta la variable de entorno TZ. Sin --timezone, imprime cada entrada en la zona horaria registrada cuando se escribió. Fuerza UTC para las líneas de tiempo:

log show --archive case.logarchive --timezone UTC --style ndjson \
  --start "2026-09-20 00:00:00" --end "2026-09-21 00:00:00" > day.ndjson

--start y --end aceptan YYYY-MM-DD, YYYY-MM-DD HH:MM:SS o un valor con desfase explícito (HH:MM:SSZZZZZ).

Retención

La rotación depende del tamaño, no de la antigüedad: logd elimina los archivos .tracev3 más antiguos para mantener el almacén dentro de su presupuesto, de modo que un Mac con mucha actividad puede conservar solo días y uno tranquilo, semanas. Mandiant observó unos 52 archivos Persist de unos 10,5 MB cada uno (unos 550 MB en total). Las entradas Special llevan un tiempo de vida y pueden durar más que las de Persist. sudo log erase borra el almacén principal y los datos en curso, y --all elimina además el contenido con TTL, de fallos y de errores.

Adquisición

# Live: whole store (preferred), or a time slice
sudo log collect --output /Volumes/EVIDENCE/host.logarchive
sudo log collect --output /Volumes/EVIDENCE/last3d.logarchive --last 3d

# Offline store (recovery, mounted image): build an archive from a copied tree
sudo log collect --directory /Volumes/Image/private/var/db/diagnostics \
  --output ./case.logarchive

--directory necesita una carpeta uuidtext junto a la carpeta diagnostics, igual que en un volumen real.

  • sysdiagnose incluye un .logarchive.
  • UAC copia *.tracev3, uuidtext y timesync (files/logs/macos_unified_logs.yaml).
  • mac_apt UNIFIEDLOGEXPORT exporta diagnostics y uuidtext desde una imagen para analizarlos con macos-UnifiedLogs.
  • Aftermath no copia el almacén; ejecuta un conjunto de predicados de log show (fallos de sudo, inicios de sesión, TCC, SSH, compartición de pantalla, XProtect Remediator, instalación manual de perfiles) y acepta los tuyos con --logs.

Calcula el hash del contenido del archivo: un .logarchive es un directorio.

Análisis

  • log show / log stats en un Mac con la misma versión de macOS o una más reciente: la implementación de referencia.
  • macos-UnifiedLogs (Mandiant, Rust): github.com/mandiant/macos-UnifiedLogs. El ejemplo unifiedlog_iterator admite sistemas en vivo, archivos de logs y archivos sueltos:
unifiedlog_iterator --mode log-archive --input case.logarchive \
  --output case.jsonl --format jsonl
  • Parser unified_logging de Plaso (no está en el preset por defecto de macOS, hay que indicarlo explícitamente): log2timeline.py --parsers unified_logging --storage-file ul.plaso ./case.logarchive.

Predicados de partida (adáptalos a la versión analizada):

log show --archive case.logarchive --timezone UTC --style syslog --predicate '
  (process == "sudo" AND eventMessage CONTAINS "COMMAND=")
  OR process == "sshd"
  OR subsystem == "com.apple.TCC"
  OR process == "syspolicyd"
  OR subsystem == "com.apple.DiskArbitration.diskarbitrationd"'

Unified Log Parser abre en el navegador una .logarchive, las carpetas diagnostics y uuidtext o una exportación de log show, aplica reglas de triaje DFIR y exporta a CSV o Timesketch; no se sube nada.

Consejos para la investigación

  • Anota la marca de tiempo más antigua y la más reciente de cada arranque (log stats, o primeras y últimas líneas) antes de afirmar que "no pasó nada" en una ventana temporal.
  • Conserva siempre uuidtext junto a los archivos tracev3. Sin él, las herramientas multiplataforma muestran mensajes incompletos.
  • En macOS 26 la herramienta log registra sus propias ejecuciones en el subsistema com.apple.log, con el proceso padre y los argumentos. Busca ahí comandos log erase o log show amplios lanzados por un intruso.
  • Un inicio brusco del historial justo después de un arranque en un Mac poco activo, con datos más antiguos en Special pero no en Persist, merece contrastarse con un posible borrado.
  • Valida la salida de los parsers de terceros frente a log show para todo aquello sobre lo que vayas a declarar, y anota la versión del parser.
  • Desde aquí, continúa en las páginas específicas: logs de sudo, dispositivos USB, Gatekeeper y XProtect, TCC.db. La guía de Unified Logs incluye más predicados.

Ver también