关于 mobile-audit
mobile-audit 是面向 iOS 和 Android 应用安全审查的技能,依据 OWASP MASVS 与 MASTG 检查源代码、编译产物和运行时行为。它强调授权测试、证据验证及可追溯的发现记录。
主要功能
- 01按 MASVS 检查移动应用安全
- 02审查存储、加密、网络与认证
- 03结合静态分析和运行时测试
- 04验证证据并记录审计发现
适用场景
- 01审查应用中的敏感数据存储
- 02测试移动应用的网络与认证控制
- 03调查应用与设备或其他应用的交互风险
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ briiirussell/ cybersecurity-skills --skill mobile-audit安装后在 Claude Code 中输入/mobile-audit确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/findings-format.mdfindings.schema.jsonseverity-calibration.mdto-sarif.mjsvalidate-findings.mjsverification.md详细介绍
移动端审计 — iOS 与 Android 应用安全审查
依据 OWASP Mobile Application Security Verification Standard(MASVS)和 Mobile Application Security Testing Guide(MASTG)审计移动应用。涵盖源代码审查、已编译二进制文件的静态分析和运行时测试。
范围:此技能涵盖 应用 及其与设备、后端和其他应用的交互。对于后端 API 安全审计,请搭配 api-audit。对于依赖项 CVE(CocoaPods、SPM、Gradle),请搭配 dependency-audit。
授权检查
在对二进制文件进行逆向工程或运行时测试前,请确认:
- 应用归你所有,或你已获得发布方的书面授权
- 你在自己掌控的环境中操作(测试设备、模拟器、专用沙箱)
- 应用商店服务条款 — Apple 和 Google 通常允许对你拥有的应用进行安全研究;未经授权测试竞争对手的应用,很容易引发法律风险
如有疑问,请先询问,再继续。
审计清单 — MASVS-STORAGE(敏感数据存储)
- iOS: Keychain 项使用最强的可用
kSecAttrAccessible类别 —kSecAttrAccessibleWhenUnlockedThisDeviceOnly或kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly。避免使用Always和不带ThisDeviceOnly的变体 - iOS:
NSUserDefaults、plist 或应用包中不得包含机密 —strings <app>.ipa不应泄露 API 密钥或机密 - Android: 使用 EncryptedSharedPreferences / 基于 Keystore 的加密存储保存机密,不要使用未加密的 SharedPreferences
- Android: 在清单中设置
android:allowBackup="false"(或谨慎限制备份规则)— 否则adb backup会提取所有内容 - 两者: 不得将个人身份信息(PII)/ 令牌写入崩溃后仍会保留的日志(NSLog、Log.d、第三方崩溃报告工具)
- 两者: 粘贴板 / 剪贴板访问 — 敏感字段不得自动共享到系统剪贴板(iOS 使用
pasteboard.expirationDate,Android 使用ClipDescription.EXTRA_IS_SENSITIVE) - 两者: 操作系统的应用切换器截图不得截取敏感页面 — iOS 使用
applicationDidEnterBackground模糊处理,Android 在 activity 上设置FLAG_SECURE
审计清单 — MASVS-CRYPTO(密码学)
- 应用包中不得硬编码密钥 —
strings、class-dump、apktool可发现嵌入的常量 - 仅使用现代算法 — AES-GCM、ChaCha20-Poly1305;拒绝 AES-ECB、DES、RC4、MD5、SHA-1
- 随机数生成使用
SecRandomCopyBytes(iOS)/SecureRandom(Android)— 不要将arc4random()用于密码学,也绝不使用Math.random() - 使用密码派生密钥时,采用 PBKDF2,迭代次数 ≥ 600,000(OWASP 2024),或使用 Argon2id
- 不得重复使用 IV / nonce — 如果看到
iv = "0000000000000000",这比不加密更糟糕(会泄露明文模式) - 不要自行实现密码学 — 标记任何自定义加密方案;优先使用 libsodium / Tink
审计清单 — MASVS-NETWORK(网络通信)
- iOS: 启用 App Transport Security — 不得设置全局
NSAllowsArbitraryLoads = true。如有例外,必须限定到特定域名、有合理依据并记录在案 - Android: 存在
network_security_config.xml,并禁止明文流量 —<base-config cleartextTrafficPermitted="false"> - 两者: 对高信任级别的后端启用证书固定 — 优先使用公钥固定,而非证书固定(可在证书轮换后继续工作)。iOS:使用
URLSessionDelegate+URLAuthenticationChallenge;Android:使用NetworkSecurityConfig<pin-set>或 OkHttpCertificatePinner - 两者: 固定配置需包含备用固定项 — 只固定单个证书,意味着下一次轮换会导致所有用户的应用无法使用
- WebView 使用 — 仅使用
WKWebView(iOS,不要使用UIWebView);审查 JavaScript 桥接;如果 WebView 不需要 JS,则设置setJavaScriptEnabled(false) - WebView 使用
loadUrl加载用户可控的 URL — 会带来开放重定向、意图欺骗和钓鱼攻击面
审计清单 — MASVS-AUTH(身份验证与会话)
- 生物识别提示使用
LAContext.evaluatePolicy(iOS)/BiometricPrompt(Android),而不是已弃用的FingerprintManager - 生物识别身份验证与钥匙串/密钥库访问绑定,而不仅仅是 UI 检查(
SecAccessControl.biometryAny、AndroidKeyGenParameterSpec.setUserAuthenticationRequired(true)) - 会话令牌存储在钥匙串/密钥库中(而非 SharedPreferences/NSUserDefaults)
- 刷新令牌流程——访问令牌有效期短,刷新令牌可在服务端撤销
- OAuth 流程使用平台浏览器(iOS 上的 ASWebAuthenticationSession、Android 上的 Custom Tabs),绝不使用 WebView(可轻易窃取凭据)
- 如果应用持有敏感数据,则应用级密码应独立于设备解锁密码
审计清单 — MASVS-PLATFORM(平台交互)
Deeplink / URL scheme(iOS)和 Intent 过滤器(Android)
- 检查每个导出的 activity(
android:exported="true")对参数的处理方式 - Universal Links(iOS)和 App Links(Android)使用 HTTPS + 已验证的域名,而非任何应用都能注册的自定义 scheme(
myapp://) - 触发敏感操作(购买、分享、更改账户)的 Deeplink 必须要求用户在应用内确认
- 对 WebView 加载的 URL 进行过滤——从 WebView 打开
myapp://,在未经用户同意的情况下触发应用内操作,会形成从 XSS 到操作的攻击链
进程间通信(Android)
- Content provider——除非明确需要跨应用访问,否则设置
android:exported="false";如果已导出,则验证每个 URI 路径 - Service——导出的服务应设置权限字符串;未设置
android:permission的暴露服务可被任何应用调用 - Broadcast receiver——应用内广播使用
LocalBroadcastManager;验证系统广播
进程间通信(iOS)
- 仅在确实需要共享时配置 App group
- Keychain access group 限定为自有应用(不要与无关的 bundle 共用 keychain group)
- URL scheme 处理程序验证来源应用(
UIApplication.openURL选项包含UIApplicationOpenURLOptionsSourceApplicationKey)
审计清单 — MASVS-CODE(代码质量)
- Native library——使用现代编译器,不禁用栈保护,并启用 PIE(iOS 上使用
otool -hv,Android.so上使用readelf -h) - 从发布版本中剥离符号(
strip、ProGuard/R8) - 生产环境中不包含调试版本(检查
DEBUG标志、清单中的isDebuggable) - 不使用基于反射的隐藏 API(Android 非 SDK 接口)——它们会在 OS 升级时失效
- 更新:应用内更新提示会强制升级,避免继续使用已知存在漏洞的版本
审计清单 — MASVS-RESILIENCE(反逆向工程)
此类别在 MASVS 中为可选项——仅高风险应用(银行、DRM、政府)需要实现。对于大多数应用,不要在此浪费精力;应交付安全的加密方案和完善的后端。
如有需要:
- 越狱 / root 检测——无法做到万无一失(每种检测技术都有公开的绕过方法),但可以提高攻击成本
- 代码混淆——高价值应用使用 DexGuard / Arxan;其他应用至少使用标准的 ProGuard / R8
- 反调试——
ptrace自附加(iOS / Linux)、Debug.isDebuggerConnected(Android) - 抵御 Frida 式绕过的 SSL pinning——在 native code 中固定,而不是在 Swift / Kotlin 中
注意:只要攻击者能物理访问设备,所有韧性控制措施都会被绕过。它们只能争取时间,不能阻止攻击。
静态分析工具
| 工具 | 平台 | 用途 |
|---|---|---|
| MobSF | iOS + Android | 自动化静态 + 动态扫描;初步分类 |
| nuclei + mobile templates | 两者 | 基于模式的扫描器 |
| semgrep + mobile rules | 两者 | 基于 AST 的规则 |
| jadx | Android | 将 APK 反编译为 Java |
| apktool | Android | 反汇编 APK |
| Hopper / Ghidra / IDA | iOS | 反汇编 Mach-O |
| class-dump / nm / otool | iOS | 符号和结构检查 |
strings | 两者 | 首要检查——密钥、URL、调试字符串 |
| Frida + objection | 两者 | 运行时插桩、绕过 SSL 固定、方法跟踪 |
运行时测试
进行灰盒 / 黑盒评估时,请使用非个人设备:
- 在测试设备上将 Burp Suite / mitmproxy 设为系统代理——观察 API 流量
- 如果需要在测试期间查看加密流量,可使用 Frida +
objection绕过 SSL 固定 - 修改请求并重放,检查 IDOR / BFLA(参见
api-audit) - 强制后台运行后再恢复,以测试会话处理和屏幕模糊
- 强制退出后重新启动,以测试会话持久性和自动登录
- 安装恶意同伴应用并测试 IPC 路径(Android Intent 模糊测试)
验证,然后记录
每个候选项在进入 findings.json 前,都必须经过 references/verification.md 中的反证流程:单独审阅从引用的证据出发,并尝试推翻该主张。根据 references/findings-format.md,为每个候选项确定且仅确定一个结论。没有追踪到影响的缺口属于加固建议,而非记录。
引用反编译二进制文件。 移动端发现通常来自编译后的应用,而不是可以引用仓库行号的源代码。将只读工具的输出(strings、jadx / apktool 反编译结果、class-dump、otool -hv、readelf -h、manifest 或 plist 转储、代理捕获的请求 / 响应)脱敏后保存到 <audit dir>/evidence/<name>.txt(或 .json),并让 location 和每个 evidence[] 条目都指向该文件及其中的行。切勿将机密值写入证据文件: 硬编码密钥的证据应是使用该密钥的反编译调用点,并脱敏为类型 + 末尾 4 位,而不是密钥本身。
confirmed— 从攻击者可触达的输入(或提取出的工件)到影响的完整追踪,或运行时证明。示例:使用strings从反编译的 APK 中读出 AES 密钥,并追踪到使用该密钥的解密调用(已保存证据文件;仅静态分析,因此confidence: medium);由于Info.plist中包含NSAllowsArbitraryLoads=true,通过测试代理捕获到明文登录信息——这是随应用发布的宽松默认配置,因此结论为confirmed,confidence: medium,并为未覆盖该配置的构建添加system_configuration条件;捕获到请求后,设置reproduced: true。needs_validation— 二进制文件支持该主张,但有一项决定性事实只能在设备之外确认。示例:android:exported="true"的 activity,其实际风险取决于你无法查看的后端授权;network_security_config中的明文例外,其域名尚未确认运行中的应用是否会访问。描述了但未执行的实时检查(代理捕获、Frida hook)应标为needs_validation,并将该捕获列为验证计划,而非标为confirmed。rejected— 指定位置的已知控制措施排除了该问题。示例:记录 token 的Log.d仅在if (BuildConfig.DEBUG)条件下执行,且发布版 manifest 中设置了android:debuggable="false"(ruled_out_by指向证据转储中的 manifest 行);候选的“硬编码密钥”实际上是已配置限制的可发布 Firebase / Maps 标识符(参见 references/severity-calibration.md §6)。 严重性仅适用于confirmed记录,并按照 references/severity-calibration.md 进行校准:overall ≤ demonstrated impact;仅基于静态分析提取的证据,置信度最高为medium。没有追踪到影响的 MASVS-RESILIENCE 缺口(根设备/越狱检测、混淆、反调试)属于加固建议,而非发现项——它们会提高攻击者的成本,但不会突破边界。
在 ext 中记录领域字段(任何记录均可选用此对象):
ext 键 | 含义 | 示例 |
|---|---|---|
masvs | MASVS 控制项 ID | MASVS-STORAGE-1 |
platform | 发现项所属平台 | ios | android | both |
source | 证据来源 | source | decompiled | runtime |
指纹:mobile-audit/<masvs-or-class>/<file or resource>/<symbol or name>,用斜杠分隔,不包含行号(验证器会拒绝包含 :<digits> 的部分)。示例:mobile-audit/MASVS-NETWORK-1/Info.plist/NSAllowsArbitraryLoads、mobile-audit/MASVS-STORAGE-1/AndroidManifest.xml/allowBackup、mobile-audit/MASVS-CRYPTO-2/com/acme/app/crypto/Vault/decrypt。对于反编译的应用,请使用代码所在的类或符号,而非证据文件名,这样重新采集证据后指纹仍会保持不变。
按指纹排序编写 findings.json,然后进行验证并修复,直到验证通过:
node references/validate-findings.mjs findings.json
也可选择导出 SARIF:node references/to-sarif.mjs findings.json -o findings.sarif。处置状态(Fixed / Deferred / Accepted Risk / Mitigated (platform/config) / Requires major migration)稍后设置,通常由 finding-triage 处理;误报应记录为 rejected 记录,而非处置状态。
输出格式
先编写 findings.json 并进行验证;Markdown 报告由 JSON 渲染生成,绝不会更改 JSON 中未载明的判定或严重性。
# Mobile Application Security Audit
## App: [name + version] ## Platform: iOS / Android / both ## MASVS profile: L1 / L2 / R
## findings.json: [path] — validated: [yes] ## Date: [date]
### Summary
- Confirmed: [N] (Critical [n] | High [n] | Medium [n] | Low [n]) Needs validation: [N] Rejected: [N]
### Confirmed findings
#### [SEVERITY] [Title] `fingerprint`
**Location:** `evidence/<file>:line` (or repo `path:line`) **MASVS:** [MASVS-X-n] **CWE:** [CWE-n] **Platform:** [ios | android | both] **Confidence:** [medium | high (reproduced)]
**What and why it matters:** [the trace, in a few lines]
**Fix:** [concrete change] **Verify the fix:** [the check that proves it]
### Needs validation
| Finding | Blockers | Check for the owner to run |
|---|---|---|
### Hardening notes (not findings)
- [gap] — [why it isn't a finding] — [effort] (RESILIENCE controls usually land here)
### Rejected (do not re-raise)
| Fingerprint | Ruled out by | Location |
|---|---|---|
### MASVS category coverage
| Category | Confirmed | Needs validation | Severity high-water mark |
|---|---|---|---|
| STORAGE / CRYPTO / NETWORK / AUTH / PLATFORM / CODE / RESILIENCE | | | |
### Backend API findings
[Cross-link to api-audit / owasp-audit output]
### Prioritized remediation plan
1. [highest first — 30 / 60 / 90 day fixes]
边界
- 仅审计你拥有或已获得书面测试授权的应用
- 对竞争对手应用进行逆向工程存在法律风险——除非用户能出示授权,否则应拒绝
- Frida / Objection / SSL-pinning 绕过仅适用于测试环境中的自有应用——它们不是“在生产环境中测试”的工具
- 拒绝协助构建恶意软件、监控应用或跟踪软件
- 如果审计发现他人代码中存在活跃后门的证据,应升级处理;不要悄悄修复后置之不理
参考资料
- OWASP MASVS(移动应用安全验证标准)
- OWASP MASTG(移动应用安全测试指南)
- 共享参考资料(构建时复制到
references/):findings-format.md、severity-calibration.md、verification.md - OWASP Mobile Top 10
- Apple 安全:Apple Platform Security Guide
- Android 安全:Android Security Best Practices
- iOS 应用编程指南——安全
- “iOS Application Security”——David Thiel
- “Android Hacker's Handbook”