Aller au contenu

ExécutionPersistance

TCC.db : autorisations de confidentialité sous macOS

Les bases TCC de macOS indiquent quelles apps ont obtenu ou non l'accès à la caméra, au micro, à l'écran, au disque et à l'automatisation, et quand.

Emplacement
/Library/Application Support/com.apple.TCC/TCC.db
Prouve
Quels programmes ont demandé ou obtenu des autorisations de confidentialité sensibles, par qui, et quand la décision a changé pour la dernière fois
Horodatages
Secondes d'époque Unix (UTC) dans last_modified
Accès
Accès complet au disque pour la lecture ; base système également protégée par SIP
Rétention
Jusqu'à la modification de la ligne, sa réinitialisation (tccutil) ou la suppression de l'application
Collecte
Aftermath, mac_apt, UAC, Velociraptor

Ce que c'est

Transparency, Consent and Control (TCC) est le framework macOS qui contrôle l'accès aux ressources sensibles pour la vie privée : caméra, microphone, capture d'écran, surveillance des saisies, API d'accessibilité, dossiers utilisateur protégés, accès complet au disque et automatisation par Apple Events. Le démon tccd prend les décisions et les stocke dans des bases SQLite nommées TCC.db, une pour le système et une par utilisateur.

Chaque ligne est une décision permanente pour un client (bundle ID ou chemin) et un service. La base est un registre d'autorisations, pas un journal d'utilisation : elle indique ce qu'un programme avait le droit de faire, pas chaque fois qu'il l'a fait.

Où il se trouve

PortéeCheminNotes de versionProtection
Système/Library/Application Support/com.apple.TCC/TCC.dbSchéma access modifié dans 11 Big Sur et 14 SonomaSIP + TCC, accès complet au disque requis pour la lecture
Par utilisateur~/Library/Application Support/com.apple.TCC/TCC.dbMême schéma que la base systèmeTCC, accès complet au disque requis pour la lecture
Autorisations MDM/Library/Application Support/com.apple.TCC/MDMOverrides.plistMac gérésRépertoire protégé par SIP
Dates de rappel d'enregistrement d'écran~/Library/Group Containers/group.com.apple.replayd/ScreenCaptureApprovals.plist15 Sequoia et ultérieurProtégé par TCC

Collectez les fichiers compagnons WAL et SHM (TCC.db-wal, TCC.db-shm) avec chaque base. Chaque compte sous /Users possède sa propre copie utilisateur.

Ce qu'il prouve

  • Qu'une application ou un binaire donné détient, ou s'est vu refuser, l'accès complet au disque, l'accessibilité, l'enregistrement d'écran, la surveillance des saisies, la caméra ou le microphone.
  • Qu'un client identifié par chemin (client_type = 1), comme un binaire non signé ou un interpréteur de scripts, a obtenu une capacité, ce qui est inhabituel pour un logiciel légitime.
  • Qu'une autorisation d'automatisation permet à une application d'envoyer des Apple Events à une autre (cible dans indirect_object_identifier).
  • Que la décision émane de l'utilisateur, du système ou d'une politique MDM (auth_reason, à recouper avec MDMOverrides.plist).
  • L'heure approximative du dernier changement d'une décision (last_modified).

Elle ne prouve pas que l'autorisation a réellement été utilisée, à quelle fréquence, ni ce qui a été capturé. Une ligne absente ne prouve pas qu'une autorisation n'a jamais été accordée : tccutil reset supprime des lignes.

Champs clés

Table access (Big Sur et ultérieur) :

ColonneSignification
serviceIdentifiant de service, par exemple kTCCServiceSystemPolicyAllFiles (accès complet au disque), kTCCServiceAccessibility, kTCCServiceScreenCapture, kTCCServiceListenEvent, kTCCServiceAppleEvents
clientBundle ID ou chemin absolu du programme demandeur
client_type0 bundle ID, 1 chemin absolu
auth_value0 refusé, 1 inconnu, 2 autorisé, 3 limité
auth_reasonDocumenté par la communauté : 1 erreur, 2 consentement de l'utilisateur, 3 défini par l'utilisateur, 4 défini par le système, 5 politique de service, 6 politique MDM, 7 politique de remplacement, 8 chaîne d'usage manquante, 9 délai d'invite dépassé, 10 preflight inconnu, 11 entitlement, 12 politique par type d'application
auth_versionVersion du format de l'enregistrement
csreqBlob d'exigence de signature de code identifiant le client
policy_idLien vers une politique MDM, le cas échéant
indirect_object_identifier_type, indirect_object_identifier, indirect_object_code_identityCible de l'autorisation (automatisation)
flagsDrapeaux supplémentaires
last_modifiedDernière modification de la ligne
pid, pid_version, boot_uuid, last_remindedAjoutés dans macOS 14 Sonoma

Sous Mojave et Catalina, la table utilisait allowed et prompt_count au lieu de auth_value et auth_reason. Lancez toujours .schema access en premier.

Horodatages

