IOS中大多数情况,开发者都会使用OC提供的api函数,CFNetworkCopySystemProxySettings来进行代理检测;
CFNetworkCopySystemProxySettings
检测函数直接会检测这些ip和端口等:
采用直接附加页面进程:
frida -UF -l 通杀代理抓包.js
上通杀脚本:
var _imports = Process.findModuleByName("XXX").enumerateImports();var _CFNetworkCopySystemProxySettings = null;for (var i = 0; i < _imports.length; i++) { //查找CFNetworkCopySystemProxySettings系统代理函数 if (_imports[i].name.indexOf("CFNetworkCopySystemProxySettings") !== -1) { console.log(_imports[i].name, _imports[i].address); _CFNetworkCopySystemProxySettings = _imports[i].address; }}if (_CFNetworkCopySystemProxySettings) { Interceptor.attach(_CFNetworkCopySystemProxySettings, { onEnter: function (agrgs) { }, onLeave: function (retval) { console.log("retval: ", ObjC.Object(retval)); //将返回值全部nop retval.replace(0); } })}
NSURL URLWithString:
> frida-trace -U -f 包名 -m "+[NSURL URLWithString:]"
更改url得传入得参数,及堆栈打印,也叫url定位
{ onEnter(log, args, state) {console.log('CCCryptorCreate called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE) .map(DebugSymbol.fromAddress).join('\n') + '\n');log(`+[NSURL URLWithString:]` + ObjC.Object(args[2])); }, onLeave(log, retval, state) { }}
双向证书:
资源路径操作,可以入手关键函数;
> frida-trace -UF -m "-[NSBundle pathForResource*]"
{ onEnter(log, args, state) {console.log('NSBundle pathForResource called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE) .map(DebugSymbol.fromAddress).join('\n') + '\n'); log(`-[NSBundle pathForResource:${ObjC.Object(args[2])} ofType:${ObjC.Object(args[3])}]`); }, onLeave(log, retval, state) { }}
HOOK抓包
基于底层ssl库来实现:
//请求var ssl_write = Module.findExportByName("libboringssl.dylib", "SSL_write");console.log("ssl_write", ssl_write); //ssl input lenInterceptor.attach(ssl_write, { onEnter: function (args) { console.log("================================================="); console.log("CurrentThreadId: ", Process.getCurrentThreadId(), ", ssl_write onEnter args[1]: ", hexdump(args[1], {length: args[2].toInt32()})); }, onLeave: function (retval) { }});//返回响应var ssl_read = Module.findExportByName("libboringssl.dylib", "SSL_read");console.log("ssl_read", ssl_read); //ssl output lenInterceptor.attach(ssl_read, { onEnter: function (args) { this.args1 = args[1]; this.args2 = args[2]; }, onLeave: function (retval) { console.log("================================================="); console.log("CurrentThreadId: ", Process.getCurrentThreadId(), ", ssl_read onLeave args[1]: ", this.args1.readByteArray(this.args2.toInt32()) ); }});
r0Capture 肉师傅的安卓应用层抓包通杀脚本
这个在之前安卓也说过,ios和安卓都通用的;
详见:https://codeooo.blog.csdn.net/article/details/127123371
function initializeGlobals() { var resolver = new ApiResolver("module"); var exps = [ [Process.platform == "darwin" ? "*libboringssl*" : "*libssl*", ["SSL_read", "SSL_write", "SSL_get_fd", "SSL_get_session", "SSL_SESSION_get_id"]], // for ios and Android [Process.platform == "darwin" ? "*libsystem*" : "*libc*", ["getpeername", "getsockname", "ntohs", "ntohl"]] ];
源码里三目运算符,也说明了,ios用 libboringssl 动态库 , 安卓 libssl库;
同时还hook了,”SSL_read", “SSL_write” ,等等~
Interceptor.attach(addresses["SSL_read"], { onEnter: function (args) { var message = getPortsAndAddresses(SSL_get_fd(args[0]), true); message["ssl_session_id"] = getSslSessionId(args[0]); message["function"] = "SSL_read"; message["stack"] = SSLstackread; this.message = message; this.buf = args[1]; }, onLeave: function (retval) { retval |= 0; // Cast retval to 32-bit integer. if (retval <= 0) { return; } send(this.message, Memory.readByteArray(this.buf, retval)); } });Interceptor.attach(addresses["SSL_write"], { onEnter: function (args) { var message = getPortsAndAddresses(SSL_get_fd(args[0]), false); message["ssl_session_id"] = getSslSessionId(args[0]); message["function"] = "SSL_write"; message["stack"] = SSLstackwrite; send(message, Memory.readByteArray(args[1], parseInt(args[2]))); }, onLeave: function (retval) { } });
来源地址:https://blog.csdn.net/weixin_38927522/article/details/129129544