Mach utilise des **tâches** comme **unité la plus petite** pour partager des ressources, et chaque tâche peut contenir **plusieurs threads**. Ces **tâches et threads sont mappés 1:1 sur les processus et threads POSIX**.
La communication entre les tâches se fait via la communication inter-processus (IPC) de Mach, en utilisant des canaux de communication unidirectionnels. **Les messages sont transférés entre les ports**, qui agissent comme des **files d'attente de messages** gérées par le noyau.
Les droits de port, qui définissent les opérations qu'une tâche peut effectuer, sont essentiels à cette communication. Les **droits de port** possibles sont :
* **Droit de réception**, qui permet de recevoir des messages envoyés au port. Les ports Mach sont des files d'attente MPSC (multiple-producteur, unique-consommateur), ce qui signifie qu'il ne peut y avoir **qu'un seul droit de réception pour chaque port** dans tout le système (contrairement aux pipes, où plusieurs processus peuvent tous détenir des descripteurs de fichier pour l'extrémité de lecture d'un pipe).
* Une **tâche avec le droit de réception** peut recevoir des messages et **créer des droits d'envoi**, lui permettant d'envoyer des messages. À l'origine, seule la **propre tâche a le droit de réception sur son port**.
* **Droit de jeu de ports**, qui indique un _ensemble de ports_ plutôt qu'un seul port. Le défilement d'un message à partir d'un ensemble de ports défile un message à partir de l'un des ports qu'il contient. Les ensembles de ports peuvent être utilisés pour écouter plusieurs ports simultanément, un peu comme `select`/`poll`/`epoll`/`kqueue` dans Unix.
* **Nom mort**, qui n'est pas un droit de port réel, mais simplement un espace réservé. Lorsqu'un port est détruit, tous les droits de port existants sur le port deviennent des noms morts.
**Les tâches peuvent transférer des droits d'ENVOI à d'autres**, leur permettant d'envoyer des messages en retour. **Les droits d'ENVOI peuvent également être clonés, de sorte qu'une tâche peut dupliquer et donner le droit à une troisième tâche**. Cela, combiné à un processus intermédiaire connu sous le nom de **serveur de démarrage**, permet une communication efficace entre les tâches.
3. La tâche **A** établit une **connexion** avec le **serveur de démarrage**, fournissant le **nom de service du port** et le **droit d'envoi** par une procédure connue sous le nom d'enregistrement de démarrage.
4. La tâche **B** interagit avec le **serveur de démarrage** pour exécuter une **recherche de démarrage pour le service**. Si elle réussit, le **serveur duplique le droit d'envoi** reçu de la tâche A et **le transmet à la tâche B**.
Le serveur de démarrage ne peut pas authentifier le nom de service revendiqué par une tâche. Cela signifie qu'une **tâche** pourrait potentiellement **usurper n'importe quelle tâche système**, en revendiquant faussement un nom de service d'autorisation, puis en approuvant chaque demande.
Ensuite, Apple stocke les **noms des services fournis par le système** dans des fichiers de configuration sécurisés, situés dans des répertoires protégés par SIP : `/System/Library/LaunchDaemons` et `/System/Library/LaunchAgents`. À côté de chaque nom de service, le **binaire associé est également stocké**. Le serveur de démarrage créera et conservera un **droit de réception pour chacun de ces noms de service**.
Pour ces services prédéfinis, le **processus de recherche diffère légèrement**. Lorsqu'un nom de service est recherché, launchd démarre le service dynamiquement. Le nouveau flux de travail est le suivant :
* La tâche **A** (le service) effectue un **enregistrement de démarrage**. Ici, le **serveur de démarrage crée un droit d'envoi, le retient et transfère le droit de réception à la tâche A**.
Cependant, ce processus ne s'applique qu'aux tâches système prédéfinies. Les tâches non système fonctionnent toujours comme décrit initialement, ce qui pourrait potentiellement permettre l'usurpation.
Notez comment l'**expéditeur** **alloue** un port, crée un **droit d'envoi** pour le nom `org.darlinghq.example` et l'envoie au **serveur de démarrage** tandis que l'expéditeur a demandé le **droit d'envoi** de ce nom et l'a utilisé pour **envoyer un message**.
* **Port hôte**: Si un processus a le privilège **Envoyer** sur ce port, il peut obtenir des **informations** sur le **système** (par exemple, `host_processor_info`).
* **Port privilégié hôte**: Un processus avec le droit **Envoyer** sur ce port peut effectuer des actions **privilégiées** comme le chargement d'une extension de noyau. Le **processus doit être root** pour obtenir cette autorisation.
* De plus, pour appeler l'API **`kext_request`**, il est nécessaire de disposer de l'attribution **`com.apple.private.kext`**, qui n'est donnée qu'aux binaires Apple.
* **Port de nom de tâche**: Une version non privilégiée du _port de tâche_. Il fait référence à la tâche, mais ne permet pas de la contrôler. La seule chose qui semble être disponible à travers elle est `task_info()`.
* **Port de tâche** (alias port de noyau)**:** Avec l'autorisation d'envoi sur ce port, il est possible de contrôler la tâche (lecture/écriture de mémoire, création de threads...).
* Appelez `mach_task_self()` pour **obtenir le nom** de ce port pour la tâche appelante. Ce port n'est **hérité** qu'à travers **`exec()`**; une nouvelle tâche créée avec `fork()` obtient un nouveau port de tâche (dans un cas particulier, une tâche obtient également un nouveau port de tâche après l'exécution d'un binaire suid). La seule façon de lancer une tâche et d'obtenir son port est d'effectuer la ["danse d'échange de port"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) tout en faisant un `fork()`.
* Voici les restrictions d'accès au port (à partir de `macos_task_policy` du binaire `AppleMobileFileIntegrity`):
* Si l'application a l'attribution **`com.apple.security.get-task-allow`**, les processus de l'**utilisateur peuvent accéder au port de tâche**, (communément ajouté par Xcode pour le débogage). Le processus de **notarisation** ne le permettra pas pour les versions de production.
* Les applications ayant l'attribution **`com.apple.system-task-ports`** peuvent obtenir le **port de tâche pour n'importe quel** processus, sauf le noyau. Dans les versions antérieures, il était appelé **`task_for_pid-allow`**. Cela n'est accordé qu'aux applications Apple.
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**: a low-level IPC mechanism used by the kernel and many system services.
- **XPC**: a high-level IPC mechanism used by many system services and applications.
- **Distributed Objects**: a legacy IPC mechanism used by some system services and applications.
Mach ports are a low-level IPC mechanism used by the kernel and many system services. Mach ports are used to send messages between processes and to create inter-process communication channels. Mach ports are identified by a port name, which is an integer value. Processes can send messages to a port by sending a message to the port name. Processes can receive messages by waiting for a message on a port.
Mach ports are a critical part of the macOS security model. Mach ports are used by many system services and applications to communicate with each other and with the kernel. Mach ports are also used by macOS to implement sandboxing and other security features.
Mach ports are protected by a set of access controls called **port rights**. Port rights are used to control which processes can send messages to a port, receive messages from a port, or perform other operations on a port. Port rights are managed by the kernel and are enforced by the Mach port subsystem.
Mach ports can be a source of security vulnerabilities if they are not properly secured. Attackers can use Mach ports to perform a variety of attacks, including:
To protect against these attacks, it is important to properly secure Mach ports and limit access to them. This can be done by using **entitlements** and other access controls.
XPC is a high-level IPC mechanism used by many system services and applications. XPC provides a simple and secure way for processes to communicate with each other and share data. XPC is based on a client-server model, where a client process sends messages to a server process and the server process responds to the messages.
XPC services are defined using **XPC service bundles**. An XPC service bundle is a directory that contains an executable file and a property list file that describes the service. The property list file contains information about the service, including its name, version, and entitlements.
XPC services are registered with the system using a special **launchd** configuration file. The launchd configuration file specifies the executable file for the service and the conditions under which the service should be launched.
XPC services can be a source of security vulnerabilities if they are not properly secured. Attackers can use XPC services to perform a variety of attacks, including:
To protect against these attacks, it is important to properly secure XPC services and limit access to them. This can be done by using sandboxing, code signing, entitlements, and other access controls.
**Compilez** le programme précédent et ajoutez les **droits** nécessaires pour pouvoir injecter du code avec le même utilisateur (sinon vous devrez utiliser **sudo**).
Dans macOS, les **threads** peuvent être manipulés via **Mach** ou en utilisant l'API **posix `pthread`**. Le thread que nous avons généré dans l'injection précédente a été généré en utilisant l'API Mach, donc **il n'est pas conforme à posix**.
Il était possible d'**injecter un simple shellcode** pour exécuter une commande car il **n'avait pas besoin de travailler avec des API conformes à posix**, seulement avec Mach. Des injections **plus complexes** nécessiteraient donc que le **thread** soit également **conforme à posix**.
Par conséquent, pour **améliorer le shellcode**, il devrait appeler **`pthread_create_from_mach_thread`** qui va **créer un pthread valide**. Ensuite, ce nouveau pthread pourrait **appeler dlopen** pour **charger notre dylib** depuis le système.
XPC, qui signifie Communication inter-processus XNU (le noyau utilisé par macOS), est un framework pour la **communication entre les processus** sur macOS et iOS. XPC fournit un mécanisme pour effectuer des **appels de méthode asynchrones et sûrs entre différents processus** sur le système. C'est une partie du paradigme de sécurité d'Apple, permettant la **création d'applications séparées par privilèges** où chaque **composant** s'exécute avec **seulement les autorisations dont il a besoin** pour faire son travail, limitant ainsi les dommages potentiels d'un processus compromis.
XPC utilise une forme de communication inter-processus (IPC), qui est un ensemble de méthodes pour différents programmes s'exécutant sur le même système pour s'envoyer des données.
1.**Sécurité** : En séparant le travail en différents processus, chaque processus peut se voir accorder uniquement les autorisations dont il a besoin. Cela signifie que même si un processus est compromis, il a une capacité limitée à nuire.
2.**Stabilité** : XPC aide à isoler les plantages dans le composant où ils se produisent. Si un processus plante, il peut être redémarré sans affecter le reste du système.
3.**Performance** : XPC permet une concurrence facile, car différentes tâches peuvent être exécutées simultanément dans différents processus.
Le seul **inconvénient** est que **séparer une application en plusieurs processus** les faisant communiquer via XPC est **moins efficace**. Mais dans les systèmes d'aujourd'hui, cela n'est presque pas perceptible et les avantages sont bien meilleurs.
Un exemple peut être vu dans QuickTime Player, où un composant utilisant XPC est responsable du décodage vidéo. Le composant est spécifiquement conçu pour effectuer des tâches de calcul, ainsi, en cas de violation, il ne fournirait pas de gains utiles à l'attaquant, tels que l'accès aux fichiers ou au réseau.
Les composants XPC d'une application sont **à l'intérieur de l'application elle-même**. Par exemple, dans Safari, vous pouvez les trouver dans **`/Applications/Safari.app/Contents/XPCServices`**. Ils ont l'extension **`.xpc`** (comme **`com.apple.Safari.SandboxBroker.xpc`**) et sont **également des bundles** avec le binaire principal à l'intérieur : `/Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/MacOS/com.apple.Safari.SandboxBroker`
Comme vous pouvez le penser, un **composant XPC aura des autorisations et des privilèges différents** des autres composants XPC ou du binaire principal de l'application. SAUF si un service XPC est configuré avec [**JoinExistingSession**](https://developer.apple.com/documentation/bundleresources/information\_property\_list/xpcservice/joinexistingsession) défini sur "True" dans son fichier **Info.plist**. Dans ce cas, le service XPC s'exécutera dans la même session de sécurité que l'application qui l'a appelé.
Les services XPC sont **démarrés** par **launchd** lorsque cela est nécessaire et **arrêtés** une fois que toutes les tâches sont **terminées** pour libérer les ressources système. **Les composants XPC spécifiques à l'application ne peuvent être utilisés que par l'application**, réduisant ainsi le risque associé aux vulnérabilités potentielles.
Les services XPC système sont accessibles à tous les utilisateurs. Ces services, soit launchd soit de type Mach, doivent être **définis dans des fichiers plist** situés dans des répertoires spécifiés tels que **`/System/Library/LaunchDaemons`**, **`/Library/LaunchDaemons`**, **`/System/Library/LaunchAgents`** ou **`/Library/LaunchAgents`**.
Ces fichiers plist auront une clé appelée **`MachServices`** avec le nom du service, et une clé appelée **`Program`** avec le chemin d'accès au binaire :
Ceux dans **`LaunchDameons`** sont exécutés par root. Donc, si un processus non privilégié peut communiquer avec l'un d'entre eux, il pourrait être en mesure d'escalader les privilèges.
Les applications peuvent **s'abonner** à différents **messages d'événements**, leur permettant d'être **initiées à la demande** lorsque de tels événements se produisent. La **configuration** de ces services est effectuée dans des fichiers **plist de lancement**, situés dans les **mêmes répertoires que les précédents** et contenant une clé supplémentaire **`LaunchEvent`**.
Lorsqu'un processus essaie d'appeler une méthode via une connexion XPC, le **service XPC doit vérifier si ce processus est autorisé à se connecter**. Voici les moyens courants de vérifier cela et les pièges courants :
Apple permet également aux applications de **configurer certains droits et la manière de les obtenir** afin que si le processus appelant les possède, il serait **autorisé à appeler une méthode** du service XPC :
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**: A low-level IPC mechanism that allows processes to send messages to each other.
- **Unix domain sockets**: A mechanism that allows processes to communicate with each other over the network.
- **Distributed Objects**: A high-level IPC mechanism that allows objects to be passed between processes.
## Mach Ports
Mach ports are a low-level IPC mechanism that allows processes to send messages to each other. Mach ports are used extensively by macOS to implement various system services, such as the WindowServer, launchd, and the kernel itself.
Mach ports are identified by a 32-bit integer called a port name. When a process creates a Mach port, it is given a port name that is unique within the process. The process can then send messages to other processes by sending them the port name.
Mach ports can be used to perform various tasks, such as:
- **Task port**: A Mach port that represents a process. A process can use its own task port to perform various operations on itself, such as reading and writing its memory, suspending and resuming itself, and terminating itself.
- **Thread port**: A Mach port that represents a thread within a process. A process can use a thread port to perform various operations on the thread, such as suspending and resuming it, and getting information about its state.
- **Task access port**: A Mach port that represents a process and allows another process to perform operations on it. For example, a debugger can use a task access port to read and write the memory of the process being debugged.
- **Notification port**: A Mach port that is used to receive notifications from the kernel or other processes. For example, a process can create a notification port and register it with the kernel to receive notifications when certain events occur, such as a file being modified.
Mach ports are a powerful IPC mechanism that can be used to perform a wide range of tasks. However, they can also be a security risk if not used properly. For example, if a process exposes a Mach port that allows another process to perform operations on it without proper authentication and authorization, it can lead to privilege escalation and other security issues.
## Unix Domain Sockets
Unix domain sockets are a mechanism that allows processes to communicate with each other over the network. Unlike regular network sockets, Unix domain sockets are implemented entirely within the kernel and do not require any network stack processing.
Unix domain sockets are identified by a file path on the filesystem. When a process creates a Unix domain socket, it creates a file on the filesystem that represents the socket. Other processes can then connect to the socket by opening the file and sending messages to it.
Unix domain sockets can be used to perform various tasks, such as:
- **Inter-process communication**: Processes can use Unix domain sockets to communicate with each other and share data.
- **Daemonization**: A process can create a Unix domain socket and listen for connections on it. When another process connects to the socket, the first process can fork itself and continue running as a daemon, while the second process communicates with the daemon over the socket.
- **Locking**: Processes can use Unix domain sockets to implement locking mechanisms that allow multiple processes to coordinate access to a shared resource.
Unix domain sockets are a powerful IPC mechanism that can be used to perform a wide range of tasks. However, they can also be a security risk if not used properly. For example, if a process creates a Unix domain socket with insecure permissions, it can allow unauthorized access to sensitive data or functionality.
## Distributed Objects
Distributed Objects is a high-level IPC mechanism that allows objects to be passed between processes. Distributed Objects is built on top of Mach ports and provides a simple and convenient way for processes to communicate with each other.
Distributed Objects allows objects to be passed between processes by serializing them into a binary format and sending them over Mach ports. The receiving process then deserializes the object and can use it as if it were a local object.
Distributed Objects can be used to perform various tasks, such as:
- **Inter-process communication**: Processes can use Distributed Objects to communicate with each other and share data.
- **Remote procedure calls**: Processes can use Distributed Objects to call methods on objects in other processes.
- **Shared objects**: Processes can use Distributed Objects to share objects between them, allowing them to coordinate their actions.
Distributed Objects is a powerful IPC mechanism that can be used to perform a wide range of tasks. However, it can also be a security risk if not used properly. For example, if a process exposes a Distributed Object that allows another process to perform operations on it without proper authentication and authorization, it can lead to privilege escalation and other security issues.
La communication inter-processus (IPC) est un mécanisme qui permet à des processus de communiquer entre eux. Sur macOS, IPC est implémenté via XPC (eXtensible Procedure Call), qui est un système de communication de processus léger et sécurisé.
XPC est utilisé pour la communication entre les processus de l'espace utilisateur et les démons de l'espace noyau. Les démons de l'espace noyau sont des processus qui s'exécutent en mode privilégié et qui fournissent des services système. Les processus de l'espace utilisateur peuvent communiquer avec les démons de l'espace noyau via XPC.
XPC utilise des connexions pour la communication entre les processus. Une connexion est un canal de communication bidirectionnel entre un client et un serveur. Les clients envoient des messages aux serveurs via des connexions, et les serveurs répondent aux messages via les mêmes connexions.
Les connexions XPC sont sécurisées par défaut. Les messages envoyés via les connexions sont chiffrés et signés pour empêcher les attaques de type man-in-the-middle et les attaques de falsification de messages.
Les connexions XPC sont également isolées les unes des autres. Cela signifie que si un processus est compromis, il ne peut pas accéder aux connexions d'autres processus.
Cependant, les connexions XPC peuvent être vulnérables aux attaques de fuite d'informations. Si un processus envoie des données sensibles via une connexion XPC non sécurisée, un attaquant peut intercepter ces données et les lire.
Dans cette section, nous allons examiner comment utiliser XPC pour la communication inter-processus sur macOS, ainsi que les vulnérabilités potentielles associées à l'utilisation de XPC.
Inter-Process Communication (IPC) is a mechanism that allows processes to communicate with each other and share data. macOS provides several IPC mechanisms, including:
Each of these mechanisms has its own strengths and weaknesses, and can be used for different purposes. In this section, we will focus on Mach ports and UNIX domain sockets, as they are the most commonly used IPC mechanisms on macOS.
Mach ports are a low-level IPC mechanism provided by the Mach kernel. They are used extensively by macOS and iOS to implement various system services and APIs. Mach ports are similar to UNIX file descriptors in that they are represented by small integers that can be passed between processes. However, unlike file descriptors, Mach ports can be used to send and receive messages between processes.
Mach ports can be either send rights or receive rights. A send right allows a process to send messages to a port, while a receive right allows a process to receive messages from a port. When a process creates a port, it is given both a send right and a receive right. The process can then pass the send right to another process, allowing that process to send messages to the port. Similarly, the process can pass the receive right to another process, allowing that process to receive messages from the port.
Mach ports are a powerful IPC mechanism, but they can also be a source of security vulnerabilities. For example, if a process has a send right to a port that is used by a system service, it may be able to send malicious messages to the service and cause it to execute arbitrary code. Similarly, if a process has a receive right to a port that is used by a system service, it may be able to receive sensitive information from the service.
UNIX domain sockets are a high-level IPC mechanism provided by the UNIX operating system. They are widely used on macOS and other UNIX-based systems to implement various system services and APIs. UNIX domain sockets are similar to network sockets in that they provide a bidirectional communication channel between processes. However, unlike network sockets, UNIX domain sockets are implemented entirely within the operating system and do not require any network hardware or protocols.
UNIX domain sockets can be either stream sockets or datagram sockets. Stream sockets provide a reliable, byte-stream-oriented communication channel between processes, while datagram sockets provide an unreliable, message-oriented communication channel.
UNIX domain sockets are a relatively simple and secure IPC mechanism, but they can still be a source of security vulnerabilities. For example, if a process has access to a socket that is used by a system service, it may be able to send malicious messages to the service and cause it to execute arbitrary code. Similarly, if a process has access to a socket that is used by a system service, it may be able to receive sensitive information from the service.
IPC is a powerful mechanism that allows processes to communicate with each other and share data. However, it can also be a source of security vulnerabilities if not used properly. When designing and implementing IPC mechanisms, it is important to consider the security implications and take appropriate measures to prevent unauthorized access and malicious use.
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).