mcpField
P
performing-dynamic-analysis-of-android-app

performing-dynamic-analysis-of-android-app

github.com/mukul975セキュリティ35.2k77 回インストール8 週間前に更新
リポジトリ

performing-dynamic-analysis-of-android-app について

Androidアプリを実行中に調べるセキュリティ分析向けスキルです。FridaとObjectionを使ったメソッドのフック、実行時データの観察、Root検知などの防御機能の検証を扱います。

主な機能

  1. 01Fridaの設定とアプリ検出
  2. 02メソッドのフックと引数確認
  3. 03ネットワークと暗号処理の監視
  4. 04実行時データと秘密情報の調査
  5. 05Root検知の動作確認

活用シーン

  1. 01静的解析結果の実行時検証
  2. 02難読化アプリの動作調査
  3. 03API呼び出しと復号データの観察
  4. 04Root検知とアンチデバッグの評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill performing-dynamic-analysis-of-android-app

インストール後、Claude Code で/performing-dynamic-analysis-of-android-appを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

詳細

Android アプリの動的解析の実施

使用する場面

次の場合にこのスキルを使用します:

  • 静的解析の結果を、実際の Android デバイス上でランタイム検証する必要がある
  • 対象アプリが難読化(DexGuard、カスタムパッカー)を使用しており、効果的な静的解析ができない
  • 実際の API 呼び出し、復号されたデータ、またはランタイム生成値を観察する必要がある
  • ルート検出、改ざん検出、またはアンチデバッグの実装を評価する

許可なく本番環境でこのスキルを使用しないでください。動的インストルメンテーションはアプリの動作を変化させ、セキュリティアラートを引き起こす可能性があります。

前提条件

  • ルート化済み Android デバイスまたはエミュレーター(Genymotion、書き込み可能なシステムを備えた Android Studio AVD)
  • デバイスのアーキテクチャ(arm64、x86_64)に適合する Frida サーバーがインストールされていること
  • frida-tools および objection パッケージを含む Python 3.10 以降
  • ADB が設定済みで、デバイスが接続されていること
  • 対象 APK がデバイスにインストールされていること

ワークフロー

ステップ 1:Android デバイスに Frida サーバーをセットアップする
# Check device architecture
adb shell getprop ro.product.cpu.abi
# Output: arm64-v8a

# Download matching Frida server from GitHub releases
# https://github.com/frida/frida/releases
# Push to device
adb push frida-server-16.x.x-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &

# Verify Frida connection
frida-ps -U
ステップ 2:アプリケーションの攻撃対象領域を列挙する
# List all packages
frida-ps -U -a

# Attach Objection for high-level exploration
objection --gadget com.target.app explore

# List activities, services, receivers
android hooking list activities
android hooking list services
android hooking list receivers

# List loaded classes
android hooking list classes
android hooking search classes com.target.app
ステップ 3:機密性の高いメソッドをフックする
# Hook all methods of a class
android hooking watch class com.target.app.auth.LoginManager

# Hook specific method with argument dumping
android hooking watch class_method com.target.app.auth.LoginManager.authenticate --dump-args --dump-return

# Hook crypto operations
android hooking watch class javax.crypto.Cipher --dump-args
android hooking watch class java.security.MessageDigest --dump-args