last_modified est en secondes d'époque Unix, UTC, contrairement à la plupart des bases Apple qui utilisent le temps absolu Mac. Il reflète la dernière écriture de la ligne (invite validée, interrupteur basculé, politique appliquée), pas la première autorisation.

SELECT service, client, auth_value, auth_reason,
       datetime(last_modified, 'unixepoch') AS last_modified_utc
FROM access ORDER BY last_modified DESC;

last_reminded (Sonoma et ultérieur) est lui aussi en secondes Unix ; sa valeur par défaut dans le schéma est strftime('%s','now'). Les dates de naissance et de modification de TCC.db dans le système de fichiers (APFS, précision à la nanoseconde) indiquent seulement quand la base a changé, pas quelle ligne.

Rétention

Les lignes persistent jusqu'à ce que la décision soit modifiée, que le client soit réinitialisé avec tccutil reset <service> [bundle-id], que l'utilisateur réinitialise les autorisations dans les Réglages Système ou que la base soit reconstruite. Il n'y a pas de vieillissement automatique. Des lignes supprimées peuvent survivre un temps dans le fichier WAL ou les pages libres, et des copies plus anciennes peuvent exister dans des snapshots APFS locaux ou des sauvegardes Time Machine.

Collecte

Sur un système live, le processus de collecte (Terminal, l'agent ou le binaire de l'outil) doit disposer de l'accès complet au disque, sinon la copie échoue silencieusement ou revient vide.

# Live, with FDA granted to Terminal
sudo ditto "/Library/Application Support/com.apple.TCC" ./case/tcc_system
for u in /Users/*; do
  [ -d "$u/Library/Application Support/com.apple.TCC" ] && \
  sudo ditto "$u/Library/Application Support/com.apple.TCC" "./case/tcc_$(basename "$u")"
done
  • Aftermath copie les TCC.db système et utilisateur ainsi que MDMOverrides.plist (à exécuter en root avec l'accès complet au disque), mais pas TCC.db-wal : les modifications encore dans le WAL, et les anciennes versions de lignes qu'il contient, sont perdues.
  • UAC collecte la TCC.db système et celles des utilisateurs (files/system/tcc.yaml), mais pas TCC.db-wal ni TCC.db-shm, avec la même perte. Copiez vous-même les fichiers compagnons, comme dans les commandes ci-dessus.
  • Velociraptor MacOS.System.TCC lit directement les deux bases.
  • Analyse à froid : montez le volume Data en lecture seule ; TCC et SIP ne restreignent pas la lecture depuis une machine d'analyse.

Analyse

  • sqlite3 sur une copie, avec les requêtes ci-dessus.
  • Plugin TCC de mac_apt : python mac_apt.py -o out E01 mac.E01 TCC.
  • Plugin SQLite macostcc de Plaso : log2timeline.py --parsers 'sqlite/macostcc' --storage-file tcc.plaso ./case.
  • Artefact Velociraptor MacOS.System.TCC pour la chasse à l'échelle d'un parc.

Revue des autorisations à risque :

SELECT service, client, client_type, auth_value, auth_reason,
       datetime(last_modified,'unixepoch') AS changed_utc
FROM access
WHERE auth_value = 2
  AND (service IN ('kTCCServiceSystemPolicyAllFiles','kTCCServiceAccessibility',
                   'kTCCServiceScreenCapture','kTCCServiceListenEvent',
                   'kTCCServicePostEvent')
       OR client_type = 1);

TCC Parser décode dans le navigateur les TCC.db système et utilisateur avec leur -wal (y compris les anciennes versions de lignes extraites du WAL), MDMOverrides.plist et les blobs csreq, et signale les autorisations à risque ; rien n'est envoyé.

Conseils d'investigation

  • Les autorisations accordées à des interpréteurs ou terminaux (/bin/bash, /usr/bin/osascript, com.apple.Terminal) couvrent tout ce qui est lancé à travers eux. Poursuivez vers l'historique du shell et les tâches launchd.
  • Une ligne refusée (auth_value = 0) reste la preuve d'une demande, souvent la première tentative visible d'un logiciel malveillant.
  • auth_reason = 6 renvoie au MDM. Confirmez avec MDMOverrides.plist et sudo profiles show -type configuration ; un profil illégitime est en soi une découverte.
  • Les décisions de tccd sont journalisées sous le sous-système com.apple.TCC dans les Unified Logs : c'est là que se trouvent les preuves demande par demande.
  • Sous Sequoia, des dates très lointaines dans ScreenCaptureApprovals.plist indiquent que quelqu'un a supprimé le rappel périodique d'enregistrement d'écran.
  • Endpoint Security expose les modifications TCC aux outils EDR à partir de macOS 15.4 (ES_EVENT_TYPE_NOTIFY_TCC_MODIFY) ; cherchez dans la télémétrie EDR des changements que la base ne montre plus.
  • Comparez csreq avec la signature du binaire sur disque : une ligne par bundle ID s'applique à tout code qui satisfait l'exigence enregistrée.
  • Consultez le guide d'analyse forensique de la base TCC pour les listes de services et les modèles de requêtes.

Voir aussi