Documentation
AI Tracer
Forensic de l'activité des agents IA : utilisation, options, gestion des affaires, sources analysées, corrélation système, détections et rapport.
Présentation
AI Tracer reconstitue l'activité d'une IA sur un poste à partir des traces locales, et en produit un rapport d'expertise. La version actuelle couvre Claude Code (CLI, IDE) et Claude Desktop.
L'outil répond à trois questions : qu'a fait l'IA, qu'a fait le système pendant ce temps, et quelque chose de suspect s'est-il produit (injection de prompt, commande dangereuse, exfiltration) ?
Principes forensic
- Un exécutable natif par OS : sans Python, sans runtime, sans installation. Il se lance depuis une clé USB.
- Lecture seule : les sources sont ouvertes sans écriture et sans verrou. Sous Linux,
O_NOATIMEévite de modifier les dates d'accès. - Hachage systématique : chaque fichier lu est haché en SHA-256, puis re-vérifié après lecture.
- Écriture confinée : seul le dossier de sortie est écrit. L'outil refuse un dossier non vide ou situé dans une zone de preuve.
- Traçabilité : chaque événement du rapport renvoie à sa source (
fichier:ligne).
Installation et compilation
Aucune installation n'est nécessaire : on copie le binaire adapté à l'OS cible, par exemple sur une clé USB, et on le lance.
| Plateforme | Architectures | Remarque |
|---|---|---|
| Windows | x64, ARM64 | Runtime C lié statiquement, aucune DLL requise |
| Linux | x64, ARM64 | Binaires statiques (musl) |
| macOS | Apple Silicon, Intel | — |
Compiler soi-même
cargo build --release # binaire : target/release/aitrace(.exe)
cargo test # tests unitaires
Le workflow .github/workflows/build.yml lance d'abord cargo test, puis produit les binaires des six cibles avec leurs empreintes.
Les tests couvrent les fonctions déterministes : parsing des dates, base64, détection d'injections et de commandes, masquage des secrets, classement des journaux et remappage de chemins.
Droits nécessaires : un compte simple suffit pour analyser son propre profil. Il faut être administrateur ou root pour --all-users et pour lire les journaux du système.
Tutoriel vidéo
Dévérouillage du logiciel avec l'utilisation d'une clé de sécurité (YubiKey).
Démarrage rapide
Le cas le plus courant : analyser les 7 derniers jours d'un poste en fonctionnement, rattachés à une affaire.
# 1. Créer l'affaire (une seule fois)
aitrace case new CAS-42 --case-desc "Poste RH compromis" --examiner "J. Brochard"
# 2. Lancer l'analyse (en administrateur / root pour les journaux système)
aitrace --case CAS-42 --all-users --since 7d --tz local --out E:\cas42\run-01
# 3. Ouvrir le rapport
E:\cas42\run-01\report.html
Sans argument, depuis un terminal, aitrace pose les questions utiles (affaire, examinateur, dossier de sortie). Sans --out, un dossier rapport-<affaire>-<horodatage> est créé à côté de l'exécutable.
Autres lancements typiques
aitrace --since 2026-10-01 --until 2026-10-13 --tz local --out E:\cas42 --case-id CAS-42
sudo ./aitrace --all-users --since 7d --out /media/usb/cas42
./aitrace --root /mnt/image --out ./cas42 --collect-raw # image montée en lecture seule
aitrace --case CAS-42 --resume --out E:\cas42\run-02 # reprendre après la dernière analyse
Référence des options
Syntaxe : aitrace [OPTIONS] ou aitrace <COMMANDE>, où la commande est case (registre des affaires) ou help. Les options marquées « répétable » s'utilisent plusieurs fois.
Période et fuseaux
| Option | Rôle | Défaut |
|---|---|---|
--since <DEBUT> |
Début de la période : 2026-10-01, 2026-10-01T14:30, "2026-10-01 14:30" ou relatif 30m, 24h, 7d, 2w |
Aucune borne |
--until <FIN> |
Fin de la période, même format ; une date seule inclut toute la journée | Aucune borne |
--tz <TZ> |
Fuseau pour interpréter les dates et afficher le rapport : UTC, local, +02:00 |
UTC |
--log-tz <TZ> |
Fuseau des journaux Claude Desktop qui n'en indiquent pas | local |
Périmètre
| Option | Rôle | Défaut |
|---|---|---|
--all-users |
Analyser tous les profils de la machine (administrateur ou root conseillé) | Profil courant |
--root <CHEMIN> |
Racine d'une image disque montée en lecture seule (hors ligne) ; implique --all-users |
— |
--claude-dir <DIR> |
Dossier Claude Code à analyser explicitement (répétable) | Détection auto |
--desktop-dir <DIR> |
Dossier Claude Desktop à analyser explicitement (répétable) | Détection auto |
--project <TEXTE> |
Ne garder que les projets dont le chemin contient ce texte | Tous |
--session <PREFIXE> |
Ne garder que la session dont l'identifiant commence par ce préfixe | Toutes |
--no-thinking |
Exclure les blocs de raisonnement de la chronologie | Inclus |
Sortie et preuves
| Option | Rôle | Défaut |
|---|---|---|
-o, --out <DIR> |
Dossier de sortie, nouveau ou vide | rapport-… à côté de l'exécutable |
--collect-raw |
Copier les sources dans <out>/evidence, à partir des octets déjà lus et hachés |
Non |
--redact |
Masquer les secrets apparents (clés, jetons) dans le rapport, pour une diffusion | Non |
Affaire et chaîne de possession
| Option | Rôle | Défaut |
|---|---|---|
--case-id <REF> |
Référence de l'affaire affichée dans le rapport | Vide |
--examiner <NOM> |
Nom de l'examinateur (répétable) | — |
--case-desc <TEXTE> |
Description libre de l'affaire | — |
--seal <NUM> |
Numéro de scellé de la preuve (répétable) | — |
--tag <MOT> |
Mot-clé de classement (répétable) | — |
--case-file <JSON> |
Fiche d'affaire préremplie ; les options ci-dessus la complètent ou la surchargent | — |
--case <REF> |
Rattacher l'analyse à une affaire du registre (créée si absente) | — |
--registry <CHEMIN> |
Emplacement du registre des affaires | ~/.aitrace/cases.json |
--resume |
Avec --case : reprendre après la dernière analyse (fixe --since) |
Non |
--note <TEXTE> |
Commentaire attaché à cette analyse | — |
--no-input |
Ne jamais poser de questions, même sur un terminal | Non |
Journaux système et corrélation
| Option | Rôle | Défaut |
|---|---|---|
--no-system-logs |
Ne pas analyser les journaux du système | Analysés |
--evtx-dir, --evtx <CHEMIN> |
Dossier ou fichier .evtx isolé (répétable) |
winevt\Logs du système ou de --root |
--syslog-dir, --syslog <CHEMIN> |
Dossier ou fichier de journal texte Linux/macOS (répétable) | /var/log |
--journal-json <FICHIER> |
Export journalctl -o json à analyser (répétable) |
— |
--window <SEC> |
Marge autour des périodes d'activité IA pour la corrélation | 300 |
--slack <SEC> |
Tolérance pour rattacher un processus système à une commande IA | 10 |
Détection et automatisation
| Option | Rôle | Défaut |
|---|---|---|
--ioc <FICHIER> |
Liste d'IOC à recouper : un hôte, une IP ou un SHA-256 par ligne (répétable) | — |
--fail-on <NIVEAU> |
Code de sortie 1 si un signalement atteint none, low, medium ou high |
none |
-h, --help |
Afficher l'aide | — |
-V, --version |
Afficher la version | — |
La sortie console est colorée sur un terminal. Les couleurs sont désactivées en pipe ou en redirection, et respectent la variable NO_COLOR.
Gestion des affaires
Un registre unique, un seul fichier JSON, regroupe toutes les affaires et l'historique de leurs analyses. On retrouve ainsi une affaire et on reprend là où on s'était arrêté.
Emplacement par défaut : ~/.aitrace/cases.json. On le déplace avec --registry <chemin>, par exemple vers le poste de l'examinateur ou un support externe.
Sous-commandes
| Commande | Effet |
|---|---|
aitrace case new <REF> [--case-desc …] [--examiner …] |
Créer une affaire ; sans référence, création guidée question par question |
aitrace case list |
Lister les affaires |
aitrace case show <REF> |
Afficher la fiche, les machines analysées et l'historique par machine |
aitrace case note <REF> "<texte>" |
Ajouter un commentaire horodaté à l'affaire |
aitrace case rm <REF> |
Retirer l'affaire du registre ; les rapports produits sont conservés |
Rattacher une analyse
Avec --case <REF>, l'analyse est enregistrée dans l'historique de l'affaire, qui est créée si elle n'existe pas. Sont consignés : les bornes de période, le dossier de sortie, les nombres d'événements et de signalements, l'empreinte agrégée des sources et la ligne de commande.
- Une affaire peut couvrir plusieurs machines : chaque analyse enregistre la machine analysée.
--noteattache un commentaire à une analyse précise ;case noteen attache un à l'affaire entière.
Reprise avec --resume
--resume cale --since sur la fin de la fenêtre analysée la dernière fois. À défaut de borne, il prend l'heure de cette analyse. Un --since explicite reste prioritaire.
aitrace --case CAS-42 --since 7d --out E:\cas42\run-01
aitrace --case CAS-42 --resume --out E:\cas42\run-02
Mode interactif
Lancé depuis un terminal sans --case ni --case-id, l'outil propose un menu : quitter, créer une affaire, reprendre une affaire existante, ou n'en associer aucune. En création, il demande la référence, la description, les examinateurs, les scellés, les mots-clés, le dossier de sortie et un commentaire facultatif.
Les questions ne se posent que sur un vrai terminal. En pipe, en tâche planifiée ou depuis un script, rien n'est demandé. --no-input force ce silence même sur un terminal ; la référence d'affaire doit alors être passée en argument.
Fiche d'affaire et chaîne de possession
La fiche d'affaire contient la référence, la description, les examinateurs, les numéros de scellé et les mots-clés. Elle se renseigne de trois façons combinables, de la base vers la surcharge :
- Le registre, via
--case. - Un fichier réutilisable, via
--case-file <JSON>. - Les options
--case-id,--case-desc,--examiner,--seal,--tag.
Les options complètent les listes (examinateurs, scellés, mots-clés), qui sont fusionnées et dédoublonnées. Elles surchargent les valeurs uniques (référence, description).
aitrace --case-id CAS-42 --examiner "J. Brochard" --examiner "A. Dupont" \
--case-desc "Poste RH compromis" --seal SCELLE-7 --tag phishing \
--out E:\cas42
À chaque analyse, la fiche est écrite dans case.json, réutilisable tel quel avec --case-file.
Section « Chaîne de possession » du rapport
Elle reprend la fiche et les conditions d'exécution :
- outil et version ;
- mode : système en fonctionnement ou image hors ligne ;
- machine, compte et horodatages de l'analyse ;
- ligne de commande complète ;
- nombre de sources lues ;
- empreinte SHA-256 agrégée de l'ensemble des sources : un condensé unique qui change dès qu'une source change, est ajoutée ou retirée.
Le dossier de sortie reste auto-contenu. Seul le registre, hors du dossier de sortie, est mis à jour, et uniquement avec --case.
Sources analysées
Les dossiers sont recherchés selon les conventions des trois OS. On peut donc analyser depuis Windows une image macOS ou Linux, et inversement.
Claude Code
| Emplacement | Contenu exploité |
|---|---|
~/.claude/projects/**/*.jsonl |
Transcripts, sous-agents compris : prompts, réponses, appels d'outils (commandes, fichiers, web, MCP), résultats, erreurs, modèle, version, mode de permissions, coût |
~/.claude/history.jsonl |
Historique des prompts saisis, contenus collés compris |
settings*.json, CLAUDE.md, agents/, commands/, skills/, plugins/ |
Hooks, permissions, instructions persistantes, extensions |
~/.claude.json |
Serveurs MCP et réglages par projet ; valeurs sensibles masquées |
.claude/, .mcp.json, CLAUDE.md des projets touchés |
Configuration propre à chaque projet |
file-history/, shell-snapshots/, todos/, debug/… |
Inventaire : nombre de fichiers, taille, dates, fichiers dans la période |
.credentials.json |
Jamais lu ; seule son existence est consignée |
Claude Desktop
| OS | Emplacement |
|---|---|
| Windows | %APPDATA%\Claude |
| macOS | ~/Library/Application Support/Claude, ~/Library/Logs/Claude |
| Linux | ~/.config/Claude |
Contenu exploité : journaux applicatifs et MCP (appels tools/call), claude_desktop_config.json, extensions, sessions .jsonl.
Corrélation avec les journaux système
L'outil lit les journaux de l'OS et les recoupe avec l'activité de l'IA. Il faut le lancer en administrateur ou en root pour y accéder. Les événements retenus entrent aussi dans la chronologie générale, avec le type system_log.
Journaux lus
| Système | Journaux | Événements retenus |
|---|---|---|
| Windows | winevt\Logs : Security, System, PowerShell, Sysmon, TaskScheduler, Defender, RDP |
Processus (4688, Sysmon 1), scripts PowerShell (4104, 400), sessions, comptes et groupes, services, tâches planifiées, Defender, effacements de journal (1102, 104), réseau, fichiers et registre (Sysmon) |
| Linux / macOS | /var/log : auth.log, secure, syslog, messages, system.log, audit/audit.log (.gz compris) ; export journalctl -o json |
sudo, su, SSH, sessions, gestion des comptes, cron, exécutions (auditd EXECVE), commandes privilégiées |
| Tous | Historiques bash, zsh, fish et PowerShell des utilisateurs | Commandes saisies par un humain, quand elles sont horodatées |
Analyses produites
| Analyse | Ce qu'elle montre |
|---|---|
| Périodes d'activité IA | Rafales d'événements IA, élargies de la marge --window (300 s par défaut) |
| Attribution | Chaque processus système rattaché à la commande IA qui l'a lancé (texte et heure, tolérance --slack) ou à l'arbre de processus de Claude |
| Activité non attribuée | Ce qui s'est passé pendant les périodes d'IA sans venir de l'IA. C'est la liste à examiner en priorité. |
| Commandes IA sans trace système | Commandes lancées par l'IA, journalisation active, mais sans processus correspondant |
| Intégrité des journaux | Effacements, journaux commençant après le début de l'activité IA, journalisation des processus absente |
Prérequis pour recouper les commandes
La machine doit journaliser les créations de processus :
- Windows : audit 4688 avec ligne de commande, ou Sysmon.
- Linux : auditd avec une règle
execve.
Sans cela, le rapport le signale et la corrélation reste partielle.
Détections et scénarios
Après la collecte, l'outil parcourt les événements, hors ligne et sans dépendance, et produit des signalements classés par gravité. La détection est heuristique : elle oriente l'examen sans décider. Chaque signalement renvoie à sa source (fichier:ligne).
Catégories
| Catégorie | Ce qui est examiné | Exemples de signaux |
|---|---|---|
| Injection de prompt | Contenu arrivé par un canal non fiable : sortie d'outil, fichier lu, page web, résultat MCP, pièce jointe, notification. Les prompts de l'humain et les réponses du modèle ne sont pas scrutés. | « ignore previous instructions » et variantes FR, redéfinition de rôle, extraction du prompt système, consignes d'exfiltration ou de dissimulation, jailbreak |
| Caractères Unicode masqués | Tout contenu non fiable, et les prompts (canal d'exfiltration) | Caractères de balise Unicode (« ASCII smuggling », message décodé dans le rapport), caractères de largeur nulle, contrôles bidirectionnels |
| Commande suspecte | Commandes Bash/PowerShell lancées par l'IA et commandes relevées dans les journaux système | curl … \| sh, -EncodedCommand, base64, reverse shell (/dev/tcp, nc -e), vol d'identifiants (LSASS, SAM, /etc/shadow, clés SSH), effacement de journaux, neutralisation des défenses, persistance, création de comptes, exfiltration, destruction |
| Contenu collé | Texte collé dans les prompts (pastedContents), traité comme non fiable |
Mêmes motifs que l'injection |
| Indicateur de compromission | Avec --ioc : hôtes et IP des accès réseau, empreintes SHA-256 des sources |
Hôte ou empreinte présent dans la liste |
Règles de gravité
- Une commande suspecte exécutée en mode
bypassPermissionsvoit sa gravité relevée, et le mode est cité dans la justification. - Le mode
acceptEditsest signalé sans aggraver.
Déobfuscation
Une commande encodée (base64, -EncodedCommand) est décodée, affichée en clair et analysée à son tour. Un IEX / DownloadString caché déclenche donc les règles correspondantes. Une commande tronquée se déplie dans le rapport (« Voir en entier »).
Cartographie
Chaque signalement porte ses techniques MITRE ATT&CK (ex. T1059, T1552.004, T1070.001) et sa catégorie OWASP LLM / ASI (ex. LLM01:2025 Prompt Injection, LLM06:2025 Excessive Agency).
Scénarios (injection → action)
L'outil relie une injection reçue par un canal non fiable aux actions de la même session survenues dans les 5 minutes suivantes : commande, modification de fichier, accès réseau, lecture de fichier sensible.
On obtient un récit plutôt qu'une liste : « injection reçue à T, lecture d'une clé SSH à T+6 s, envoi réseau à T+13 s ». Ces scénarios figurent dans la section « Scénarios » du rapport et dans chains.json.
Rapport produit
Le dossier de sortie est auto-contenu. report.html sert à la lecture humaine, les fichiers JSON à l'outillage, et SHA256SUMS.txt à vérifier l'ensemble.
| Fichier | Contenu |
|---|---|
report.html |
Rapport autonome, sans ressource externe, protégé par une CSP stricte, avec thème clair/sombre automatique |
events.json / events.csv |
Chronologie complète ; le CSV neutralise les formules (pas d'injection Excel) |
sessions.json, config.json, inventory.json |
Sessions, configuration et inventaire structurés |
case.json |
Fiche d'affaire, réutilisable avec --case-file |
findings.json |
Signalements avec mapping ATT&CK / OWASP |
findings.sarif.json |
Mêmes signalements au format SARIF 2.1.0 |
chains.json |
Scénarios d'attaque (injection → actions) |
system_events.json |
Événements système retenus |
log_coverage.json |
Couverture de chaque journal |
correlation.json |
Résultats de la corrélation |
manifest.json |
Contexte d'exécution et SHA-256 de chaque source |
SHA256SUMS.txt |
Empreintes des fichiers du rapport |
evidence/ |
Copie des sources, avec --collect-raw uniquement |
Sections de report.html
Une navigation par ancres en tête mène aux sections principales : Contexte, Chaîne de possession, Intégrité des sources, Synthèse, Détections, Chronologie.
Le rapport contient aussi : corrélation système, sessions, outils, fichiers modifiés, commandes, accès réseau et MCP, configuration, inventaire et manifeste de preuve. Les détections sont filtrables par gravité et liées à la chronologie, elle-même filtrable.
Vérifier l'intégrité du rapport
# Linux / macOS
cd /media/usb/cas42 && sha256sum -c SHA256SUMS.txt
# Windows (PowerShell), fichier par fichier
Get-FileHash .\report.html -Algorithm SHA256
Recettes
Poste en fonctionnement (live)
Lancer depuis une clé USB, en administrateur ou root, vers un dossier de sortie sur la clé. Fermer Claude si possible, pour éviter que des fichiers changent pendant la lecture.
aitrace.exe --case CAS-42 --all-users --since 7d --tz local --collect-raw --out E:\cas42\run-01
sudo ./aitrace --case CAS-42 --all-users --since 7d --collect-raw --out /media/usb/cas42/run-01
Image disque montée (hors ligne)
Monter l'image en lecture seule, puis pointer sa racine. --root implique --all-users ; les dossiers Claude, EVTX et /var/log sont cherchés sous cette racine.
./aitrace --root /mnt/image --out ./cas42 --collect-raw
./aitrace --root /mnt/image --claude-dir /mnt/image/home/alice/.claude --out ./cas42-alice
Artefacts isolés
--evtx et --syslog acceptent un dossier ou un fichier unique, même renommé. Un EVTX est reconnu par son contenu. Un fichier texte est traité en syslog, ou en auditd si son nom le suggère. Un chemin introuvable est signalé dans les remarques sans interrompre l'analyse.
aitrace --evtx E:\preuves\Security.evtx --syslog E:\preuves\auth.log --out E:\cas42
aitrace --journal-json E:\preuves\journal.json --out E:\cas42
Cibler une session ou un projet
aitrace --project webapp --since 2026-10-10 --until 2026-10-12 --out E:\cas42\webapp
aitrace --session 3f2a9c --out E:\cas42\session-3f2a9c
Rapport à diffuser
aitrace --case CAS-42 --redact --no-thinking --out E:\cas42\diffusion
Automatisation et codes de sortie
| Code | Signification |
|---|---|
0 |
Analyse terminée, aucun signalement au niveau de --fail-on |
1 |
Au moins un signalement atteint la gravité de --fail-on |
2 |
Erreur d'exécution |
aitrace --no-input --case CAS-42 --since 24h --ioc iocs.txt --fail-on high --out /srv/aitrace/$(date +%F)
Limites connues et bonnes pratiques
Limites (v1)
| Limite | Conséquence | Ce qu'on peut faire |
|---|---|---|
| Fichiers modifiés pendant la lecture sur un système en fonctionnement | Signalés dans le manifeste | Fermer Claude avant l'analyse, ou travailler sur une image |
| Conversations « chat » de Claude Desktop stockées côté serveur | Caches Electron (IndexedDB, Local Storage) inventoriés mais pas encore décodés | Demander l'export côté compte si nécessaire |
Purge automatique des transcripts (cleanupPeriodDays, 30 jours par défaut) |
Sessions de history.jsonl sans transcript, signalées par l'outil |
Intervenir vite ; chercher des copies plus anciennes (sauvegardes, clichés) |
| Détection heuristique (correspondance de motifs) | Faux positifs et faux négatifs possibles | Toujours revenir à la source fichier:ligne avant de conclure |
O_NOATIME sous Linux seulement |
Sous Windows et macOS, la lecture peut mettre à jour l'atime (contenu inchangé, haché et revérifié) | Pour une lecture strictement inaltérée, analyser une image montée en lecture seule |
| Registre écrit de façon atomique, mais sans verrou | Deux exécutions simultanées sur le même registre peuvent se télescoper | Un seul examinateur à la fois par registre, surtout sur un support partagé |
Bonnes pratiques
- Préférer l'analyse d'une image montée en lecture seule dès que l'affaire peut aller au contentieux.
- Lancer en administrateur / root pour obtenir la corrélation système.
- Vérifier dans le rapport la section Intégrité des journaux avant d'interpréter l'absence d'une trace.
- Utiliser
--tz localpour un rapport lisible, et noter le fuseau retenu dans la fiche d'affaire. - Activer
--collect-rawpour conserver les sources avec le rapport. - Diffuser uniquement des rapports produits avec
--redact. - Archiver le dossier de sortie complet, avec
SHA256SUMS.txtetmanifest.json.