# Hook network calls
android hooking watch class okhttp3.OkHttpClient --dump-args
android hooking watch class java.net.URL --dump-args
ステップ 4:詳細な解析のためのカスタム Frida スクリプトを作成する
// hook_crypto.js - Intercept encryption/decryption operations
Java.perform(function() {
    var Cipher = Java.use("javax.crypto.Cipher");

    Cipher.doFinal.overload("[B").implementation = function(input) {
        var mode = this.getAlgorithm();
        console.log("[Cipher] Algorithm: " + mode);
        console.log("[Cipher] Input: " + bytesToHex(input));

        var result = this.doFinal(input);
        console.log("[Cipher] Output: " + bytesToHex(result));
        return result;
    };

    function bytesToHex(bytes) {
        var hex = [];
        for (var i = 0; i < bytes.length; i++) {
            hex.push(("0" + (bytes[i] & 0xFF).toString(16)).slice(-2));
        }
        return hex.join("");
    }
});
# Execute custom Frida script
frida -U -f com.target.app -l hook_crypto.js --no-pause
ステップ 5:ルート検出を回避する
// root_bypass.js - Common root detection bypass
Java.perform(function() {
    // Bypass RootBeer library
    var RootBeer = Java.use("com.scottyab.rootbeer.RootBeer");
    RootBeer.isRooted.implementation = function() {
        console.log("[RootBeer] isRooted() bypassed");
        return false;
    };

    // Bypass generic file-based root checks
    var File = Java.use("java.io.File");
    var originalExists = File.exists;
    File.exists.implementation = function() {
        var path = this.getAbsolutePath();
        var rootPaths = ["/system/app/Superuser.apk", "/system/xbin/su",
                         "/sbin/su", "/system/bin/su", "/data/local/bin/su"];
        if (rootPaths.indexOf(path) >= 0) {
            console.log("[Root] Blocked check for: " + path);
            return false;
        }
        return originalExists.call(this);
    };

    // Bypass SafetyNet/Play Integrity
    try {
        var SafetyNet = Java.use("com.google.android.gms.safetynet.SafetyNetApi");
        console.log("[SafetyNet] Class found - may need additional bypass");
    } catch(e) {}
});
ステップ 6:ネットワーク通信をランタイムに解析する
// network_monitor.js - Monitor all HTTP requests
Java.perform(function() {
    // Hook OkHttp3
    try {
        var OkHttpClient = Java.use("okhttp3.OkHttpClient");
        var Interceptor = Java.use("okhttp3.Interceptor");
        var Chain = Java.use("okhttp3.Interceptor$Chain");

        console.log("[OkHttp] Monitoring network requests...");

        var Request = Java.use("okhttp3.Request");
        Request.url.implementation = function() {
            var url = this.url();
            console.log("[OkHttp] URL: " + url.toString());
            return url;
        };
    } catch(e) {
        console.log("[OkHttp] Not found, trying HttpURLConnection");
    }

    // Hook HttpURLConnection
    var URL = Java.use("java.net.URL");
    URL.openConnection.overload().implementation = function() {
        console.log("[URL] Opening: " + this.toString());
        return this.openConnection();
    };
});
ステップ 7:復号されたデータとシークレットを抽出する
# Using Objection for quick extraction
objection --gadget com.target.app explore

# Dump Android Keystore entries
android keystore list
android keystore dump

# Search heap for sensitive objects
android heap search instances com.target.app.model.User
android heap evaluate <handle> "JSON.stringify(clazz)"

# Memory string search
memory search "password" --string
memory search "api_key" --string

主な概念

用語定義
動的インストルメンテーション実行中のプロセスにコードを挿入し、ランタイムにアプリケーションの動作を変更すること
メソッドフッキング引数と戻り値を傍受するために、関数の実装を置き換える、またはラップすること
Frida サーバーホストからインストルメンテーションコマンドを受信する、対象デバイス上で実行されるデーモン
Dalvik/ART ランタイムAndroid のランタイム環境。Frida は ART レベルで Java/Kotlin メソッドをフックします
ヒープ検査アプリケーションのメモリヒープ内にあるライブオブジェクトを調べ、ランタイムデータを抽出すること

ツールとシステム

  • Frida:ネイティブ Android プロセスに JavaScript を挿入するための動的インストルメンテーションツールキット
  • Objection:Android および iOS のセキュリティテスト用コマンドをあらかじめ備えた、高水準の Frida ラッパー
  • frida-trace:アプリの動作をすばやく調査するための、自動メソッドトレースユーティリティ
  • Drozer:IPC とエクスポートされたコンポーネントをテストするための Android セキュリティ評価フレームワーク
  • Android Studio Profiler:CPU、メモリ、ネットワークのアクティビティをランタイムに監視するツール

よくある落とし穴

  • Frida のバージョン不一致:デバイス上の Frida サーバーは、ホスト上の frida-tools のバージョンと一致している必要があります。バージョンが一致しないと接続に失敗します。
  • Frida の検出:Frida サーバープロセスの確認、メモリ内の Frida シグネチャのスキャン、または /proc/self/maps の監視によって Frida を検出するアプリがあります。Frida Gadget の挿入やカスタムサーバービルドを使用してください。
  • 難読化されたクラス名:ProGuard/R8 が適用されると、クラス名とメソッド名は短縮されます(例:a.b.c.d())。android hooking search classes を使用して、実際のランタイム名を特定してください。
  • Multi-DEX アプリ:複数の DEX ファイルに分割された大規模なアプリでは、起動時にすべてのクラスが読み込まれるとは限りません。クラスローダーをフックするか、アプリの初期化が完全に終わった後に Java.enumerateLoadedClasses() を使用してください。

コメント