当前位置: 首页 > news >正文

安卓高版本APP抓包失败原因与BurpSuite+雷电模拟器9实战绕过指南

1. 为什么高版本安卓APP抓包变得像拆弹——从Android 7到12的证书信任机制演进

你有没有试过把BurpSuite的CA证书拖进雷电模拟器9里,双击安装,弹出“已安装但无法启用”的提示?或者App一启动就报“网络连接异常”,连登录页都打不开?这不是你的Burp配置错了,也不是雷电模拟器坏了——这是Android系统在2016年埋下的一颗逻辑炸弹,到2023年才全面引爆。

核心关键词:BurpSuite、雷电模拟器9、安卓高版本APP、抓包、证书安装、SSL Pinning、network_security_config、用户证书信任域

这件事的本质,是Android从7.0(Nougat)开始推行的应用级网络安全性强制隔离策略。在此之前,只要把Burp的CA证书放进系统证书存储区(/system/etc/security/cacerts/),所有App都会无条件信任它;但从Android 7起,系统默认只信任系统预置证书,而将用户手动安装的证书(包括Burp导出的der/crt文件)划入“不可信区域”——哪怕你用root权限把它cp进去,App层也会在TLS握手阶段主动拒绝验证通过。

更关键的是,从Android 9(Pie)起,系统引入了StrictMode对Cleartext Traffic的硬性拦截,默认禁止HTTP明文请求;而从Android 10(Q)开始,默认启用TLS 1.2+强制协商,且多数厂商ROM(包括雷电9基于Android 11定制的内核)会主动屏蔽TLS 1.0/1.1握手尝试;到了Android 12(S),Google进一步收紧了用户证书在WebView和OkHttp栈中的可见性窗口——即使你绕过了系统层限制,App内部使用的OkHttp 4.x+或Retrofit 2.9+仍会调用CertificatePinner做二次校验。

我去年帮一个金融类App做兼容性测试时,在雷电9(Android 11)上反复失败。最初以为是Burp代理设置问题,折腾了三天重装JDK、换Java版本、重配监听端口……最后发现,真正卡住的不是代理链路,而是App的res/xml/network_security_config.xml里写了这么一行:

<domain-config> <domain includeSubdomains="true">api.bankapp.com</domain> <pin-set> <pin digest="SHA-256">YV2sLqZvz8jKXfGtBnHmPqRwSxTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGmHnIoJpKqLrMsNtOuPvQwRxSyTzUaVbWcXdYeZfAgBhCiDjEkFlGm......</pin> </pin-set> </domain-config>

这串SHA-256 pin值,是App开发者把他们线上服务器的公钥指纹硬编码进APK里的。Burp生成的中间人证书,哪怕CA根证书已安装,其公钥指纹也完全不匹配——OkHttp在CertificatePinner.check()方法里直接抛出SSLPeerUnverifiedException,App进程立刻崩溃或静默失败。

所以,“用BurpSuite+雷电模拟器9抓包安卓高版本APP”这件事,早已不是“打开代理→安装证书→开刷”三步走的简单流程。它是一场横跨系统层、应用层、网络协议栈、证书信任链、反调试机制五重关卡的协同突破。而所谓“保姆级”,不是手把手教你点哪里,而是让你真正理解:每一处报错背后,是哪一层机制在拦截;每一次成功,是绕过了哪个设计者的防御逻辑。

接下来的内容,我会以雷电模拟器9(Android 11)为基准环境,从Burp配置、证书生成、系统级注入、App级绕过、实测验证五个维度,逐层拆解这套组合拳。所有操作均基于真实项目复现,参数、路径、命令全部可直接复制粘贴,且每一步都附带“为什么必须这样”的底层原理说明——因为只有懂了机制,你才能在下次遇到Android 13或自研ROM时,自己推导出新解法。

2. BurpSuite端的精准配置:不是监听所有流量,而是只捕获目标App的TLS握手

很多人第一步就栽在Burp的代理监听设置上。他们习惯性地在Proxy → Options里把“Bind to port”设成8080,勾选“Support invisible proxying”,然后在雷电模拟器Wi-Fi设置里填上本机IP:8080——结果发现,浏览器能抓到,但目标App的请求一条都不见。这不是App没发请求,而是它压根没走你设的代理端口。

2.1 关键认知:高版本安卓App默认不走系统代理

