移动端防抓包实践
# 21.移动端防抓包实践
本篇定位:抓包是 App 安全的"第一关"——抓包能看到所有接口、参数、token、签名规则。本文从一次"接口被刷 200 万次"的攻防讲起,回答三个核心问题——抓包到底在抓什么?业界四道防线怎么搭?怎么和黑产持续对抗?
# 目录介绍
# 01.被抓包的那一夜
# 1.1 接口被刷 200 万次
某电商 App 周五凌晨突然报警:"领优惠券"接口被请求了 200 万次——平时每日才 5 万次。
flowchart TD
A[黑产抓包 App] --> B[拿到"领券"接口]
B --> C[拿到签名规则]
C --> D[写脚本绕过 App 直接调接口]
D --> E[200 万账号自动领券]
E --> F[2000 万元优惠券池被领光]
F --> G[正常用户领不到 → 大量投诉]
Cause[根因] --> R1[只用了 HTTPS<br/>没做证书绑定]
Cause --> R2[签名算法可逆向<br/>放在 Java 层]
Cause --> R3[没检测代理]
Cause --> R4[没行为风控]
style F fill:#ffebee
style G fill:#ffebee
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1.2 攻击扩散链路
黑产的标准攻击流程:
sequenceDiagram
participant H as 黑产
participant Phone as 测试机
participant Charles as 抓包工具
participant App as 你的 App
participant Server as 服务端
Note over H,Phone: 第一步: 装抓包环境
H->>Phone: 装 Charles 证书 + 设代理
Note over Phone,Server: 第二步: 抓包分析
H->>App: 操作 App
App->>Charles: 请求被抓
Charles->>Server: 透传
Server->>Charles: 响应
Charles->>App: 透传
Note over H,Charles: 第三步: 分析签名规则
H->>H: 反编译 App 看签名代码
Note over H,Server: 第四步: 写脚本批量调用
H->>Server: 直接构造请求 + 签名
Server-->>H: 业务通过 → 套利
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.3 反思防抓包
事后这个团队总结了三个最深刻的教训:
- HTTPS 不等于安全——它只防中间人,不防"自家用户安装抓包证书"
- 客户端能做的有限,最终要靠服务端兜底——风控、行为分析、限流
- 防抓包是持续战争——黑产工具一直在更新,防御也要持续迭代
防抓包的目标不是"绝对防住"——这不可能,而是"提高攻击成本":让黑产破解一次需要 2 周,而不是 2 小时。
# 02.要解决的核心矛盾
# 2.1 抓包原理拆解
抓包工具(如 Charles / Fiddler)的本质:
graph LR
App[App] -->|流量| Proxy[抓包代理<br/>Charles]
Proxy -->|可见明文| Server[真实服务器]
Server -->|可见明文| Proxy
Proxy -->|流量| App
Note[抓包工具扮演"中间人"<br/>需要 App 信任它的证书]
style Proxy fill:#ffebee
style Note fill:#fff3e0
2
3
4
5
6
7
8
9
10
HTTPS 抓包的关键:用户主动安装抓包工具的根证书 → 系统信任它 → HTTPS 解密。HTTPS 防的是被动中间人,不防主动安装证书。
# 2.2 安全与体验
graph LR
A[严格防御<br/>检测到代理就拒绝] --> B[误伤公司代理用户]
B --> C[投诉]
A2[宽松防御<br/>什么都允许] --> B2[黑产畅通无阻]
A3[分级防御<br/>普通业务允许 + 关键业务严防] --> B3[平衡]
style C fill:#fff3e0
style B2 fill:#fff3e0
style B3 fill:#e8f5e8
2
3
4
5
6
7
8
9
10
11
# 2.3 攻防的螺旋
flowchart LR
V1[V1 HTTPS] --> Crack1[抓包+证书安装破解]
Crack1 --> V2[V2 证书绑定]
V2 --> Crack2[Hook 绕过校验]
Crack2 --> V3[V3 SO 实现 + 加固]
V3 --> Crack3[Frida 动态调试]
Crack3 --> V4[V4 反调试 + 反 Hook]
V4 --> Crack4[内存 dump]
Crack4 --> V5[V5 端云协同 + 行为风控]
style V1 fill:#e3f2fd
style V3 fill:#fff3e0
style V5 fill:#e8f5e8
2
3
4
5
6
7
8
9
10
11
12
13
# 2.4 防抓包的本质
防抓包 = 提高黑产的破解成本
它不是"绝对安全",而是 让破解时间 > 业务红利时间——黑产破解一次需要 2 周,但活动只搞 1 周,破解了也来不及刷。
# 03.业界主流方案
# 03.1 主流抓包工具
| 工具 | 平台 | 特点 |
|---|---|---|
| Charles | Mac/Windows | 商业、易用、UI 友好 |
| Fiddler | Windows | 老牌、免费 |
| Wireshark | 全平台 | 网络层、底层抓包 |
| mitmproxy | 全平台 | 命令行、可编程 |
| HTTPCanary(小黄鸟) | Android | 手机本地抓包,黑产常用 |
| Stream | iOS | 手机本地抓包 |
# 03.2 防抓包四道线
graph TB
L1[第一道: HTTPS<br/>防被动中间人]
L2[第二道: 证书绑定<br/>防自签证书攻击]
L3[第三道: 代理检测<br/>发现可疑环境]
L4[第四道: 端到端加密<br/>抓到也是密文]
L1 --> L2 --> L3 --> L4
Bonus[业务兜底]
Bonus --> B1[服务端风控]
Bonus --> B2[行为分析]
Bonus --> B3[限流限频]
style L4 fill:#e8f5e8
style Bonus fill:#fff3e0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 03.3 横向对比矩阵
| 方案 | 防御强度 | 实现难度 | 误伤率 | 性能影响 |
|---|---|---|---|---|
| HTTPS | ⭐ | ⭐ | 0% | 低 |
| 证书绑定 | ⭐⭐⭐ | ⭐⭐ | 极低 | 低 |
| 代理检测 | ⭐⭐ | ⭐⭐ | 中(公司代理) | 低 |
| VPN 检测 | ⭐⭐ | ⭐⭐ | 高(VPN 用户多) | 低 |
| 端到端加密 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 0% | 中 |
| 应用加固 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 0% | 中 |
| 服务端风控 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 低 | 0 |
# 04.设计核心原则
# 04.1 多层防御原则
不要押注单一方案——任何一道线都可能被破。
graph LR
A[攻击者] --> L1{HTTPS}
L1 -.破.-> L2{证书绑定}
L2 -.破.-> L3{代理检测}
L3 -.破.-> L4{端到端加密}
L4 -.破.-> Server[服务端风控]
Note[每多一道线<br/>破解成本 +N 倍]
style Server fill:#e8f5e8
style Note fill:#fff3e0
2
3
4
5
6
7
8
9
10
11
# 04.2 检测与拒绝
检测到风险后的处理策略:
mindmap
root((检测到风险))
立即拒绝
最严格
但容易误伤
降级显示
关键功能不可用
普通功能正常
悄悄上报
让黑产以为成功
埋点抓黑产画像
动态加签
检测到风险时<br/>切换签名算法
2
3
4
5
6
7
8
9
10
11
12
13
最佳实战:不要立即拒绝,而是悄悄上报 + 后台风控——让黑产以为成功,避免他们立即换方案。
# 04.3 服务端兜底
铁律:任何客户端的安全都不可信——所有关键校验必须在服务端做。
graph TB
subgraph "❌ 错误: 依赖客户端"
C1[客户端校验金额]
C1 --> Server1[服务端直接信任]
Server1 --> Loss[黑产改 0.01 元也通过]
end
subgraph "✅ 正确: 服务端兜底"
C2[客户端校验金额<br/>提升体验]
C2 --> Server2[服务端再校验<br/>金额/库存/用户/限额]
Server2 --> Safe[安全]
end
style Loss fill:#ffebee
style Safe fill:#e8f5e8
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 04.4 持续对抗原则
防抓包不是"做一次就完事"——必须持续:
- 监控黑产工具更新(HTTPCanary 升级了?)
- 业务有"刷子"信号时升级防御
- 关键活动前做"红队演练"
# 05.方案落地实战
# 05.1 整体架构
graph TB
subgraph "客户端 4 层防御"
Net[网络层 HTTPS + 证书绑定]
Env[环境检测 代理 / VPN / Root / 越狱]
Code[代码加固 混淆 + SO + 反 Hook]
Data[数据层 端到端加密 + 签名]
end
subgraph "服务端兜底"
WAF[WAF 防护]
Risk[风控引擎]
Limit[限流]
Behavior[行为分析]
end
Net --> Env --> Code --> Data
Data --> WAF --> Risk --> Limit --> Behavior
style Net fill:#e3f2fd
style Env fill:#fff3e0
style Code fill:#f3e5f5
style Data fill:#e8f5e8
style Risk fill:#ffebee
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 05.2 第一道线 HTTPS
只用 HTTPS 的限制:
| 防 | 不防 |
|---|---|
| ✅ 公网中间人 | ❌ 用户安装抓包证书 |
| ✅ 流量被运营商劫持 | ❌ 被恶意 App 嗅探 |
| ✅ 传输加密 | ❌ 用户主动 MITM |
强烈建议:
- TLS 1.3(更安全更快)
- HSTS(强制 HTTPS)
- 禁用 TLS 1.0/1.1
# 05.3 第二道线 证书绑定
SSL Pinning(证书绑定):客户端不仅校验"证书有效",还校验"证书是不是我们家的"。
sequenceDiagram
participant App as App
participant Charles as 抓包工具
participant Server as 真实服务
Note over Charles: 自签证书<br/>用户已安装其根证书
App->>Charles: HTTPS 请求
Charles-->>App: 自签证书
App->>App: 1. 系统校验通过 (信任了 Charles 根证书)
App->>App: 2. SSL Pinning 校验:<br/>这个证书 != 内置的我们的证书!
App->>App: 3. 拒绝
Note over App: 抓包失败
2
3
4
5
6
7
8
9
10
11
12
13
14
15
实现方式:
| 方式 | 描述 |
|---|---|
| Public Key Pinning | 绑定服务端公钥的哈希 |
| Certificate Pinning | 绑定证书 |
| CA Pinning | 绑定 CA 颁发机构 |
实战推荐:Public Key Pinning——证书更换不影响绑定。
// OkHttp 实现 Public Key Pinning
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com", "sha256/AAAAAAAAAAAAAA=")
.add("api.example.com", "sha256/BBBBBBBBBBBB=") // 备用
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
2
3
4
5
6
7
8
9
# 05.4 第三道线 代理检测
代理检测的常见方法:
// Android: 检测 HTTP 代理
fun isProxy(): Boolean {
val host = System.getProperty("http.proxyHost")
val port = System.getProperty("http.proxyPort")
return !host.isNullOrEmpty() && !port.isNullOrEmpty()
}
// 检测 VPN
fun isVpnActive(context: Context): Boolean {
val cm = context.getSystemService<ConnectivityManager>()
val networks = cm?.allNetworks
return networks?.any { network ->
cm.getNetworkCapabilities(network)
?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
} ?: false
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
注意:代理检测误伤率高(公司网、海外 VPN、加速器)——只在关键操作时检测,不要全局拦截。
# 05.5 第四道线 端到端加密
业务数据自己加密(即使被抓包也是密文):
flowchart LR
Body[业务数据] --> AES[AES 加密<br/>使用动态会话密钥]
AES --> SignFlow[签名]
SignFlow --> Send[发送]
SessionKey[会话密钥协商<br/>RSA/DH] --> AES
style AES fill:#e8f5e8
style SignFlow fill:#fff3e0
2
3
4
5
6
7
8
9
典型流程:
| 步骤 | 描述 |
|---|---|
| 1. 启动握手 | 客户端用服务端公钥加密一个随机 sessionKey |
| 2. 服务端解密 | 双方都有了 sessionKey |
| 3. 业务通信 | 用 sessionKey 做 AES 加密 |
| 4. 签名 | 用 deviceKey 做请求签名 |
抓到的内容:
{
"encrypted_body": "AES加密的密文,看不懂",
"sign": "签名",
"timestamp": "1234567890",
"nonce": "abc123"
}
2
3
4
5
6
# 06.关键问题解决
# 06.1 双向证书绑定
升级方案:mTLS 双向证书——服务端也校验客户端证书。
sequenceDiagram
participant App as App + 客户端证书
participant Server as Server + 服务端证书
App->>Server: ClientHello
Server->>App: 服务端证书
App->>App: 校验服务端证书 + Pinning
Server->>App: 请求客户端证书
App->>Server: 客户端证书
Server->>Server: 校验客户端证书
Note over App,Server: 双向验证通过
2
3
4
5
6
7
8
9
10
11
12
13
适合场景:金融、银行 App。
# 06.2 越狱 Root 检测
越狱 / Root 设备的风险:黑产可以 Hook 任何 API。
检测手段:
| Android Root 检测 | iOS 越狱检测 |
|---|---|
| 检查 su 命令 | 检查 cydia 文件 |
| 检查 Magisk | 检查 /private 写权限 |
| 检查 root 文件 | 检查 fork 是否成功 |
| Build.TAGS 包含 test-keys | 检查 dyld 注入 |
注意:黑产工具能伪造检测结果——不要完全信任客户端检测。
# 06.3 应用加固混淆
mindmap
root((应用加固))
代码混淆
ProGuard
R8
变量名 a, b, c
SO 加固
关键算法移到 C/C++
JNI 调用
二进制混淆
反调试
检测 Frida
检测 Xposed
检测断点
反 Hook
校验关键函数指针
Inline Hook 检测
完整性校验
签名校验
Dex 哈希校验
防 Patch
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
业界主流加固服务:360 加固、腾讯乐固、阿里聚安全、网易易盾。
# 07.常见陷阱与反例
# 07.1 只用 HTTPS 反例
反例:开篇电商,只用了 HTTPS 就以为安全。
教训:HTTPS 防不了"自家用户主动抓包"。必须 + 证书绑定。
# 07.2 客户端独大反例
反例:金额校验、库存校验、用户身份校验全在客户端做——黑产改一行代码就绕过。
教训:所有关键校验必须服务端做,客户端只是体验优化。
# 07.3 防御静止反例
反例:3 年前做了一套防抓包,3 年没更新——黑产工具早就升级 N 代。
教训:
- 关注黑产工具更新动态
- 关键活动前升级防御
- 持续做攻防演练
mindmap
root((三大反例))
只用 HTTPS
不防主动抓包
必须 + 证书绑定
客户端独大
关键校验在客户端
改代码就绕过
服务端必须兜底
防御静止
不更新
黑产工具升级
持续攻防对抗
2
3
4
5
6
7
8
9
10
11
12
13
# 08.演进路线
# 08.1 V1 仅 HTTPS
特征:业务起步、低安全要求。
做法:
- HTTPS(TLS 1.2+)
- 基础参数签名
适用阶段:MVP / 内部 App
# 08.2 V2 多重加固
特征:业务上规模、有黑产关注。
做法:
- HTTPS + 证书绑定
- 代理 / VPN 检测
- 端到端加密
- 应用加固(混淆 + SO)
- 反调试反 Hook
适用阶段:互联网常规 App
# 08.3 V3 持续攻防对抗
特征:高价值业务(金融、电商大促、游戏)。
做法:
- 一切 V2 措施
- mTLS 双向证书
- 端云协同风控
- 行为指纹 + 设备指纹
- 红蓝对抗演练
适用阶段:金融 / 大型电商 / 头部游戏
flowchart LR
V1[V1 仅 HTTPS<br/>起步] --> V2[V2 多重加固<br/>主流]
V2 --> V3[V3 持续对抗<br/>金融/大厂]
style V1 fill:#e3f2fd
style V2 fill:#e8f5e8
style V3 fill:#fff3e0
2
3
4
5
6
7
# 09.总结与决策
# 09.1 上线检查表
App 上线前对照:
- [ ] HTTPS 全启用 + TLS 1.2+
- [ ] HSTS 启用
- [ ] 证书绑定(Public Key Pinning)
- [ ] 备用证书(防主证书过期)
- [ ] 代理检测(关键操作时)
- [ ] 越狱 / Root 检测(高安全场景)
- [ ] 端到端加密(关键接口)
- [ ] 接口签名 + 防重放
- [ ] 应用混淆(ProGuard/R8)
- [ ] 应用加固(必要时)
- [ ] 反调试 / 反 Hook
- [ ] 服务端 WAF + 风控
- [ ] 限流 / 限频
- [ ] 异常监控告警
- [ ] 应急预案(密钥泄露、签名破解)
# 09.2 选型决策树
flowchart TD
Start([防抓包选型]) --> Q1{业务价值?}
Q1 -->|低 内部/工具| L[HTTPS + 基础签名]
Q1 -->|中 普通互联网| M[L + 证书绑定<br/>+ 端到端加密<br/>+ 加固]
Q1 -->|高 金融/大促| H[M + mTLS<br/>+ 反调试<br/>+ 服务端风控]
Q2([技术能力?]) --> Skill{有安全团队?}
Skill -->|否| ThirdParty[用第三方加固服务<br/>360/腾讯/阿里]
Skill -->|是| Self[自研 + 持续对抗]
style L fill:#e3f2fd
style M fill:#e8f5e8
style H fill:#fff3e0
style ThirdParty fill:#f3e5f5
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最后一句话:防抓包是和黑产的"持续军备竞赛"——目标不是"绝对防住",而是"让破解成本 > 业务红利"。开篇 200 万次刷券的根因,是只用了一道 HTTPS 防线。
好的防抓包设计 = 多层防御、持续迭代、客户端检测、服务端兜底。