Android高版本抓包实战:从证书不信任到系统级信任的完整指南
1. Android高版本抓包的核心痛点
如果你最近尝试在Android 7.0及以上版本的设备上抓包,可能会遇到一个让人头疼的问题:明明已经安装了抓包工具的CA证书,系统却提示"已安装证书授权中心 受到不明第三方的监控",导致HTTPS流量无法正常解析。这个问题的根源在于Android 7.0引入的网络安全策略变更。
在Android 7.0之前,系统会信任所有安装在用户证书目录下的CA证书。但从7.0开始,系统默认只信任预装在/system分区中的系统证书,不再自动信任用户安装的CA证书。这个设计主要是为了防止中间人攻击,提升系统安全性,但却给开发者和安全测试人员带来了不小的麻烦。
我最近在一个金融类App的安全测试中就遇到了这个问题。客户要求测试App在Android 11设备上的安全性,但无论我怎么安装Charles的证书,App始终无法建立HTTPS连接。经过一番折腾,终于找到了几种可靠的解决方案,下面我会详细分享这些实战经验。
2. 证书准备与格式转换
2.1 从抓包工具导出证书
首先,我们需要从抓包工具中导出CA证书。以Burp Suite为例,你可以通过以下步骤导出证书:
- 打开Burp Suite,进入"Proxy" -> "Options"选项卡
- 在"Proxy Listeners"部分,点击"Import/export CA certificate"按钮
- 选择"Export certificate in DER format",保存为burp.cer文件
Charles等其他抓包工具的导出方式类似,通常在代理设置或CA证书管理部分可以找到导出选项。如果你使用的是Fiddler,证书导出路径在"Tools" -> "Options" -> "HTTPS"选项卡中。
2.2 证书格式转换
Android设备对证书格式有一定要求,导出的证书可能需要转换格式。常见的问题包括:
- 导出的证书是DER格式(.cer),但Android需要PEM格式(.crt或.pem)
- 证书扩展名不被Android识别
- 证书链不完整
我推荐使用OpenSSL进行格式转换,这是最可靠的方法。以下是转换命令示例:
# 将DER格式转换为PEM格式 openssl x509 -inform DER -in burp.cer -out burp.crt # 如果需要查看证书详情 openssl x509 -text -in burp.crt -noout如果你不熟悉命令行,也可以使用浏览器进行转换。以Firefox为例:
- 打开Firefox选项,进入"隐私与安全" -> "证书" -> "查看证书"
- 在"证书管理器"中导入之前导出的burp.cer文件
- 选择该证书并导出,格式选择"PEM证书链"或"PEM证书"
转换完成后,你会得到一个.crt或.pem文件,这就是我们需要安装到Android设备上的证书。
3. 安装用户证书的常规方法
3.1 将证书传输到Android设备
有几种方式可以将证书文件传输到Android设备:
- USB数据线连接:将证书文件复制到设备存储的任意目录,比如Download文件夹
- 通过ADB命令推送:
adb push burp.crt /sdcard/Download/ - 通过电子邮件或云存储应用发送到设备
我个人更喜欢使用ADB命令,因为它不需要数据线反复插拔,特别是有多台测试设备时效率更高。
3.2 在Android设备上安装证书
证书传输到设备后,按照以下步骤安装:
- 打开Android设置,进入"安全"或"加密与凭据"
- 选择"安装证书"或"从存储设备安装"
- 浏览找到之前传输的burp.crt文件
- 为证书命名(如"Burp CA"),然后确认安装
安装完成后,你可以在"信任的凭据" -> "用户"标签下看到新安装的证书。但这时候问题来了 - 在Android 7.0+设备上,大多数App仍然不会信任这个用户证书。
4. 解决证书不信任问题
4.1 方法一:将证书安装为系统证书
这是最彻底的解决方案,但需要设备已root。具体步骤如下:
获取证书的hash值:
openssl x509 -subject_hash_old -in burp.crt命令输出第一行就是hash值,比如"a1b2c3d4"
将证书重命名为hash值加.0后缀:
cp burp.crt a1b2c3d4.0将证书文件推送到系统证书目录:
adb push a1b2c3d4.0 /system/etc/security/cacerts/设置正确的文件权限:
adb shell chmod 644 /system/etc/security/cacerts/a1b2c3d4.0 adb shell chown root:root /system/etc/security/cacerts/a1b2c3d4.0
对于Android 14及以上版本,还需要将证书复制到新的APEX目录:
adb push a1b2c3d4.0 /apex/com.android.conscrypt/cacerts/常见问题解决:
如果遇到/system分区只读的问题,可以尝试以下命令重新挂载:
adb root adb remount如果设备厂商锁定了system分区,可以尝试使用Magisk的"Move Certificates"模块,它会自动将用户证书复制到系统证书目录。
4.2 方法二:修改APK的网络配置
如果无法root设备,可以尝试修改目标APK的网络配置。这种方法适用于你自己开发的App或可以重新打包的第三方App。
使用apktool反编译APK:
apktool d target.apk -o output_dir检查或添加networkSecurityConfig: 在AndroidManifest.xml的 标签中添加或修改:
android:networkSecurityConfig="@xml/network_security_config"创建或修改res/xml/network_security_config.xml文件:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config> </network-security-config>重新打包并签名APK:
apktool b output_dir -o modified.apk jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore your.keystore modified.apk alias_name
这种方法的好处是不需要root权限,但缺点是如果APK有签名校验或加固保护,重新打包可能会导致App无法运行。
4.3 方法三:使用ADB临时挂载证书
这是一个比较新的解决方案,由HTTP Toolkit团队提出,可以在不永久修改system分区的情况下加载系统证书。
创建一个临时目录并复制现有系统证书:
adb shell "mkdir -m 700 /data/local/tmp/htk-ca-copy" adb shell "cp /system/etc/security/cacerts/* /data/local/tmp/htk-ca-copy/"在系统证书目录上挂载tmpfs:
adb shell "mount -t tmpfs tmpfs /system/etc/security/cacerts"将证书复制回挂载点:
adb shell "mv /data/local/tmp/htk-ca-copy/* /system/etc/security/cacerts/" adb shell "cp /sdcard/burp.crt /system/etc/security/cacerts/a1b2c3d4.0"设置正确的权限:
adb shell "chown root:root /system/etc/security/cacerts/*" adb shell "chmod 644 /system/etc/security/cacerts/*" adb shell "chcon u:object_r:system_file:s0 /system/etc/security/cacerts/*"
这种方法的优点是无需永久修改系统,重启后更改会自动恢复。缺点是每次重启后都需要重新执行这些步骤。
5. 针对不同Android版本的优化策略
不同Android版本对证书的处理方式有所不同,我们需要根据目标设备的Android版本选择合适的方案。
Android 7.0-13:
- 系统证书目录:/system/etc/security/cacerts/
- 主要问题:不信任用户证书
- 解决方案:上述三种方法都适用
Android 14+:
- 新增APEX证书目录:/apex/com.android.conscrypt/cacerts/
- 变化:系统证书通过APEX机制动态更新
- 解决方案:需要同时向两个目录安装证书,或使用Magisk模块
针对不同targetSdkVersion的App:
- targetSdkVersion < 24:信任用户证书
- targetSdkVersion >= 24:默认不信任用户证书
- 特殊框架应用(如Flutter):可能需要额外配置
在实际测试中,我发现金融类App通常会将targetSdkVersion设置为较高版本,并且会额外实现证书固定(Certificate Pinning),这种情况下即使安装了系统证书也可能无法抓包,需要配合其他技术如Frida来绕过证书检查。
6. 常见问题排查与解决
即使按照上述方法操作,实践中仍可能遇到各种问题。以下是我总结的一些常见问题及解决方法:
问题1:证书已安装但抓包仍失败
- 检查证书是否真的被系统信任
- 尝试用设备浏览器访问https网站,验证基础抓包功能
- 检查App是否实现了证书固定
问题2:ADB无法remount system分区
- 尝试不同的remount命令:
adb root adb disable-verity adb reboot adb root adb remount - 某些设备需要特定的解锁命令,参考厂商文档
问题3:Magisk模块安装失败
- 确保Magisk版本是最新的
- 检查设备是否真的已root
- 尝试其他证书管理模块,如"MagiskTrustUserCerts"
问题4:修改APK后无法运行
- 检查APK签名是否正确
- 确认是否绕过了签名校验
- 尝试使用原始签名证书重新签名
问题5:特定浏览器不信任证书
- Chrome浏览器有独立的证书信任策略
- Firefox需要启用"信任第三方CA证书"选项
- 系统WebView可能也有特殊要求
在最近的一个项目中,我遇到一个特别棘手的情况:设备是Android 12,system分区完全锁定,无法root,目标APK又有加固保护。最终是通过结合ADB临时挂载证书和Xposed模块绕过证书检查才解决问题。这种复杂情况需要根据具体环境灵活应对。
