<summary><strong>Aprende hacking en AWS de cero a héroe con</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
Mach utiliza **tareas** como la **unidad más pequeña** para compartir recursos, y cada tarea puede contener **múltiples hilos**. Estas **tareas e hilos se mapean 1:1 a procesos y hilos POSIX**.
La comunicación entre tareas se realiza a través de la Comunicación Inter-Procesos (IPC) de Mach, utilizando canales de comunicación unidireccionales. **Los mensajes se transfieren entre puertos**, que actúan como **colas de mensajes** gestionadas por el kernel.
Cada proceso tiene una **tabla IPC**, donde es posible encontrar los **puertos mach del proceso**. El nombre de un puerto mach es en realidad un número (un puntero al objeto del kernel).
Un proceso también puede enviar un nombre de puerto con algunos derechos **a una tarea diferente** y el kernel hará que esta entrada aparezca en la **tabla IPC de la otra tarea**.
* **Derecho de recepción**, que permite recibir mensajes enviados al puerto. Los puertos Mach son colas MPSC (multiple-producer, single-consumer), lo que significa que solo puede haber **un derecho de recepción para cada puerto** en todo el sistema (a diferencia de los pipes, donde varios procesos pueden tener descriptores de archivo para el extremo de lectura de un pipe).
* Una **tarea con el derecho de Recepción** puede recibir mensajes y **crear derechos de Envío**, permitiéndole enviar mensajes. Originalmente solo la **tarea propia tiene derecho de Recepción sobre su puerto**.
* **Derecho de envío**, que permite enviar mensajes al puerto.
* El derecho de Envío puede ser **clonado** para que una tarea que posea un derecho de Envío pueda clonar el derecho y **otorgárselo a una tercera tarea**.
* **Derecho de envío único**, que permite enviar un mensaje al puerto y luego desaparece.
* **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, muy parecido a `select`/`poll`/`epoll`/`kqueue` en Unix.
* **Nombre muerto**, que no es un derecho de puerto real, sino simplemente un marcador de posición. Cuando un puerto se destruye, todos los derechos de puerto existentes al puerto se convierten en nombres muertos.
**Las tareas pueden transferir derechos de ENVÍO a otras**, permitiéndoles 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 intermediario conocido como el **servidor de arranque**, permite una comunicación efectiva entre tareas.
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 realizar 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**.
6. Para una comunicación bidireccional, usualmente la tarea **B** genera un nuevo puerto con un derecho de **RECEPCIÓN** y un derecho de **ENVÍO**, y da el derecho de **ENVÍO a la Tarea A** para que pueda enviar mensajes a la TAREA B (comunicación bidireccional).
El servidor de arranque **no puede autenticar** el nombre del servicio reclamado por una tarea. Esto significa que una **tarea** podría potencialmente **suplantar a cualquier tarea del sistema**, como falsamente **reclamar un nombre de servicio de autorización** y luego aprobar cada solicitud.
Entonces, 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 **B** inicia una búsqueda de arranque **para un nombre de servicio**.
* **launchd** verifica si la tarea está en ejecución y si no lo está, **la inicia**.
* La tarea **A** (el servicio) realiza un **chequeo 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**.
* La tarea **B** genera un nuevo puerto con un derecho de **RECEPCIÓN** y un derecho de **ENVÍO**, y da el derecho de **ENVÍO a la Tarea A** (el svc) para que pueda enviar mensajes a la TAREA B (comunicación bidireccional).
Sin embargo, este proceso solo se aplica a tareas del sistema predefinidas. Las tareas que no son del sistema aún operan como se describió originalmente, lo que podría permitir potencialmente la suplantación.
Los mensajes Mach se envían o reciben utilizando la **función `mach_msg`** (que es esencialmente una syscall). Al enviar, el primer argumento para esta llamada debe ser el **mensaje**, que debe comenzar con un **`mach_msg_header_t`** seguido del payload real:
El proceso que puede **recibir** mensajes en un puerto mach se dice que posee el _**derecho de recepción**_, mientras que los **emisores** tienen un _**derecho de envío**_ o un _**derecho de envío único**_. Como su nombre indica, el envío único solo se puede utilizar para enviar un único mensaje y luego se invalida.
Para lograr una **comunicación bidireccional** fácil, un proceso puede especificar un **puerto mach** en el **encabezado del mensaje mach** llamado el _puerto de respuesta_ (**`msgh_local_port`**) donde el **receptor** del mensaje puede **enviar una respuesta** a este mensaje. Los bitflags en **`msgh_bits`** se pueden utilizar para **indicar** que se debe derivar y transferir un **derecho de envío único** para este puerto (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
Nota que este tipo de comunicación bidireccional se utiliza en mensajes XPC que esperan una respuesta (`xpc_connection_send_message_with_reply` y `xpc_connection_send_message_with_reply_sync`). Pero **generalmente se crean puertos diferentes** como se explicó anteriormente para crear la comunicación bidireccional.
Nota que **los mensajes mach se envían a través de un **_**puerto mach**_, que es un canal de comunicación de **un solo receptor**, **múltiples emisores** integrado en el kernel mach. **Múltiples procesos** pueden **enviar mensajes** a un puerto mach, pero en cualquier momento solo **un solo proceso puede leer** de él.
Puedes instalar esta herramienta en iOS descargándola desde [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
Observa 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 utilizó para **enviar un mensaje**.
* **Puerto del host**: Si un proceso tiene privilegio de **Enviar** sobre este puerto, puede obtener **información** sobre el **sistema** (por ejemplo, `host_processor_info`).
* **Puerto priv del host**: Un proceso con derecho de **Enviar** sobre este puerto puede realizar **acciones privilegiadas** como cargar una extensión del kernel. El **proceso debe ser root** para obtener este permiso.
* Además, para llamar a la API **`kext_request`** se necesitan otros derechos **`com.apple.private.kext*`** que solo se otorgan 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 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 que llama. 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()` en un binario suid). La única forma de generar una tarea y obtener su puerto es realizar el ["baile de intercambio de puertos"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) mientras se hace un `fork()`.
* Estas son las restricciones para acceder al puerto (de `macos_task_policy` del binario `AppleMobileFileIntegrity`):
* Si la aplicación tiene el derecho **`com.apple.security.get-task-allow`** procesos del **mismo usuario pueden acceder al puerto de tarea** (comúnmente agregado por Xcode para depuración). El proceso de **notarización** no lo permitirá en lanzamientos de producción.
* Las aplicaciones con el derecho **`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 concede a aplicaciones de Apple.
* **Root puede acceder a puertos de tarea** de aplicaciones **no** compiladas con un **runtime endurecido** (y no de Apple).
En macOS los **hilos** pueden ser manipulados a través de **Mach** o usando la **API `pthread` de posix**. El hilo que generamos en la inyección anterior, fue creado usando la API de Mach, por lo que **no cumple 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** requerirían que el **hilo** también fuera **compatible con posix**.
Por lo tanto, para **mejorar el hilo** debería llamar a **`pthread_create_from_mach_thread`**, lo cual **creará un pthread válido**. Luego, este nuevo pthread podría **llamar a dlopen** para **cargar una dylib** del sistema, así que en lugar de escribir nuevo shellcode para realizar diferentes acciones es posible cargar bibliotecas personalizadas.
XPC, que significa XNU (el kernel utilizado por macOS) Comunicación entre Procesos, es un marco para **comunicación entre procesos** en macOS e iOS. XPC proporciona un mecanismo para realizar **llamadas a métodos seguras y asíncronas entre diferentes procesos** en el sistema. Es parte del paradigma de seguridad de Apple, permitiendo la **creación de aplicaciones con separación de privilegios** donde cada **componente** se ejecuta con **solo los permisos que necesita** para realizar su trabajo, limitando así el daño potencial de un proceso comprometido.
MIG fue creado para **simplificar el proceso de creación de código IPC de Mach**. Básicamente **genera el código necesario** para que el servidor y el cliente se comuniquen con una definición dada. Aunque el código generado no sea estético, un desarrollador solo necesitará importarlo y su código será mucho más simple que antes.
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de Telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) en github.