Android 14/15 HTTPS抓包实战:系统证书注入与Frida绕过证书固定 1. 项目概述为什么在Android 14/15上抓包变得如此棘手如果你最近尝试在最新的Android 14或15设备上抓取HTTPS流量大概率会碰一鼻子灰。传统的“用户证书”安装法在Chrome和很多主流App上已经彻底失效你会看到“网络错误”或“证书不受信任”的提示。这不是你的操作有问题而是Google从Android 7.0开始引入、并在后续版本中不断强化的网络安全策略——网络安全性配置Network Security Configuration和证书固定Certificate Pinning——在Android 14/15上达到了一个新的高度。简单来说系统对非系统级根证书的信任度降到了冰点尤其是对于以targetSdkVersion为目标的新应用。这个项目的核心就是攻克这两座大山系统证书注入和应用进程级捕获。前者解决的是“让设备信任你的抓包工具如Charles、Fiddler”的问题后者解决的是“如何绕过应用自身的证书锁定和代码混淆看到明文流量”的问题。这不再是一个简单的“设置代理、安装证书”就能搞定的事情它涉及到对Android系统安全模型的理解、ADB调试权限的深度利用、以及一些“非常规”但有效的实战技巧。我花了相当长时间在各种品牌和型号的Android 14/15设备上反复测试总结出了一套稳定、可复现的完整流程其中就包括如何利用一些社区工具如sh /storage/emulated/0/android/data/com.omarea.vtools/up.sh这类脚本的变体思路来简化系统级操作。2. 核心思路与前置准备理解Android的证书信任链在动手之前我们必须搞清楚Android是如何决定信任一个证书的。这直接决定了我们的操作路径。2.1 Android的证书存储与信任机制Android维护着两套主要的证书存储用户证书存储路径通常为/data/misc/user/0/cacerts-added。用户手动安装的CA证书如通过下载.cer文件安装就放在这里。在Android 6.0及以前应用默认会信任这里的证书。但从Android 7.0开始应用可以通过声明Network Security Configuration文件选择不信任用户证书。到了Android 14/15越来越多的系统组件和预装应用包括WebView默认就不信任用户证书了。系统证书存储路径为/system/etc/security/cacerts/。这里的证书拥有最高的信任级别所有应用除非使用了证书固定都必须信任。我们的终极目标就是把抓包工具的CA证书放到这个目录下并赋予正确的权限。2.2 关键前提获取系统级权限向/system分区写入文件需要极高的权限。通常有两种途径Root权限最直接但会触发设备保修失效、安全支付失效、且过程复杂风险高不适用于所有设备特别是国行旗舰机。ADB Root系统调试桥Root这是本次实战的核心依赖。它要求你的设备系统镜像通常是自定义ROM或开发者预览版在编译时启用了ro.debuggable1和ro.adb.secure0等属性使得通过adb shell获得的shell用户通常是shell或root本身就拥有挂载系统分区为可写rw的权限。很多Pixel设备刷入原生Android开发者预览版DP或一些开源AOSP构建版本后就具备这个条件。这也是为什么社区里流传的很多一键脚本包括原理类似up.sh的脚本都明确要求设备已开启“ADB Root”。准备工作清单一台已开启“开发者选项”和“USB调试”的Android 14/15设备。强烈建议使用Pixel系列刷入最新Android DP版本或使用官方Android模拟器其系统镜像默认具备ADB Root。一台电脑安装好对应设备的USB驱动、Android SDK Platform-Tools包含adb命令。抓包工具Charles、Fiddler、mitmproxy任选其一。本文以Charles为例因其界面友好原理通用。基础命令行操作知识。3. 系统证书注入实战将CA证书写入/system分区这是最关键的步骤一旦成功设备上绝大多数HTTPS流量在抓包工具看来都将“畅通无阻”。3.1 第一步从抓包工具导出根证书首先确保电脑和手机在同一个局域网Wi-Fi并在抓包工具中设置好代理如Charles默认的0.0.0.0:8888。在Charles中点击Help - SSL Proxying - Save Charles Root Certificate...。选择保存类型为.cer文件二进制的DER格式。记住保存路径比如charles_root.cer。注意不要保存为.pemBase64编码格式虽然可以转换但直接使用.cer更简单。3.2 第二步转换证书格式与计算哈希Android系统证书存储要求证书文件以特定的哈希值命名。我们需要将.cer文件转换为.pem格式并计算其哈希。使用OpenSSL命令电脑上需安装OpenSSL或使用Git Bash等自带环境# 将 .cer (DER) 转换为 .pem openssl x509 -inform DER -in charles_root.cer -out charles_root.pem # 计算 .pem 证书的哈希值Subject Hash openssl x509 -inform PEM -subject_hash_old -in charles_root.pem | head -1这条命令会输出一个8位的十六进制字符串例如a0b1c2d3。这就是你的证书在系统存储中的文件名不含扩展名。3.3 第三步推送证书并挂载系统分区ADB Root环境这里就是体现“系统级”操作的地方。假设上一步得到的哈希是a0b1c2d3。连接设备并获取ADB Root Shelladb devices # 确认设备已连接 adb shell # 进入设备的shell环境进入后命令行提示符应该是$或#。如果是#说明已经是root。如果是$尝试输入su如果成功切换为#则说明有ADB Root。挂载系统分区为可读写/system分区默认是只读ro的。我们需要重新挂载它。# 查看/system分区挂载点通常是 /dev/block/by-name/system 或类似挂载在 /system mount | grep system # 输出可能类似/dev/block/sda1 on /system type ext4 (ro,seclabel,relatime) # 重新挂载为可读写 mount -o rw,remount /system # 或者使用更明确的分区路径 # mount -o rw,remount /dev/block/sda1 /system执行成功后/system分区就暂时可写了。推送并放置证书文件 保持adb shell在#状态在电脑的另一个命令行窗口执行# 将.pem证书文件推送到设备的临时目录 adb push charles_root.pem /data/local/tmp/ # 回到adb shell窗口执行以下命令 cd /data/local/tmp # 将证书复制到系统证书目录并以哈希值命名后缀为.0 cp charles_root.pem /system/etc/security/cacerts/a0b1c2d3.0 # 至关重要设置正确的文件权限和所有者 chmod 644 /system/etc/security/cacerts/a0b1c2d3.0 chown root:root /system/etc/security/cacerts/a0b1c2d3.0实操心得权限644所有者可读写其他人只读和所有者root:root是系统证书的标准配置必须严格设置否则系统可能忽略该证书。恢复系统分区只读属性并重启# 将/system分区改回只读这是一个好习惯避免误操作破坏系统 mount -o ro,remount /system # 或者 mount -o ro,remount /dev/block/sda1 /system # 重启设备让系统重新加载证书存储 reboot设备重启后你的Charles根证书就已经成为系统信任的根证书了。你可以在手机的设置 - 安全 - 更多安全设置 - 加密与凭据 - 信任的凭据 - 系统中找到以“Charles Proxy”或你自定义名称显示的证书。3.4 关于“一键脚本”的解读网络上流传的类似sh /storage/emulated/0/android/data/com.omarea.vtools/up.sh的命令其本质就是将上述第三步的复杂命令序列写成了一个Shell脚本。这个脚本通常会被放在设备的某个可访问路径如SD卡然后通过adb shell sh 脚本路径来执行。脚本内部一般包含检查是否具有root权限。将预先放在同目录或指定位置的证书文件如cacert.pem复制到/system/etc/security/cacerts/。计算哈希并重命名设置权限。可能包含挂载/system为可写的命令。使用此类脚本的注意事项绝对不要运行来源不明的脚本。脚本中如果包含rm -rf /之类的命令你的设备就变砖了。运行前最好用文本编辑器打开脚本检查其具体操作。确保脚本中的证书文件路径正确且证书文件确实存在。它并不能绕过“ADB Root”这个根本前提。如果设备本身不具备ADB Root权限脚本会在挂载/system那一步失败。4. 应用进程级捕获攻克证书固定与代码混淆即使完成了系统证书注入你仍然可能遇到一些“顽固”的应用它们使用了证书固定Certificate Pinning。这意味着应用在代码里硬编码了只信任特定的证书通常是它自己服务器的证书或特定的CA完全忽略系统证书存储。对于这类应用我们需要进行“进程级”的干预。4.1 方法一使用高版本Android的“用户证书”变通方案针对部分App在Android 14上Google为高级用户留了一个后门。你可以通过ADB命令强制将用户证书以更高权限安装。adb shell am start -a android.settings.MANAGE_CA_CERTIFICATES这个命令会打开一个隐藏的“管理CA证书”界面如果你的系统有。更直接的方法是使用ADB安装# 将证书文件推送到设备 adb push charles_root.cer /data/local/tmp/ # 使用特权命令安装 adb shell su -c cp /data/local/tmp/charles_root.cer /data/misc/user/0/cacerts-added/$(openssl x509 -inform DER -outform PEM -in /data/local/tmp/charles_root.cer | openssl x509 -hash -noout).0这种方法有时可以绕过一些只检查“用户证书”而非“系统证书”的较弱实现但面对强证书固定依然无效。4.2 方法二使用Frida进行运行时Hook推荐这是目前最强大、最通用的解决方案。Frida是一个动态代码插桩工具可以注入JavaScript到目标应用的进程中实时修改其内存和行为。我们可以用它来Hook住应用执行SSL/TLS验证的代码使其无条件信任我们的证书或直接绕过验证。准备工作在电脑上安装Fridapip install frida-tools在Android设备上安装Frida-server。需要根据设备CPU架构arm,arm64,x86_64下载对应版本并通过ADB推送到设备上运行。adb push frida-server-16.1.11-android-arm64 /data/local/tmp/frida-server adb shell chmod 755 /data/local/tmp/frida-server adb shell /data/local/tmp/frida-server 使用现成的Frida脚本 社区有很多优秀的脚本可以绕过SSL Pinning。例如frida-ssl-unpinning这个仓库收集了针对不同框架OkHttp, Android原生, Xamarin等的脚本。找到目标应用使用的网络库可以通过反编译APK查看AndroidManifest.xml或库文件猜测或直接尝试通用脚本。在电脑上运行Frida命令注入脚本frida -U -f com.example.targetapp -l ssl_unpinning.js --no-pause-U表示连接USB设备-f后面跟包名以启动应用-l指定要加载的JavaScript脚本。编写简单的通用Hook脚本 如果你不想用现成的一个非常暴力的通用方法是Hook住java.security.cert.Certificate的验证方法。创建一个bypass_ssl.js文件Java.perform(function() { var CertificateFactory Java.use(java.security.cert.CertificateFactory); var X509Certificate Java.use(java.security.cert.X509Certificate); var TrustManagerImpl null; // 尝试Hook常见的TrustManager实现 try { TrustManagerImpl Java.use(com.android.org.conscrypt.TrustManagerImpl); TrustManagerImpl.checkServerTrusted.implementation function(chain, authType, host) { console.log([] Bypassing checkServerTrusted for: host); return; // 直接返回不抛异常即表示信任 }; } catch(e) { console.log([-] TrustManagerImpl not found: e); } // Hook X509Certificate的检查方法 X509Certificate.checkValidity.implementation function() { console.log([] Bypassing certificate validity check); return; }; });运行frida -U -f com.example.app -l bypass_ssl.js然后操作应用观察Frida控制台输出和抓包工具很多情况下流量就出来了。踩坑实录Frida-server的版本必须与电脑端frida-tools的版本兼容。最好使用相同的主要版本号。此外一些应用如银行、支付类会有反调试、反Frida的机制可能需要更复杂的对抗手段如隐藏Frida特征、使用ptrace附加等这属于更高级的范畴。4.3 方法三使用第三方修改版应用或核心破解Magisk模块这是一种“釜底抽薪”的方法但需要设备已Root不仅仅是ADB Root。核心破解Core PatchMagisk模块这是一个非常流行的模块它可以在系统层面全局禁用证书固定和签名验证。安装后绝大多数应用的证书固定都会失效。这对于不想折腾Frida脚本的用户来说是最方便的选择。修改版应用在一些第三方应用市场或论坛可能存在已经去除了证书固定代码的App修改版。使用这类版本自然可以抓包。但安全风险极高你无法保证修改者没有加入恶意代码仅推荐在测试专用机上使用。5. 网络配置与抓包工具设置证书问题解决后基础的网络配置也不能出错。配置设备代理在手机已连接的Wi-Fi网络设置中修改代理为手动填入运行抓包工具的电脑的局域网IP地址和代理端口如Charles的8888。配置Charles SSL代理在Charles中进入Proxy - SSL Proxying Settings添加一个*:*的条目主机为*端口为*表示代理所有SSL连接。安装Charles证书到设备仅辅助尽管我们已经注入了系统证书但有时为了方便仍可以在设备浏览器访问chls.pro/ssl来安装Charles的用户证书。这对于抓取一些不严格校验证书来源的流量如某些内嵌WebView可能有帮助。针对特定应用的抓包在Charles的Proxy - Access Control Settings中确保允许你的设备IP连接。你还可以在Proxy - SSL Proxying Settings中更精确地添加需要抓包的具体域名和端口而不是使用通配符。6. 实战问题排查与进阶技巧即使按照上述步骤操作你可能还是会遇到问题。以下是一些常见坑点及解决方案。6.1 流量依旧不通或证书错误检查代理配置确认手机Wi-Fi代理的IP和端口绝对正确。电脑防火墙是否放行了8888端口可以尝试在手机浏览器访问http://电脑IP:8888应该能看到Charles的欢迎页。确认证书生效重启设备后再次adb shell进入执行ls -l /system/etc/security/cacerts/ | grep 你的证书哈希确认文件存在且权限是-rw-r--r-- root root。清除应用数据有些应用会在首次启动时缓存证书链。在注入系统证书后去手机设置里找到目标应用强制停止并清除其缓存和数据然后重新启动应用。检查目标应用特性使用adb shell dumpsys package 包名 | grep targetSdk查看应用的targetSdkVersion。如果大于等于28Android 9它默认就不信任用户证书我们的系统证书注入法对它就是必需的。如果大于等于34Android 14其网络限制会更严格。6.2 使用了WebView或网络库的特定配置一些应用内嵌的WebView或使用了像OkHttp这样的网络库它们可能有独立的证书信任管理器。对于自定义WebView应用可能通过WebViewClient的onReceivedSslError方法处理错误或者配置了自己的WebViewAssetLoader。这需要更具体的Frida脚本来Hook。对于OkHttpOkHttp的证书固定非常常见。使用针对OkHttp的Frida脚本如HookCertificatePinner类通常能解决问题。社区脚本frida-ssl-unpinning里通常包含okhttp3.pinning.js。6.3 应对高强度加固与反调试金融、社交类大型App常使用梆梆、腾讯御安全等第三方加固并具备反调试、反注入能力。过反调试Frida默认特征明显。可以尝试使用-f参数启动应用后立即暂停然后使用frida -U --attach 进程名来附加而不是启动时注入。或者使用修改了特征名的Frida-server。过内存检测有些应用会定期检查关键内存地址是否被修改。这需要动态分析找到检测点并用Frida绕过属于高阶逆向工程。使用Xposed/EdXposed/LSPosed如果设备已Root可以安装LSPosed框架并安装诸如“TrustMeAlready”、“SSLUnpinning”之类的模块。这些模块在系统层面工作兼容性有时比Frida脚本更好但需要设备有完整的Magisk环境。6.4 抓包工具的选择与对比Charles/Fiddler图形化界面友好功能强大适合分析HTTP/HTTPS流量查看请求/响应详情重放和断点调试。是入门和日常开发的首选。mitmproxy命令行工具功能强大且可脚本化适合自动化测试和高级用户。它同样需要安装CA证书。Wireshark抓取底层网络包TCP/IP层无需代理设置但无法直接解密HTTPS流量除非有服务器的私钥。它更适合分析协议问题、网络延迟而不是应用层数据抓取。tcpdumpAndroid在Android设备上直接运行tcpdump可以抓取设备自身的网络包然后导出到电脑用Wireshark分析。这需要设备有root权限并且也无法解密HTTPS。我个人在Android 14/15上的组合是系统证书注入 Charles日常分析 Frida应对顽固应用。这个组合覆盖了95%以上的场景。最后所有抓包行为请务必在你自己拥有完全控制权的设备和测试环境中进行并严格遵守相关法律法规和服务条款。抓包是强大的分析和调试工具正确使用它能极大提升开发、测试和安全研究效率。