Aller au contenu

JournauxExécutionActivité utilisateur

Unified Logs : la journalisation tracev3 de macOS

Les Unified Logs de macOS (tracev3 et uuidtext) enregistrent connexions, sudo, TCC, Gatekeeper, installations et périphériques à la sous-seconde.

Emplacement
/private/var/db/diagnostics/
Prouve
Ce que les processus et sous-systèmes ont signalé, et quand : connexions, élévations de privilèges, contrôles de sécurité, périphériques
Horodatages
Temps Mach converti via les enregistrements timesync ; log show affiche de l'ISO 8601 avec décalage UTC
Accès
root (le groupe admin peut lire le magasin) ; log collect nécessite sudo
Rétention
Rotation par taille, en général de quelques jours à quelques semaines
Collecte
log collect, sysdiagnose, mac_apt, UAC, Aftermath

Ce que c'est

Le système Unified Logging (apparu avec macOS 10.12 Sierra) est le journal central du noyau, des démons Apple et du code tiers qui utilise os_log. logd écrit des fichiers binaires compressés .tracev3 ; les chaînes de format lisibles ne sont pas stockées dans chaque entrée mais dans des fichiers uuidtext et de cache partagé (dsc) distincts, indexés par l'UUID du binaire émetteur.

Pour l'enquêteur, c'est l'enregistrement chronologique le plus riche d'un Mac : authentification, sudo, décisions TCC, activité Gatekeeper et XProtect, installations, montages de disques et changements réseau y aboutissent tous. Ses limites comptent tout autant : rotation par quota, niveaux jamais persistés et masquage <private>.

Où il se trouve

CheminContenuRemarques
/private/var/db/diagnostics/Persist/Magasin .tracev3 principalJusqu'à environ 10,5 Mo par fichier (observation Mandiant)
/private/var/db/diagnostics/Special/Entrées moins volumineuses avec leur propre durée de vieSouvent plus anciennes que Persist
/private/var/db/diagnostics/Signpost/Signposts de performanceAffichés uniquement avec --signpost
/private/var/db/diagnostics/HighVolume/Données à fort volume, lorsqu'elles sont utiliséesSouvent vide
/private/var/db/diagnostics/timesync/Enregistrements de corrélation démarrage/horlogeNécessaires pour convertir les horodatages
/private/var/db/uuidtext/00 à FF, dsc/Chaînes de format et chemins d'images, chaînes du cache partagéNécessaires pour reconstituer les messages
*.logarchivePaquet portable issu de log collect ou de sysdiagnoseAutonome

Le répertoire diagnostics appartient à root:admin avec le mode 750 sur les versions actuelles : collectez en root, et accordez l'accès complet au disque au terminal si la même exécution copie aussi des données utilisateur protégées par TCC. Les entrées qui n'existent qu'en mémoire (la plupart des messages info et debug) sont perdues à l'extinction.

Ce qu'il prouve

  • Quel processus (processImagePath) et quelle bibliothèque (senderImagePath) ont émis un message, avec PID, thread et identifiant utilisateur.
  • Des séquences d'événements de sécurité : usage de sudo, connexions SSH et locales, invites et résultats TCC, évaluations Gatekeeper, analyses XProtect Remediator, installations de profils de configuration.
  • L'activité des périphériques et volumes (stockage de masse USB, montages DiskArbitration), les changements réseau et Wi-Fi.
  • Les sessions de démarrage (bootUUID) et la fenêtre de temps réellement couverte par le magasin.

Il ne prouve pas une absence. Une entrée manquante peut signifier que le niveau n'était pas persisté, que la valeur a été masquée, que la formulation du message a changé d'une version à l'autre ou que le fichier est sorti de la rotation.

Champs clés

Noms de champs tels qu'émis par log show --style json ou ndjson :

ChampSignification
timestampHeure murale avec décalage UTC, précision à la microseconde
machTimestampTemps Mach brut de l'entrée
bootUUIDSession de démarrage à laquelle appartient l'entrée
processImagePath, processIDProcessus émetteur
senderImagePath, senderImageUUIDBinaire ou bibliothèque ayant émis le message
subsystem, categorySous-système en DNS inversé et catégorie, par exemple com.apple.TCC
messageTypeDefault, Info, Debug, Error, Fault
eventTypePar exemple logEvent, activityCreateEvent, signpostEvent
eventMessage, formatStringTexte rendu et modèle dont il provient
userID, threadID, activityIdentifier, traceIDContexte pour la corrélation
timezoneNameFuseau horaire enregistré avec l'entrée

