9.0 KiB
9.0 KiB
name, type, description, capabilities
| name | type | description | capabilities | |
|---|---|---|---|---|
| re-macos | atomic | macOS 原生应用逆向:App Bundle/签名公证、entitlements、沙箱与 TCC、钥匙串与 Secure Enclave。 触发词:macOS逆向、mac app、entitlements、Secure Enclave、钥匙串、TCC、codesign、公证。 |
|
macOS 应用逆向
何时使用 / 何时不用
- 用:macOS 原生/闭源应用(.app/.dylib/.framework)、带签名公证与沙箱的目标、钥匙串/Secure Enclave 硬件密钥场景
- 用:授权/分发状态判定——签名者、公证、hardened runtime、Team ID 是谁(分发面/信任面分析)
- 用:信任链问题——Dylib Hijacking、注入面、TCC 依赖(哪些隐私能力被请求/使用)
- 不用:iOS 应用(转 re-ios);纯 Mach-O 格式解析(转 re-format-macho)
- 不用:Linux/Windows 目标(各走 re-gdb / re-x64dbg)
- 不用:只想抓网络流量/文件行为(无 macOS 特有面时走 re-behavior / re-netcap 通用路径)
- 注意:TCC 与钥匙串数据属系统隐私范畴,只读分析不导出内容(红线)
工具准备
codesign / spctl / otool / lipo(签名与 Mach-O 工具,macOS 内置)
- macOS: 系统自带(Xcode 命令行工具
xcode-select --install) - Linux: 可静态分析 Mach-O(
llvm-otool,brew install llvm或发行版 llvm 包),签名解析受限 - 验证:
codesign --version、macOS:otool --version;Linux:llvm-otool --version
plutil / xattr(Info.plist 与 quarantine 检查,macOS 内置)
- 验证:
plutil -help、xattr -h - 用途: Info.plist 键解析(
plutil -p);com.apple.quarantine扩展属性决定 Gatekeeper 是否拦截
Hopper / IDA / Ghidra(反编译底座)
lldb(动态调试)
- 安装与验证见 re-lldb;attach 前先处理 PT_DENY_ATTACH(步骤 6)
操作步骤
按顺序执行,每步产物存档(路径 + sha256,见 re-triage)。签名/entitlements 信息按 re-analyze/analysis-contract 契约记录。
-
包结构与签名检查:
file Sample.app/Contents/MacOS/Sample codesign -dv Sample.app 2>&1 | head # 签名者/Team ID(要求需 `-d -r-` 查看) spctl -a -vv Sample.app 2>&1 # 公证状态(Gatekeeper) defaults read Sample.app/Contents/Info.plist # Info.plist 关键键- 关注:签名者(Apple 开发者/分发证书)、Team ID、CDHash、Hardened Runtime(runtime 标志)、Info.plist 的 CFBundleIdentifier/版本/最低系统版本
- 架构确认:
file输出/x86_64 与 arm64 通用二进制(lipo -archs)——决定反编译与动态环境(Apple Silicon 上 arm64e 有 PAC 差异,见 gotchas) - 公证派生检查:
spctl -a通过不保证本地有 staple——xcrun stapler validate Sample.app查票证是否随包 - 隔离属性检查:
xattr -l Sample.app看com.apple.quarantine(隔离标志 + 时间戳 + 责任方 App;不含来源 URL——来源信息在 Spotlight 属性里,用mdls -name kMDItemWhereFroms Sample.app查)
-
entitlements 与沙箱:
codesign -d --entitlements :- Sample.app 2>&1 | head -30- 关键键分组:
com.apple.security.app-sandbox(沙箱总开关)、network.client/server(网络)、files.user-selected.*(用户选文件)、device.camera/microphone(设备)、application-groups(组共享)、cs.allow-dyld-environment-variables/cs.disable-library-validation(注入面)、get-task-allow(调试权限,发布版不应有) - 沙箱 profile 决定能力边界——分析授权逻辑与攻击面时先看 entitlements 清单,动态行为再交叉验证
- 异常信号:发布版带
get-task-allow(本应只用于开发调试)或越权组合(如无 UI 却开device.camera)——记录为可疑项进结论
- 关键键分组:
-
TCC 权限库:
# 用户级 TCC 库(授权记录) ls ~/Library/Application\ Support/com.apple.TCC/ # 系统级 TCC 库 ls /Library/Application\ Support/com.apple.TCC/- 前置检查:TCC.db 自身受 TCC 保护——无 Full Disk Access 时读取会权限失败,先确认授权再读
- TCC.db(SQLite)记录各 App 对隐私资源的授权;分析目标对 TCC 的依赖(请求了什么权限、何时请求、失败路径)
- 注意:TCC 数据属系统隐私数据,只读分析不导出内容(红线)
-
钥匙串与 Secure Enclave:
- 钥匙串条目类型(通用密码/互联网密码/密钥)与访问条件——
kSecAttrAccessible是可访问性(设备处于什么状态时可读:非锁定/首次解锁/此设备),不是 ACL;访问控制是kSecAttrAccessControl/SecAccessControl(生物识别/密码门槛),macOS 传统 ACL 另有SecAccess/kSecAttrAccess(见 gotchas) - Secure Enclave 密钥:用
SecKeyCreateRandomKey(属性含kSecAttrTokenID: kSecAttrTokenIDSecureEnclave)在设备内生成——SecKeyCreateWithData是从外部 key data 导入/恢复,SE 私钥永不出芯片、无法导入,别把它当 SE 生成接口;私钥不可提取(等价 Android Keystore 硬件背书,见 re-android-native Keystore 审计) - 分析:目标读哪些钥匙串条目(SecItemCopyMatching 调用点)、密钥是否 Secure Enclave 绑定(不可提取 → 记录用途与访问条件而非找字节)
- 钥匙串条目类型(通用密码/互联网密码/密钥)与访问条件——
-
dyld 加载链:
otool -L Sample.app/Contents/MacOS/Sample | head # LC_LOAD_DYLIB 依赖 otool -l Sample.app/Contents/MacOS/Sample | grep -A4 LC_RPATH- 依赖清单与 RPATH → Dylib Hijacking 面(可写目录 + 缺失依赖组合)
- 注入面:DYLD_INSERT_LIBRARIES 受 hardened runtime 限制——entitlements 无
cs.allow-dyld-environment-variables时不生效;system 完整性保护下对系统路径注入无效 - 注入验证:环境变量 + 沙箱内试跑
DYLD_INSERT_LIBRARIES=/path/to/hook.dylib ./Sample,无效即回到静态路径(re-ghidra),不硬注入
-
反调试与保护:
-
证据核对(收尾):签名者/Team ID/entitlements 原文、TCC 依赖点、钥匙串条目用途、dyld 依赖清单——按 re-analyze/analysis-contract 入档;动态结论与静态清单对照(能力边界以动态行为为准,见 decision-tree)
跨域联合
- re-format-macho:Mach-O 格式底座(LC_* 解析)
- re-ios:iOS 侧互补(越狱生态与 entitlements 差异)
- re-lldb:动态调试
- re-frida:动态插桩(macOS 桌面支持)
- re-sandbox / re-analyze/platform-tips:动态执行隔离(签名/行为观察在沙箱内进行)
- re-analyze/analysis-contract:签名/entitlements 信息按数据契约传递
- re-patching:PT_DENY_ATTACH 与签名校验点的持久化处理
- Swift 层分析(mangling/witness table)→ re-swift
常见坑与陷阱
- 签名校验多处触发:现象——patch 后运行即退;原因——加载/运行/更新多处校验;对策——逐点定位(步骤 6),先处理校验点再过逻辑
- Secure Enclave 密钥不可提取:现象——内存搜不到私钥;原因——硬件背书;对策——记录用途与访问条件,不找字节(见步骤 4)
- TCC 权限导致功能缺失:现象——目标功能灰掉;原因——TCC 未授权;对策——分析其请求逻辑而非绕过系统权限(红线)
- 公证检查离线不可复现:现象——离线环境 spctl 结果异常;原因——公证需要网络查询(含吊销状态);对策——用 codesign 本地签名信息替代,标注「公证状态未验证」
- hardened runtime 限制注入:现象——DYLD_INSERT_LIBRARIES 无效;原因——runtime 标志未含 allow-dyld 环境变量;对策——静态分析路径(re-ghidra),不硬注入
- quarantine 干扰运行:现象——目标下载来源时崩溃/弹窗;原因——
com.apple.quarantine触发 Gatekeeper 检查;对策——xattr -dr com.apple.quarantine去除后重测(仅测试环境) - 嵌套签名漏处理:现象——patch 后运行时校验失败;原因——framework/helper/扩展各自独立签名,只重签主程序不够;对策——
codesign --deep或逐层重签,核对每层 CDHash - 决策分支(动态可行性判定/数据目标分级)见 decision-tree;签名/注入/TCC 边界与反例见 gotchas;全部在沙箱内执行(re-analyze/platform-tips 最高原则)