从Android 9开始,系统对WebView和原生网络请求做了代理策略分离:

  • WebView组件(如H5页面、内嵌浏览器)会读取系统Wi-Fi代理设置,并走Burp监听端口;
  • 但绝大多数商业App(尤其是金融、电商、社交类)使用OkHttp/Retrofit等独立网络库,它们默认忽略系统代理配置,而是通过代码显式指定OkHttpClient.Builder().proxy(Proxy.NO_PROXY)或直接调用System.setProperty("http.proxyHost", ...)——这意味着,即使你在雷电模拟器里设置了代理,App的HTTP Client仍直连服务器,完全绕过Burp。

因此,Burp的第一步配置,不是“让它能监听”,而是“让它只监听该监听的流量”,避免被无关请求干扰判断。我建议采用以下三重过滤策略:

第一重:绑定到特定网卡,而非0.0.0.0

在Burp Suite → Proxy → Options → Proxy Listeners → Edit → Binding中:

  • 取消勾选 “All interfaces”
  • 勾选 “Specific address” 并填入你本机连接雷电模拟器的网卡IP(通常是127.0.0.1或192.168.x.x,绝不是0.0.0.0)

提示:雷电模拟器9默认使用NAT模式,其虚拟网卡与宿主机通信走的是127.0.0.1:5555端口映射。如果你用的是桥接模式,则需查宿主机对应网段(如ipconfigifconfig查看vEthernet (LeiDian)适配器的IPv4地址)。绑定到0.0.0.0会导致Burp同时监听本地回环、局域网、甚至公网端口,极易被安全软件误报为恶意服务。

第二重:启用Invisible Proxying并精确匹配Host

在Proxy Listeners → Edit → Request Handling中:

  • 勾选 “Support invisible proxying (enable only if needed)”
  • 在下方“Redirect to host”栏填入目标App的主域名(如api.xxx.com
  • 务必勾选 “Use listener’s port in redirection responses”

这个设置的原理是:当App发起HTTPS请求时,Burp会先收到一个CONNECT请求(如CONNECT api.xxx.com:443 HTTP/1.1),然后Burp主动向该域名建立TLS隧道。启用Invisible Proxying后,Burp会将原始请求头中的Host: api.xxx.com保留,并在响应中重写Location头,确保重定向不暴露Burp自身端口。这对防止App检测到“非标准端口代理”至关重要。

第三重:关闭无关插件,启用TLS握手日志

在Extender → Extensions中:

  • 禁用所有非必要插件(特别是Logger++Autorize等可能干扰TLS握手的扩展)
  • 安装并启用TLS Logger(官方插件,无需额外下载)

注意:TLS Logger不是用来“看加密内容”的(那需要解密密钥),而是记录完整的Client Hello / Server Hello交互过程。当你发现App连接失败时,打开TLS Logger的Log标签页,你能看到:

  • Client Hello中声明支持的TLS版本(是否含TLS 1.0?)
  • 提供的Cipher Suites列表(是否含TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256?)
  • SNI字段值(是否与目标域名一致?)

这些信息比抓不到包本身更有诊断价值。比如某次我看到Client Hello里SNI是api.xxx.com,但Server Hello返回的证书Subject是*.cdn.yyy.net——立刻判断出App用了CDN中转,需在Burp里手动添加CDN域名到Target Scope。

2.2 Burp证书导出:必须用DER格式,且文件名不能含空格或特殊字符

Burp的CA证书导出位置在:Proxy → Options → Import / export CA certificate → Export → Certificate in DER format。

这里有两个致命细节,90%的人会踩坑:

  1. 必须选DER格式,不能选PEM或CER
    雷电模拟器9(基于Android 11)的证书安装器对文件头校验极严。PEM格式以-----BEGIN CERTIFICATE-----开头,Android系统证书管理器会将其识别为“文本文件”而非“证书文件”,导致双击无反应;而DER是二进制格式,系统能正确解析ASN.1结构。

  2. 导出文件名必须是纯英文+数字,且长度≤12字符,后缀为.cer
    我实测过:burp_ca_cert.crt→ 安装失败;burp.der→ 安装失败;burpca.cer→ 成功;b1.cer→ 成功。原因在于Android证书安装器底层调用PackageManager.installPackage()时,会对文件名做正则过滤:^[a-zA-Z0-9_\\-\\.]{1,12}\\.cer$。含中文、空格、下划线过多、超长,都会触发INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME异常。

导出后,我习惯用命令行快速校验DER有效性(Windows PowerShell):

# 检查是否为合法DER证书(输出应为"Certificate") openssl x509 -in burpca.cer -inform DER -text -noout # 检查证书有效期(确认未过期) openssl x509 -in burpca.cer -inform DER -dates -noout

如果openssl报错“unable to load certificate”,说明导出格式错误,需重新导出。

2.3 Burp TLS解密配置:强制降级到TLS 1.2,禁用不安全套件

高版本App常因TLS协商失败而静默断连。根本原因是:Burp默认启用TLS 1.0/1.1兼容模式,而Android 11+系统内核会主动拒绝这些老旧协议;同时,某些App(如银行类)要求服务端必须提供ECDSA签名证书,而Burp自签证书默认用RSA。

解决方案是在Burp → Proxy → Options → SSL Pass Through中:

  • 添加目标域名规则*api.xxx.com(注意星号通配)
  • 在Proxy → Options → SSL tab中,点击“SSL negotiation settings”
    • 勾选 “Use specific TLS versions” → 仅勾选TLSv1.2
    • 取消勾选所有含SSLv3TLSv1.0TLSv1.1的选项
    • 在“Cipher suites”区域,手动删除所有含NULLEXPORTRC4DES的套件,仅保留:
      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

这个配置的底层逻辑是:Android 11的BoringSSL实现中,SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)是硬编码的最低版本,任何低于此的Client Hello都会被内核直接丢弃;而RC4等弱套件在Android安全白皮书中被明确定义为“禁止使用”,App层会主动终止握手。

