TCC.db: permisos de privacidad concedidos en macOS
Las bases TCC de macOS registran qué apps obtuvieron o no acceso a cámara, micrófono, pantalla, disco y automatización, y cuándo cambió por última vez.
- Ubicación
- /Library/Application Support/com.apple.TCC/TCC.db
- Prueba
- Qué programas solicitaron u obtuvieron permisos de privacidad sensibles, quién los concedió y cuándo cambió la decisión por última vez
- Marcas de tiempo
- Segundos de época Unix (UTC) en last_modified
- Acceso
- Full Disk Access para leer; la base de datos del sistema está además protegida por SIP
- Retención
- Hasta que la fila se modifica, se restablece (tccutil) o se elimina la app
- Adquisición
- Aftermath, mac_apt, UAC, Velociraptor
Herramientas
Comparar todas las herramientas- TCC ParserNavegador
- mac_aptCLI · código abierto
- PlasoCLI · código abierto
- VelociraptorPlataforma · código abierto
- sqlite3CLI · incluido en macOS
Qué es
Transparency, Consent and Control (TCC) es el framework de macOS que controla el acceso a recursos sensibles para la privacidad: cámara, micrófono, captura de pantalla, monitorización de entrada, APIs de accesibilidad, carpetas de usuario protegidas, Full Disk Access y automatización mediante Apple Events. El daemon tccd toma las decisiones y las guarda en bases de datos SQLite llamadas TCC.db, una para el sistema y otra por usuario.
Cada fila es una decisión vigente para un cliente (bundle ID o ruta) y un servicio. La base de datos es un registro de permisos, no un log de uso: indica qué se permitió hacer a un programa, no cada vez que lo hizo.
Dónde se encuentra
| Ámbito | Ruta | Notas de versión | Protección |
|---|---|---|---|
| Sistema | /Library/Application Support/com.apple.TCC/TCC.db | El esquema de access cambió en 11 Big Sur y 14 Sonoma | SIP + TCC, requiere Full Disk Access para leer |
| Por usuario | ~/Library/Application Support/com.apple.TCC/TCC.db | Mismo esquema que la del sistema | TCC, requiere Full Disk Access para leer |
| Concesiones MDM | /Library/Application Support/com.apple.TCC/MDMOverrides.plist | Macs gestionados | Directorio protegido por SIP |
| Fechas de recordatorio de grabación de pantalla | ~/Library/Group Containers/group.com.apple.replayd/ScreenCaptureApprovals.plist | 15 Sequoia+ | Protegido por TCC |
Recopila los archivos WAL y SHM asociados (TCC.db-wal, TCC.db-shm) con cada base de datos. Cada cuenta de /Users tiene su propia copia por usuario.
Qué prueba
- Que una app o un binario tiene, o se le denegó, Full Disk Access, Accesibilidad, Grabación de pantalla, Monitorización de entrada, cámara o micrófono.
- Que un cliente basado en ruta (
client_type = 1), como un binario sin firmar o un intérprete de scripts, obtuvo una capacidad, algo poco habitual en software legítimo. - Que una concesión de Automatización permite a una app enviar Apple Events a otra (destino en
indirect_object_identifier). - Que la decisión vino del usuario, del sistema o de una política MDM (
auth_reason, contrastado conMDMOverrides.plist). - La hora aproximada del último cambio de una decisión (
last_modified).
No prueba que el permiso se usara realmente, con qué frecuencia ni qué se capturó. La ausencia de una fila no prueba que el permiso nunca se concediera: tccutil reset borra filas.
Campos clave
Tabla access (Big Sur y posteriores):
| Columna | Significado |
|---|---|
service | Identificador del servicio, p. ej. kTCCServiceSystemPolicyAllFiles (Full Disk Access), kTCCServiceAccessibility, kTCCServiceScreenCapture, kTCCServiceListenEvent, kTCCServiceAppleEvents |
client | Bundle ID o ruta absoluta del programa solicitante |
client_type | 0 bundle ID, 1 ruta absoluta |
auth_value | 0 denegado, 1 desconocido, 2 permitido, 3 limitado |
auth_reason | Documentado por la comunidad: 1 error, 2 consentimiento del usuario, 3 fijado por el usuario, 4 fijado por el sistema, 5 política del servicio, 6 política MDM, 7 política de anulación, 8 falta la cadena de uso, 9 tiempo de espera de la solicitud agotado, 10 preflight desconocido, 11 con entitlement, 12 política por tipo de app |
auth_version | Versión del formato del registro |
csreq | Blob de requisito de firma de código que identifica al cliente |
policy_id | Enlace a una política MDM, si existe |
indirect_object_identifier_type, indirect_object_identifier, indirect_object_code_identity | Destino de la concesión (Automatización) |
flags | Flags adicionales |
last_modified | Último cambio de la fila |
pid, pid_version, boot_uuid, last_reminded | Añadidos en macOS 14 Sonoma |
En Mojave y Catalina la tabla usaba allowed y prompt_count en lugar de auth_value y auth_reason. Ejecuta siempre .schema access primero.
Marcas de tiempo
last_modified está en segundos de época Unix, UTC, a diferencia de la mayoría de las bases de datos de Apple, que usan Mac absolute time. Refleja la última escritura en esa fila (solicitud respondida, interruptor cambiado, política aplicada), no la primera concesión.
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 y posteriores) también está en segundos Unix; su valor por defecto en el esquema es strftime('%s','now'). Las horas de creación y modificación de TCC.db en el sistema de archivos (APFS, precisión de nanosegundos) solo indican cuándo cambió la base de datos, no qué fila.
Retención
Las filas persisten hasta que la decisión cambia, el cliente se restablece con tccutil reset <service> [bundle-id], el usuario restablece los permisos en Ajustes del Sistema o la base de datos se reconstruye. No hay caducidad automática. Las filas borradas pueden sobrevivir un tiempo en el archivo WAL o en páginas libres, y pueden existir copias más antiguas en snapshots locales de APFS o en copias de Time Machine.
Adquisición
En un sistema en vivo, el proceso de adquisición (Terminal, el agente o el binario de la herramienta) debe tener Full Disk Access; de lo contrario, la copia falla sin avisar o sale vacía.
# 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 copia las
TCC.dbdel sistema y de cada usuario yMDMOverrides.plist(ejecútalo como root con FDA), pero noTCC.db-wal: los cambios que siguen en el WAL, y las versiones anteriores de filas que contiene, se pierden. - UAC recopila tanto la
TCC.dbdel sistema como las de cada usuario (files/system/tcc.yaml), pero noTCC.db-walniTCC.db-shm, con la misma pérdida. Copia tú mismo los archivos asociados, como en los comandos anteriores. - Velociraptor
MacOS.System.TCClee ambas bases de datos directamente. - Análisis en frío: monta el volumen Data en solo lectura; TCC y SIP no restringen la lectura desde un equipo de análisis.
Análisis
- sqlite3 sobre una copia, con las consultas anteriores.
- Plugin
TCCde mac_apt:python mac_apt.py -o out E01 mac.E01 TCC. - Plugin SQLite
macostccde Plaso:log2timeline.py --parsers 'sqlite/macostcc' --storage-file tcc.plaso ./case. - Artefacto
MacOS.System.TCCde Velociraptor para búsquedas a escala de flota.
Revisión de alto riesgo:
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 decodifica en el navegador las TCC.db del sistema y de usuario con su -wal (incluidas versiones anteriores de filas recuperadas del WAL), MDMOverrides.plist y los blobs csreq, y señala los permisos de riesgo; no se sube nada.
Consejos para la investigación
- Las concesiones a intérpretes o terminales (
/bin/bash,/usr/bin/osascript,com.apple.Terminal) cubren todo lo que se lanza a través de ellos. Continúa por el historial de shell y los trabajos de launchd. - Una fila denegada (
auth_value = 0) sigue siendo prueba de una solicitud, a menudo el primer intento visible de un malware. auth_reason = 6apunta a MDM. Confírmalo conMDMOverrides.plistysudo profiles show -type configuration; un perfil ilegítimo es un hallazgo en sí mismo.- Las decisiones de
tccdse registran en el subsistemacom.apple.TCCde los unified logs, que es donde está la evidencia de cada solicitud. - En Sequoia, fechas muy lejanas en el futuro dentro de
ScreenCaptureApprovals.plistindican que alguien suprimió el recordatorio periódico de Grabación de pantalla. - Endpoint Security expone los cambios de TCC a las herramientas EDR desde macOS 15.4 (
ES_EVENT_TYPE_NOTIFY_TCC_MODIFY); revisa la telemetría de tu EDR en busca de cambios que la base de datos ya no muestra. - Compara
csreqcon la firma del binario en disco: una fila por bundle ID se aplica a cualquier código que cumpla el requisito almacenado. - Consulta la guía forense de la base de datos TCC para listas de servicios y patrones de consulta.