Evasión de Gatekeeper: Acceso inicial en entornos corporativos macOS
Introducción
En un ejercicio reciente de Red Team, surgió la necesidad de encontrar un mecanismo para la entrega y ejecución de un payload en el contexto de una campaña de spear phishing. Normalmente, nuestros ejercicios suelen desarrollarse en entornos Windows, para los que existen multitud de TTP ampliamente documentadas.
Sin embargo, en este caso nos encontramos principalmente con sistemas macOS y con un alto nivel de madurez en cuestiones de protección y concienciación frente a campañas de ingeniería social. A esto hay que sumar que la información pública sobre TTPs de acceso inicial en macOS es menos común y que muchas de las técnicas más populares, a priori, no parecían viables para este escenario. Por todo ello, fue necesario combinar TTPs ya empleadas internamente con otras procedentes de contextos distintos, adaptándolas a nuestras necesidades.
A diferencia de Windows, macOS presenta controles de seguridad como Gatekeeper, XProtect, System Integrity Protection (SIP) y Transparency, Consent, and Control (TCC). Estos controles reducen significativamente la efectividad de TTPs utilizadas habitualmente en campañas de phishing.
En este post describimos la estrategia que finalmente nos permitió alcanzar el objetivo del ejercicio.
Evasión de Gatekeeper
Una estrategia sólida para un escenario de ingeniería social tiene que cumplir los siguientes requisitos: un método eficaz de entrega de payloads y un pretexto creíble que permitan la ejecución bajo el radar de la solución EDR y de los controles de macOS.
De los controles nativos listados en la introducción, Gatekeeper es el primero al que debe enfrentarse una cadena de acceso inicial, por lo que encontrar una vía de evasión se convirtió en nuestro primer objetivo.
De forma resumida, Gatekeeper tiene como objetivo principal asegurar que solo se ejecute software de confianza en el sistema, verificando que las aplicaciones descargadas o procedentes de orígenes externos estén firmadas con un ID de desarrollador válido reconocido por Apple y, en muchos casos, que hayan pasado por el proceso de notarización (un análisis automatizado de Apple en busca de código malicioso).
En general, evadir Gatekeeper requiere una de las siguientes circunstancias (o una combinación):
- Una vulnerabilidad en el propio control de seguridad.
- Software o flujos de trabajo que no aplican o propagan el atributo
com.apple.quarantinecorrectamente (o están diseñados para no aplicarlo). - Abuso de certificados válidos para la firma de aplicaciones.
- Tácticas de ingeniería social para convencer al usuario de que realice una serie de pasos con el objetivo de ejecutar un payload al mismo tiempo que se evade o elimina la protección.
En este contexto, se comienza por una primitiva conocida: el montaje de unidades de red de forma remota para proporcionar acceso a un payload fuera del sistema de archivos local. De las categorías listadas arriba, este vector podría combinar un flujo de trabajo en el que el atributo com.apple.quarantine no se propaga con interacción del usuario.
Para ello, se prueban diferentes métodos de conexión, incluyendo manejadores de URL para ficheros .inetloc y el comando nativo open para montar una unidad remota a través de diferentes protocolos como WebDAV, FTP, AFP o SMB.
Al utilizar estos métodos, observamos cómo el atributo de cuarentena se aplicaba de forma correcta a los ficheros remotos. Como consecuencia, Gatekeeper aplicaba sus controles, impidiendo la ejecución de binarios o aplicaciones desconocidas:

Sin embargo, nos dimos cuenta de que existe una excepción: si la unidad remota se monta a través de la opción Connect to Server, disponible en el menú superior de Finder (Cmd + K), utilizando SMB no se aplica la cuarentena a los ficheros remotos:

A pesar de que esta acción requiere interacción del usuario, se nos ocurrieron varios escenarios en los que un usuario podría ser engañado para abrir una unidad remota a través de este sistema.
Posteriormente, descubrimos que este comportamiento ya había sido descrito anteriormente por Karol Mazurek, quien publicó un artículo en el que expone esta técnica utilizando el protocolo WebDAV. En cualquier caso, creemos que es algo poco conocido y que puede ser aprovechado de forma efectiva como mostramos a continuación.
Diseño del payload
Después de encontrar una forma de ejecutar un payload sin restricciones de Gatekeeper, el siguiente problema fue determinar qué ejecutar. En este punto, nuestro foco pasó de evadir los mecanismos de seguridad nativos de macOS a evadir las capacidades de detección del EDR.
De todas las opciones disponibles, los application bundles ofrecen la mayor flexibilidad y facilidad desde el punto de vista del usuario: se ejecutan con doble clic y es posible manipular el nombre y el icono para hacerlos pasar por otros tipos de documentos.
La estructura típica de un application bundle es la siguiente:
Payload.app/
Contents/
Info.plist
MacOS/
Executable
Resources/
Frameworks/
Plugins/
_CodeSignature/
A modo de resumen, el fichero Info.plist contiene una referencia a un ejecutable almacenado en el directorio Contents/MacOS. Este ejecutable puede ser un binario compilado o un script.
Afortunadamente, se tenía acceso a un entorno de pruebas con el mismo EDR de nuestro objetivo, lo que facilitó encontrar una vía para ejecutar nuestro agente sin ser detectado.
Algunas de las cosas que dieron buen resultado durante este proceso fueron las siguientes:
En primer lugar, utilizamos un script como punto de entrada para el application bundle, pero en lugar de Bash, usamos Perl (actualmente disponible en entornos macOS) lo cual nos permitió evitar una detección que alertaba del uso de scripts en Bash.
#!/usr/bin/perl use strict; use warnings; use File::Path qw(make_path); use File::Basename; use File::Copy; use POSIX qw(setsid); use Archive::Zip; ...
Posteriormente, seguimos una estrategia de “Bring-Your-Own-Interpreter” (BYOI) para ejecutar nuestro agente. Para ello, se incluyó un archivo ZIP con una instalación de Python dentro del application bundle, el cual es descomprimido por el script en Perl en el directorio ~/Library/Application Support/. La idea era aprovechar un binario firmado utilizado habitualmente en entornos macOS para ocultar la ejecución de nuestro agente.
Finalmente, en lugar de ejecutar directamente el implante, el application bundle se encarga de desplegar un LaunchAgent. Esto tiene dos aspectos positivos:
- Sirve como mecanismo de persistencia, ya que permite asegurar que el implante será ejecutado automáticamente cuando el usuario inicie sesión, desacoplando su ejecución de la del application bundle.
- Permite realizar la configuración de diferentes variables de entorno necesarias para que nuestra instalación de Python desplegada funcione correctamente.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.sometool.support.update</string>
<key>ProgramArguments</key>
<array>
<string>/Users/<username>/Library/Application Support/com.sometool.support/sometool-python3</string>
<string>/Users/<username>/Library/Application Support/com.sometool.support/.resources/files/sometool-update.py</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>DYLD_FALLBACK_FRAMEWORK_PATH</key>
<string>/Users/<username>/Library/Application Support/com.sometool.support/.resources/files/Frameworks/</string>
<key>DYLD_FALLBACK_LIBRARY_PATH</key>
<string>/Users/<username>/Library/Application Support/com.sometool.support/.resources/files/Frameworks/lib</string>
<key>PATH</key>
<string>/Users/<username>/Library/Application Support/com.sometool.support/.resources/files/Frameworks/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
...
</dict>
</plist>
Estrategia de entrega
En este punto valoramos diferentes estrategias para convencer a los usuarios objetivo de montar nuestra unidad de red remota a través de Finder. Finalmente, nos decantamos por un escenario en el que pudimos reutilizar varias TTPs relacionadas con el abuso del procesamiento de invitaciones a reuniones en Gmail (puedes leer más acerca de estas técnicas en Abusing automatic calendar processing for initial access and lateral movement).
Utilizando algunas de las técnicas descritas en el post, creamos una reunión con un aspecto legítimo utilizando un pretexto que justificaba la presencia de una persona externa, es decir, un miembro de nuestro equipo. Uno de nuestros operadores se encargó de compartir una presentación en la que se explicaba a los usuarios objetivo que, para completar un proceso determinado (como podría ser una formación externa, una demo de un proveedor o algo similar) tenían que realizar una serie de pasos entre los que se incluyeron los necesarios para montar la unidad remota y ejecutar el application bundle:

Esta estrategia tuvo éxito por múltiples razones. La presencia de una persona externa, con una apariencia y un comportamiento que generaban confianza, creó la presión social suficiente para que los asistentes quisieran colaborar y seguir las instrucciones. El uso de una presentación con aspecto profesional también aportó legitimidad a la reunión, y la inclusión de los pasos maliciosos pasó desapercibida al estar integrada en un flujo que, en conjunto, no levantaba sospechas.
Conclusiones
La principal conclusión a la que llegamos a raíz de esta experiencia es que incluso en entornos con una postura de seguridad madura, es posible obtener buenos resultados encadenando ideas simples.
Durante el ejercicio, reportamos el comportamiento de la característica “Connect to Server” a Apple, que nos indicó que es una característica que funciona así por diseño. Independientemente de si estamos de acuerdo o no, creemos que este post demuestra que es posible abusar de esta característica incluso en entornos protegidos por un EDR. Confiar en las protecciones por defecto no es suficiente, lo que ilustra, una vez más, la necesidad de contar con capacidades avanzadas para la detección proactiva basada en reglas y monitorización.