我曾用Wireshark抓包对比过:未配置前,Client Hello发出后无Server Hello返回;配置后,Server Hello正常抵达,且Cipher Suite字段明确匹配TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256——这才是TLS握手成功的铁证。

3. 雷电模拟器9的系统级证书注入:root权限不是万能钥匙,而是解锁工具箱的钥匙

很多教程说“给雷电9 root,然后把证书cp到/system/etc/security/cacerts/”,听起来很美,但实际执行时你会发现:cp: cannot create '/system/etc/security/cacerts/xxx.0': Read-only file system。这是因为从Android 8.0起,/system分区默认挂载为ro(read-only),即使root了,也得先remount才能写。

但更深层的问题是:把证书放进/system/etc/security/cacerts/只是完成了系统层信任,App层仍可能拒绝使用它。原因有二:一是Android 7+引入了user-added CA certificates are not trusted by default for apps targeting API level 24+的策略;二是雷电9的定制ROM对/system分区做了额外保护(如dm-verity校验),强行写入可能导致启动失败。

所以,真正的“系统级注入”,不是暴力覆盖,而是遵循Android的证书信任链规范,分三步走:获取root → 解除/system只读限制 → 按标准命名规则注入证书。

3.1 雷电9 root权限获取与验证

雷电模拟器9自带root功能,但默认关闭。开启路径:
设置 → 更多设置 → 开发者选项 → Root权限 → 开启

开启后,需验证root是否生效:

  1. 在雷电9桌面打开“终端模拟器”(如未安装,从应用商店搜索“Termux”安装)
  2. 输入命令:
    su # 若提示“允许”并出现#号,说明root成功 mount | grep system # 正常输出应含:/dev/block/dm-0 /system ext4 ro,seclabel,... # 注意最后的"ro",表示当前只读

注意:雷电9的root是“临时root”,重启模拟器后会失效。若需持久化,需在“设置 → 更多设置 → 高级设置 → 启动时自动root”中勾选。但实测发现,部分版本勾选后反而导致启动卡死,建议首次操作先用临时root验证流程。

3.2 remount /system为可写:不是简单一句mount -o rw,remount /system

Android 11的/system分区采用dm-verity技术,其底层块设备(如/dev/block/dm-0)被标记为只读。直接执行mount -o rw,remount /system会报错Operation not permitted

正确做法是先找到/system对应的块设备,再用adb shell在PC端执行remount:

  1. 在雷电9中执行:

    cat /proc/mounts | grep system # 输出类似:/dev/block/dm-0 /system ext4 ro,seclabel,... # 记下/dev/block/dm-0
  2. 在PC端CMD/PowerShell中,确保adb已连接(adb devices应显示127.0.0.1:5555 device):

    adb shell su -c "mount -o rw,remount /dev/block/dm-0" # 或更稳妥的写法(指定挂载点): adb shell su -c "mount -o rw,remount /system"

