macOS Launch/Environment Constraints & Trust Cache
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Las restricciones de lanzamiento en macOS se introdujeron para mejorar la seguridad al regular cómo, quién y desde dónde se puede iniciar un proceso. Iniciadas en macOS Ventura, proporcionan un marco que categoriza cada binario del sistema en distintas categorías de restricción, que se definen dentro de la caché de confianza, una lista que contiene binarios del sistema y sus respectivos hashes. Estas restricciones se extienden a cada binario ejecutable dentro del sistema, implicando un conjunto de reglas que delinean los requisitos para lanzar un binario particular. Las reglas abarcan restricciones propias que un binario debe satisfacer, restricciones parentales que deben ser cumplidas por su proceso padre, y restricciones responsables que deben ser respetadas por otras entidades relevantes.
El mecanismo se extiende a aplicaciones de terceros a través de Restricciones de Entorno, comenzando desde macOS Sonoma, permitiendo a los desarrolladores proteger sus aplicaciones especificando un conjunto de claves y valores para las restricciones de entorno.
Definís restricciones de entorno de lanzamiento y de biblioteca en diccionarios de restricciones que guardás en archivos de lista de propiedades de launchd
, o en archivos de lista de propiedades separados que usás en la firma de código.
Hay 4 tipos de restricciones:
Restricciones Propias: Restricciones aplicadas al binario en ejecución.
Proceso Padre: Restricciones aplicadas al padre del proceso (por ejemplo, launchd
ejecutando un servicio XPC).
Restricciones Responsables: Restricciones aplicadas al proceso que llama al servicio en una comunicación XPC.
Restricciones de carga de biblioteca: Usá restricciones de carga de biblioteca para describir selectivamente el código que puede ser cargado.
Así que cuando un proceso intenta lanzar otro proceso — llamando a execve(_:_:_:)
o posix_spawn(_:_:_:_:_:_:)
— el sistema operativo verifica que el archivo ejecutable satisface su propia restricción propia. También verifica que el ejecutable del proceso padre satisface la restricción de padre del ejecutable, y que el ejecutable del proceso responsable satisface la restricción del proceso responsable del ejecutable. Si alguna de estas restricciones de lanzamiento no se satisface, el sistema operativo no ejecuta el programa.
Si al cargar una biblioteca, alguna parte de la restricción de biblioteca no es verdadera, tu proceso no carga la biblioteca.
Un LC está compuesto por hechos y operaciones lógicas (y, o...) que combinan hechos.
Los hechos que un LC puede usar están documentados. Por ejemplo:
is-init-proc: Un valor booleano que indica si el ejecutable debe ser el proceso de inicialización del sistema operativo (launchd
).
is-sip-protected: Un valor booleano que indica si el ejecutable debe ser un archivo protegido por la Protección de Integridad del Sistema (SIP).
on-authorized-authapfs-volume:
Un valor booleano que indica si el sistema operativo cargó el ejecutable desde un volumen APFS autorizado y autenticado.
on-authorized-authapfs-volume
: Un valor booleano que indica si el sistema operativo cargó el ejecutable desde un volumen APFS autorizado y autenticado.
Volumen de Cryptexes
on-system-volume:
Un valor booleano que indica si el sistema operativo cargó el ejecutable desde el volumen del sistema actualmente iniciado.
Dentro de /System...
...
Cuando un binario de Apple es firmado, se asigna a una categoría de LC dentro de la caché de confianza.
Las categorías de LC de iOS 16 fueron invertidas y documentadas aquí.
Las categorías de LC actuales (macOS 14 - Sonoma) han sido invertidas y sus descripciones se pueden encontrar aquí.
Por ejemplo, la Categoría 1 es:
(on-authorized-authapfs-volume || on-system-volume)
: Debe estar en el volumen del sistema o Cryptexes.
launch-type == 1
: Debe ser un servicio del sistema (plist en LaunchDaemons).
validation-category == 1
: Un ejecutable del sistema operativo.
is-init-proc
: Launchd
Tienes más información sobre esto aquí, pero básicamente, están definidos en AMFI (AppleMobileFileIntegrity), así que necesitas descargar el Kernel Development Kit para obtener el KEXT. Los símbolos que comienzan con kConstraintCategory
son los interesantes. Al extraerlos obtendrás un flujo codificado DER (ASN.1) que necesitarás decodificar con ASN.1 Decoder o la biblioteca python-asn1 y su script dump.py
, andrivet/python-asn1 que te dará una cadena más comprensible.
Estas son las Launch Constraints configuradas en aplicaciones de terceros. El desarrollador puede seleccionar los hechos y operandos lógicos a utilizar en su aplicación para restringir el acceso a sí mismo.
Es posible enumerar las Environment Constraints de una aplicación con:
En macOS hay algunos cachés de confianza:
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
/System/Library/Security/OSLaunchPolicyData
Y en iOS parece que está en /usr/standalone/firmware/FUD/StaticTrustCache.img4
.
En macOS que se ejecuta en dispositivos Apple Silicon, si un binario firmado por Apple no está en el caché de confianza, AMFI se negará a cargarlo.
Los archivos de caché de confianza anteriores están en formato IMG4 y IM4P, siendo IM4P la sección de carga útil de un formato IMG4.
Puedes usar pyimg4 para extraer la carga útil de las bases de datos:
(Otra opción podría ser usar la herramienta img4tool, que funcionará incluso en M1 aunque la versión sea antigua y para x86_64 si la instalas en las ubicaciones adecuadas).
Ahora puedes usar la herramienta trustcache para obtener la información en un formato legible:
El caché de confianza sigue la siguiente estructura, así que la categoría LC es la 4ª columna
Then, you could use a script such as this one to extract data.
From that data you can check the Apps with a launch constraints value of 0
, which are the ones that aren't constrained (check here for what each value is).
Las restricciones de lanzamiento habrían mitigado varios ataques antiguos al asegurar que el proceso no se ejecute en condiciones inesperadas: Por ejemplo, desde ubicaciones inesperadas o siendo invocado por un proceso padre inesperado (si solo launchd debería estar lanzándolo).
Además, las restricciones de lanzamiento también mitigan ataques de degradación.
Sin embargo, no mitigan abusos comunes de XPC, inyecciones de código de Electron o inyecciones de dylib sin validación de biblioteca (a menos que se conozcan los IDs de equipo que pueden cargar bibliotecas).
En la versión Sonoma, un punto notable es la configuración de responsabilidad del servicio daemon XPC. El servicio XPC es responsable de sí mismo, a diferencia del cliente que se conecta que es responsable. Esto está documentado en el informe de retroalimentación FB13206884. Esta configuración puede parecer defectuosa, ya que permite ciertas interacciones con el servicio XPC:
Lanzamiento del Servicio XPC: Si se asume que es un error, esta configuración no permite iniciar el servicio XPC a través del código del atacante.
Conexión a un Servicio Activo: Si el servicio XPC ya está en funcionamiento (posiblemente activado por su aplicación original), no hay barreras para conectarse a él.
Si bien implementar restricciones en el servicio XPC podría ser beneficioso al reducir la ventana para ataques potenciales, no aborda la preocupación principal. Asegurar la seguridad del servicio XPC requiere fundamentalmente validar efectivamente al cliente que se conecta. Este sigue siendo el único método para fortalecer la seguridad del servicio. También vale la pena señalar que la configuración de responsabilidad mencionada está actualmente operativa, lo que podría no alinearse con el diseño previsto.
Incluso si se requiere que la aplicación sea abierta por LaunchService (en las restricciones de los padres). Esto se puede lograr utilizando open
(que puede establecer variables de entorno) o utilizando la API de Launch Services (donde se pueden indicar variables de entorno).
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)