mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-20 18:14:15 +00:00
429 lines
19 KiB
Markdown
429 lines
19 KiB
Markdown
|
# macOS XPC
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
|
||
|
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
|
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
|
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
|
||
|
</details>
|
||
|
|
||
|
## Informações básicas
|
||
|
|
||
|
XPC, que significa Comunicação Interprocessos (IPC) do XNU (o kernel usado pelo macOS), é uma estrutura para **comunicação entre processos** no macOS e iOS. O XPC fornece um mecanismo para fazer **chamadas de método seguras e assíncronas entre diferentes processos** no sistema. É parte do paradigma de segurança da Apple, permitindo a **criação de aplicativos com privilégios separados**, onde cada **componente** é executado com **apenas as permissões necessárias** para realizar seu trabalho, limitando assim os danos potenciais de um processo comprometido.
|
||
|
|
||
|
O XPC usa uma forma de Comunicação Interprocessos (IPC), que é um conjunto de métodos para que diferentes programas em execução no mesmo sistema enviem dados de ida e volta.
|
||
|
|
||
|
Os principais benefícios do XPC incluem:
|
||
|
|
||
|
1. **Segurança**: Ao separar o trabalho em diferentes processos, cada processo pode receber apenas as permissões necessárias. Isso significa que, mesmo que um processo seja comprometido, ele tem capacidade limitada de causar danos.
|
||
|
2. **Estabilidade**: O XPC ajuda a isolar falhas no componente onde ocorrem. Se um processo falhar, ele pode ser reiniciado sem afetar o restante do sistema.
|
||
|
3. **Desempenho**: O XPC permite fácil concorrência, pois diferentes tarefas podem ser executadas simultaneamente em diferentes processos.
|
||
|
|
||
|
A única **desvantagem** é que **separar um aplicativo em vários processos** que se comunicam via XPC é **menos eficiente**. Mas nos sistemas de hoje isso quase não é perceptível e os benefícios são maiores.
|
||
|
|
||
|
## Serviços XPC específicos do aplicativo
|
||
|
|
||
|
Os componentes XPC de um aplicativo estão **dentro do próprio aplicativo**. Por exemplo, no Safari, você pode encontrá-los em **`/Applications/Safari.app/Contents/XPCServices`**. Eles têm a extensão **`.xpc`** (como **`com.apple.Safari.SandboxBroker.xpc`**) e também são **bundles** com o binário principal dentro dele: `/Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/MacOS/com.apple.Safari.SandboxBroker` e um `Info.plist: /Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/Info.plist`
|
||
|
|
||
|
Como você pode estar pensando, um **componente XPC terá diferentes direitos e privilégios** do que os outros componentes XPC ou o binário principal do aplicativo. EXCETO se um serviço XPC for configurado com [**JoinExistingSession**](https://developer.apple.com/documentation/bundleresources/information\_property\_list/xpcservice/joinexistingsession) definido como "True" em seu arquivo **Info.plist**. Nesse caso, o serviço XPC será executado na **mesma sessão de segurança do aplicativo** que o chamou.
|
||
|
|
||
|
Os serviços XPC são **iniciados** pelo **launchd** quando necessário e **encerrados** quando todas as tarefas são **concluídas** para liberar recursos do sistema. **Os componentes XPC específicos do aplicativo só podem ser utilizados pelo aplicativo**, reduzindo assim o risco associado a possíveis vulnerabilidades.
|
||
|
|
||
|
## Serviços XPC em todo o sistema
|
||
|
|
||
|
Os serviços XPC em todo o sistema são acessíveis a todos os usuários. Esses serviços, sejam do tipo launchd ou Mach, precisam ser **definidos em arquivos plist** localizados em diretórios especificados, como **`/System/Library/LaunchDaemons`**, **`/Library/LaunchDaemons`**, **`/System/Library/LaunchAgents`** ou **`/Library/LaunchAgents`**.
|
||
|
|
||
|
Esses arquivos plist terão uma chave chamada **`MachServices`** com o nome do serviço e uma chave chamada **`Program`** com o caminho para o binário:
|
||
|
```xml
|
||
|
cat /Library/LaunchDaemons/com.jamf.management.daemon.plist
|
||
|
|
||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
|
<plist version="1.0">
|
||
|
<dict>
|
||
|
<key>Program</key>
|
||
|
<string>/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon</string>
|
||
|
<key>AbandonProcessGroup</key>
|
||
|
<true/>
|
||
|
<key>KeepAlive</key>
|
||
|
<true/>
|
||
|
<key>Label</key>
|
||
|
<string>com.jamf.management.daemon</string>
|
||
|
<key>MachServices</key>
|
||
|
<dict>
|
||
|
<key>com.jamf.management.daemon.aad</key>
|
||
|
<true/>
|
||
|
<key>com.jamf.management.daemon.agent</key>
|
||
|
<true/>
|
||
|
<key>com.jamf.management.daemon.binary</key>
|
||
|
<true/>
|
||
|
<key>com.jamf.management.daemon.selfservice</key>
|
||
|
<true/>
|
||
|
<key>com.jamf.management.daemon.service</key>
|
||
|
<true/>
|
||
|
</dict>
|
||
|
<key>RunAtLoad</key>
|
||
|
<true/>
|
||
|
</dict>
|
||
|
</plist>
|
||
|
```
|
||
|
Os presentes em **`LaunchDameons`** são executados pelo root. Portanto, se um processo não privilegiado puder se comunicar com um deles, ele poderá conseguir privilégios elevados.
|
||
|
|
||
|
## Mensagens de Evento XPC
|
||
|
|
||
|
As aplicações podem **se inscrever** em diferentes **mensagens de evento**, permitindo que sejam **iniciadas sob demanda** quando esses eventos ocorrerem. A **configuração** desses serviços é feita em arquivos **plist do launchd**, localizados nos **mesmos diretórios dos anteriores** e contendo uma chave adicional **`LaunchEvent`**.
|
||
|
|
||
|
### Verificação do Processo de Conexão XPC
|
||
|
|
||
|
Quando um processo tenta chamar um método por meio de uma conexão XPC, o **serviço XPC deve verificar se esse processo tem permissão para se conectar**. Aqui estão as maneiras comuns de verificar isso e as armadilhas comuns:
|
||
|
|
||
|
{% content-ref url="macos-xpc-connecting-process-check.md" %}
|
||
|
[macos-xpc-connecting-process-check.md](macos-xpc-connecting-process-check.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
## Autorização XPC
|
||
|
|
||
|
A Apple também permite que os aplicativos **configurem alguns direitos e como obtê-los**, para que, se o processo de chamada os tiver, ele seja **autorizado a chamar um método** do serviço XPC:
|
||
|
|
||
|
{% content-ref url="macos-xpc-authorization.md" %}
|
||
|
[macos-xpc-authorization.md](macos-xpc-authorization.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
## Exemplo de Código C
|
||
|
|
||
|
{% tabs %}
|
||
|
{% tab title="xpc_server.c" %}
|
||
|
```c
|
||
|
// gcc xpc_server.c -o xpc_server
|
||
|
|
||
|
#include <xpc/xpc.h>
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
```
|
||
|
{% tab title="xpc_client.c" %}
|
||
|
```c
|
||
|
// gcc xpc_client.c -o xpc_client
|
||
|
|
||
|
#include <xpc/xpc.h>
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
```
|
||
|
{% tab title="xyz.hacktricks.service.plist" %}
|
||
|
```xml
|
||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0">
|
||
|
<dict>
|
||
|
<key>Label</key>
|
||
|
<string>xyz.hacktricks.service</string>
|
||
|
<key>MachServices</key>
|
||
|
<dict>
|
||
|
<key>xyz.hacktricks.service</key>
|
||
|
<true/>
|
||
|
</dict>
|
||
|
<key>Program</key>
|
||
|
<string>/tmp/xpc_server</string>
|
||
|
<key>ProgramArguments</key>
|
||
|
<array>
|
||
|
<string>/tmp/xpc_server</string>
|
||
|
</array>
|
||
|
</dict>
|
||
|
</plist>
|
||
|
```
|
||
|
{% 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
|
||
|
```
|
||
|
## Exemplo de Código Objective-C
|
||
|
|
||
|
{% tabs %}
|
||
|
{% tab title="oc_xpc_server.m" %}
|
||
|
```objectivec
|
||
|
// gcc -framework Foundation oc_xpc_server.m -o oc_xpc_server
|
||
|
#include <Foundation/Foundation.h>
|
||
|
|
||
|
@protocol MyXPCProtocol
|
||
|
- (void)sayHello:(NSString *)some_string withReply:(void (^)(NSString *))reply;
|
||
|
@end
|
||
|
|
||
|
@interface MyXPCObject : NSObject <MyXPCProtocol>
|
||
|
@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 <NSXPCListenerDelegate>
|
||
|
@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 <NSXPCListenerDelegate> delegate = [MyDelegate new];
|
||
|
listener.delegate = delegate;
|
||
|
[listener resume];
|
||
|
|
||
|
sleep(10); // Fake something is done and then it ends
|
||
|
}
|
||
|
```
|
||
|
{% tab title="oc_xpc_client.m" %}
|
||
|
```objectivec
|
||
|
// gcc -framework Foundation oc_xpc_client.m -o oc_xpc_client
|
||
|
#include <Foundation/Foundation.h>
|
||
|
|
||
|
@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;
|
||
|
}
|
||
|
```
|
||
|
{% tab title="xyz.hacktricks.svcoc.plist" %}
|
||
|
|
||
|
O arquivo `xyz.hacktricks.svcoc.plist` é um arquivo de propriedades do Launchd usado para definir e controlar serviços no macOS. O Launchd é o sistema de inicialização e gerenciamento de processos do macOS. O arquivo plist contém informações sobre o serviço, como o caminho do executável, argumentos, variáveis de ambiente e outras configurações.
|
||
|
|
||
|
Para explorar vulnerabilidades de escalonamento de privilégios usando o arquivo `xyz.hacktricks.svcoc.plist`, você pode tentar manipular as configurações do serviço para executar comandos maliciosos com privilégios elevados. Isso pode ser feito modificando o arquivo plist para incluir comandos ou scripts maliciosos no campo `ProgramArguments` ou usando outras técnicas de injeção de código.
|
||
|
|
||
|
No entanto, é importante ressaltar que a exploração de vulnerabilidades de escalonamento de privilégios é ilegal e antiética, a menos que você tenha permissão explícita para fazê-lo em um ambiente controlado, como parte de um teste de penetração autorizado.
|
||
|
|
||
|
Recomenda-se sempre seguir as leis e regulamentos aplicáveis e obter permissão adequada antes de realizar qualquer atividade de hacking ou teste de penetração.
|
||
|
```xml
|
||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0">
|
||
|
<dict>
|
||
|
<key>Label</key>
|
||
|
<string>xyz.hacktricks.svcoc</string>
|
||
|
<key>MachServices</key>
|
||
|
<dict>
|
||
|
<key>xyz.hacktricks.svcoc</key>
|
||
|
<true/>
|
||
|
</dict>
|
||
|
<key>Program</key>
|
||
|
<string>/tmp/oc_xpc_server</string>
|
||
|
<key>ProgramArguments</key>
|
||
|
<array>
|
||
|
<string>/tmp/oc_xpc_server</string>
|
||
|
</array>
|
||
|
</dict>
|
||
|
</plist>
|
||
|
```
|
||
|
{% 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
|
||
|
```
|
||
|
## Cliente dentro de um código Dylb
|
||
|
|
||
|
O código a seguir demonstra como criar um cliente dentro de um código Dylb para se comunicar com um serviço XPC em um sistema macOS.
|
||
|
|
||
|
```objective-c
|
||
|
#include <xpc/xpc.h>
|
||
|
|
||
|
int main(int argc, const char * argv[]) {
|
||
|
xpc_connection_t connection = xpc_connection_create_mach_service("com.example.service", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
|
||
|
|
||
|
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
|
||
|
// Manipule as respostas recebidas do serviço XPC aqui
|
||
|
});
|
||
|
|
||
|
xpc_connection_resume(connection);
|
||
|
|
||
|
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
|
||
|
xpc_dictionary_set_string(message, "key", "value");
|
||
|
|
||
|
xpc_connection_send_message_with_reply(connection, message, dispatch_get_main_queue(), ^(xpc_object_t response) {
|
||
|
// Manipule a resposta recebida do serviço XPC aqui
|
||
|
});
|
||
|
|
||
|
dispatch_main();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Certifique-se de substituir `"com.example.service"` pelo identificador do serviço XPC ao qual você deseja se conectar. Você também pode personalizar as manipulações de eventos e respostas de acordo com suas necessidades.
|
||
|
|
||
|
Este código cria uma conexão com o serviço XPC especificado e define manipuladores de eventos para lidar com as respostas recebidas do serviço. Em seguida, ele cria uma mensagem XPC e a envia para o serviço XPC usando a função `xpc_connection_send_message_with_reply()`. Por fim, o código entra em um loop de execução principal usando `dispatch_main()` para manter a conexão ativa.
|
||
|
|
||
|
Certifique-se de compilar e executar o código em um ambiente macOS adequado com as permissões necessárias para se comunicar com o serviço XPC desejado.
|
||
|
```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 <Foundation/Foundation.h>
|
||
|
|
||
|
@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;
|
||
|
}
|
||
|
```
|
||
|
<details>
|
||
|
|
||
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
|
||
|
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
|
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
|
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
|
||
|
</details>
|