11、网络协议抓包分析:Charles与Burp Suite配置、HTTPS证书绑定绕过、Protobuf解析
各位同学,今天我们来聊聊抓包。说实话,做逆向分析,抓包是基本功。你拿不到网络通信的数据,后面的分析基本就是盲人摸象。我个人习惯把抓包分为两个阶段:先看明文,再解协议。今天我们就从工具配置讲起,一路深入到Protobuf的解析。
11.1 抓包工具的选择:Charles vs Burp Suite
这两款工具,我都在项目里用过。简单说下我的感受:
- Charles:更适合看HTTP/HTTPS的流量,界面直观,过滤方便。我经常用它来快速定位某个接口的请求参数。
- Burp Suite:强在可编程性,你可以写插件、改请求、重放攻击。做安全测试时,我几乎离不开它。
但说实话,很多场景下两者可以互换。你习惯哪个就用哪个。我这里重点讲一下HTTPS的配置,因为这是新手最容易卡住的地方。
11.2 HTTPS证书配置与代理设置
抓HTTPS的包,核心就是中间人攻击(MITM)。工具会生成一个根证书,你需要把它安装到手机上,并信任它。
Charles的配置步骤
- 打开Charles,点击 Proxy → SSL Proxying Settings,勾选 Enable SSL Proxying。
- 添加要抓包的主机地址和端口(比如 *:443 表示所有443端口)。
- 手机设置代理:IP填你电脑的局域网IP,端口填8888(Charles默认)。
- 手机浏览器访问 chls.pro/ssl,下载并安装证书。
- Android 7.0+ 需要额外处理:要么把证书安装到系统证书目录(需要root),要么用Xposed模块绕过。
Burp Suite的配置步骤
- Burp默认监听在127.0.0.1:8080。你需要改成0.0.0.0:8080,才能让手机连上来。
- 手机浏览器访问 http://burp,下载证书。
- 安装证书后,同样面临Android 7.0+的信任问题。
嗯,这里要注意:Burp的证书和Charles的证书不能混用。你手机上装的是哪个工具的证书,就只能用哪个工具抓包。
11.3 HTTPS证书绑定绕过
为什么有些App你配好证书还是抓不到包?因为它们用了证书绑定(Certificate Pinning)。说白了,App在代码里写死了它信任的证书指纹。你中间人的证书不在白名单里,连接就被断开了。
我曾经在一个金融App上栽过跟头。配了Charles,装了证书,结果所有请求都是空响应。后来一查,人家用了OkHttp的CertificatePinner。
绕过方法
- 方法一:Hook框架绕过。用Frida或Xposed,Hook掉证书校验的方法。比如Hook OkHttp的checkServerTrusted方法,直接返回true。
- 方法二:修改APK。反编译App,找到证书绑定的代码,删掉或注释掉。然后重打包、签名、安装。
- 方法三:使用JustTrustMe(Xposed模块)或SSLUnpinning(Frida脚本)。这些工具一键绕过,省时省力。
11.4 Protobuf解析
抓到包了,但数据是乱码?别慌,很可能是Protobuf。Protobuf是Google的序列化协议,体积小、速度快,现在很多App都在用。
Protobuf的数据是二进制的,没有.proto文件你基本看不懂。但我们可以通过一些技巧来还原它。
识别Protobuf
抓包时,如果看到Content-Type是application/x-protobuf或application/grpc,那基本就是Protobuf了。另外,数据开头如果是0x0A、0x12这种小数字,也很有可能是Protobuf的字段标记。
解析Protobuf的几种方式
- 方式一:有.proto文件。直接用protoc命令反序列化:
protoc --decode_raw < data.bin。或者用Python的protobuf库加载.proto文件后解析。 - 方式二:没有.proto文件。用
protoc --decode_raw可以输出字段编号和类型。然后根据字段编号,反推.proto文件的结构。我经常这么干。 - 方式三:使用工具。比如Protobuf Inspector(Chrome插件)或BlackDex(脱壳+解析)。
protoc --decode_raw看看字段结构。然后写一个Python脚本,用google.protobuf.internal.decoder模块手动解析。虽然麻烦,但能解决问题。
代码示例:用Python解析Protobuf
import sys
from google.protobuf import descriptor_pb2
from google.protobuf import json_format
from google.protobuf import symbol_database
# 假设你有一个.proto文件编译后的_pb2.py
import myapp_pb2
# 读取二进制数据
with open('data.bin', 'rb') as f:
data = f.read()
# 解析
msg = myapp_pb2.MyMessage()
msg.ParseFromString(data)
# 转成JSON方便查看
json_str = json_format.MessageToJson(msg)
print(json_str)
如果你没有_pb2.py文件,可以用protoc --decode_raw先看看字段编号,然后手动构造一个DescriptorProto,再用动态消息解析。嗯,这个有点复杂,我们课上再细讲。
11.5 知识体系图
下面这张图,帮你理清本章的核心脉络:
11.6 避坑指南
最后,分享几个我踩过的坑:
- 证书装了对,但抓不到包?检查一下代理设置。有时候Wi-Fi代理配了,但App用了VPN或者直连,流量根本不走代理。
- Protobuf解析出来全是0?大概率是字段编号对不上。Protobuf的字段编号是int32,如果你用错了编号,解析出来的就是默认值。
- Frida Hook了但没效果?检查一下App是否用了多进程。有些App的网络请求在子进程里,你Hook的是主进程,当然没反应。
我曾经在一个直播App上折腾了两天,最后发现人家用了自定义的TLS实现,根本不走系统的SSL库。嗯,这种情况就只能硬啃二进制协议了。
好了,本章的内容就到这里。抓包是个实践活,光看文档没用。你回去把Charles和Burp配好,找个App练练手,遇到问题再来问我。