Analyse forensique de knowledgeC.db : le guide macOS
Ce que knowledgeC.db enregistre sous macOS, où il se trouve, comment lire ZOBJECT et ses flux, convertir ses horodatages et ce que ces données ne prouvent pas.
En bref. knowledgeC.db est une base SQLite écrite par le framework CoreDuet d'Apple. Elle enregistre les événements de « pattern of life » de macOS sous forme d'intervalles : une app utilisée, l'écran allumé, le Mac verrouillé ou sur secteur, un domaine web visité. Il existe une copie système et une copie par utilisateur, toutes deux en mode WAL. Chaque ligne de la table ZOBJECT appartient à un flux comme /app/usage et porte des heures de début et de fin en temps absolu Mac. Elle indique quelles apps ont été utilisées et quand ; elle ne dit pas qui était au clavier. Sur les versions actuelles de macOS, de nombreux flux, dont l'app au premier plan, sont passés dans Biome : examinez donc les deux sources.
Ce qu'est knowledgeC.db
La base knowledgeC est un magasin Core Data, d'où le préfixe Z de ses tables et colonnes. CoreDuet y écrit une ligne par événement, regroupée par flux. Contrairement aux horodatages du système de fichiers, qui indiquent seulement quand un fichier a changé, chaque ligne a un début et une fin : la base répond donc aux questions de durée. Combien de temps Terminal a-t-il été utilisé, quand l'écran s'est-il éteint, le Mac était-il sur secteur pendant la nuit ?
C'est donc une source de chronologie, pas une source de contenu. Vous obtenez des bundle IDs, des URL, des domaines et des états actif/inactif. Vous n'obtenez ni documents, ni frappes clavier, ni commandes.
Où elle se trouve
| Portée | Chemin | Protection |
|---|---|---|
| Système | /private/var/db/CoreDuet/Knowledge/knowledgeC.db | Propriété de root, restreinte par la protection de l'intégrité du système (SIP) |
| Utilisateur | ~/Library/Application Support/Knowledge/knowledgeC.db | Protégée par TCC : le processus de collecte a besoin de l'Accès complet au disque |
Les deux bases fonctionnent en mode WAL de SQLite. Les fichiers compagnons knowledgeC.db-wal et knowledgeC.db-shm doivent être collectés avec le fichier principal : les événements les plus récents n'existent souvent que dans le WAL. Les commandes de collecte, les options UAC et Velociraptor et les arbitrages liés à SIP sont traités dans knowledgeC.db : emplacement et collecte des flux Biome ; ce que contient le WAL et comment le lire, dans knowledgeC.db-wal : retrouver les événements récents.
La structure de la base
Trois tables portent presque tout ce dont l'analyste a besoin.
ZOBJECT : une ligne par événement
ZOBJECT est la table des événements.
| Colonne | Signification |
|---|---|
ZSTREAMNAME | Flux, par exemple /app/usage ou /display/isBacklit |
ZVALUESTRING | Valeur textuelle principale, en général un bundle ID ou une URL |
ZVALUEINTEGER / ZVALUEDOUBLE | Valeur numérique pour les flux d'état ou de mesure |
ZSTARTDATE / ZENDDATE | Début et fin de l'intervalle |
ZCREATIONDATE | Moment où la ligne a été écrite |
ZSECONDSFROMGMT | Décalage UTC de l'appareil, en secondes, au moment de l'événement |
ZSTARTDAYOFWEEK | Jour de la semaine, 1 = dimanche |
ZUUID | UUID de l'événement |
ZSOURCE | Lien vers la table ZSOURCE |
ZSTRUCTUREDMETADATA | Lien vers la table ZSTRUCTUREDMETADATA |
ZSOURCE : qui a produit l'événement
ZSOURCE décrit le producteur, avec des colonnes comme ZBUNDLEID et ZDEVICEID. APOLLO interprète ZDEVICEID comme l'identifiant de l'appareil d'origine, ce qui compte, car des lignes synchronisées depuis un autre appareil du même compte Apple peuvent apparaître dans la base. Regroupez par appareil avant d'attribuer quoi que ce soit au Mac examiné.
ZSTRUCTUREDMETADATA : les compléments propres à chaque flux
ZSTRUCTUREDMETADATA contient des colonnes supplémentaires par flux, par exemple Z_DKDIGITALHEALTHMETADATAKEY__WEBDOMAIN et Z_DKDIGITALHEALTHMETADATAKEY__WEBPAGEURL pour l'usage web, Z_DKSAFARIHISTORYMETADATAKEY__TITLE pour l'historique Safari, ou Z_DKNOTIFICATIONUSAGEMETADATAKEY__BUNDLEID pour les notifications.
Les colonnes évoluent d'une version de macOS à l'autre. Lisez le schéma de la copie dont vous disposez avant de lancer une requête toute faite.
Les flux que vous rencontrerez
Les valeurs ci-dessous sont celles utilisées par les modules d'APOLLO.
| Flux | Valeur | Signification |
|---|---|---|
/app/usage | ZVALUESTRING = bundle ID | App utilisée, avec début et fin |
/app/inFocus | ZVALUESTRING = bundle ID | App au premier plan |
/device/isLocked | ZVALUEINTEGER 1 / 0 | 1 = verrouillé, 0 = déverrouillé |
/display/isBacklit | ZVALUEINTEGER 1 / 0 | 1 = écran allumé |
/device/isPluggedIn | ZVALUEINTEGER 1 / 0 | 1 = sur secteur |
/safari/history | ZVALUESTRING = URL | Titre de la page dans les métadonnées structurées |
/app/webUsage | bundle ID | Domaine et URL dans les métadonnées structurées |
/notification/usage | ZVALUESTRING = type de notification | Bundle ID dans les métadonnées structurées |
Les modules macOS d'APOLLO couvrent aussi des flux comme /app/activity, /app/intents, /app/mediaUsage et /bluetooth/isConnected. Tous les Mac n'ont pas tous les flux : commencez donc par recenser ceux qui sont réellement présents :
SELECT ZSTREAMNAME, COUNT(*),
datetime(MIN(ZSTARTDATE)+978307200,'unixepoch') AS first_utc,
datetime(MAX(ZSTARTDATE)+978307200,'unixepoch') AS last_utc
FROM ZOBJECT GROUP BY ZSTREAMNAME ORDER BY 2 DESC;
Horodatages et fuseaux horaires
ZSTARTDATE, ZENDDATE et ZCREATIONDATE sont exprimés en temps absolu Mac : des secondes, souvent fractionnaires, écoulées depuis le 2001-01-01 00:00:00 UTC. Ajoutez 978307200 pour obtenir des secondes Unix.
Les valeurs stockées sont en UTC. ZSECONDSFROMGMT enregistre le décalage appliqué par l'appareil à ce moment-là : vous pouvez ainsi afficher l'heure locale sans deviner le fuseau horaire, et un changement de cette valeur entre deux événements est un bon indice de déplacement ou de changement de fuseau.
SELECT datetime(ZSTARTDATE + 978307200, 'unixepoch') AS start_utc,
datetime(ZSTARTDATE + ZSECONDSFROMGMT + 978307200, 'unixepoch') AS start_local
FROM ZOBJECT LIMIT 5;
Prenez l'UTC comme référence dans le rapport et affichez l'heure locale à côté. Mélanger les deux dans une même chronologie est la cause la plus fréquente des erreurs d'une ou deux heures.
Durée de conservation
Sarah Edwards (mac4n6) a documenté environ quatre semaines d'événements dans knowledgeC. La purge se fait par flux et varie selon les versions : ne citez donc pas dans un rapport un chiffre tiré de la littérature. Le ZSTARTDATE le plus ancien de chaque flux, dans la requête ci-dessus, donne la fenêtre de conservation effective sur vos éléments de preuve, et elle a sa place dans vos constatations.
knowledgeC et Biome
Sur les versions récentes de macOS, Apple a transféré de nombreux flux vers Biome, qui les stocke sous forme de fichiers SEGB contenant des enregistrements protobuf ; l'app au premier plan, par exemple, est attendue dans App.InFocus plutôt que dans /app/inFocus. La correspondance flux par flux et ce qu'il faut attendre selon la version sont détaillés dans knowledgeC ou Biome.
Ce qu'elle prouve, et ce qu'elle ne prouve pas
knowledgeC permet d'étayer des affirmations comme :
- ce bundle ID était utilisé ou au premier plan de telle heure à telle heure ;
- l'écran était allumé, le Mac déverrouillé, ou sur secteur, pendant cet intervalle ;
- ce domaine ou cette URL a été visité dans cette app, lorsque les flux web existent.
Elle ne prouve pas :
- qui était au clavier. Un Mac déverrouillé avec une app au premier plan est compatible avec le fait que quelqu'un l'utilisait, pas avec une personne nommément désignée. La méthode pour construire ce raisonnement, et ses limites, est décrite dans qui était au clavier ;
- ce qui a été fait dans une app. Il n'y a ni noms de fichiers ni lignes de commande ;
- une utilisation active dans tous les cas. Une app « utilisée » peut être une fenêtre laissée au premier plan devant un écran inactif. Croisez les intervalles d'app avec
/display/isBacklitet/device/isLocked; - un effacement, lorsqu'un flux est vide. Sur un Mac récent, un
/app/inFocusvide est attendu.
Séparez aussi les lignes locales des lignes synchronisées depuis d'autres appareils à l'aide de ZSOURCE.ZDEVICEID.
Outils d'analyse
| Outil | Ce qu'il fait |
|---|---|
| APOLLO | Modules SQL par flux, fusionnés en une chronologie |
| Plaso | Parseur sqlite/mac_knowledgec pour les super-chronologies |
| Velociraptor | Artefact Exchange MacOS.Applications.KnowledgeC, qui analyse sur place les lignes /app/activity et /app/inFocus |
| sqlite3 | SQL ad hoc, uniquement sur une copie |
| KnowledgeC Parser | Dans le navigateur : applique le WAL, signale les lignes présentes uniquement dans le WAL ou supprimées par lui, fusionne knowledgeC et Biome |
Quel que soit l'outil, travaillez sur des copies. Ouvrir une base en mode WAL avec un client SQLite ordinaire peut déclencher un checkpoint, qui réécrit le fichier principal et peut vider le WAL que vous vouliez examiner.
Un court exemple (synthétique)
La collecte d'exemple fournie avec l'outil est fictive. Sur le MacBook FIN-MBP-03, utilisatrice dana.whitlock, la base système montre un déverrouillage /device/isLocked à 10:04:31 UTC le 2026-09-14, avec ZSECONDSFROMGMT = 7200, soit 12:04 heure locale, alors qu'elle était en pause déjeuner. /app/usage montre ensuite Terminal, Réglages Système et Finder, et la base utilisateur montre /app/webUsage pour transfer.example, avant un verrouillage à 10:49 UTC. Toutes ces lignes se trouvent dans le -wal, pas dans le fichier principal. Sans le WAL, la fenêtre de l'incident paraîtrait vide.
Ce que cela établit : le Mac était déverrouillé et ces apps étaient utilisées pendant cette fenêtre. Ce que cela n'établit pas : que Dana, ou qui que ce soit en particulier, en soit l'auteur. Pour charger l'exemple et suivre les mêmes étapes, voir analyser knowledgeC et Biome dans votre navigateur.
Questions fréquentes
Où se trouve knowledgeC.db sous macOS ?
Il en existe deux copies. La base système est /private/var/db/CoreDuet/Knowledge/knowledgeC.db (propriété de root et restreinte par SIP) et la base utilisateur est ~/Library/Application Support/Knowledge/knowledgeC.db (protégée par TCC : le processus de collecte a donc besoin de l'Accès complet au disque). Les deux fonctionnent en mode WAL : collectez knowledgeC.db-wal et knowledgeC.db-shm avec le fichier principal.
Comment convertir les horodatages de knowledgeC ?
ZSTARTDATE, ZENDDATE et ZCREATIONDATE sont exprimés en temps absolu Mac : des secondes écoulées depuis le 2001-01-01 00:00:00 UTC. Ajoutez 978307200 pour obtenir un temps Unix. Les valeurs stockées sont en UTC ; ZSECONDSFROMGMT donne le décalage, en secondes, appliqué par l'appareil au moment de l'événement.
Pourquoi /app/inFocus est-il vide sur un Mac récent ?
Sur les versions actuelles de macOS, l'app au premier plan est attendue dans le flux Biome App.InFocus plutôt que dans knowledgeC : un /app/inFocus clairsemé ou vide est donc normal et ne prouve pas un effacement. Vérifiez aussi que le fichier -wal a bien été collecté, car les lignes les plus récentes n'existent souvent que là.
knowledgeC.db prouve-t-il qui a utilisé le Mac ?
Non. Il montre qu'une app était utilisée ou au premier plan, que l'écran était allumé ou le Mac déverrouillé, à des moments donnés. Il n'identifie pas la personne au clavier et n'enregistre ni noms de fichiers ni lignes de commande. L'attribution exige d'être corroborée par d'autres artefacts.