首页
社区
课程
招聘
[原创]某App 抓包全流程技术文档
发表于: 1小时前 50

[原创]某App 抓包全流程技术文档

1小时前
50

对 Android 端 xxx App 进行 HTTPS 抓包,获取其商品列表、商品详情、购买信息等核心业务 API 的请求与响应数据。

xxx App 采用了梆梆安全加固方案(Bangcle),拥有业内顶级的多层防护体系,几乎封堵了所有常规抓包手段:

核心挑战:这些防护层相互配合,要成功抓包必须同时绕过所有防护,单独突破任何一层都不够。

为什么用 Shamiko 而不是 DenyList?
Magisk 自带的 DenyList 隐藏能力较弱,梆梆安全的检测能穿透。Shamiko 通过 Zygisk 在更底层实现进程隔离,能有效隐藏 Root 和 Magisk 痕迹。但 Shamiko 要求关闭 Enforce DenyList(由 Shamiko 自己接管)。

在找到最终方案前,经历了大量尝试。记录这些失败对理解 App 的防护强度非常有价值。

结论:模拟器路线完全不可行,必须使用真机。

最终的方案是多层协同绕过,每一层解决一个特定的防护问题,且不触发其他防护:

Magisk 28.1 + Shamiko v1.2.1 (blacklist mode)

这是最关键的技术环节。app没有使用 network_security_config.xml,SSL Pinning 在代码中通过 BoringSSL 的验证函数实现。

Android 11 使用 conscrypt APEX 模块提供 SSL/TLS 实现,其中的 libssl.so 包含证书验证函数。通过 patch 这些函数,可以让所有 SSL 验证都变成"不验证"模式。

① 从手机拉取原始 libssl.so

