阅读时长:约10分钟
附件/链接:点击查看原文下载
本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载
❝
先开启 tcpdump 抓包,接着使用 frida hook TLS 的 pre_master_secret,最后保存抓取的数据并在 wireshark 中完成数据解密。适用于遇到APP无法进行常规抓包的场景下,获取https明文数据。
❞
SSL/TLS 握手过程
-
Clienthello:发送客户端的功能和首选项给服务器,在连接建立后,当希望重协商、或者响应服务器的重协商请求时会发送。 -
version:客户端支持的最佳协议版本 -
Random:共32字节,28字节随机数,4字节额外信息,受客户端时钟影响(为了避免浏览器指纹采集,现在一般会对4字节时钟做扭曲) -
Session ID:32字节随机数,用于和服务器重建会话,为空表示新建会话 -
cipher suit:客户端支持的所有密码套件,按优先级排列 -
Compression:客户端支持的压缩算法,默认无压缩 -
Extensions:由任意数量的扩展组成,携带额外数据
-
-
ServerHello: -
选择客户端提供的参数反馈客户端 -
服务器无需支持客户端支持的最佳版本,如果服务器不支持客户端版本,可以提供其他版本以期待客户端可以接受
-
-
Certificate: -
用于携带服务器X.509证书链 -
主证书必须第一个发送,中间证书按照正确的顺序跟在主证书之后 -
服务器必须保证发送的证书和选择的算法套件一致 -
Certificate消息时可选的
-
-
ServerKeyExchange: 携带密钥交换的额外数据,取决于加密套件 -
ServerHelloDone:服务器已将所有预计的握手消息发送完毕 -
ClientkeyExchange:携带客户端为密钥交换提供的信息 -
ChangeCipherSpec:发送端已取得用以连接参数的足够的信息 -
Finish:握手完成,消息内容加密,双方可以交换验证,整个握手完整性所需的数据 -
算法:verrify_data = PRF(master_secret , finished_label,hash(handshake_message))
-
要解密HTTPS流量,需要得到加密密钥,加密密钥由主密钥、客户端随机数、服务器随机数生成。由上述握手过程可知,客户端随机数和服务器随机数在双方握手消息中传递,而主密钥(master_secret)则由预主密钥(pre_master_secret)结合两个随机数生成。预主密钥通过密码套件中的密钥交换算法进行交换(DH、RSA)。
tcpdump 抓包
确保 mac 中已安装好 xcode 命令行工具:
xcode-select --install
连接 iOS 设备,并获取它的 UDID :
system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p;/iPhone/,/Serial/p;/iPod/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}'
启动远程虚拟接口:
rvictl -s "获取的UDID"
使用 tcpdump 捕获流量:
tcpdump -i rvi0 -w capture.pcap -P
Frida Hook 提取 TLS 密钥
BoringSSL 默认有支持使用日志行调用回调的函数:在ios中与日志回调有关的函数是:
SSL_CTX_set_info_callback
, 它传递包含指向日志记录回调函数的指针的结构的地址:
void SSL_CTX_set_info_callback( SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) {
ctx->info_callback = cb;
}
可以通过 frida-trace 动态调试观察 SSL_CTX_set_info_callback
函数的调用:
frida-trace -U com.apple.WebKit.Networking -I 'libboringssl.dylib'
大概思路就是拦截
SSL_CTX_set_info_callback
函数,然后自定义一个日志记录回调函数,写入到 SSL 结构中的相应位置。写入地址对应的偏移量可以在 libboringssl.dylib -> ssl_log_secret
中找到:
0000000199381680 int64_t bssl::ssl_log_secret(void* arg1, int64_t arg2, char* arg3, int64_t arg4)
0000000199381680 sub sp, sp, #0x60
0000000199381684 stp x22, x21, [sp, #0x30]
0000000199381688 stp x20, x19, [sp, #0x40]
000000019938168c stp x29, x30, [sp, #0x50]
0000000199381690 add x29, sp, #0x50
0000000199381694 ldr x8, [x0, #0x78]
0000000199381698 ldr x8, [x8, #0x2f8]
000000019938169c cbz x8, 0x1993817a4
frida hook 脚本:ios-tls-keylogger.js
/* https://github.com/jankais3r/Frida-iOS-15-TLS-Keylogger/blob/main/ios-tls-keylogger.js */*
var CALLBACK_OFFSET = 0x2f8;
function key_logger(ssl, line) {
console.log(new NativePointer(line).readCString());
}
var key_log_callback = new NativeCallback(key_logger, 'void', ['pointer', 'pointer']);
var SSL_CTX_set_info_callback = Module.findExportByName('libboringssl.dylib', 'SSL_CTX_set_info_callback');
Interceptor.attach(SSL_CTX_set_info_callback, {
onEnter: function(args) {
var ssl = new NativePointer(args[0]);
var callback = new NativePointer(ssl).add(CALLBACK_OFFSET);
callback.writePointer(key_log_callback);
}
});
指定需要抓包的 APP 注入脚本,并保存密钥结果:
frida -UF -l ios-tls-keylogger.js -o keylogfile.log
假设获取到 keylogfile.log 的内容如下:
wireshark 解密 TLS 流量
使用 wireshark 打开 capture.pcap
文件:
open capture.pcap
接着找到 TLS 协议的位置,指定 keylogfile.log 的路径:完成后就可以看到解密后的 https 数据包内容了:
参考链接
使用 Frida 从 iOS 应用程序捕获和解密 HTTPS 流量 (andydavies.me)
Wireshark解密HTTPS流量的两种方法 - 豫让 - 博客园 (cnblogs.com)
那么它很快会成为你的习惯,学习亦是如此。
原文始发于微信公众号(WgpSec狼组安全团队):IOS安全 APP TLS 数据强制抓包与解包
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论