IOS_CFNetworkCopySystemProxySettings绕过
首先打开项目App,会出现越狱检测,这里使用flex
已经出现完成了
出现被拦截代理的问题,我这里使用的Shadowrocket
进行代理转发到Charles
使用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找不到');
}
但是在这边整半天,本来砸了壳想分析来着,奈何太久了,然后想到有个自带获取当前代理的函数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没有该函数!");
}
然后反手打印一下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没有找到哟!");
}
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
函数,并在它返回之前修改其返回值,并且已经证明是有效的可以欺骗应用程序,使其认为系统没有使用任何代理。这种方法的关键在于构造一个与原始返回值结构相同,使内容经过修改的新字典对象。
例如,可以将代理相关的字段(如 HTTPEnable
、HTTPProxy
)设置为表示代理未启用的值,或者完全移除这些字段。通过这种技术,我成功地绕过了应用程序的代理检测,从而无缝使用代理进行网络连接,而不触发应用程序的任何警告或限制。
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加密很麻烦,反手放弃