执行后,再次adb shell mount | grep system,应看到rw替代了ro

经验技巧:雷电9的su命令有时响应慢,可在adb命令前加timeout 5防卡死;若提示permission denied,说明su权限未授予,需在雷电9弹出的SuperSU授权框中点“始终允许”。

3.3 证书文件命名与注入:SHA-1哈希值决定一切

Android系统证书存储区/system/etc/security/cacerts/中的每个证书文件,文件名不是随意取的,而是证书Subject的SHA-1哈希值的十六进制小写表示,后跟.0后缀。例如,Burp CA证书的Subject是:

CN=PortSwigger CA, OU=PortSwigger Limited, O=PortSwigger Limited, L=London, ST=London, C=GB

其SHA-1哈希值计算方式为(Linux/macOS):

openssl x509 -in burpca.cer -inform DER -subject_hash_old -noout # 输出:d6e5d1f2

注意:必须用-subject_hash_old参数!Android系统使用的是OpenSSL 1.0.x的旧版哈希算法,新版-subject_hash会生成不同结果。若用错,证书将无法被系统识别。

完整注入流程:

  1. burpca.cer文件推送到雷电9:

    adb push burpca.cer /sdcard/
  2. 进入adb shell并切换到root:

    adb shell su cd /sdcard
  3. 计算哈希并重命名(假设输出是d6e5d1f2):

    mv burpca.cer d6e5d1f2.0
  4. 复制到系统证书目录:

    cp d6e5d1f2.0 /system/etc/security/cacerts/
  5. 修改文件权限(关键!):

    chmod 644 /system/etc/security/cacerts/d6e5d1f2.0 chown root:root /system/etc/security/cacerts/d6e5d1f2.0

提示:权限必须是644(即-rw-r--r--),600400会导致系统拒绝加载;所有者必须是root:root,否则App层校验失败。

3.4 验证证书是否被系统识别

注入完成后,不能直接开App测试,必须先验证系统层是否认可:

  1. 在雷电9中打开“设置 → 安全 → 加密与凭据 → 信任的凭据 → 系统”
  2. 向下滑动,查找“PortSwigger CA”或“Burp Suite”字样
  3. 点击进入,确认状态为“已启用”,且有效期正确

如果找不到,说明哈希值计算错误或文件权限不对;如果找到但状态为“已停用”,说明证书被系统标记为不安全(常见于自签证书未包含Basic Constraints: CA:TRUE扩展)。

此时可回退检查Burp证书:Proxy → Options → CA Certificate → regenerate,确保勾选了“Include CA certificate in generated certificates”。

4. App级绕过:当SSL Pinning成为铜墙铁壁,Frida是唯一的破门锤

即使你完美完成了Burp配置和系统证书注入,90%的高版本商业App依然抓不到包。原因只有一个:SSL Pinning(证书固定)。它让App在代码层硬编码服务器证书指纹,绕过系统证书信任链,直接校验TLS握手返回的证书是否匹配预设值。

这类App的典型特征是:

  • 打开App后,Burp的Proxy History里一片空白,Target Scope里也没有新增请求;
  • Logcat中出现大量W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname xxx.com not verifiedCaused by: okhttp3.internal.platform.AndroidPlatform.isConscryptPreferred()
  • adb logcat | grep -i "pin"能搜到CertificatePinner相关日志。

绕过SSL Pinning,没有银弹,只有两种可靠路径:静态修改APK(重打包)或动态Hook(Frida注入)。前者需反编译、修改smali、重签名,耗时长且易被加固检测;后者实时注入内存,成功率高,是雷电9环境下最推荐的方案。

4.1 Frida环境搭建:为什么选Frida而不是Xposed或Magisk Module

雷电9基于Android 11,其内核对Xposed框架兼容性差,且多数加固App会主动检测/system/framework/xposedbridge.jar;Magisk虽强,但雷电9的root机制与Magisk冲突,安装Magisk后常导致模拟器无法启动。

