.LastGKReject: rechazos de Gatekeeper como evidencia
Qué registra .LastGKReject cuando Gatekeeper bloquea un elemento, dónde está, cómo recopilarlo y cómo vincular el rechazo con una descarga.
TL;DR. Cuando Gatekeeper se niega a ejecutar un elemento, syspolicyd escribe una pequeña lista de propiedades llamada .LastGKReject. Contiene un marcador (bookmark) al elemento rechazado, del que se pueden leer la ruta de destino y el volumen, un TimeStamp y un número XProtectMalwareType. Solo se conserva el último rechazo y el archivo puede no existir, pero cuando está presente convierte una descarga en cuarentena en un intento de ejecución concreto, fechado y bloqueado por macOS.
Qué comprueba Gatekeeper
Gatekeeper está implementado por el daemon syspolicyd. En la primera ejecución de código en cuarentena comprueba la firma del código, si está firmado con un Developer ID, si está notarizado, y ejecuta XProtect. El vínculo con el resto de esta serie es el atributo de cuarentena: las comprobaciones dependen del valor com.apple.quarantine que la app de descarga o la Utilidad de Archivo dejó en el archivo. La guía de flags explica ese valor en detalle.
Dos resultados dejan rastro. Si el usuario aprueba un elemento, el atributo recibe el flag de aprobación del usuario 0x0040, de modo que un valor como 0083 pasa a 00c3. Desde macOS 15 ya no existe el antiguo atajo de Control-clic y las excepciones se gestionan en Ajustes del Sistema. Si Gatekeeper rechaza el elemento, syspolicyd registra el fallo en .LastGKReject.
Qué es .LastGKReject
.LastGKReject es una lista de propiedades, XML o binaria, que syspolicyd escribe cuando Gatekeeper rechaza un elemento. En el código abierto Security de Apple, quien la escribe es PolicyEngine::recordFailure. Dos propiedades definen cómo leerla:
- Solo se conserva el último rechazo. Cada rechazo nuevo sustituye al registro anterior.
- Puede no existir. Un Mac en el que Gatekeeper nunca rechazó nada, o en el que se borró el archivo, simplemente no lo tiene.
El archivo también puede existir y estar vacío. En un sistema macOS 26.6 examinado en vivo, /private/var/db/.LastGKReject no existía, mientras que /private/var/db/SystemPolicyConfiguration/.LastGKReject existía como una lista de propiedades XML de 181 bytes, legible por todos, con un diccionario vacío. Quarantine Parser indica ese caso como «ningún rechazo registrado». Es una observación en un único sistema, no una regla documentada.
Dónde está
Las fuentes de Apple indican dos ubicaciones; compruebe ambas:
| Fuente | Ruta |
|---|---|
| Fuentes antiguas de Apple | /var/db/.LastGKReject (= /private/var/db/.LastGKReject) |
| Fuentes actuales de Apple | /var/db/SystemPolicyConfiguration/.LastGKReject |
Ambas están en directorios del sistema, así que leerlas requiere root.
Las claves
El plugin QUARANTINE de mac_apt lee tres claves, y Quarantine Parser lee la misma información:
- BookmarkData: un marcador al elemento rechazado. Un marcador es una referencia de archivo serializada, no una simple cadena con la ruta; la herramienta extrae de él la ruta de destino y el volumen.
- TimeStamp: cuándo se registró el rechazo.
- XProtectMalwareType: un número. mac_apt atribuye esta correspondencia a Patrick Wardle: 2 app/programa sin firmar, 3 bundle modificado, 5 app firmada, 7 app modificada. Es una correspondencia reportada, no documentada por Apple.
Lea XProtectMalwareType como una categoría de rechazo, no como el nombre de una familia de malware. Un valor 2 indica que el elemento rechazado se reportó como no firmado; no dice qué hace el código.
Cómo recopilarlo
En un Mac encendido, desde un Terminal con acceso total al disco, este comando de la guía de recopilación copia el archivo que exista de los dos:
for f in /private/var/db/.LastGKReject /private/var/db/SystemPolicyConfiguration/.LastGKReject; do
[ -f "$f" ] && sudo cp -p "$f" ~/qcase/"$(basename "$(dirname "$f")")_LastGKReject"
done
Las copias llevan el nombre de su directorio padre (db_LastGKReject o SystemPolicyConfiguration_LastGKReject), así que se sabe de qué ubicación procede cada una. Ejecútelo después de crear ~/qcase y copiar la base de datos de cuarentena, como se muestra en la comparativa de herramientas de recopilación. Calcule los hashes de las copias antes de analizarlas.
Sobre una imagen montada, mac_apt analiza tanto la base de datos de cuarentena como .LastGKReject:
python mac_apt.py -o out MOUNTED /Volumes/evidence QUARANTINE
En Quarantine Parser, arrastre el archivo copiado solo, o junto con la base de datos y un listado de xattr. La herramienta acepta listas de propiedades XML y binarias, muestra la hora, la ruta de destino, el volumen y XProtectMalwareType, y genera un hallazgo de rechazo de Gatekeeper. El análisis se hace en su navegador; no se sube nada.
Vincular el rechazo con la descarga
Por sí solo, .LastGKReject indica que algo se rechazó. Su valor aparece al unirlo con la descarga que lo trajo. Para una imagen de disco, la cadena típica tiene tres eslabones.
- El evento de cuarentena. En QuarantineEventsV2 se encuentra la descarga de la imagen de disco: agente, URL y hora. La guía de la base de datos describe las columnas.
- El volumen montado. Montar una imagen de disco en cuarentena pone su contenido en cuarentena, y por eso la app que contiene pasó por Gatekeeper. La ruta rechazada está bajo
/Volumes/<nombre>/, y el volumen leído del marcador lo nombra. - La app rechazada. El
TimeStampdebería caer poco después de la descarga, y el nombre de la app debería encajar con la imagen.
En la muestra sintética del sitio, la cadena queda así:
2026-09-14 10:26:30 UTC QuarantineEventsV2 Safari https://transfer.example/d/Qm7/sync-agent.dmg
2026-09-14 10:27:05 UTC .LastGKReject /Volumes/Sync Agent/SyncAgent.app XProtectMalwareType 2
Treinta y cinco segundos separan la descarga del rechazo, el nombre del volumen coincide con la imagen y el tipo reportado es «app/programa sin firmar». Ninguna de las claves citadas es el UUID de cuarentena, así que este vínculo se basa en el nombre y la hora, no en un identificador compartido. Indíquelo en su informe. El caso práctico paso a paso sigue la misma muestra de principio a fin.
Si el elemento rechazado sigue en el disco, lea también su valor com.apple.quarantine. Un flag 00c3 o 00c1 significa que se aprobó después. Una ruta bajo /private/var/folders/.../AppTranslocation/ en otras evidencias significa que una app en cuarentena se ejecutó desde un montaje aleatorio de solo lectura; consulte App Translocation.
Límites
- Un solo registro. Cualquier rechazo posterior, incluso inofensivo, sobrescribe el que le interesa. Recopile pronto.
- Sin registro no significa sin incidentes. El archivo puede no haberse escrito nunca o haberse borrado.
- Etiquetas no documentadas. La correspondencia de
XProtectMalwareTypeprocede de investigación de terceros. - Un rechazo no es el final de la historia. El usuario pudo aprobar el elemento en Ajustes del Sistema, o el atributo de cuarentena pudo eliminarse con
xattr -d com.apple.quarantine, tras lo cual Gatekeeper no tiene nada que evaluar. Busque el flag 0x0040 y archivos que conservan un WhereFroms pero perdieron el atributo de cuarentena, como se explica en kMDItemWhereFroms frente a la cuarentena. - El marcador apunta a donde estaba el elemento. El volumen de una imagen de disco desaparece al desmontarla; la ruta puede dejar de resolverse.
- Sin URL de origen. El registro no dice de dónde vino el elemento. Para eso están la base de datos y el atributo de cuarentena.
Dónde más buscar
- Registros unificados.
syspolicydrealiza la evaluación, así que sus entradas de registro en torno alTimeStampson la siguiente fuente natural. Pueden mostrar evaluaciones y rechazos que.LastGKReject, que solo guarda el último, ya no conserva. - ExecPolicy. En macOS recientes, los archivos pueden llevar un atributo
com.apple.provenancede 11 bytes, una clave opaca hacia la tablaprovenance_trackingde ExecPolicy. Quarantine Parser no decodifica ninguno de los dos; trátelos como pistas para otras herramientas. - Datos de cuarentena. La fila del evento de la imagen, el atributo en la imagen y en cualquier copia de la app, y los registros recuperados del espacio libre si se borró una fila.
Para un resumen de estos artefactos en una sola página, consulte la ficha de Gatekeeper y XProtect de nuestro sitio hermano.
Preguntas frecuentes
¿.LastGKReject enumera todos los elementos bloqueados por Gatekeeper?
No. Solo guarda el rechazo más reciente, así que un rechazo posterior lo sustituye. También puede no existir, y su ausencia no demuestra nada sobre lo que se bloqueó o no.
¿Dónde se guarda .LastGKReject?
Las fuentes antiguas de Apple usan /var/db/.LastGKReject (el mismo archivo que /private/var/db/.LastGKReject); las fuentes actuales de Apple usan /var/db/SystemPolicyConfiguration/.LastGKReject. Compruebe ambas ubicaciones y copie el archivo con privilegios de root.
¿Qué significa XProtectMalwareType?
Es un número guardado en el registro. mac_apt, que atribuye la correspondencia a Patrick Wardle, indica 2 para una app o programa sin firmar, 3 para un bundle modificado, 5 para una app firmada y 7 para una app modificada. Apple no documenta estos valores, así que trate la etiqueta como un indicio, no como un veredicto.