formatString est utile quand les valeurs sont <private> : le modèle montre toujours de quel type d'événement il s'agit.

Horodatages

Les entrées stockent des valeurs de temps Mach, pas une époque. Les enregistrements timesync font correspondre le temps Mach de chaque démarrage à l'heure murale ; sur Apple silicon, la valeur brute est exprimée en ticks de base de temps et non en nanosecondes, d'où le besoin du dossier timesync pour les parseurs tiers. Le résultat est un instant UTC.

Sur les versions actuelles de macOS, log show ne tient pas compte de la variable d'environnement TZ. Sans --timezone, il affiche chaque entrée dans le fuseau horaire enregistré au moment de son écriture. Forcez l'UTC pour les chronologies :

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 et --end acceptent YYYY-MM-DD, YYYY-MM-DD HH:MM:SS ou une valeur avec un décalage explicite (HH:MM:SSZZZZZ).

Rétention

La rotation se fait par taille, pas par ancienneté : logd supprime les fichiers .tracev3 les plus anciens pour rester dans son budget, si bien qu'un Mac très actif ne conserve que quelques jours quand un Mac calme en garde plusieurs semaines. Mandiant a observé environ 52 fichiers Persist d'environ 10,5 Mo chacun (soit quelque 550 Mo au total). Les entrées Special portent une durée de vie et peuvent survivre à Persist. sudo log erase supprime le magasin principal et les données en cours, et --all supprime aussi le contenu TTL, fault et error.

Collecte

# 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 exige un dossier uuidtext à côté du dossier diagnostics, comme sur un vrai volume.

  • sysdiagnose inclut un .logarchive.
  • UAC copie *.tracev3, uuidtext et timesync (files/logs/macos_unified_logs.yaml).
  • mac_apt UNIFIEDLOGEXPORT exporte diagnostics et uuidtext depuis une image pour analyse avec macos-UnifiedLogs.
  • Aftermath ne copie pas le magasin ; il exécute un ensemble de prédicats log show (échecs sudo, connexions, TCC, SSH, partage d'écran, XProtect Remediator, installations manuelles de profils) et accepte les vôtres avec --logs.

Calculez l'empreinte du contenu de l'archive : un .logarchive est un répertoire.

Analyse

  • log show / log stats sur un Mac avec la même version de macOS ou une plus récente : l'implémentation de référence.
  • macos-UnifiedLogs (Mandiant, Rust) : github.com/mandiant/macos-UnifiedLogs. L'exemple unifiedlog_iterator gère les systèmes live, les archives de journaux et les fichiers isolés :
unifiedlog_iterator --mode log-archive --input case.logarchive \
  --output case.jsonl --format jsonl
  • Plaso, parseur unified_logging (absent du preset macOS par défaut, nommez-le explicitement) : log2timeline.py --parsers unified_logging --storage-file ul.plaso ./case.logarchive.

Prédicats de départ (à adapter à la version ciblée) :

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 ouvre dans le navigateur une .logarchive, les dossiers diagnostics et uuidtext ou un export log show, applique des règles de triage DFIR et exporte en CSV ou Timesketch ; rien n'est envoyé.

Conseils d'investigation

  • Relevez le premier et le dernier horodatage de chaque démarrage (log stats, ou premières et dernières lignes) avant d'affirmer que « rien ne s'est passé » dans une fenêtre donnée.
  • Conservez toujours uuidtext avec les fichiers tracev3. Sans lui, les outils multiplateformes produisent des messages incomplets.
  • Sur macOS 26, l'outil log enregistre ses propres exécutions sous le sous-système com.apple.log, avec le processus parent et les arguments. Cherchez-y des commandes log erase ou des log show très larges lancées par un intrus.
  • Un historique qui commence brutalement juste après un démarrage sur un Mac peu actif, avec des données plus anciennes dans Special mais pas dans Persist, mérite d'être confronté à l'hypothèse d'un effacement.
  • Validez la sortie des parseurs tiers contre log show pour tout ce que vous présenterez en justice, et notez la version du parseur.
  • Poursuivez vers les pages dédiées : journaux sudo, périphériques USB, Gatekeeper et XProtect, TCC.db. Le guide des Unified Logs propose d'autres prédicats.

Voir aussi