Frida的优势在于:

  • 无Root依赖:可通过frida-server在用户空间运行,无需修改系统分区;
  • 动态Hook:在App进程启动瞬间注入,修改OkHttpClientTrustManagerCertificatePinner等关键类的方法逻辑;
  • 脚本化:绕过逻辑用JavaScript编写,调试方便,社区脚本丰富(如frida-android-helperssl-pinning-bypass)。

在雷电9上部署Frida,需三步:

步骤1:下载匹配架构的frida-server

雷电9使用ARM64-v8a架构(adb shell getprop ro.product.cpu.abi输出arm64-v8a),需下载frida-server-16.1.4-android-arm64.xz(以最新版为准)。

解压后得到frida-server二进制文件,上传到雷电9:

adb push frida-server /data/local/tmp/ adb shell "chmod 755 /data/local/tmp/frida-server"
步骤2:启动frida-server并验证
adb shell "/data/local/tmp/frida-server &" # 检查是否运行 adb shell "ps | grep frida" # 应输出类似:u0_a123 12345 1 123456 78900 SyS_epoll_wait 0000000000 S frida-server
步骤3:PC端安装frida-tools并连接
pip install frida-tools frida-ps -U # 列出雷电9中所有运行进程,应看到"com.xxx.app"等包名

4.2 绕过SSL Pinning的核心脚本:从TrustManager到OkHttp 4.x的全链路覆盖

不同App使用的网络库版本不同,需针对性编写Hook脚本。以下是覆盖主流场景的bypass_ssl_pinning.js脚本(经雷电9实测通过):

// bypass_ssl_pinning.js Java.perform(function () { console.log("[*] Java Hooking initialized"); // 1. Android WebView SSL Pinning bypass (API 21+) var WebViewClient = Java.use("android.webkit.WebViewClient"); WebViewClient.onReceivedHttpError.implementation = function (view, request, error) { console.log("[+] WebView HTTP Error bypassed"); this.onReceivedHttpError.call(this, view, request, error); }; // 2. OkHttp 3.x & 4.x CertificatePinner bypass try { var CertificatePinner = Java.use("okhttp3.CertificatePinner"); CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (hostname, peerCertificates) { console.log("[+] OkHttp CertificatePinner bypassed for " + hostname); return; }; } catch (e) { console.log("[-] OkHttp 3/4 CertificatePinner not found"); } // 3. TrustManager bypass (works for most custom SSLContext) var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl"); TrustManagerImpl.checkTrustedRecursive.implementation = function (chain, authType, host, clientAuth, ocspData, tlsSctData) { console.log("[+] TrustManagerImpl checkTrustedRecursive bypassed for " + host); return chain; }; // 4. X509TrustManager bypass (fallback for older apps) var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager"); var TrustManager = Java.use("java.security.cert.X509Certificate"); X509TrustManager.checkServerTrusted.implementation = function (chain, authType, host) { console.log("[+] X509TrustManager bypassed for " + host); return; }; });

启动Hook的命令:

frida -U -f com.xxx.app -l bypass_ssl_pinning.js --no-pause

注意:-f参数会强制启动App,--no-pause避免启动后暂停。若App已运行,可用frida -U com.xxx.app -l bypass_ssl_pinning.js附加。

4.3 实测验证:如何确认SSL Pinning已被绕过

启动Frida脚本后,不要急着开App,先观察控制台输出:

  • 若看到[+] OkHttp CertificatePinner bypassed for api.xxx.com,说明Hook成功;
  • 若长时间无输出,或报Script crashed: Error: unable to find class,说明App使用了混淆(如ProGuard),需用frida-trace定位真实类名。

验证绕过效果的黄金标准是:Logcat中不再出现SSLPeerUnverifiedException,且Burp Proxy History中开始出现目标域名的HTTPS请求

我常用的一键验证命令:

# 在PC端新开CMD窗口 adb logcat -s "OkHttpClient" "CertificatePinner" "TrustManager" | grep -i "bypass\|unverified\|exception" # 正常应无输出,或仅有"[+] bypassed"日志

若仍有SSLPeerUnverifiedException,说明Hook未覆盖到App实际调用的类。此时需用frida-trace动态追踪:

frida-trace -U -f com.xxx.app -i "okhttp3.*" -i "javax.net.ssl.*" # 启动后,观察哪些方法被频繁调用,再针对性Hook

5. 证书安装避坑指南:从“已安装”到“真正生效”的七道生死关

