IOS_CFNetworkCopySystemProxySettings绕过

首先打开项目App,会出现越狱检测,这里使用flex已经出现完成了

image-20231115113817590

出现被拦截代理的问题,我这里使用的Shadowrocket进行代理转发到Charles

image-20231115112311294

使用HOOKexit函数进行定位,处理脚本如下

var exit = Module.findExportByName('libSystem.B.dylib', 'exit');

// 确保exit函数存在
if (exit) {
    Interceptor.attach(exit, {
        onEnter: function (args) {
            console.log('exit(' + args[0] + ')');
            console.log('Stack trace:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE)
                .map(DebugSymbol.fromAddress).join('\n'));
        }
    });
} else {
    console.log('exit找不到');
}

image-20231115112955454

但是在这边整半天,本来砸了壳想分析来着,奈何太久了,然后想到有个自带获取当前代理的函数CFNetworkCopySystemProxySettings,于是乎直接Hook看看是否存在调用

var CFNetworkCopySystemProxySettings = Module.findExportByName("CFNetwork", "CFNetworkCopySystemProxySettings");

if (CFNetworkCopySystemProxySettings) {
    Interceptor.attach(CFNetworkCopySystemProxySettings, {
        onEnter: function (args) {
            console.log("CFNetworkCopySystemProxySettings调用了");
        },
        onLeave: function (retval) {
        }
    });
} else {
    console.log("CFNetworkCopySystemProxySettings没有该函数!");
}

image-20231115120345147

然后反手打印一下CFNetworkCopySystemProxySettings内容,处理脚本如下

var CFNetworkCopySystemProxySettings = Module.findExportByName("CFNetwork", "CFNetworkCopySystemProxySettings");

if (CFNetworkCopySystemProxySettings) {
    Interceptor.attach(CFNetworkCopySystemProxySettings, {
        onLeave: function (retval) {
            if (!retval.isNull()) {
                var proxySettings = new ObjC.Object(retval);
                console.log("当前代理设置:", proxySettings.toString());
                var keys = proxySettings.allKeys();
                var count = keys.count();
                for (var i = 0; i < count; i++) {
                    var key = keys.objectAtIndex_(i);
                    var value = proxySettings.objectForKey_(key);
                    console.log(key.toString() + ": " + value.toString());
                }
            } else {
                console.log("没有返回代理设置.");
            }
        }
    });
} else {
    console.log("CFNetworkCopySystemProxySettings没有找到哟!");
}

image-20231115114031764

Current Proxy Settings: <__NSFrozenDictionaryM 0x280986920> {
        HTTPEnable = 1;
        HTTPSProxy = "127.0.0.1";
        ProxyAutoConfigEnable = 0;
        HTTPSPort = 1082;
        FTPEnable = 0;
        ExceptionsList = [
                "192.168.43.1.dns",
                "captive.apple.com",
                "localhost",
                "10.0.0.0/8",
                "*.local",
                "172.16.0.0/12",
                "240e:47c:4ec0:6b78::26.dns",
                "198.18.0.0/15",
                "192.168.0.0/16"
        ];
        __SCOPED__ = {
                en0 = {
                        ExceptionsList = [
                                "*.local",
                                "169.254/16"
                        ];
                        FTPPassive = 1
                };
                utun4 = {
                        HTTPEnable = 1;
                        HTTPSProxy = "127.0.0.1";
                        ProxyAutoConfigEnable = 0;
                        HTTPSPort = 1082;
                        FTPEnable = 0;
                        ExceptionsList = [
                                "192.168.43.1.dns",
                                "captive.apple.com",
                                "localhost",
                                "10.0.0.0/8",
                                "*.local",
                                "172.16.0.0/12",
                                "240e:47c:4ec0:6b78::26.dns",
                                "198.18.0.0/15",
                                "192.168.0.0/16"
                        ];
                        ProxyAutoDiscoveryEnable = 0;
                        ExcludeSimpleHostnames = 1;
                        HTTPProxy = "127.0.0.1";
                        GopherEnable = 0;
                        RTSPEnable = 0;
                        HTTPSEnable = 1;
                        SOCKSEnable = 0;
                        HTTPPort = 1082;
                        FTPPassive = 1
                }
        };
        ProxyAutoDiscoveryEnable = 0;
        ExcludeSimpleHostnames = 1;
        HTTPProxy = "127.0.0.1";
        GopherEnable = 0;
        RTSPEnable = 0;
        HTTPSEnable = 1;
        SOCKSEnable = 0;
        HTTPPort = 1082;
        FTPPassive = 1
}
HTTPEnable: 1
HTTPSProxy: 127.0.0.1
ProxyAutoConfigEnable: 0
HTTPSPort: 1082
FTPEnable: 0
ExceptionsList: <__NSCFArray 0x2827db400> [
        "192.168.43.1.dns",
        "captive.apple.com",
        "localhost",
        "10.0.0.0/8",
        "*.local",
        "172.16.0.0/12",
        "240e:47c:4ec0:6b78::26.dns",
        "198.18.0.0/15",
        "192.168.0.0/16"
]
__SCOPED__: <__NSDictionaryM 0x280986900> {
        en0 = {
                ExceptionsList = [
                        "*.local",
                        "169.254/16"
                ];
                FTPPassive = 1
        };
        utun4 = {
                HTTPEnable = 1;
                HTTPSProxy = "127.0.0.1";
                ProxyAutoConfigEnable = 0;
                HTTPSPort = 1082;
                FTPEnable = 0;
                ExceptionsList = [
                        "192.168.43.1.dns",
                        "captive.apple.com",
                        "localhost",
                        "10.0.0.0/8",
                        "*.local",
                        "172.16.0.0/12",
                        "240e:47c:4ec0:6b78::26.dns",
                        "198.18.0.0/15",
                        "192.168.0.0/16"
                ];
                ProxyAutoDiscoveryEnable = 0;
                ExcludeSimpleHostnames = 1;
                HTTPProxy = "127.0.0.1";
                GopherEnable = 0;
                RTSPEnable = 0;
                HTTPSEnable = 1;
                SOCKSEnable = 0;
                HTTPPort = 1082;
                FTPPassive = 1
        }
}
ProxyAutoDiscoveryEnable: 0
ExcludeSimpleHostnames: 1
HTTPProxy: 127.0.0.1
GopherEnable: 0
RTSPEnable: 0
HTTPSEnable: 1
SOCKSEnable: 0
HTTPPort: 1082
FTPPassive: 1

