Files

3.8 KiB
Raw Permalink Blame History

macOS 应用逆向决策树与证据分级

场景决策树(入口 → 分支)

1. 目标形态分支(第一级)

目标对象
├─ .app bundle → 解包 Contents/,先读 Info.plist 与可执行文件
├─ 单二进制(命令行工具/daemon)→ 直接 codesign/Mach-O 分析
├─ dylib / framework → 依赖关系与导出面为主(otool -L / nm)
├─ 安装包(pkg/dmg)→ 先解包提取载荷(pkgutil --expand)
└─ 无签名/adhoc 签名 → 跳过签名面,直接静态分析

2. 签名与分发状态分支(第二级,决定动态方案)

codesign -dv 结果
├─ Apple 开发者/分发签名
│  ├─ 公证通过(spctl -a 过)→ 正规分发;仍按恶意面分析(公证≠安全)
│  ├─ 公证失败/未公证 → Gatekeeper 会拦;本地仍可分析
│  └─ Hardened Runtime 开 → 注入受限(见分支 3)
├─ 第三方/自签 → 注入面大,但可能带自定义校验
└─ 无签名 → 最容易动态,但注意系统会拦截运行(Gatekeeper/AMFI)

3. 动态可行性分支(第三级)

想动态执行(lldb attach / DYLD_INSERT_LIBRARIES / frida)
├─ Hardened Runtime 且无 cs.allow-dyld-environment-variables
│  └─ DYLD 注入不可行 → lldb attach 或静态分析([[re-ghidra]])
├─ PT_DENY_ATTACH(ptrace 拦截)→ 先 patch 调用点([[re-patching]])再 attach
├─ 沙箱开启 → 动态观察被限制在沙箱能力内(以 entitlements 为准)
└─ 全无限制 → 标准 lldb / frida 流程(沙箱环境内,[[re-analyze/platform-tips]])

4. 数据目标分支(第四级)

要拿什么
├─ 网络行为 → 抓包([[re-netcap]])+ 沙箱网络权限确认
├─ 钥匙串条目 → 定位 SecItemCopyMatching 调用点,读用途与访问条件(可访问性/访问控制,不导出内容,红线)
├─ Secure Enclave 密钥 → 确认 tokenID,记录用途(不可提取,不找字节)
├─ 本地文件/偏好 → 容器路径(沙箱下在 ~/Library/Containers/)分析
└─ 授权/注册逻辑 → 校验 API 调用点 → [[re-license]] 方法论

证据分级表

级别 证据形态 示例 用途
A 强 动态 + 静态交叉闭合 动态观察到网络外传,静态代码与 entitlements(network.client)一致 可下「恶意行为」结论
B 中 单侧完整证据链 静态完整还原调用链(含触发条件),未动态确认 可下「高可疑」
C 弱 静态特征 只有高危 entitlement(如 device.* 全开)+ 高混淆 只支持「需深入」
反证 良性解释 权限声明与功能相符、行为与声明一致 记录并存档
  • 能力边界以动态行为为准:entitlements 声明的能力 ≠ 实际使用的能力,两者都要记录
  • 签名/公证结论与恶意结论分开陈述(「分发状态」与「行为定性」是两个维度)

实现教训(内化)

  • 先读 Info.plist + entitlements 再定动态方案——hardened runtime/沙箱直接决定注入与观察手段
  • 签名信息本地可查(codesign -d -r- / -dv),公证状态需网络——离线时用本地信息替代并标注
  • TCC 数据只读分析、不导出内容(红线);Full Disk Access 是读取前置,先确认授权
  • Secure Enclave 密钥记用途不找字节;钥匙串条目记录访问条件与访问点而非口令内容
  • 动态观察在沙箱内进行(re-sandbox,re-analyze/platform-tips 最高原则)
  • 证据链记录:签名者/Team ID、entitlements 原文、TCC 依赖点、dyld 依赖清单、动态行为对照

使用注意

  • 沙箱内执行动态(re-sandbox);TCC/钥匙串数据只读不导出(红线)
  • 结论按本表分级标注,签名/公证维度与行为维度分开陈述