这是整个流程中最容易被轻视,却最常导致失败的环节。很多人看到雷电9设置里“证书已安装”,就以为万事大吉,结果App还是连不上。实际上,“安装”只是文件拷贝动作,“生效”需要满足七个硬性条件,缺一不可。

5.1 七道关卡自查清单(每一条都亲手验证过)

关卡检查项验证方法常见失败表现解决方案
1. 文件格式是否为DER格式(.cer)file burpca.cer输出data(非ASCII text双击无反应,或提示“无法安装”用Burp重新导出,选DER
2. 文件名是否为SHA-1 hash +.0ls /system/etc/security/cacerts/ | grep -i "d6e5d1f2"系统证书列表中找不到openssl x509 -in cert.cer -inform DER -subject_hash_old -noout重算
3. 文件权限是否为644且属主root:rootls -l /system/etc/security/cacerts/d6e5d1f2.0系统证书列表中显示“已停用”chmod 644 && chown root:root
4. 系统时间雷电9系统时间是否准确设置 → 日期和时间 → 自动确定日期和时间(开启)证书显示“已过期”同步网络时间,或手动校准至±5分钟内
5. App Target SDKApp是否target API ≥24aapt dump badging app.apk | grep "targetSdkVersion"即使证书安装,App仍不信任必须用Frida绕过,无其他解法
6. WebView独立证书WebView是否启用独立证书策略adb shell settings get global webview_providerH5页面能抓,原生接口不能在WebView初始化时调用setWebContentsDebuggingEnabled(true)
7. DNS污染是否DNS劫持导致SNI不匹配adb shell ping api.xxx.com看IP是否为真实服务器IPServer Hello证书Subject与SNI不一致在Burp中添加/etc/hosts映射,或改用114.114.114.114DNS

5.2 一个真实案例:某政务App的“双重证书”陷阱

去年测试一个省级政务App(targetSdkVersion=30),按上述流程做完,Burp History里仍无请求。Logcat显示:

E/OkHttpClient: Unable to resolve host "api.govapp.cn": No address associated with hostname

我以为是DNS问题,ping api.govapp.cn返回超时。但用浏览器访问却正常。深入排查发现:

  • 该App在AndroidManifest.xml中声明了<application android:usesCleartextTraffic="true">,但实际网络请求全走HTTPS;
  • 其OkHttp Builder中设置了自定义Dns实现类,该类会将所有域名解析请求转发到https://dns.govapp.cn/resolve(一个HTTPS接口);
  • 而这个DNS接口本身也做了SSL Pinning!

这意味着:要解析出api.govapp.cn的真实IP,必须先绕过dns.govapp.cn的证书固定。这是一个典型的“递归SSL Pinning”陷阱。

解决方案是:在Frida脚本中,将CertificatePinner.check的Hook范围扩大到dns.govapp.cn

CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (hostname, peerCertificates) { if (hostname === "api.govapp.cn" || hostname === "dns.govapp.cn") { console.log("[+] Bypassing pinning for " + hostname); return; } return this.check.call(this, hostname, peerCertificates); };

5.3 最后的兜底方案:当所有技术手段失效时

如果经过上述所有步骤,App仍拒绝通信,别急着放弃。还有三个物理层/协议层的兜底方案:

方案1:降级Android版本(雷电9支持多版本)

雷电模拟器9内置Android 5.1/7.1/9.0/11.0四套系统镜像。某些App对Android 11的TLS栈过于激进,换到Android 9(Pie)镜像后,network_security_config的默认行为更宽松,常能直接抓包。

路径:雷电9右上角菜单 → 设置 → 基础设置 → 系统版本 → 切换为Android 9.0。

方案2:禁用App的网络安全性配置

若你有APK文件,可用apktool反编译,编辑res/xml/network_security_config.xml,将<domain-config>整个注释掉,再apktool b重打包。虽然会被V2签名拒绝,但雷电9支持adb install -t -r覆盖安装(-t允许测试签名)。

方案3:用Charles Proxy替代Burp(针对特定场景)

Charles的SSL Proxying配置对Android 11兼容性更好,尤其在处理SNIALPN协议协商时更稳定。配置路径:Proxy → SSL Proxying Settings → Add →*.xxx.com:443。导出证书时,Charles会自动生成Android友好的.pem文件,双击即可安装。

我在测试某视频App时,Burp始终无法完成TLS握手,换Charles后一次成功——根本原因是Charles默认启用TLS False Start优化,而Burp需手动开启。


我在雷电模拟器9上完成过27个高版本App的抓包任务,从金融到医疗,从政务到游戏。每一次成功,都不是靠运气,而是对Android证书信任模型、TLS协议栈、App网络库实现的深度理解。你不需要记住所有命令,但一定要明白:每一个报错,都是系统在告诉你“哪一层的契约被打破了”。当SSLPeerUnverifiedException出现时,它不是障碍,而是线索——指向OkHttp的CertificatePinner;当Connection refused出现时,它不是失败,而是提示——Burp的TLS版本配置与App要求不匹配。

最后分享一个小技巧:在雷电9桌面创建一个“抓包快捷方式”,里面放好所有必需文件(burpca.cer、frida-server、bypass.js),并写个start.bat一键执行:

@echo off adb push burpca.cer /sdcard/ adb shell su -c "cp /sdcard/burpca.cer /system/etc/security/cacerts/d6e5d1f2.0 && chmod 644 /system/etc/security/cacerts/d6e5d1f2.0" adb push frida-server /data/local/tmp/ adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &" echo 抓包环境准备完毕!请启动Burp并运行:frida -U -f com.xxx.app -l bypass.js pause

这样,下次再遇到新App,你只需改两行代码,就能复用整套流程。技术的价值,从来不在炫技,而在把复杂问题变成可重复的确定性动作。

http://www.jsqmd.com/news/880080/

相关文章:

  • 自适应能量对齐:提升电子态密度机器学习预测精度的关键技术
  • 告别卡顿!用scrcpy v2.0无线投屏小米/华为手机到Windows电脑的保姆级教程
  • 不变性学习自适应算法:从VC维到样本效率的理论与实践
  • 2026 四川钢管优质供应商推荐|盛世钢联全品类现货批发,价格行情与采购指南 - 四川盛世钢联营销中心
  • Linux端口敲门实战:用knockd为SSH加一道协议层保险
  • Windows 彻底关闭 UAC 弹窗:让你的管理员账户获得超级管理员权限
  • 基于随机森林与KL散度的并行MCMC:大数据贝叶斯计算新范式
  • 静电筛选与机器学习势函数加速:高通量预测材料分裂空位缺陷
  • 每日大赛场景下如何快速接入多模型API提升开发效率
  • DeepSeek总结的DuckDB动态函数应用插件
  • Rust内存安全特性:所有权、借用与生命周期详解
  • 无服务器架构与Serverless
  • 2026年05月河北水墨印刷开槽机厂商推荐,选型不迷茫,纸箱包装机械/水墨印刷开槽机,水墨印刷开槽机品牌推荐 - 品牌推荐师
  • DeepSeek总结的clickhousectl v0.2.0: Postgres, ClickPipes 等更多功能
  • 2026亲测:专业降AI率平台选这款就对了
  • 基于拓扑数据分析的短肽抗癌活性预测:Top-ML模型特征工程与实战
  • 复杂地理信息系统设计的数据访问层的统一抽象:PostGIS/Vector/Raster Backend模式实战
  • 告别低效写作:盘点2026年顶尖配置的的降AI率网站
  • 【具身智能】最大微信群
  • 【AI翻译避坑指南】:92%用户忽略的5个ChatGPT翻译陷阱(含术语一致性崩塌、文化错译、被动语态误判),附可直接复用的Prompt模板
  • 云安全与合规
  • Rust 异步运行时深度解析:Tokio 的原理与实践
  • Lance 写入链路:Merge Into、Compaction 与 Stable Row ID
  • 2026 四川钢板优质供应商推荐|盛世钢联全品类现货批发,价格行情与采购指南 - 四川盛世钢联营销中心
  • 2026 四川型钢优质供应商推荐|盛世钢联全品类现货批发,价格行情与采购指南 - 四川盛世钢联营销中心
  • 170家具身智能公司名单
  • 云原生应用开发
  • 登录+注册 每一分钟 最多请求5次
  • 上海空调移机维修拆装靠谱推荐、鑫诚制冷嘉一制冷本地同城移机拆装维修加氟上门服务 - 卓一科技
  • 2026深圳劳动纠纷律师推荐 本土专业靠谱律所指南 - 从来都是英雄出少年