② 用 Python 脚本 Patch(patch_libssl.py

脚本解析 ELF 文件的动态符号表,找到 4 个 SSL 验证函数,将每个函数的第一条 ARM64 指令替换为 MOV W1, #0

为什么 patch W1 而不是直接 RET? ARM64 调用约定中 W1 是第二个参数(mode),将其设为 0 即 SSL_VERIFY_NONE。函数仍然正常执行后续逻辑(设置回调指针等),只是验证模式变成了"不验证",这比直接 RET 更稳定。

③ 推送并用 Mount Bind 替换

④ 验证 mount bind 生效

为什么用 Mount Bind 而不是直接替换文件?
APEX 模块是只读挂载的,无法直接修改文件。Mount Bind 在文件系统层面将一个路径"覆盖"到另一个路径上,读取目标路径时实际读到的是我们的 patched 文件。这完全不影响原始文件,App 的完整性校验检查的是 APK 签名,不会发现 SO 被替换了。

新版增加了 libbangcle_risk.so(梆梆风控 SDK),其中包含代理和 VPN 检测逻辑。

脚本解析 ELF 的 DYNAMIC 段(因为 section header 被混淆),通过字符串引用搜索找到 JNI_OnLoad 函数入口,patch 为直接返回 JNI_VERSION_1_6

同时 patch .init_arrayDT_INIT 中的初始化函数为 RET,禁止风控 SDK 在库加载时执行任何初始化逻辑。

部署方式同样用 Mount Bind:

即使 patch 了 libbangcle_risk.so,风控 SDK 仍可能通过 Java 层检测到异常并启动退出页面。解决方案极其巧妙——直接禁用风控 Activity 组件

原理:风控检测发现异常后,会尝试启动 com.bangcle.everisk.core.c 这个 Activity 来显示"设备异常"的退出页面。禁用这个组件后,Activity 无法启动,但 App 的主进程不会因此崩溃——它只是无法显示退出弹窗了,于是静默地继续运行。

注意:每次重启手机后需要重新执行此命令。

mitmproxy 的 CA 证书通过 Magisk 模块安装到系统级信任存储:

安装后重启,证书出现在"系统" → "安全" → "信任的凭据"中。

所有绕过措施准备好后,每次抓包的操作流程如下:

关键点

H5 Token 需要从抓包中的 Cookie 字段获取。

手机重启后以下设置会失效,需要重新执行:

手机没有 SIM 卡时自动时间同步可能不工作,需要手动同步:

mitmproxy 12.x 默认对 Web UI 启用认证,启动时需要设置 --set web_password='密码',然后在浏览器中输入密码。

五层缺一不可。

防护层 技术实现 效果
代理检测 libbangcle_risk.so 检测系统 HTTP 代理设置 检测到代理后弹窗退出
VPN 检测 检测 VPN 网络接口(tun0 等) 检测到 VPN 后弹窗退出
SSL Pinning 代码级 SSL 证书锁定(非 network_security_config.xml HTTPS 请求无法被中间人解密
注入检测 检测 Frida、Xposed 等注入框架的进程特征 检测到后 native crash(fault addr 0xdeadcab1
Root 检测 检测 su 二进制、Magisk 等 Root 痕迹 检测到后弹窗"设备异常"退出
模拟器检测 libemulator_check.so + XOX SDK 多层检测 x86 翻译层/内核特征/硬件特征全覆盖
完整性校验 APK 签名校验 + SO 文件完整性校验 修改 APK 或 SO 后闪退
风控 SDK com.bangcle.everisk 运行时风控引擎 采集设备信息并动态判定风险
设备 规格 说明
Mac Apple Silicon (macOS 15) 抓包主机
Pixel 4 XL Android 11, 序列号 99111FFBA00BP3 目标设备(必须真机,模拟器无法绕过检测)
USB 数据线 USB-C 连接 Mac 和手机
软件 版本 用途
Magisk v28.1 (28100) Root 方案 + 模块管理
Zygisk 内置于 Magisk 28.1 Shamiko 运行依赖
Shamiko v1.2.1 (383) Root 隐藏(blacklist 模式)
LSPosed v1.9.2 Xposed 框架(Zygisk 版,仅安装未对xx启用模块)
xxx v1.9.4 目标 App
软件 版本 用途
ADB Android SDK Platform-Tools 设备通信
mitmproxy / mitmweb v12.2.1 HTTPS 中间人代理 + Web 可视化界面
Python 3.12+ 脚本工具 & ELF Patch
# 方案 失败原因
1 MuMu 模拟器 + Frida hook XOX SDK 检测到 x86 翻译层,native crash
2 MuMu + LSPosed + Device Emulator XOX native 层检测绕不过
3 MuMu + Shamiko 同上
4 AVD ARM64 (API 34, 干净) 弹窗"非安全场景"(模拟器内核特征被检测)
5 AVD + Magisk + LSPosed XOX 检测到 root,crash
6 AVD + Frida Server 被检测,crash (state=543)
7 AVD + Frida Gadget (改名 libhelper.so) XOX 通过文件内容特征识别 Frida,crash
8 AVD + resetprop 改属性 部分属性改成功,但内核级特征改不了
9 AVD + patch libemulator_check.so 绕过完整性校验后,libhaotiansec.so 内部还有检测
10 AVD + patch 所有安全 so 的 init_array 加固壳不工作,app 卡住
11 AVD + 选择性 patch init_array 每个 init 函数都是加固壳需要的,不能动
# 方案 结果
1 Magisk 23.0 + MagiskHide 旧版 XOX 检测到 root,crash
2 Magisk 26.4 + DenyList 不够强,还是被检测
3 Magisk 26.4 + Shamiko v1.0.1 还是被检测
4 Magisk 28.1 + Shamiko v1.2.1 旧版 正常运行 ✓
5 更新apk后 新版 everisk 检测到异常,10 秒退出
方案 失败原因
mitmproxy + 系统代理 App 检测到代理设置
VPN 模式抓包 App 检测到 VPN
Xposed SSL Bypass 模块 被 App 检测到 Xposed 注入,直接退出
API 来源 Token 类型 传递方式
Native App API (app.xxx.com.cn) MT-Token HTTP Header
H5 WebView API (h5.xxx.com.cn) MT-Token-Wap Cookie
Zygisk:           已启用
Enforce DenyList: 已关闭 ← Shamiko 要求必须关闭
DenyList:         com.xxx.mall 及所有子进程已加入
Magisk App 包名:  已隐藏(随机化)
┌─────────────────────────────────────────────────────┐
│                    xx App                         │
├─────────────────────────────────────────────────────┤
│  Layer 5: 风控 Activity 禁用                        │ ← pm disable
│  Layer 4: 代理/VPN 检测绕过                         │ ← patch libbangcle_risk.so
│  Layer 3: SSL Pinning 绕过                          │ ← patch libssl.so
│  Layer 2: Root 隐藏                                 │ ← Shamiko v1.2.1
│  Layer 1: Root 权限                                 │ ← Magisk 28.1
├─────────────────────────────────────────────────────┤
│  Android 11 (Pixel 4 XL)                            │
└─────────────────────────────────────────────────────┘
# 找到 conscrypt APEX 中的 libssl.so
adb shell "su -c 'find /apex/com.android.conscrypt -name libssl.so'"
# 输出: /apex/com.android.conscrypt/lib64/libssl.so

# 拉取到本地
adb shell "su -c 'cp /apex/com.android.conscrypt/lib64/libssl.so /data/local/tmp/libssl_orig.so && chmod 644 /data/local/tmp/libssl_orig.so'"
adb pull /data/local/tmp/libssl_orig.so /tmp/libssl_orig.so
# ARM64 指令: mov w1, #0
# 将 SSL 验证模式参数强制设为 SSL_VERIFY_NONE (0)
MOV_W1_0 = struct.pack('<I', 0x52800001)

# 目标函数
targets = [
    'SSL_CTX_set_verify',       # 设置 SSL 上下文验证模式
    'SSL_set_verify',           # 设置 SSL 连接验证模式
    'SSL_CTX_set_custom_verify', # 设置自定义验证回调
    'SSL_set_custom_verify',     # 设置自定义验证回调
]
# 推送 patched 文件到手机
adb push /tmp/libssl_patched.so /data/local/tmp/libssl_patched.so

# 使用 Magisk 的 --mount-master 进行 mount bind
# 这样不修改原始文件,绕过完整性校验
adb shell "su --mount-master -c 'mount --bind /data/local/tmp/libssl_patched.so /apex/com.android.conscrypt/lib64/libssl.so'"
# 比较 MD5,应该一致
adb shell "su -c 'md5sum /apex/com.android.conscrypt/lib64/libssl.so /data/local/tmp/libssl_patched.so'"
# 找到 JNI_OnLoad 的函数序言 (STP x29, x30, [sp, #imm]!)
# 替换为:
#   movz w0, #6         → 0x528000c0
#   movk w0, #1, lsl #16 → 0x72a00020  (w0 = 0x10006 = JNI_VERSION_1_6)
#   ret                  → 0xd65f03c0
adb push /tmp/libbangcle_risk_patched.so /data/local/tmp/libbangcle_risk_patched.so
adb shell "su --mount-master -c 'mount --bind /data/local/tmp/libbangcle_risk_patched.so /data/app/<包路径>/lib/arm64/libbangcle_risk.so'"
adb shell "su -c 'pm disable com.moutai.mall/com.bangcle.everisk.core.c'"
# 在手机上创建 Magisk 模块目录
mkdir -p /data/adb/modules/mitm_cert/system/etc/security/cacerts/

# 将 mitmproxy CA 证书(~/.mitmproxy/mitmproxy-ca-cert.cer)
# 转换为 Android 系统证书格式并推送到该目录
# 文件名格式: <hash>.0
# 1. 连接手机(USB)
adb devices -l
# 确认: 99111FFBA00BP3  device  usb:0-1  ...

# 2. 禁用风控 Activity(每次重启后需要)
adb shell "su -c 'pm disable com.xxx.mall/com.bangcle.everisk.core.c'"

# 3. 验证 SSL mount bind 是否还在(重启后会失效)
adb shell "su -c 'md5sum /apex/com.android.conscrypt/lib64/libssl.so /data/local/tmp/libssl_patched.so'"
# 如果 MD5 不一致,需要重新 mount bind:
# adb shell "su --mount-master -c 'mount --bind /data/local/tmp/libssl_patched.so /apex/com.android.conscrypt/lib64/libssl.so'"

# 4. 设置 USB 端口转发
adb reverse tcp:8080 tcp:8080

# 5. 设置系统代理
adb shell "settings put global http_proxy 127.0.0.1:8080"

# 6. 启动 mitmweb(带可视化 Web 界面)
mitmweb -p 8080 --web-port 8081 \
  --set block_global=false \
  --set web_password='你的密码' \
  --showhost \
  --no-web-open-browser

# 7. 浏览器打开 bb0K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5J5y4#2)9J5k6e0m8Q4x3X3f1H3i4K6u0W2x3g2)9K6b7e0R3H3z5o6p5`. 查看抓包界面

# 8. 启动 App
adb shell "monkey -p com.xxx.mall -c android.intent.category.LAUNCHER 1"

传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 1小时前 被灵谷编辑 ,原因:
收藏
免费 3
打赏
分享
最新回复 (2)
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
感谢分享
43分钟前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
1
30分钟前
0
游客
登录 | 注册 方可回帖
返回