它返回一个 CFDictionaryRef 类型的对象,这个对象包含了各种代理设置,例如 HTTP、HTTPS 代理的地址和端口,以及是否启用代理的标志。这些设置通常由用户在 iOS 的“设置”中配置,或者由企业环境中的网络管理策略自动指定。深入研究这个函数的返回值,我发现可以通过修改这些代理配置来影响应用程序的网络行为。具体来说,如果应用程序使用 CFNetworkCopySystemProxySettings 来检测代理设置并对此作出反应(例如显示警告或限制某些功能),那么可以通过Frida动态修改这个函数的返回值,来绕过这种代理检测机制。

使用Frida拦截 CFNetworkCopySystemProxySettings 函数,并在它返回之前修改其返回值,并且已经证明是有效的可以欺骗应用程序,使其认为系统没有使用任何代理。这种方法的关键在于构造一个与原始返回值结构相同,使内容经过修改的新字典对象。

例如,可以将代理相关的字段(如 HTTPEnableHTTPProxy)设置为表示代理未启用的值,或者完全移除这些字段。通过这种技术,我成功地绕过了应用程序的代理检测,从而无缝使用代理进行网络连接,而不触发应用程序的任何警告或限制。

var CFNetworkCopySystemProxySettings = Module.findExportByName("CFNetwork", "CFNetworkCopySystemProxySettings");

if (CFNetworkCopySystemProxySettings) {
    Interceptor.attach(CFNetworkCopySystemProxySettings, {
        onLeave: function (retval) {
            if (!retval.isNull()) {
                var proxySettings = new ObjC.Object(retval).mutableCopy();

                // 设置为关闭代理
                proxySettings.setObject_forKey_(0, 'HTTPEnable');
                proxySettings.setObject_forKey_(0, 'HTTPSEnable');
                proxySettings.setObject_forKey_(0, 'FTPEnable');
                proxySettings.setObject_forKey_(0, 'SOCKSEnable');

                // 清除代理服务器地址和端口
                proxySettings.removeObjectForKey_('HTTPProxy');
                proxySettings.removeObjectForKey_('HTTPSProxy');
                proxySettings.removeObjectForKey_('HTTPPort');
                proxySettings.removeObjectForKey_('HTTPSPort');

                // 清除其它相关设置
                proxySettings.removeObjectForKey_('ExceptionsList');
                proxySettings.removeObjectForKey_('__SCOPED__');

                // 替换原始的返回值
                retval.replace(proxySettings.handle);
            }
        }
    });
} else {
    console.log("CFNetworkCopySystemProxySettings没有找到!");
}

然后发现App加密很麻烦,反手放弃

image-20231115115141601

本文链接:

https://www.linqi.net.cn/index.php/archives/513/