damyan-deshev/ssl-pinning-toolkit

GitHub: damyan-deshev/ssl-pinning-toolkit

面向授权安全研究的 Android TLS 证书锁定检测工具包,通过 Frida hook 和原生库指纹识别实现对现代 Android 应用多层 TLS 实现的可重复审计。

Stars: 0 | Forks: 0

# Android TLS 检查工具包 用于检查 Android TLS pinning 攻击面的授权研究工具包:包含 Frida hooks、原生库指纹以及适用于现代 arm64 应用的可重复验证协议。 本仓库特意仅包含工具和协议。不包含目标 APK、提取的应用资产、流量捕获、凭据、生产日志或客户数据。 ## 1) 目的 现代 Android 应用通常结合使用 Java pinning、Cronet、原生 BoringSSL 路径、剥离的符号以及特定构建的原生库。本项目旨在使这项工作保持可检查性: - 通过 build-id、`.rodata` 哈希或 ELF header 哈希来识别原生库指纹; - 将已知构建映射到明确的 hook 目标和签名; - 将探测模式和签名窗口与活动 hooks 分离; - 记录验证过程,以便结果可重复且可审查。 ## 2) 本仓库的作用 - 在受控的 Android 测试环境中提供用于授权 TLS 检查的 Frida agent。 - 检测特定的原生库构建,并应用已知、可审查的 hook 偏移量。 - 支持可选的 anchor 扫描,以检查未知构建而无需自动推导偏移量。 - 为安全分析师和工程师的可重复工作流提供简短和详细的测试协议。 ## 3) 本仓库的局限性 - 不包含目标应用程序、提取的 APK 内容、流量捕获或私人测试数据。 - 不授予测试第三方系统的授权。 - 不能自动解决每一个自定义加密或应用层加密方案。 - 不包含完整的熵追踪器或基于 Stalker 的分析。 - 当前版本不支持 32 位架构。 ## 4) 受众与角色 - 管理人员:阅读第 1、5、8 和 13 节以了解进展和成果。 - 分析师:遵循 `TESTING_PROTOCOL_EXTENDED.md` 中的协议。 - 工程师:使用 `sigdb.py`,更新 `sig_db.json`,并运行 `ssl_kill.js`。 ## 5) 安全与授权 仅测试您被明确授权分析的应用程序。使用专用的测试设备、合成账户和经过净化的测试夹具。请勿使用个人或生产账户。 ## 6) 仓库结构 - `ssl_kill.js`:执行 SSL 绕过和签名数据库查找的 Frida agent。 - `sig_db.json`:以 build-id 或哈希为键的签名数据库。 - `sigdb.py`:用于提取库指纹和添加数据库条目的辅助工具。 - `TESTING_PROTOCOL.md`:简短的分步测试指南。 - `TESTING_PROTOCOL_EXTENDED.md`:适用于混合受众的详细协议。 ## 7) 支持的环境 - 仅限 Android arm64(当前版本)。 - 带有 Frida server 的已 root 设备。 - 带有 Python 3、Frida CLI 和 ADB 的主机。 ## 8) 核心概念(通俗语言 + 技术细节) ### 8.1 签名数据库 签名数据库(`sig_db.json`)将特定的库构建映射到我们要 hook 的函数偏移量。“构建”通过以下方式识别: 1. `build_id`(最佳情况) 2. `.rodata` 哈希(备选方案) 3. ELF header 哈希(最后手段) 数据库 schema 刻意保持简单并具备前瞻性: ``` { "schema_version": 1, "offset_base": "module", "arm64": { "libcronet.so": { "enable_anchor_scan": true, "probe_defaults": { "enabled": false, "min_hits": 1, "deadline_sec": 12 }, "builds": { "build_id:abcd...": { "source": "build_id", "targets": [ { "name": "x509_verify_cert", "offset": "0x1234", "hook": "ret1", "sig": { "win1": { "off": "0x0", "bytes": "fd7bbfa9fd030091", "mask": "ffffffffffffffff" }, "win2": { "off": "0x18", "bytes": "f40300aa", "mask": "ffff00ff" } } } ] } }, "anchors": [ { "id": "boringssl_global_config", "type": "string", "value": "Global configuration for BoringSSL" } ] } } } ``` ### 8.2 模块基址偏移量 所有偏移量都是相对于模块基址的。请勿使用 `.text` 相对偏移量。这可以避免与 ASLR 混淆并保持计算简单: ``` module_base + offset = hook_address ``` ### 8.3 Hook 类型 Hook 类型刻意仅限于简单的返回值覆盖: - `ret1`:强制成功(返回 1) - `ret0`:强制成功(返回 0) ### 8.4 签名窗口(字节 + 掩码) 每个目标可以选择包含双窗口签名检查: - `win1`:靠近函数序言(稳定性检查) - `win2`:深入函数内部(版本检查) 每个窗口包含长度相等的 `bytes` 和 `mask`。掩码允许将与重定位相关的字节进行通配处理。 ### 8.5 探测与提交 目标可以从 `probe` 模式(仅计数)开始,并在达到足够命中次数后提升为活动模式。 - 可以为每个库设置 `probe_defaults`。 - 仅头部指纹匹配仅保持探测模式,除非签名匹配。 这可以保持 hooks 稳定,并避免调用未知的代码路径。 ### 8.4 Anchor 扫描 当构建未知时,脚本可以扫描字符串锚点(错误消息)以帮助定位验证逻辑。这由以下内容控制: ``` "enable_anchor_scan": true ``` Anchor 扫描仅记录候选地址。目前尚不能自动推导偏移量。 ## 9) 基本工作流程(简版) 1. 从 APK 中提取目标库。 2. 使用 `sigdb.py` 提取库指纹。 3. 查找验证函数偏移量(手动分析)。 4. 在 `sig_db.json` 中注册偏移量。 5. 使用 `ssl_kill.js` 运行应用程序。 6. 初始化数据库并重新扫描。 7. 验证 TLS 拦截。 ## 10) 命令示例 指纹提取: ``` python sigdb.py fingerprint /path/to/libcronet.so ``` 注册目标: ``` python sigdb.py add --db sig_db.json --arch arm64 --lib libcronet.so \ --elf /path/to/libcronet.so \ --target x509_verify_cert:0x1234:ret1 \ --target ssl_get_verify_result:0x5678:ret0 ``` 注册带有签名的目标(按目标,有序): ``` python sigdb.py add --db sig_db.json --arch arm64 --lib libcronet.so \ --elf /path/to/libcronet.so \ --target x509_verify_cert:0x1234:ret1 \ --sig @sig_x509.json \ --target ssl_get_verify_result:0x5678:ret0 \ --sig @sig_verify_result.json ``` 签名文件示例(`sig_x509.json`): ``` { "win1": { "off": "0x0", "bytes": "fd7bbfa9fd030091", "mask": "ffffffffffffffff" }, "win2": { "off": "0x18", "bytes": "f40300aa", "mask": "ffff00ff" } } ``` 运行 Frida: ``` frida -U -f com.target.app -l ssl_kill.js --no-pause ``` ## 11) RPC 用法(技术性) Frida 脚本期望通过 RPC 传递数据库: 伪流程: 1. 加载脚本 2. 调用 `init(db_json)` 3. 调用 `rescan()` 示例(Python,最小化): ``` import frida, json device = frida.get_usb_device() pid = device.spawn(["com.target.app"]) session = device.attach(pid) with open("sig_db.json", "r", encoding="utf-8") as fh: db = json.load(fh) script = session.create_script(open("ssl_kill.js", "r", encoding="utf-8").read()) script.load() script.exports.init(db) script.exports.rescan() device.resume(pid) ``` ## 12) 测试协议 - 使用 `TESTING_PROTOCOL.md` 获取简短检查清单。 - 使用 `TESTING_PROTOCOL_EXTENDED.md` 获取详细的 SOP 和故障排除指南。 ## 13) 操作说明(实用指南) - 如果存在 build-id,它是最可靠的匹配键。 - 仅头部匹配被视为弱匹配;建议使用签名以确保安全使用。 - 如果启用了 anchor 扫描,在大型模块上可能会很慢。仅在必要时使用。 - 务必验证偏移量是基于模块的。错误的偏移量可能导致应用程序崩溃。 - Cronet 可能通过 `android_dlopen_ext` 加载;脚本会 hook 该路径。 ## 14) 故障排除(快速) - Frida 无法附加:验证 frida-server 版本和 root 状态。 - 未应用 hooks:检查数据库条目、指纹键和偏移量。 - 代理中无流量:验证 CA 安装以及应用是否使用 Cronet。 - Anchor 扫描无日志输出:字符串可能已被剥离或压缩。 ## 15) 局限性与未来工作 当前局限性: - 仅限 arm64 - 没有从 anchors 自动进行 XREF 解析 - 没有针对应用层加密的熵追踪 未来可能的工作: - 自动 ADRP/ADD XREF 解析 - 可选的熵追踪器(Stalker)用于 ALE 发现 - 支持其他架构 ## 16) 支持与上报 如果您遇到阻碍: 1. 捕获日志和错误。 2. 保存库文件和指纹输出。 3. 上报给工程师以进行偏移量提取和数据库更新。 由 [Damyan Deshev](https://github.com/damyan-deshev) 维护 - 本地优先软件、安全研究工具、确定性诊断和实用的产品系统。
标签:Android安全, arm64, BoringSSL, Cronet, ELF解析, Frida Hook, Homebrew安装, SSL Pinning绕过, TLS检查, 云资产清单, 原生库分析, 安全合规, 授权测试, 数据可视化, 测试协议, 目录枚举, 移动安全, 移动应用安全, 网络代理, 网络安全, 自定义脚本, 逆向工程, 隐私保护