Mach utiliza **tareas** como la **unidad más pequeña** para compartir recursos, y cada tarea puede contener **múltiples hilos**. Estas **tareas y hilos se asignan 1:1 a procesos y hilos POSIX**.
La comunicación entre tareas se realiza a través de la Comunicación entre Procesos de Mach (IPC), utilizando canales de comunicación unidireccionales. **Los mensajes se transfieren entre puertos**, que actúan como **colas de mensajes** gestionadas por el kernel.
Los derechos de puerto, que definen las operaciones que una tarea puede realizar, son clave para esta comunicación. Los posibles **derechos de puerto** son:
* **Derecho de recepción**, que permite recibir mensajes enviados al puerto. Los puertos de Mach son colas MPSC (múltiples productores, un solo consumidor), lo que significa que solo puede haber **un derecho de recepción para cada puerto** en todo el sistema (a diferencia de las tuberías, donde varios procesos pueden tener descriptores de archivo para el extremo de lectura de una tubería).
* Una **tarea con el derecho de recepción** puede recibir mensajes y **crear derechos de envío**, lo que le permite enviar mensajes. Originalmente, solo la **propia tarea tiene el derecho de recepción sobre su puerto**.
* **Derecho de conjunto de puertos**, que denota un _conjunto de puertos_ en lugar de un solo puerto. Desencolar un mensaje de un conjunto de puertos desencola un mensaje de uno de los puertos que contiene. Los conjuntos de puertos se pueden usar para escuchar varios puertos simultáneamente, como `select`/`poll`/`epoll`/`kqueue` en Unix.
* **Nombre muerto**, que no es un derecho de puerto real, sino simplemente un marcador de posición. Cuando se destruye un puerto, todos los derechos de puerto existentes para el puerto se convierten en nombres muertos.
**Las tareas pueden transferir derechos de ENVÍO a otros**, lo que les permite enviar mensajes de vuelta. **Los derechos de ENVÍO también se pueden clonar, por lo que una tarea puede duplicar y dar el derecho a una tercera tarea**. Esto, combinado con un proceso intermedio conocido como el **servidor de arranque**, permite una comunicación efectiva entre tareas.
Como se menciona, para establecer el canal de comunicación, está involucrado el **servidor de arranque** (**launchd** en mac).
1. La tarea **A** inicia un **nuevo puerto**, obteniendo un **derecho de RECEPCIÓN** en el proceso.
2. La tarea **A**, siendo la titular del derecho de RECEPCIÓN, **genera un derecho de ENVÍO para el puerto**.
3. La tarea **A** establece una **conexión** con el **servidor de arranque**, proporcionando el **nombre del servicio del puerto** y el **derecho de ENVÍO** a través de un procedimiento conocido como registro de arranque.
4. La tarea **B** interactúa con el **servidor de arranque** para ejecutar una **búsqueda de arranque para el nombre del servicio**. Si tiene éxito, el **servidor duplica el derecho de ENVÍO** recibido de la tarea A y **lo transmite a la tarea B**.
5. Al adquirir un derecho de ENVÍO, la tarea **B** es capaz de **formular** un **mensaje** y enviarlo **a la tarea A**.
El servidor de arranque **no puede autenticar** el nombre del servicio reclamado por una tarea. Esto significa que una **tarea** podría potencialmente **suplantar cualquier tarea del sistema**, como **falsamente reclamar un nombre de servicio de autorización** y luego aprobar cada solicitud.
Luego, Apple almacena los **nombres de los servicios proporcionados por el sistema** en archivos de configuración seguros, ubicados en directorios protegidos por SIP: `/System/Library/LaunchDaemons` y `/System/Library/LaunchAgents`. Junto a cada nombre de servicio, también se almacena el **binario asociado**. El servidor de arranque creará y mantendrá un **derecho de RECEPCIÓN para cada uno de estos nombres de servicio**.
Para estos servicios predefinidos, el **proceso de búsqueda difiere ligeramente**. Cuando se busca un nombre de servicio, launchd inicia el servicio dinámicamente. El nuevo flujo de trabajo es el siguiente:
* La tarea **A** (el servicio) realiza un **registro de arranque**. Aquí, el servidor de arranque crea un derecho de ENVÍO, lo retiene y **transfiere el derecho de RECEPCIÓN a la tarea A**.
* launchd duplica el **derecho de ENVÍO y lo envía a la tarea B**.
Sin embargo, este proceso solo se aplica a las tareas predefinidas del sistema. Las tareas que no son del sistema aún operan como se describe originalmente, lo que podría permitir la suplantación.
Observe cómo el **emisor****asigna** un puerto, crea un **derecho de envío** para el nombre `org.darlinghq.example` y lo envía al **servidor de arranque** mientras que el emisor solicitó el **derecho de envío** de ese nombre y lo usó para **enviar un mensaje**.
{% tabs %}
{% tab title="receiver.c" %}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
* **Puerto de host**: si un proceso tiene el privilegio **Enviar** sobre este puerto, puede obtener **información** sobre el **sistema** (por ejemplo, `host_processor_info`).
* **Puerto de host privado**: un proceso con el derecho de **Enviar** sobre este puerto puede realizar acciones **privilegiadas** como cargar una extensión del kernel. El **proceso necesita ser root** para obtener este permiso.
* Además, para llamar a la API **`kext_request`** es necesario tener la autorización **`com.apple.private.kext`**, que solo se otorga a binarios de Apple.
* **Puerto de nombre de tarea**: una versión no privilegiada del _puerto de tarea_. Hace referencia a la tarea, pero no permite controlarla. Lo único que parece estar disponible a través de él es `task_info()`.
* **Puerto de tarea** (también conocido como puerto del kernel)**:** con el permiso de Enviar sobre este puerto, es posible controlar la tarea (leer/escribir memoria, crear hilos...).
* Llame a `mach_task_self()` para **obtener el nombre** de este puerto para la tarea del llamador. Este puerto solo se **hereda** a través de **`exec()`**; una nueva tarea creada con `fork()` obtiene un nuevo puerto de tarea (como caso especial, una tarea también obtiene un nuevo puerto de tarea después de `exec()`ing un binario suid). La única forma de generar una tarea y obtener su puerto es realizar la ["danza de intercambio de puertos"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) mientras se realiza un `fork()`.
* Estas son las restricciones para acceder al puerto (de `macos_task_policy` del binario `AppleMobileFileIntegrity`):
* Si la aplicación tiene la autorización **`com.apple.security.get-task-allow`**, los procesos del **mismo usuario pueden acceder al puerto de tarea** (comúnmente agregado por Xcode para depurar). El proceso de **notarización** no lo permitirá en las versiones de producción.
* Las aplicaciones con la autorización **`com.apple.system-task-ports`** pueden obtener el **puerto de tarea para cualquier** proceso, excepto el kernel. En versiones anteriores se llamaba **`task_for_pid-allow`**. Esto solo se otorga a las aplicaciones de Apple.
Los entitlements son una forma de especificar los permisos que una aplicación necesita para realizar ciertas acciones en el sistema. Estos permisos pueden incluir acceso a ciertos recursos del sistema, como la cámara o el micrófono, o la capacidad de realizar ciertas operaciones de red. Los entitlements se especifican en un archivo llamado `entitlements.plist`, que se incluye en el paquete de la aplicación.
Cuando una aplicación se ejecuta, el sistema operativo verifica los entitlements de la aplicación para asegurarse de que tiene los permisos necesarios para realizar las acciones que está intentando realizar. Si la aplicación no tiene los entitlements necesarios, el sistema operativo puede denegar la acción o mostrar una alerta al usuario pidiendo permiso.
Los entitlements también se utilizan para limitar los privilegios de una aplicación. Por ejemplo, una aplicación puede tener un entitlement que le permite acceder a la cámara, pero no a la ubicación del usuario. Esto significa que la aplicación puede tomar fotos, pero no puede acceder a la información de ubicación del usuario.
En general, es importante revisar cuidadosamente los entitlements de una aplicación antes de instalarla o ejecutarla, para asegurarse de que no está solicitando permisos innecesarios o excesivos.
En macOS, los **hilos** pueden ser manipulados a través de **Mach** o utilizando la **API posix `pthread`**. El hilo que generamos en la inyección anterior fue generado utilizando la API Mach, por lo que **no es compatible con posix**.
Fue posible **inyectar un shellcode simple** para ejecutar un comando porque no necesitaba trabajar con APIs compatibles con posix, solo con Mach. **Inyecciones más complejas** necesitarían que el **hilo** también sea **compatible con posix**.
Por lo tanto, para **mejorar el shellcode**, debería llamar a **`pthread_create_from_mach_thread`**, lo que creará un pthread válido. Luego, este nuevo pthread podría **llamar a dlopen** para **cargar nuestra dylib** desde el sistema.
XPC, que significa Comunicación entre Procesos de XNU (el kernel utilizado por macOS), es un marco para la **comunicación entre procesos** en macOS e iOS. XPC proporciona un mecanismo para realizar **llamadas de método seguras y asíncronas entre diferentes procesos** en el sistema. Es parte del paradigma de seguridad de Apple, lo que permite la **creación de aplicaciones separadas por privilegios** donde cada **componente** se ejecuta con **solo los permisos que necesita** para hacer su trabajo, limitando así el daño potencial de un proceso comprometido.
XPC utiliza una forma de Comunicación entre Procesos (IPC), que es un conjunto de métodos para que los diferentes programas que se ejecutan en el mismo sistema envíen datos de ida y vuelta.
1.**Seguridad**: Al separar el trabajo en diferentes procesos, cada proceso solo puede recibir los permisos que necesita. Esto significa que incluso si un proceso está comprometido, tiene una capacidad limitada para hacer daño.
2.**Estabilidad**: XPC ayuda a aislar los fallos en el componente donde ocurren. Si un proceso falla, se puede reiniciar sin afectar al resto del sistema.
3.**Rendimiento**: XPC permite una fácil concurrencia, ya que se pueden ejecutar diferentes tareas simultáneamente en diferentes procesos.
El único **inconveniente** es que **separar una aplicación en varios procesos** para que se comuniquen a través de XPC es **menos eficiente**. Pero en los sistemas actuales esto casi no se nota y los beneficios son mucho mejores.
Un ejemplo se puede ver en QuickTime Player, donde un componente que utiliza XPC es responsable de la decodificación de video. El componente está diseñado específicamente para realizar tareas computacionales, por lo que, en caso de una violación, no proporcionaría ningún beneficio útil al atacante, como acceso a archivos o a la red.
### Servicios XPC específicos de la aplicación
Los componentes XPC de una aplicación están **dentro de la aplicación en sí**. Por ejemplo, en Safari se pueden encontrar en **`/Applications/Safari.app/Contents/XPCServices`**. Tienen la extensión **`.xpc`** (como **`com.apple.Safari.SandboxBroker.xpc`**) y también son **paquetes** con el binario principal dentro de él: `/Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/MacOS/com.apple.Safari.SandboxBroker`
Como puede estar pensando, un **componente XPC tendrá diferentes permisos y privilegios** que los otros componentes XPC o el binario principal de la aplicación. EXCEPTO si un servicio XPC está configurado con [**JoinExistingSession**](https://developer.apple.com/documentation/bundleresources/information\_property\_list/xpcservice/joinexistingsession) establecido en "True" en su archivo **Info.plist**. En este caso, el servicio XPC se ejecutará en la misma sesión de seguridad que la aplicación que lo llamó.
Los servicios XPC se **inician** por **launchd** cuando sea necesario y se **apagan** una vez que todas las tareas están **completas** para liberar los recursos del sistema. **Los componentes XPC específicos de la aplicación solo pueden ser utilizados por la aplicación**, lo que reduce el riesgo asociado con posibles vulnerabilidades.
Los **servicios XPC de todo el sistema** son accesibles para todos los usuarios. Estos servicios, ya sean de tipo launchd o Mach, deben estar **definidos en archivos plist** ubicados en directorios especificados como **`/System/Library/LaunchDaemons`**, **`/Library/LaunchDaemons`**, **`/System/Library/LaunchAgents`** o **`/Library/LaunchAgents`**.
Los que están en **`LaunchDameons`** son ejecutados por root. Por lo tanto, si un proceso no privilegiado puede comunicarse con uno de ellos, podría ser capaz de escalar privilegios.
Las aplicaciones pueden **suscribirse** a diferentes **mensajes de eventos**, lo que les permite ser **iniciadas a pedido** cuando ocurren dichos eventos. La **configuración** de estos servicios se realiza en archivos **plist de launchd**, ubicados en los **mismos directorios que los anteriores** y que contienen una clave adicional de **`LaunchEvent`**.
### Verificación del proceso de conexión XPC
Cuando un proceso intenta llamar a un método a través de una conexión XPC, el **servicio XPC debe verificar si ese proceso tiene permitido conectarse**. Aquí se presentan las formas comunes de verificar eso y las trampas comunes:
Apple también permite que las aplicaciones **configuren algunos derechos y cómo obtenerlos** para que, si el proceso que llama los tiene, se le permita **llamar a un método** del servicio XPC:
El archivo `xyz.hacktricks.service.plist` es un archivo de propiedad de Launchd que se utiliza para iniciar un servicio en macOS. Este archivo se encuentra en la ruta `/Library/LaunchDaemons/` y se ejecuta como root.
Para aprovechar este archivo, un atacante puede modificarlo para ejecutar su propio código malicioso en el sistema. Esto se puede hacer agregando un nuevo diccionario de clave-valor en el archivo plist que especifica el comando a ejecutar y los argumentos necesarios.
Una vez que se ha modificado el archivo plist, el atacante puede cargar el servicio utilizando el comando `launchctl load /Library/LaunchDaemons/xyz.hacktricks.service.plist`. Esto iniciará el servicio malicioso y permitirá al atacante ejecutar comandos con privilegios de root en el sistema.
Para evitar este tipo de ataque, se recomienda asegurarse de que los archivos plist de Launchd solo sean modificados por usuarios autorizados y de confianza. Además, se debe monitorear regularmente los archivos plist para detectar cualquier modificación no autorizada.
El servidor XPC es responsable de crear y configurar la conexión XPC. En este ejemplo, el servidor XPC se encarga de crear una conexión XPC y configurar el objeto de conexión para que pueda recibir mensajes del cliente XPC.
El servidor XPC crea una conexión XPC utilizando `xpc_connection_create_mach_service()`. Este método crea una conexión XPC y la registra como un servicio Mach. El segundo parámetro es el nombre del servicio. En este ejemplo, el nombre del servicio es "com.example.ocxpc". El tercer parámetro indica que la conexión XPC se está creando como un oyente de servicio Mach.
El servidor XPC también establece un controlador de eventos utilizando `xpc_connection_set_event_handler()`. Este método se llama cada vez que se recibe un evento en la conexión XPC. El controlador de eventos llama al método `handleMessage:` para procesar el mensaje.
El método `handleMessage:` comprueba si el mensaje es un diccionario XPC y si contiene una clave "request". Si el mensaje cumple estos requisitos, el método comprueba el valor de la clave "request". Si el valor es "hello", el método crea una respuesta con la clave "response" y el valor "world". Si el valor no es "hello", el método crea una respuesta con la clave "response" y el valor "unknown request". La respuesta se envía utilizando `xpc_connection_send_message()`.
El servidor XPC se ejecuta en un bucle de eventos utilizando `[[NSRunLoop currentRunLoop] run]`. Esto asegura que el servidor XPC siga ejecutándose y procesando mensajes hasta que se detenga explícitamente.
Inter-Process Communication (IPC) is a mechanism that allows processes to communicate with each other and share data. macOS provides several IPC mechanisms, including:
Mach ports are a low-level IPC mechanism used by macOS. They are used to send messages between processes and to create inter-process communication channels. Mach ports are used by many macOS system services, including launchd, the WindowServer, and the kernel.
Mach ports are identified by a port name, which is a 32-bit integer. Ports can be created, destroyed, and passed between processes. When a process creates a port, it can specify whether the port is a send right, a receive right, or both. A send right allows a process to send messages to the port, while a receive right allows a process to receive messages from the port.
Mach ports are a powerful IPC mechanism, but they are also complex and difficult to use correctly. Improper use of Mach ports can lead to security vulnerabilities, including privilege escalation and denial-of-service attacks.
Unix domain sockets are a type of IPC mechanism used by macOS and other Unix-based operating systems. They provide a mechanism for processes to communicate with each other over the local network. Unix domain sockets are similar to TCP/IP sockets, but they are implemented entirely within the operating system kernel.
Unix domain sockets are identified by a socket file, which is a special type of file that is used to represent the socket. When a process creates a socket, it can specify whether the socket is a stream socket or a datagram socket. Stream sockets provide a reliable, connection-oriented communication channel, while datagram sockets provide an unreliable, connectionless communication channel.
Unix domain sockets are a simpler and more lightweight IPC mechanism than Mach ports, but they are also less powerful. They are typically used for communication between processes running on the same system.
Distributed Objects is an IPC mechanism provided by macOS that allows objects to be passed between processes. It is based on the Objective-C language and provides a high-level, object-oriented interface to IPC.
Distributed Objects allows objects to be passed between processes using a proxy mechanism. When a process wants to use an object in another process, it creates a proxy object that represents the remote object. The proxy object can be used to call methods on the remote object, and the results are returned to the calling process.
Distributed Objects is a powerful IPC mechanism, but it is also complex and difficult to use correctly. Improper use of Distributed Objects can lead to security vulnerabilities, including privilege escalation and denial-of-service attacks.
XPC is a modern IPC mechanism provided by macOS. It is designed to be more secure and easier to use than Mach ports and Distributed Objects. XPC provides a high-level, object-oriented interface to IPC.
XPC is based on a client-server model. A process that wants to provide a service creates an XPC service, which is a special type of process that runs in the background and provides the service. A process that wants to use the service creates an XPC connection to the service and uses it to communicate with the service.
XPC provides a number of features, including:
* Automatic serialization and deserialization of objects
* Automatic memory management of objects
* Support for remote method invocation
* Support for distributed notifications
* Support for sandboxing and code signing
XPC is a powerful and easy-to-use IPC mechanism that is designed to be more secure than Mach ports and Distributed Objects. It is the recommended IPC mechanism for modern macOS applications.
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) **grupo de Discord** o al [**grupo de telegram**](https://t.me/peass) o **sígueme en****Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).