百趣云 百趣云的博客

iOS 抓包进阶:SSL Kill Switch 2 与证书绑定绕过

iOS 抓包的三层障碍

iOS 上抓 HTTPS 比 Android 更折腾,障碍分三层:

  1. 系统层:iOS 默认信任用户安装的 CA(描述文件装证书后还要在"设置→通用→关于→证书信任设置"里手动开完全信任——这一步 90% 的新手会漏)
  2. ATS(App Transport Security):苹果强制的安全策略,但只卡"系统 CA 不信任"的场景,装了证书就过
  3. SSL Pinning:App 代码里写死证书/公钥校验,系统信任链完全被绕过——这是真正的城墙

SSL Kill Switch 2:一键绕过 Pinning

SSL Kill Switch 2 是 iOS 上绕过证书绑定的标准工具,原理是 hook Secure Transport 和 NSURLSession 的证书校验函数,让它们永远返回"验证通过":

# 越狱设备上安装(Cydia/Sileo 加源 https://julioverne.github.io/)
# 或手动装 deb
dpkg -i com.nablac0d3.sslkillswitch2_0.14.deb
killall -HUP SpringBoard   # 重启 SpringBoard 生效

然后在"设置"里找到 SSL Kill Switch 2 开关打开。之后 Charles/mitmproxy 就能抓到做了 Pinning 的 App 流量。

原理:它 hook 了什么

理解原理才能应对它失效的场景。SSL Kill Switch 2 主要 hook 三个点:

// 1. Secure Transport 层(C API)
SSLHandshake() → 强制返回成功
SSLSetSessionOption() → 禁用校验选项

// 2. NSURLSession 的代理回调
-[NSURLSessionDelegate URLSession:didReceiveChallenge:completionHandler:]
    → 直接调 completionHandler(UseCredential, serverTrust)

// 3. NSURLConnection 的老 API

覆盖的是基于系统网络栈的 Pinning——这也是它失效场景的边界。

精髓一:Kill Switch 失效的三种情况

  1. App 用自研网络库/内嵌 BoringSSL:金融类 App 常见,网络层不走 Secure Transport,Pinning 校验在自己代码里。对策:Frida 单独分析其校验函数并 patch
  2. App 检测 hook 本身:检查关键函数是否被 inline hook(读函数开头字节验证)。对策:换更底层的 hook 点或用 Stalker 级 hook
  3. iOS 版本兼容:Kill Switch 2 停更较早,新 iOS 上部分 hook 点偏移变了。对策:用 Frida 脚本自己实现等价逻辑(社区有 ssl-kill-switch2 的 Frida 移植版)

精髓二:Frida 手写绕过(可控性更强)

// ios-pinning-bypass.js 核心逻辑
if (ObjC.available) {
    // hook NSURLSession 的 challenge 回调
    var NSURLSessionConfiguration = ObjC.classes.NSURLSessionConfiguration;
    // ... 标准绕过代码

    // hook SecTrustEvaluate(C 层)
    var SecTrustEvaluate = Module.findExportByName('Security', 'SecTrustEvaluate');
    if (SecTrustEvaluate) {
        Interceptor.replace(SecTrustEvaluate, new NativeCallback(function(trust, result) {
            // result 是 out 参数,写入 kSecTrustResultProceed(1)
            Memory.writeU32(result, 1);
            return 0;  // errSecSuccess
        }, 'int', ['pointer', 'pointer']));
    }

    // iOS 13+ 的 SecTrustEvaluateWithError
    var SecTrustEvalErr = Module.findExportByName('Security', 'SecTrustEvaluateWithError');
    if (SecTrustEvalErr) {
        Interceptor.replace(SecTrustEvalErr, new NativeCallback(function(trust, error) {
            return 1;  // true = 信任
        }, 'bool', ['pointer', 'pointer']));
    }
}

手写脚本的好处是可以按 App 定制——只绕过目标 App 的校验,不影响系统其他部分,被检测的风险也更低。

精髓三:抓不到的最后手段

所有绕过都失败时的终极方案,和 Android 殊途同归——hook 加密端点拿明文

  • iOS 的 SSL_read/SSL_write(如果 App 用 OpenSSL/BoringSSL)
  • 或 hook 应用层的加密前/解密后函数(-[NSData writeToURL:]、网络库的 send 方法)

iOS 上 Frida hook OC 方法极其方便(ObjC.classes 直接枚举),应用层拦截往往比对抗 Pinning 更省力。

总结

  1. iOS 抓包三层障碍:证书信任设置、ATS、SSL Pinning
  2. SSL Kill Switch 2 一键绕过系统网络栈的 Pinning
  3. 自研网络库/内嵌 BoringSSL 要单独分析 patch
  4. 终极方案是 hook 加密端点拿明文,iOS 的 OC hook 极其方便

交流微信:run1255

By 百趣云 阅读量:2 On