# macOS XPC
Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)! Autres moyens de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)! * Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Informations de base XPC, qui signifie XNU (le noyau utilisé par macOS) inter-Process Communication, est un cadre pour la **communication entre processus** sur macOS et iOS. XPC fournit un mécanisme pour effectuer des **appels de méthodes sûrs et asynchrones 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 les privilèges** où chaque **composant** fonctionne avec **seulement les permissions nécessaires** 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 permettant à différents programmes exécutés sur le même système d'échanger des données. Les principaux avantages de XPC incluent : 1. **Sécurité** : En séparant le travail en différents processus, chaque processus peut se voir accorder uniquement les permissions dont il a besoin. Cela signifie que même si un processus est compromis, sa capacité à nuire est limitée. 2. **Stabilité** : XPC aide à isoler les plantages au 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** qui communiquent via XPC est **moins efficace**. Mais dans les systèmes actuels, cela n'est presque pas perceptible et les avantages sont meilleurs. ## Services XPC spécifiques à l'application Les composants XPC d'une application se trouvent **à 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` et un `Info.plist : /Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/Info.plist` Comme vous pourriez le penser, un **composant XPC aura des droits et 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 nécessaire et **arrêtés** une fois toutes les tâches **complété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. ## Services XPC à l'échelle du système Les services XPC à l'échelle du système sont accessibles à tous les utilisateurs. Ces services, de type launchd ou 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 vers le binaire : ```xml cat /Library/LaunchDaemons/com.jamf.management.daemon.plist Program /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon AbandonProcessGroup KeepAlive Label com.jamf.management.daemon MachServices com.jamf.management.daemon.aad com.jamf.management.daemon.agent com.jamf.management.daemon.binary com.jamf.management.daemon.selfservice com.jamf.management.daemon.service RunAtLoad ``` Les éléments dans **`LaunchDameons`** sont exécutés par root. Ainsi, si un processus non privilégié peut communiquer avec l'un d'eux, il pourrait être capable d'escalader les privilèges. ## Messages d'événements XPC 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 les fichiers plist de **launchd**, situés dans les **mêmes répertoires que les précédents** et contenant une clé supplémentaire **`LaunchEvent`**. ### Vérification du processus de connexion XPC Lorsqu'un processus tente d'appeler une méthode via une connexion XPC, le **service XPC devrait vérifier si ce processus est autorisé à se connecter**. Voici les moyens courants de vérifier cela et les pièges courants : {% content-ref url="macos-xpc-connecting-process-check/" %} [macos-xpc-connecting-process-check](macos-xpc-connecting-process-check/) {% endcontent-ref %} ## Autorisation XPC Apple permet également aux applications de **configurer certains droits et comment les obtenir** donc si le processus appelant les possède, il serait **autorisé à appeler une méthode** du service XPC : {% content-ref url="macos-xpc-authorization.md" %} [macos-xpc-authorization.md](macos-xpc-authorization.md) {% endcontent-ref %} ## Sniffer XPC Pour renifler les messages XPC, vous pourriez utiliser [**xpcspy**](https://github.com/hot3eed/xpcspy) qui utilise **Frida**. ```bash # Install pip3 install xpcspy pip3 install xpcspy --no-deps # To not make xpcspy install Frida 15 and downgrade your Frida installation # Start sniffing xpcspy -U -r -W ## Using filters (i: for input, o: for output) xpcspy -U -t 'i:com.apple.*' -t 'o:com.apple.*' -r ``` ## Exemple de code C pour la communication XPC {% tabs %} {% tab title="xpc_server.c" %} ```c // gcc xpc_server.c -o xpc_server #include static void handle_event(xpc_object_t event) { if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { // Print received message const char* received_message = xpc_dictionary_get_string(event, "message"); printf("Received message: %s\n", received_message); // Create a response dictionary xpc_object_t response = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(response, "received", "received"); // Send response xpc_connection_t remote = xpc_dictionary_get_remote_connection(event); xpc_connection_send_message(remote, response); // Clean up xpc_release(response); } } static void handle_connection(xpc_connection_t connection) { xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { handle_event(event); }); xpc_connection_resume(connection); } int main(int argc, const char *argv[]) { xpc_connection_t service = xpc_connection_create_mach_service("xyz.hacktricks.service", dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_LISTENER); if (!service) { fprintf(stderr, "Failed to create service.\n"); exit(EXIT_FAILURE); } xpc_connection_set_event_handler(service, ^(xpc_object_t event) { xpc_type_t type = xpc_get_type(event); if (type == XPC_TYPE_CONNECTION) { handle_connection(event); } }); xpc_connection_resume(service); dispatch_main(); return 0; } ``` {% endtab %} {% tab title="xpc_client.c" %} ```c // gcc xpc_client.c -o xpc_client #include int main(int argc, const char *argv[]) { xpc_connection_t connection = xpc_connection_create_mach_service("xyz.hacktricks.service", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { // Print received message const char* received_message = xpc_dictionary_get_string(event, "received"); printf("Received message: %s\n", received_message); } }); xpc_connection_resume(connection); xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(message, "message", "Hello, Server!"); xpc_connection_send_message(connection, message); dispatch_main(); return 0; } ``` {% endtab %} {% tab title="xyz.hacktricks.service.plist" %} ```xml Label xyz.hacktricks.service MachServices xyz.hacktricks.service Program /tmp/xpc_server ProgramArguments /tmp/xpc_server ``` {% endtab %} {% endtabs %} ```bash # Compile the server & client gcc xpc_server.c -o xpc_server gcc xpc_client.c -o xpc_client # Save server on it's location cp xpc_server /tmp # Load daemon sudo cp xyz.hacktricks.service.plist /Library/LaunchDaemons sudo launchctl load /Library/LaunchDaemons/xyz.hacktricks.service.plist # Call client ./xpc_client # Clean sudo launchctl unload /Library/LaunchDaemons/xyz.hacktricks.service.plist sudo rm /Library/LaunchDaemons/xyz.hacktricks.service.plist /tmp/xpc_server ``` ## Exemple de code Objective-C pour la communication XPC {% tabs %} {% tab title="oc_xpc_server.m" %} ```objectivec // gcc -framework Foundation oc_xpc_server.m -o oc_xpc_server #include @protocol MyXPCProtocol - (void)sayHello:(NSString *)some_string withReply:(void (^)(NSString *))reply; @end @interface MyXPCObject : NSObject @end @implementation MyXPCObject - (void)sayHello:(NSString *)some_string withReply:(void (^)(NSString *))reply { NSLog(@"Received message: %@", some_string); NSString *response = @"Received"; reply(response); } @end @interface MyDelegate : NSObject @end @implementation MyDelegate - (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyXPCProtocol)]; MyXPCObject *my_object = [MyXPCObject new]; newConnection.exportedObject = my_object; [newConnection resume]; return YES; } @end int main(void) { NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:@"xyz.hacktricks.svcoc"]; id delegate = [MyDelegate new]; listener.delegate = delegate; [listener resume]; sleep(10); // Fake something is done and then it ends } ``` {% endtab %} {% tab title="oc_xpc_client.m" %} ```objectivec // gcc -framework Foundation oc_xpc_client.m -o oc_xpc_client #include @protocol MyXPCProtocol - (void)sayHello:(NSString *)some_string withReply:(void (^)(NSString *))reply; @end int main(void) { NSXPCConnection *connection = [[NSXPCConnection alloc] initWithMachServiceName:@"xyz.hacktricks.svcoc" options:NSXPCConnectionPrivileged]; connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyXPCProtocol)]; [connection resume]; [[connection remoteObjectProxy] sayHello:@"Hello, Server!" withReply:^(NSString *response) { NSLog(@"Received response: %@", response); }]; [[NSRunLoop currentRunLoop] run]; return 0; } ``` {% endtab %} {% tab title="xyz.hacktricks.svcoc.plist" %} ```xml Label xyz.hacktricks.svcoc MachServices xyz.hacktricks.svcoc Program /tmp/oc_xpc_server ProgramArguments /tmp/oc_xpc_server ``` {% endtab %} {% endtabs %} ```bash # Compile the server & client gcc -framework Foundation oc_xpc_server.m -o oc_xpc_server gcc -framework Foundation oc_xpc_client.m -o oc_xpc_client # Save server on it's location cp oc_xpc_server /tmp # Load daemon sudo cp xyz.hacktricks.svcoc.plist /Library/LaunchDaemons sudo launchctl load /Library/LaunchDaemons/xyz.hacktricks.svcoc.plist # Call client ./oc_xpc_client # Clean sudo launchctl unload /Library/LaunchDaemons/xyz.hacktricks.svcoc.plist sudo rm /Library/LaunchDaemons/xyz.hacktricks.svcoc.plist /tmp/oc_xpc_server ``` ## Client à l'intérieur d'un code Dylb ```objectivec // gcc -dynamiclib -framework Foundation oc_xpc_client.m -o oc_xpc_client.dylib // gcc injection example: // DYLD_INSERT_LIBRARIES=oc_xpc_client.dylib /path/to/vuln/bin #import @protocol MyXPCProtocol - (void)sayHello:(NSString *)some_string withReply:(void (^)(NSString *))reply; @end __attribute__((constructor)) static void customConstructor(int argc, const char **argv) { NSString* _serviceName = @"xyz.hacktricks.svcoc"; NSXPCConnection* _agentConnection = [[NSXPCConnection alloc] initWithMachServiceName:_serviceName options:4096]; [_agentConnection setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(MyXPCProtocol)]]; [_agentConnection resume]; [[_agentConnection remoteObjectProxyWithErrorHandler:^(NSError* error) { (void)error; NSLog(@"Connection Failure"); }] sayHello:@"Hello, Server!" withReply:^(NSString *response) { NSLog(@"Received response: %@", response); } ]; NSLog(@"Done!"); return; } ```
Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)! Autres moyens de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)! * Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez**-moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).