引言
在移动安全研究中,网络通信分析是理解应用行为的关键环节。对于iOS应用,虽然抓包工具(如Charles、Wireshark)可以捕获明文流量,但面对加密协议或非标准端口时,直接Hook应用层的TCP请求/响应能提供更底层的视角。本文将通过Frida工具,实现iOS应用中Objective-C层和Native层TCP通信的全面监控。
一、Frida简介
Frida是一款动态插桩工具,支持通过JavaScript脚本注入目标进程,实时修改内存数据或拦截函数调用。在iOS逆向中,Frida可用于:
-
Hook Objective-C方法
-
拦截C/C++函数
-
动态分析加密算法
-
监控文件、网络等系统调用
二、iOS网络通信机制
iOS应用通常通过以下方式处理TCP通信:
-
高级API:
-
NSURLConnection
/NSURLSession
(HTTP协议) -
CFStream
(Core Foundation层)
-
-
BSD Socket:
-
使用C函数如
socket
,connect
,send
,recv
-
-
第三方库:
-
CocoaAsyncSocket、SwiftSocket等开源封装
-
三、Hook实现步骤
1. Hook Objective-C层通信
对于使用NSURLSession
等高级API的应用,直接Hook相关类的方法:
// 监控NSURLSession的数据任务创建
ObjC.choose(ObjC.classes.NSURLSession, {
onMatch: function(session) {
var original = session.URLSession_dataTaskWithRequest_;
session.URLSession_dataTaskWithRequest_ = ObjC.implement(
session.URLSession_dataTaskWithRequest_,
function(handle, selector, session, request, completion) {
console.log(`[OC] Request URL: ${request.URL().absoluteString()}`);
console.log(`[OC] Headers: ${JSON.stringify(request.allHTTPHeaderFields())}`);
return original(handle, selector, session, request, completion);
}
);
}
});
// Hook NSURLSession的接收数据回调
var URLSessionDelegate = ObjC.protocols.NSURLSessionDataDelegate;
ObjC.classes.NSURLSession.implement_method(
URLSessionDelegate.methods[3], // didReceiveData: 方法索引可能变化
function(handle, selector, session, dataTask, data) {
var bytes = data.bytes().readByteArray(data.length());
console.log(`[OC] Response Data (${data.length()} bytes):\n${bytesToHex(bytes)}`);
}
);
2. Hook Native层BSD Socket
拦截底层C函数以捕获原始TCP数据:
// 拦截socket连接
Interceptor.attach(Module.findExportByName('libsystem_network.dylib', 'connect'), {
onEnter: function(args) {
this.fd = args[0];
var sockaddr = args[1];
var family = sockaddr.add(0).readU16();
if (family === 2) { // AF_INET
var port = sockaddr.add(2).readU16();
port = ((port & 0xFF00) >> 8) | ((port & 0xFF) << 8); // 转换端口字节序
var ip = sockaddr.add(4).readByteArray(4);
console.log(`[Native] connect -> ${ip[0]}.${ip[1]}.${ip[2]}.${ip[3]}:${port}`);
}
}
});
// 拦截send函数
Interceptor.attach(Module.findExportByName('libsystem_network.dylib', 'send'), {
onEnter: function(args) {
this.fd = args[0];
this.buf = args[1];
this.len = args[2].toInt32();
},
onLeave: function(retval) {
if (this.len > 0) {
var data = ptr(this.buf).readByteArray(this.len);
console.log(`[Native][send] fd=${this.fd}, len=${this.len}\n${bytesToHex(data)}`);
}
}
});
// 拦截recv函数
Interceptor.attach(Module.findExportByName('libsystem_network.dylib', 'recv'), {
onEnter: function(args) {
this.fd = args[0];
this.buf = args[1];
this.len = args[2].toInt32();
},
onLeave: function(retval) {
var bytesRead = retval.toInt32();
if (bytesRead > 0) {
var data = ptr(this.buf).readByteArray(bytesRead);
console.log(`[Native][recv] fd=${this.fd}, len=${bytesRead}\n${bytesToHex(data)}`);
}
}
});
3. 辅助工具函数
// 字节数组转HEX字符串
function bytesToHex(bytes) {
return Array.from(new Uint8Array(bytes), byte =>
byte.toString(16).padStart(2, '0')
).join(' ');
}
// 监听进程退出
Process.enumerateModules();
四、完整脚本使用
-
保存脚本:将代码保存为
ios_tcp_hook.js
-
注入进程:
frida -U -f com.example.app -l ios_tcp_hook.js --no-pause
-
触发网络请求:操作应用触发TCP通信
五、注意事项
-
环境要求:
-
越狱iOS设备
-
安装Frida服务(通过Cydia)
-
-
数据过滤:高频请求需添加过滤规则,避免日志爆炸
-
加密流量:若通信使用TLS,需额外Hook SSL库(如SecureTransport)
-
多线程处理:网络请求可能在子线程执行,注意线程安全
六、扩展思路
-
协议解析:将HEX数据解析为HTTP、Protobuf等格式
-
流量重放:修改数据包内容后重新发送
-
自动化分析:结合Python脚本批量处理日志
-
非越狱方案:通过Frida Gadget注入未签名应用
结语
通过Frida Hook TCP通信,开发者可以深入理解iOS应用的网络行为,快速定位协议漏洞或分析加密逻辑。本文提供的方法覆盖了从高级API到底层Socket的全链路监控,读者可根据实际需求调整Hook点,进一步提升逆向工程效率。
“知识是武器,请合法使用技术。”
附录