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
Outils
Comparer tous les outilsCe 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
| Chemin | Contenu | Remarques |
|---|---|---|
/private/var/db/diagnostics/Persist/ | Magasin .tracev3 principal | Jusqu'à environ 10,5 Mo par fichier (observation Mandiant) |
/private/var/db/diagnostics/Special/ | Entrées moins volumineuses avec leur propre durée de vie | Souvent plus anciennes que Persist |
/private/var/db/diagnostics/Signpost/ | Signposts de performance | Affichés uniquement avec --signpost |
/private/var/db/diagnostics/HighVolume/ | Données à fort volume, lorsqu'elles sont utilisées | Souvent vide |
/private/var/db/diagnostics/timesync/ | Enregistrements de corrélation démarrage/horloge | Né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 |
*.logarchive | Paquet portable issu de log collect ou de sysdiagnose | Autonome |
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 :
| Champ | Signification |
|---|---|
timestamp | Heure murale avec décalage UTC, précision à la microseconde |
machTimestamp | Temps Mach brut de l'entrée |
bootUUID | Session de démarrage à laquelle appartient l'entrée |
processImagePath, processID | Processus émetteur |
senderImagePath, senderImageUUID | Binaire ou bibliothèque ayant émis le message |
subsystem, category | Sous-système en DNS inversé et catégorie, par exemple com.apple.TCC |
messageType | Default, Info, Debug, Error, Fault |
eventType | Par exemple logEvent, activityCreateEvent, signpostEvent |
eventMessage, formatString | Texte rendu et modèle dont il provient |
userID, threadID, activityIdentifier, traceID | Contexte pour la corrélation |
timezoneName | Fuseau 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,uuidtextettimesync(files/logs/macos_unified_logs.yaml). - mac_apt
UNIFIEDLOGEXPORTexportediagnosticsetuuidtextdepuis 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 statssur 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_iteratorgè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
uuidtextavec les fichiers tracev3. Sans lui, les outils multiplateformes produisent des messages incomplets. - Sur macOS 26, l'outil
logenregistre ses propres exécutions sous le sous-systèmecom.apple.log, avec le processus parent et les arguments. Cherchez-y des commandeslog eraseou deslog showtrè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
Specialmais pas dansPersist, mérite d'être confronté à l'hypothèse d'un effacement. - Validez la sortie des parseurs tiers contre
log showpour 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.