移动/游戏
移动 App 启用 SSL Pinning…
当需要拦截 Android/iOS 应用(含 Flutter、React Native、Xamarin)的 HTTPS 流量但应用启用了证书/公钥/SPKI 固定时,按平台与框架选择对应绕过手段。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
移动 App 启用 SSL Pinnin通用
解决思路
- 先识别 pinning 类型:证书固定(固定叶子证书 DER/PEM,证书轮换即失效,多见于旧应用)、公钥固定(固定 SPKI,证书续期但密钥不变仍有效)、SPKI 哈希固定(SPKI 的 SHA-256,常见于 OkHttp、AFNetworking)、CA 固定(固定中间或根 CA,韧性高,多见于企业应用)、多 pin(主 pin + 备用 pin,韧性高)。
- 理解 pinning 原理:TLS 握手时服务端下发证书链,先做系统信任库的标准校验,再由应用层提取服务端证书/公钥/SPKI 哈希与内置 pin 比对,匹配则放行,否则拒绝连接。
- Android 首选 Frida 通用绕过脚本:用 Java.perform 依次 hook TrustManagerImpl.verifyChain(返回原始 chain)、SSLContext.init(注入自定义 X509TrustManager,checkClientTrusted/checkServerTrusted 空实现、getAcceptedIssuers 返回空数组)、OkHttp3 CertificatePinner.check 及其 check$okhttp 变体(OkHttp 4.x)、OkHttpClient$Builder.certificatePinner(返回 this 不带 pinner)、Volley HurlStack.createConnection(设置默认 HostnameVerifier)、Conscrypt 的 ConscryptFileDescriptorSocket.verifyCertificateChain、Apache HttpClient 的 AbstractVerifier.verify、HttpsURLConnection.setDefaultHostnameVerifier(忽略自定义校验器);每个 hook 用 try/catch 包裹以防类不存在。
- Android 可用 Objection 一条命令:objection -g com.target.app explore --startup-command "android sslpinning disable"。
- Android 无 root 且为 debug 包时,用 Network Security Config 覆盖:在 AndroidManifest.xml 引用 android:networkSecurityConfig="@xml/network_security_config",在 res/xml/network_security_config.xml 的 base-config/trust-anchors 中加入 <certificates src="system"/> 与 <certificates src="user"/> 以信任用户安装的 CA;流程为 apktool d target.apk -o target_dir → 修改配置与 Manifest → apktool b target_dir -o target_patched.apk → zipalign -v 4 → apksigner sign --ks my-key.keystore → adb install。
- Android 有 root 时用 Xposed/LSPosed 模块:JustTrustMe(hook TrustManager + OkHttp,按应用生效)、SSLUnpinning(hook 证书校验,按应用生效)、TrustMeAlready(全局 TrustManager 绕过,系统级生效)。
- Android 7+ 需将代理 CA 装为系统证书:用 MagiskTrustUserCerts 模块把用户 CA 移到 /system/etc/security/cacerts/,或手动 adb push burp_ca.pem /sdcard/ → su → mount -o remount,rw /system → cp 到 /system/etc/security/cacerts/9a5ba575.0 → chmod 644 → mount -o remount,ro /system;文件名哈希用 openssl x509 -inform PEM -subject_hash_old -in burp_ca.pem | head -1 获取。
- Android 无 root 且为 release 包时手动反编译改包:jadx -d decompiled/ target.apk 反编译,grep -r "CertificatePinner\|X509TrustManager\|checkServerTrusted\|ssl" 定位 pinning 代码;用 apktool d 反编译后用 smali 编辑,把 invoke-virtual {checkServerTrusted} 替换为 return-void 以 NOP 掉校验;再 apktool b 重打包、apksigner sign --ks debug.keystore 签名。
- iOS 首选 Frida hook Security 框架:Interceptor.attach SecTrustEvaluateWithError 在 onLeave 把返回值替换为 ptr(1),SecTrustEvaluate 替换为 ptr(0),SSLHandshake 在返回 -9807(errSSLXCertChainInvalid)时替换为 ptr(0);并用 ObjC.enumerateLoadedClasses 遍历查找实现了 URLSession:didReceiveChallenge:completionHandler: 的 delegate 类。
- iOS 可用 Objection 一条命令:objection -g com.target.app explore --startup-command "ios sslpinning disable"。
- iOS 越狱设备可装 SSL Kill Switch 2(com.nablac0d3.sslkillswitch2),通过 Cydia/Sileo 安装后在设置中按应用或全局关闭 pinning,其 hook 点包括 SecTrustEvaluate、SSLHandshake、SSLSetSessionOption、tls_helper_create_peer_trust。
- iOS 针对具体库 hook:AFNetworking 让 AFSecurityPolicy.evaluateServerTrust:forDomain: 返回 YES;Alamofire 跳过 ServerTrustManager.evaluate(_:forHost:);TrustKit 让 TSKPinningValidator verifyPublicKeyPin: 返回成功;NSURLSession 在 URLSession:didReceiveChallenge:completionHandler: 中以 .useCredential 调用 completionHandler。
- iOS 无越狱时手动改二进制:strings decrypted_binary | grep -i "pin\|cert\|trust" 定位校验函数,反汇编后把比较/跳转指令替换为 NOP 或无条件通过;或用 LLDB 运行时修改:lldb -n TargetApp → breakpoint set -n "SecTrustEvaluateWithError" → breakpoint command add 1 → thread return 1 → continue。
- Flutter 应用需绕过 Dart 层:其使用 dart:io + BoringSSL,Java/ObjC 层 hook 无效;用 Process.findModuleByName('libflutter.so')(Android)或 'Flutter'(iOS)定位模块,用 Memory.scan 按版本相关的特征码扫描 ssl_verify_peer_cert / ssl_crypto_x509_session_verify_cert_chain 并在 onLeave 把返回值替换为 ptr(0)(SSL_VERIFY_OK);推荐直接用 reflutter:pip install reflutter → reflutter target.apk,自动 patch Flutter 引擎中的 BoringSSL 并把流量重定向到代理。
- React Native 应用沿用平台网络栈:Android 走 OkHttp3(hook okhttp3.CertificatePinner.check,找不到时尝试 com.squareup.okhttp.CertificatePinner),iOS 走 NSURLSession(用标准 SecTrust hook);Hermes 引擎下 hook 相同但可能需额外处理 JIT。
- Xamarin 应用:pinning 通常经 ServicePointManager.ServerCertificateValidationCallback 或自定义 HttpClientHandler;可 hook Mono 运行时(如 libmonosgen-2.0.so 的 mono_runtime_invoke)或在 CIL 层 hook 托管回调,最实用的是用 Objection 的内置 Xamarin 支持执行 android sslpinning disable。
- 注意 CT/HPKP 影响:Certificate Transparency 移动端极少强制(仅 Google 系应用有自定义 CT 检查),HPKP 已于 2018 废弃但旧应用可能仍检查(需从代理响应中移除该头),Expect-CT 已于 2024 废弃,对移动测试影响极小。
- 排障常见失败与修复:脚本已加载但流量仍失败 → 存在多层 pinning,需同时 hook TrustManager + OkHttp + 自定义校验;提示 "Client certificate required" → 是 mTLS,需从应用包/钥匙串提取客户端证书导入代理;连接成功但无 HTTP 流量 → 非 HTTP 协议(MQTT、gRPC、WebSocket),改用 Wireshark 或协议专用代理;应用崩溃 → 反篡改检测到 hook,先绕过完整性校验再处理 SSL;代理 CA 不受信 → Android 7+ 用户 CA 限制,需装为系统证书;Flutter 忽略 hook → 未在 native 层 hook BoringSSL,用 reflutter;证书链校验超时 → OCSP stapling 不匹配,禁用 OCSP 或伪造 OCSP 响应。
- 诊断命令:adb shell "ls /system/etc/security/cacerts/ | grep $(openssl x509 -subject_hash_old -in ca.pem | head -1)" 验证 CA 安装;iOS 在设置→通用→关于本机→证书信任设置中确认;用 Wireshark 过滤 tcp.port == 443 and ip.addr == <device_ip> 确认是否走 SSL;frida-ps -U | grep target 确认 hook 到正确进程;frida -U -f com.target.app -l bypass.js --debug 输出详细日志。
- 按决策树选择路径:Android 有 root 先试 Frida 通用绕过,失败加 Conscrypt + Volley hook,再失败用 LSPosed + TrustMeAlready,仍失败把 CA 装为系统证书;Android 无 root 时 debug 包用 Network Security Config,release 包反编译改包重签。iOS 越狱先试 Objection ios sslpinning disable,失败用 Frida SecTrust hook,再失败用 SSL Kill Switch 2,仍失败做库级 hook;iOS 无越狱则重签注入 Frida gadget 或二进制 patch 后侧载。框架特定:Flutter 用 reflutter 或 BoringSSL native hook,React Native 用平台标准 hook,Xamarin 用 Objection 或 Mono 运行时 hook。全部失败时改用网络层分析(Wireshark/tcpdump)、检查自定义私有协议,或考虑 iptables + 透明代理。
- 代理配置:Android 用 adb shell settings put global http_proxy <host_ip>:8080 设置、adb shell settings put global http_proxy :0 移除;iOS 在设置→Wi-Fi→配置代理→手动。工具选择:Burp Suite 做完整 HTTP 分析(导入 CA 到设备)、mitmproxy 做脚本化拦截(mitmproxy --set confdir=~/.mitmproxy)、Charles Proxy 适合 macOS 原生易用、Proxyman 适合 macOS/iOS 原生直连设备、HTTP Toolkit 适合快速 Android 配置(自动装 CA + Frida 绕过)。
适用边界 · 注意事项
- 目标应用使用非 HTTP 协议(MQTT、gRPC、WebSocket)时,SSL pinning 绕过无效,应改用 Wireshark 或协议专用代理。
- 应用启用了反篡改/完整性校验时,直接注入 Frida 或改包会导致崩溃,需先绕过完整性检测。
- 应用要求 mTLS 客户端证书时,仅绕过 pinning 无法建立连接,还需从应用包或钥匙串提取客户端证书并导入代理。