Aprenda e pratique Hacking AWS:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Aprenda e pratique Hacking GCP: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-nos no****Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
Mach usa **tarefas** como a **menor unidade** para compartilhar recursos, e cada tarefa pode conter **múltiplas threads**. Essas **tarefas e threads são mapeadas 1:1 para processos e threads POSIX**.
A comunicação entre tarefas ocorre via Comunicação Inter-Processo Mach (IPC), utilizando canais de comunicação unidirecionais. **Mensagens são transferidas entre portas**, que atuam como **filas de mensagens** gerenciadas pelo kernel.
Cada processo tem uma **tabela IPC**, onde é possível encontrar as **portas mach do processo**. O nome de uma porta mach é, na verdade, um número (um ponteiro para o objeto do kernel).
Um processo também pode enviar um nome de porta com alguns direitos **para uma tarefa diferente** e o kernel fará com que essa entrada na **tabela IPC da outra tarefa** apareça.
### Direitos de Porta
Os direitos de porta, que definem quais operações uma tarefa pode realizar, são fundamentais para essa comunicação. Os possíveis **direitos de porta** são ([definições daqui](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
* **Direito de Receber**, que permite receber mensagens enviadas para a porta. As portas Mach são filas MPSC (múltiplos produtores, um único consumidor), o que significa que pode haver apenas **um direito de receber para cada porta** em todo o sistema (diferente de pipes, onde múltiplos processos podem manter descritores de arquivo para a extremidade de leitura de um pipe).
* Uma **tarefa com o Direito de Receber** pode receber mensagens e **criar Direitos de Envio**, permitindo que ela envie mensagens. Originalmente, apenas a **própria tarefa tem o Direito de Receber sobre sua porta**.
* Se o proprietário do Direito de Receber **morrer** ou matá-lo, o **direito de envio se torna inútil (nome morto).**
* **Direito de Enviar**, que permite enviar mensagens para a porta.
* O Direito de Enviar pode ser **clonado**, então uma tarefa que possui um Direito de Enviar pode clonar o direito e **concedê-lo a uma terceira tarefa**.
* Note que **direitos de porta** também podem ser **passados** através de mensagens Mac.
* **Direito de Enviar uma vez**, que permite enviar uma mensagem para a porta e depois desaparece.
* Este direito **não pode** ser **clonado**, mas pode ser **movido**.
* **Direito de Conjunto de Portas**, que denota um _conjunto de portas_ em vez de uma única porta. Desenfileirar uma mensagem de um conjunto de portas desenfileira uma mensagem de uma das portas que ele contém. Conjuntos de portas podem ser usados para escutar em várias portas simultaneamente, muito parecido com `select`/`poll`/`epoll`/`kqueue` no Unix.
* **Nome morto**, que não é um direito de porta real, mas apenas um espaço reservado. Quando uma porta é destruída, todos os direitos de porta existentes para a porta se tornam nomes mortos.
**Tarefas podem transferir direitos de ENVIO para outras**, permitindo que elas enviem mensagens de volta. **Direitos de ENVIO também podem ser clonados, então uma tarefa pode duplicar e dar o direito a uma terceira tarefa**. Isso, combinado com um processo intermediário conhecido como o **servidor de inicialização**, permite uma comunicação eficaz entre tarefas.
Portas de arquivo permitem encapsular descritores de arquivo em portas Mac (usando direitos de porta Mach). É possível criar um `fileport` a partir de um FD dado usando `fileport_makeport` e criar um FD a partir de um fileport usando `fileport_makefd`.
Como mencionado anteriormente, é possível enviar direitos usando mensagens Mach, no entanto, você **não pode enviar um direito sem já ter um direito** para enviar uma mensagem Mach. Então, como a primeira comunicação é estabelecida?
Para isso, o **servidor de inicialização** (**launchd** no mac) está envolvido, já que **qualquer um pode obter um direito de ENVIO para o servidor de inicialização**, é possível pedir a ele um direito para enviar uma mensagem para outro processo:
1. A tarefa **A** cria uma **nova porta**, obtendo o **direito de RECEBER** sobre ela.
2. A tarefa **A**, sendo a detentora do direito de RECEBER, **gera um direito de ENVIO para a porta**.
3. A tarefa **A** estabelece uma **conexão** com o **servidor de inicialização**, e **envia a ele o direito de ENVIO** para a porta que gerou no início.
* Lembre-se de que qualquer um pode obter um direito de ENVIO para o servidor de inicialização.
4. A tarefa A envia uma mensagem `bootstrap_register` para o servidor de inicialização para **associar a porta dada a um nome** como `com.apple.taska`
5. A tarefa **B** interage com o **servidor de inicialização** para executar uma **busca de inicialização pelo nome do serviço** (`bootstrap_lookup`). Para que o servidor de inicialização possa responder, a tarefa B enviará a ele um **direito de ENVIO para uma porta que criou anteriormente** dentro da mensagem de busca. Se a busca for bem-sucedida, o **servidor duplica o DIREITO DE ENVIO** recebido da Tarefa A e **transmite para a Tarefa B**.
* Lembre-se de que qualquer um pode obter um direito de ENVIO para o servidor de inicialização.
6. Com esse direito de ENVIO, a **Tarefa B** é capaz de **enviar** uma **mensagem****para a Tarefa A**.
7. Para uma comunicação bidirecional, geralmente a tarefa **B** gera uma nova porta com um **DIREITO DE RECEBER** e um **DIREITO DE ENVIO**, e dá o **DIREITO DE ENVIO para a Tarefa A** para que ela possa enviar mensagens para a TAREFA B (comunicação bidirecional).
O servidor de inicialização **não pode autenticar** o nome do serviço reivindicado por uma tarefa. Isso significa que uma **tarefa** poderia potencialmente **impersonar qualquer tarefa do sistema**, como falsamente **reivindicar um nome de serviço de autorização** e então aprovar cada solicitação.
Então, a Apple armazena os **nomes dos serviços fornecidos pelo sistema** em arquivos de configuração seguros, localizados em diretórios **protegidos pelo SIP**: `/System/Library/LaunchDaemons` e `/System/Library/LaunchAgents`. Juntamente com cada nome de serviço, o **binário associado também é armazenado**. O servidor de inicialização criará e manterá um **DIREITO DE RECEBER para cada um desses nomes de serviço**.
Para esses serviços predefinidos, o **processo de busca difere ligeiramente**. Quando um nome de serviço está sendo buscado, o launchd inicia o serviço dinamicamente. O novo fluxo de trabalho é o seguinte:
* A tarefa **B** inicia uma **busca de inicialização** por um nome de serviço.
* **launchd** verifica se a tarefa está em execução e, se não estiver, **inicia**.
* A tarefa **A** (o serviço) realiza um **check-in de inicialização** (`bootstrap_check_in()`). Aqui, o **servidor de inicialização** cria um direito de ENVIO, retém-o e **transfere o direito de RECEBER para a Tarefa A**.
* O launchd duplica o **DIREITO DE ENVIO e o envia para a Tarefa B**.
* A tarefa **B** gera uma nova porta com um **DIREITO DE RECEBER** e um **DIREITO DE ENVIO**, e dá o **DIREITO DE ENVIO para a Tarefa A** (o svc) para que ela possa enviar mensagens para a TAREFA B (comunicação bidirecional).
No entanto, esse processo se aplica apenas a tarefas do sistema predefinidas. Tarefas não do sistema ainda operam como descrito originalmente, o que poderia potencialmente permitir a impersonação.
A função `mach_msg`, essencialmente uma chamada de sistema, é utilizada para enviar e receber mensagens Mach. A função requer que a mensagem a ser enviada seja o argumento inicial. Esta mensagem deve começar com uma estrutura `mach_msg_header_t`, seguida pelo conteúdo real da mensagem. A estrutura é definida da seguinte forma:
Processos que possuem um _**direito de recebimento**_ podem receber mensagens em uma porta Mach. Por outro lado, os **remetentes** recebem um _**direito de envio**_ ou um _**direito de envio-uma-vez**_. O direito de envio-uma-vez é exclusivamente para enviar uma única mensagem, após a qual se torna inválido.
Os tipos que podem ser especificados no voucher, portas local e remota são (de [**mach/message.h**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html)):
Por exemplo, `MACH_MSG_TYPE_MAKE_SEND_ONCE` pode ser usado para **indicar** que um **direito de envio uma vez** deve ser derivado e transferido para este porto. Também pode ser especificado `MACH_PORT_NULL` para impedir que o destinatário possa responder.
Para alcançar uma fácil **comunicação bidirecional**, um processo pode especificar um **porto mach** no **cabeçalho da mensagem mach** chamado de _porto de resposta_ (**`msgh_local_port`**) onde o **destinatário** da mensagem pode **enviar uma resposta** a esta mensagem.
Observe que esse tipo de comunicação bidirecional é usado em mensagens XPC que esperam uma resposta (`xpc_connection_send_message_with_reply` e `xpc_connection_send_message_with_reply_sync`). Mas **geralmente diferentes portas são criadas** como explicado anteriormente para criar a comunicação bidirecional.
Observe que **as mensagens mach são enviadas através de um `mach port`**, que é um canal de comunicação **de um único receptor**, **múltiplos remetentes** embutido no núcleo mach. **Múltiplos processos** podem **enviar mensagens** para um porto mach, mas em qualquer momento apenas **um único processo pode ler** a partir dele.
As mensagens são então formadas pelo cabeçalho **`mach_msg_header_t`** seguido pelo **corpo** e pelo **trailer** (se houver) e pode conceder permissão para responder a ele. Nesses casos, o núcleo apenas precisa passar a mensagem de uma tarefa para a outra.
Um **trailer** é **informação adicionada à mensagem pelo núcleo** (não pode ser definido pelo usuário) que pode ser solicitado na recepção da mensagem com as flags `MACH_RCV_TRAILER_<trailer_opt>` (há diferentes informações que podem ser solicitadas).
No entanto, existem outras mensagens mais **complexas**, como aquelas que passam direitos de porta adicionais ou compartilham memória, onde o núcleo também precisa enviar esses objetos para o destinatário. Nesses casos, o bit mais significativo do cabeçalho `msgh_bits` é definido.
Os possíveis descritores a serem passados são definidos em [**`mach/message.h`**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html):
O kernel copiará os descritores de uma tarefa para outra, mas primeiro **criando uma cópia na memória do kernel**. Essa técnica, conhecida como "Feng Shui", foi abusada em vários exploits para fazer o **kernel copiar dados em sua memória**, fazendo um processo enviar descritores para si mesmo. Então, o processo pode receber as mensagens (o kernel as liberará).
Também é possível **enviar direitos de porta para um processo vulnerável**, e os direitos de porta simplesmente aparecerão no processo (mesmo que ele não esteja lidando com eles).
Note que as portas estão associadas ao namespace da tarefa, então para criar ou buscar uma porta, o namespace da tarefa também é consultado (mais em `mach/mach_port.h`):
*`mach_port_allocate` também pode criar um **conjunto de portas**: direito de recebimento sobre um grupo de portas. Sempre que uma mensagem é recebida, é indicado de qual porta ela veio.
*`mach_port_allocate_name`: Mudar o nome da porta (por padrão, inteiro de 32 bits)
* **`mach_msg`** | **`mach_msg_overwrite`**: Funções usadas para **enviar e receber mensagens mach**. A versão de sobrescrita permite especificar um buffer diferente para a recepção de mensagens (a outra versão apenas reutilizará).
Como as funções **`mach_msg`** e **`mach_msg_overwrite`** são as usadas para enviar e receber mensagens, definir um ponto de interrupção nelas permitiria inspecionar as mensagens enviadas e recebidas.
frame #9: 0x0000000181a1d5c8 dyld`invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const::$_0::operator()() const + 168
Para obter os argumentos de **`mach_msg`**, verifique os registradores. Estes são os argumentos (de [mach/message.h](https://opensource.apple.com/source/xnu/xnu-7195.81.3/osfmk/mach/message.h.auto.html)):
; 0x00131513 -> mach_msg_bits_t (msgh_bits) = 0x13 (MACH_MSG_TYPE_COPY_SEND) in local | 0x1500 (MACH_MSG_TYPE_MAKE_SEND_ONCE) in remote | 0x130000 (MACH_MSG_TYPE_COPY_SEND) in voucher
O **nome** é o nome padrão dado à porta (verifique como está **aumentando** nos primeiros 3 bytes). O **`ipc-object`** é o **identificador** único **ofuscado** da porta.\
Note também como as portas com apenas o direito de **`send`** estão **identificando o proprietário** dela (nome da porta + pid).\
Além disso, note o uso de **`+`** para indicar **outras tarefas conectadas à mesma porta**.
Também é possível usar [**procesxp**](https://www.newosxbook.com/tools/procexp.html) para ver também os **nomes de serviços registrados** (com SIP desativado devido à necessidade de `com.apple.system-task-port`):
Você pode instalar esta ferramenta no iOS baixando-a de [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
Note como o **remetente****aloca** uma porta, cria um **direito de envio** para o nome `org.darlinghq.example` e o envia para o **servidor de bootstrap**, enquanto o remetente solicitou o **direito de envio** desse nome e o usou para **enviar uma mensagem**.
Existem algumas portas especiais que permitem **realizar certas ações sensíveis ou acessar certos dados sensíveis** caso uma tarefa tenha as permissões **SEND** sobre elas. Isso torna essas portas muito interessantes do ponto de vista de um atacante, não apenas por causa das capacidades, mas porque é possível **compartilhar permissões SEND entre tarefas**.
Os direitos **SEND** podem ser obtidos chamando **`host_get_special_port`** e os direitos **RECEIVE** chamando **`host_set_special_port`**. No entanto, ambas as chamadas requerem a porta **`host_priv`**, que apenas o root pode acessar. Além disso, no passado, o root podia chamar **`host_set_special_port`** e sequestrar arbitrariamente, o que permitia, por exemplo, contornar assinaturas de código ao sequestrar `HOST_KEXTD_PORT` (o SIP agora impede isso).
Essas portas são divididas em 2 grupos: As **primeiras 7 portas são de propriedade do kernel**, sendo a 1 `HOST_PORT`, a 2 `HOST_PRIV_PORT`, a 3 `HOST_IO_MASTER_PORT` e a 7 é `HOST_MAX_SPECIAL_KERNEL_PORT`.\
As que começam **a partir** do número **8** são **de propriedade de daemons do sistema** e podem ser encontradas declaradas em [**`host_special_ports.h`**](https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/mach/host\_special\_ports.h.auto.html).
* **Porta do Host**: Se um processo tiver privilégio **SEND** sobre esta porta, ele pode obter **informações** sobre o **sistema** chamando suas rotinas como:
* **Porta Priv do Host**: Um processo com direito **SEND** sobre esta porta pode realizar **ações privilegiadas** como mostrar dados de inicialização ou tentar carregar uma extensão de kernel. O **processo precisa ser root** para obter essa permissão.
* Além disso, para chamar a API **`kext_request`**, é necessário ter outros direitos **`com.apple.private.kext*`**, que são concedidos apenas a binários da Apple.
* Como o **root** pode acessar essa permissão, ele poderia chamar `host_set_[special/exception]_port[s]` para **sequestrar portas especiais ou de exceção do host**.
É possível **ver todas as portas especiais do host** executando:
Essas são portas reservadas para serviços bem conhecidos. É possível obter/configurá-las chamando `task_[get/set]_special_port`. Elas podem ser encontradas em `task_special_ports.h`:
* **TASK\_KERNEL\_PORT**\[direito de envio da tarefa-própria]: A porta usada para controlar esta tarefa. Usada para enviar mensagens que afetam a tarefa. Esta é a porta retornada por **mach\_task\_self (veja Tarefas de Porta abaixo)**.
* **TASK\_BOOTSTRAP\_PORT**\[direito de envio de bootstrap]: A porta de bootstrap da tarefa. Usada para enviar mensagens solicitando o retorno de outras portas de serviço do sistema.
* **TASK\_HOST\_NAME\_PORT**\[direito de envio do host-próprio]: A porta usada para solicitar informações do host que contém. Esta é a porta retornada por **mach\_host\_self**.
* **TASK\_WIRED\_LEDGER\_PORT**\[direito de envio do livro-razão]: A porta que nomeia a fonte da qual esta tarefa obtém sua memória de kernel fixa.
* **TASK\_PAGED\_LEDGER\_PORT**\[direito de envio do livro-razão]: A porta que nomeia a fonte da qual esta tarefa obtém sua memória gerenciada padrão.
Originalmente, Mach não tinha "processos", tinha "tarefas", que eram consideradas mais como um contêiner de threads. Quando Mach foi fundido com o BSD, **cada tarefa foi correlacionada com um processo BSD**. Portanto, cada processo BSD tem os detalhes que precisa para ser um processo e cada tarefa Mach também tem seu funcionamento interno (exceto pelo pid inexistente 0, que é o `kernel_task`).
*`task_for_pid(target_task_port, pid, &task_port_of_pid)`: Obtém um direito de ENVIO para a porta da tarefa relacionada ao especificado pelo `pid` e o dá à `target_task_port` indicada (que geralmente é a tarefa chamadora que usou `mach_task_self()`, mas pode ser uma porta de ENVIO sobre uma tarefa diferente).
*`pid_for_task(task, &pid)`: Dado um direito de ENVIO a uma tarefa, encontra a qual PID esta tarefa está relacionada.
Para realizar ações dentro da tarefa, a tarefa precisava de um direito de `SEND` para si mesma chamando `mach_task_self()` (que usa o `task_self_trap` (28)). Com essa permissão, uma tarefa pode realizar várias ações, como:
* e mais pode ser encontrado em [**mach/task.h**](https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX11.3.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/mach/task.h)
Além disso, a task\_port também é a **`vm_map`** porta que permite **ler e manipular memória** dentro de uma tarefa com funções como `vm_read()` e `vm_write()`. Isso basicamente significa que uma tarefa com direitos de ENVIO sobre a task\_port de uma tarefa diferente será capaz de **injetar código nessa tarefa**.
Lembre-se de que, como o **kernel também é uma tarefa**, se alguém conseguir obter permissões de **SEND** sobre o **`kernel_task`**, poderá fazer o kernel executar qualquer coisa (jailbreaks).
* Chame `mach_task_self()` para **obter o nome** para esta porta para a tarefa chamadora. Esta porta é apenas **herdada** através de **`exec()`**; uma nova tarefa criada com `fork()` obtém uma nova porta de tarefa (como um caso especial, uma tarefa também obtém uma nova porta de tarefa após `exec()` em um binário suid). A única maneira de gerar uma tarefa e obter sua porta é realizar a ["dança de troca de porta"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) enquanto faz um `fork()`.
* Estas são as restrições para acessar a porta (do `macos_task_policy` do binário `AppleMobileFileIntegrity`):
* Se o aplicativo tiver a **entitlement `com.apple.security.get-task-allow`**, processos do **mesmo usuário podem acessar a porta da tarefa** (comumente adicionada pelo Xcode para depuração). O processo de **notarização** não permitirá isso em lançamentos de produção.
* Aplicativos com a **entitlement `com.apple.system-task-ports`** podem obter a **porta da tarefa para qualquer** processo, exceto o kernel. Em versões mais antigas, era chamada de **`task_for_pid-allow`**. Isso é concedido apenas a aplicativos da Apple.
* **Root pode acessar portas de tarefa** de aplicativos **não** compilados com um runtime **endurecido** (e não da Apple).
**A porta do nome da tarefa:** Uma versão não privilegiada da _porta da tarefa_. Ela referencia a tarefa, mas não permite controlá-la. A única coisa que parece estar disponível através dela é `task_info()`.
As threads também têm portas associadas, que são visíveis a partir da tarefa chamando **`task_threads`** e do processador com `processor_set_threads`. Um direito de ENVIO à porta da thread permite usar a função do subsistema `thread_act`, como:
**Compile** o programa anterior e adicione as **entitlements** para poder injetar código com o mesmo usuário (caso contrário, você precisará usar **sudo**).
No macOS, **threads** podem ser manipuladas via **Mach** ou usando a **API posix `pthread`**. A thread que geramos na injeção anterior foi gerada usando a API Mach, então **não é compatível com posix**.
Foi possível **injetar um shellcode simples** para executar um comando porque **não precisava trabalhar com apis** compatíveis com posix, apenas com Mach. **Injeções mais complexas** precisariam que a **thread** também fosse **compatível com posix**.
Portanto, para **melhorar a thread**, ela deve chamar **`pthread_create_from_mach_thread`**, que irá **criar um pthread válido**. Então, esse novo pthread poderia **chamar dlopen** para **carregar um dylib** do sistema, assim, em vez de escrever um novo shellcode para realizar diferentes ações, é possível carregar bibliotecas personalizadas.
Ao chamar `task_for_pid` ou `thread_create_*`, um contador na estrutura de tarefa do kernel é incrementado, que pode ser acessado do modo usuário chamando task\_info(task, TASK\_EXTMOD\_INFO, ...)
Quando uma exceção ocorre em uma thread, essa exceção é enviada para a porta de exceção designada da thread. Se a thread não a manipular, então é enviada para as portas de exceção da tarefa. Se a tarefa não a manipular, então é enviada para a porta do host, que é gerenciada pelo launchd (onde será reconhecida). Isso é chamado de triagem de exceção.
Note que, no final, geralmente, se não for manipulada corretamente, o relatório acabará sendo tratado pelo daemon ReportCrash. No entanto, é possível que outra thread na mesma tarefa gerencie a exceção, isso é o que ferramentas de relatórios de falhas como `PLCreashReporter` fazem.
Para modificar valores, o subsistema `clock_priv` pode ser usado com funções como `clock_set_time` e `clock_set_attributes`
### Processadores e Conjunto de Processadores
As APIs de processador permitem controlar um único processador lógico chamando funções como `processor_start`, `processor_exit`, `processor_info`, `processor_get_assignment`...
Além disso, as APIs de **conjunto de processadores** fornecem uma maneira de agrupar múltiplos processadores em um grupo. É possível recuperar o conjunto de processadores padrão chamando **`processor_set_default`**.\
Estas são algumas APIs interessantes para interagir com o conjunto de processadores:
Como mencionado em [**este post**](https://reverse.put.as/2014/05/05/about-the-processor\_set\_tasks-access-to-kernel-memory-vulnerability/), no passado isso permitia contornar a proteção mencionada anteriormente para obter portas de tarefa em outros processos para controlá-los chamando **`processor_set_tasks`** e obtendo uma porta de host em cada processo.\
Hoje em dia, você precisa ser root para usar essa função e isso é protegido, então você só poderá obter essas portas em processos não protegidos.
fprintf(stderr, "Invalid PID. Please enter a numeric value greater than 0.\n");
return 1;
}*/
int pid = 1;
task_for_pid_workaround(pid);
return 0;
}
```
````
</details>
## XPC
### Basic Information
XPC, which stands for XNU (the kernel used by macOS) inter-Process Communication, is a framework for **communication between processes** on macOS and iOS. XPC provides a mechanism for making **safe, asynchronous method calls between different processes** on the system. It's a part of Apple's security paradigm, allowing for the **creation of privilege-separated applications** where each **component** runs with **only the permissions it needs** to do its job, thereby limiting the potential damage from a compromised process.
For more information about how this **communication work** on how it **could be vulnerable** check:
{% content-ref url="macos-xpc/" %}
[macos-xpc](macos-xpc/)
{% endcontent-ref %}
## MIG - Mach Interface Generator
MIG was created to **simplify the process of Mach IPC** code creation. This is because a lot of work to program RPC involves the same actions (packing arguments, sending the msg, unpacking the data in the server...).
MIC basically **generates the needed code** for server and client to communicate with a given definition (in IDL -Interface Definition language-). Even if the generated code is ugly, a developer will just need to import it and his code will be much simpler than before.
Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.