android-app-pentesting について
android-app-pentesting は、Android APK を調査するセキュリティテスター向けの方法論スキルです。静的・動的解析、コンポーネントやストレージの検査、ネットワークテスト、保護機構の回避をツール例とともに整理します。
主な機能
- 01APKの静的解析とManifest監査
- 02Fridaによるランタイム解析
- 03コンポーネントの露出テスト
- 04ローカルデータストレージの検査
- 05ネットワーク通信とTLSのテスト
- 06保護機構の回避ガイド
活用シーン
- 01APKの公開コンポーネントを監査
- 02実行時のアプリ動作を調査
- 03ストレージ内の機密データを確認
- 04許可された評価でネットワーク保護をテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wgpsec/ aboutsecurity --skill android-app-pentestingインストール後、Claude Code で/android-app-pentestingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/android-frameworks-and-runtime.mdandroid-frida-dynamic.mdandroid-static-analysis.md詳細
Android アプリケーションの侵入テスト手法
フェーズの流れ: 環境準備 → APK 静的解析 → 動的解析(Frida) → コンポーネントのセキュリティテスト → データストレージのセキュリティ → ネットワーク通信のセキュリティ → 保護機構の回避
詳細な参考資料
- APK 静的解析の詳細なコマンドと Manifest の監査ポイント → references/android-static-analysis.md
- Frida Hook スクリプトと SSL Pinning 回避の実践 → references/android-frida-dynamic.md
- React Native / Flutter / native so / RMS / Appium のランタイム解析 → references/android-frameworks-and-runtime.md
Phase 0: 環境準備
デバイス/エミュレーターの選択
测试设备选择?
├─ 真机(推荐 Pixel 系列)
│ ├─ Magisk 刷入 → systemless root
│ ├─ 启用 Zygisk + DenyList → Root 隐藏
│ └─ 保留原始 boot.img → OTA 恢复
├─ Android Studio 模拟器
│ ├─ x86 镜像 + ARM 翻译层(速度优先)
│ └─ Google APIs 镜像(需 Play Store 测试时)
└─ Genymotion(免费个人版 + VirtualBox)
└─ Bridge 网络模式 → 方便从其他 VM 连接
コアツールチェーン
| ツール | 用途 | インストール |
|---|---|---|
| adb | デバイス通信/インストール/デバッグ | Android SDK Platform Tools |
ASC (droidasc) | 必要な部分だけ逆コンパイル + クロスリファレンス検索(まず特定し、その後パッケージ全体を調査) | pip install droidasc |
| jadx / jadx-gui | APK を Java に逆コンパイル | brew install jadx |
| apktool | Smali への逆コンパイル/リソース抽出 | brew install apktool |
| Frida + frida-tools | 動的 Hook/ランタイム解析 | pip install frida-tools |
| objection | Frida の自動化ラッパー | pip install objection |
| Drozer | コンポーネントのセキュリティテスト | GitHub Release |
| Burp Suite | トラフィックの傍受 | PortSwigger |
| MobSF | 自動静的・動的解析 | Docker でデプロイ |
| APKiD | コンパイラー/パッキング/難読化の識別 | pip install apkid |
APK の取得
# 从设备提取
adb shell pm list packages | grep target
adb shell pm path com.target.app
adb pull /data/app/com.target.app-.../base.apk
# 多 Split APK 合并
mkdir splits
adb shell pm path com.target.app | cut -d ':' -f 2 | xargs -n1 -I{} adb pull {} splits/
java -jar APKEditor.jar m -i splits/ -o merged.apk
java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
# 在线下载
# APKPure / APKMirror / APKCombo / apkd (GitHub)
# justapk: pip install justapk
justapk download com.target.app
justapk convert app.xapk -o output/
Phase 1: APK 静的解析
逆コンパイルとコード監査
大きな APK をいきなりパッケージ全体で逆コンパイルしないでください。jadx は全体を展開するため(実測では 98 MB のパッケージに 27.8 秒かかり、1374 個のファイルが生成されます)、ほとんどの問題では数個のクラスを確認するか、参照箇所を 1 つ見つけるだけで十分です。まず手元の手がかりで特定し、その後、パッケージ全体を調査するか判断します。
反编译路径选择?
├─ 已知要找什么(类名/字符串/方法名) → ASC 按需查(getclass / findrefs),不落盘
│ └─ 定位到具体类后再决定要不要 jadx 整包读上下文
├─ 不知道找什么、要广搜 → jadx -d output/ target.apk 整包 + grep
├─ 需要修改并重打包 → apktool d target.apk -o decoded/
├─ React Native 应用 → 解压 assets/index.android.bundle
├─ Xamarin 应用 → 解压 assemblies/ → dnSpy / ILSpy
└─ 加壳应用 → APKiD 识别壳类型 → 对应脱壳方案
# jadx 反编译
jadx -d jadx_output/ target.apk
# 搜索敏感信息
grep -rn "password\|api_key\|secret\|token\|firebase" jadx_output/
# apktool 反编译(Smali 级别)
apktool d target.apk -o apktool_output/
# APKiD 识别保护方案
apkid target.apk
ASC による必要な部分だけの検索(大きな APK の標準的な入口)
ASC は APK を読み取り専用のデータベースとして直接検索するため、事前に展開する必要はありません。単一クラスの逆コンパイルと参照検索はいずれも 1 秒未満で完了します。クラス名、メソッド名、文字列、または基底クラスの手がかりがある場合、まず ASC で特定し、その後、パッケージ全体を jadx で調査するか判断します。もう 1 つの用途は、基底クラスで攻撃対象領域を絞り込むことです。難読化後はクラス名を検索できませんが、システムの親クラス名は維持されるため、findrefs extends はクラス名の grep よりも信頼できます。
droidasc getmanifest target.apk -o AndroidManifest.xml # 不需要 Android SDK
droidasc listclass target.apk --prefix com.target.pay # 看包结构,避免盲搜
droidasc getclass target.apk com.target.pay.PayActivity -o PayActivity.java
droidasc findrefs target.apk string "sk-" # 这个字面量出现在哪些类
droidasc findrefs target.apk extends android.app.Service # 所有子类
droidasc findrefs target.apk impl android.os.IInterface # 所有 IPC 实现
制限事項が 2 点あります。findrefs string はあいまい検索のため、完全一致の文字列では結果が空になる場合があります(空でも存在しないとは限りません。パッケージ全体を grep してください)。また、出力されるのは参照箇所の一覧であり、ソースコードではありません。コードを読むには、getclass または jadx を使用する必要があります。サブコマンドと引数の全一覧は references/android-static-analysis.md を参照してください。
Manifest.xml の監査ポイント
# 提取 Manifest
aapt dump xmltree target.apk AndroidManifest.xml
主な確認項目:
| 属性 | リスク | 影響 |
|---|---|---|
android:debuggable="true" | 高 | デバッガーの接続/アプリデータの読み取りが可能 |
android:allowBackup="true" | 中 | adb backup でアプリデータを抽出可能 |
android:exported="true" | 高 | コンポーネントを外部から呼び出し可能 |
android:usesCleartextTraffic="true" | 中 | 平文 HTTP を許可 |
targetSdkVersion < 24 | 低 | デフォルトでユーザーがインストールした CA を信頼します。>=24 ではデフォルトでシステム CA のみを信頼するため、Network Security Config を確認する必要があります |
文字列とキーの検索
# APK 中的 URL
apkurlgrep -a target.apk
# 泄露的密钥/凭据
apkleaks -f target.apk
# Firebase 数据库检测
grep -rn "firebaseio.com" jadx_output/
# 尝试访问: curl https://xxx.firebaseio.com/.json
自動静的解析
# MobSF 静态分析
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
# 上传 APK → 自动生成报告
# mariana-trench (Facebook)
# 基于 source-sink 规则的漏洞扫描
mariana-trench --apk-path target.apk --output results/
Phase 2: 動的解析(Frida)
Frida の基本操作
# 查看运行中的应用
frida-ps -Uai
# 附加到进程
frida -U -f com.target.app
# 使用脚本注入
frida -U -f com.target.app -l hook.js
よくある Hook のシナリオ
动态分析目标?
├─ SSL Pinning 绕过 → Phase 6 详述
├─ Root 检测绕过 → Phase 7 详述
├─ 加密算法监控 → Hook javax.crypto.Cipher
├─ 敏感 API 监控 → Hook 文件/网络/短信/位置 API
├─ 生物认证绕过 → Hook BiometricPrompt
└─ 内存中搜索敏感数据 → Fridump
メモリダンプと検索
# Fridump 内存提取
python3 fridump3.py -u com.target.app
# 搜索敏感数据
strings dump/* | grep -E "password|token|Bearer"
# 搜索助记词
strings dump/* | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+$"
Keystore の監査
# Hook Keystore 操作
frida -U -f com.target.app -l tracer-cipher.js
# 脚本来源: github.com/WithSecureLabs/android-keystore-audit
Phase 3: コンポーネントのセキュリティテスト
コンポーネントの公開範囲の列挙
# Drozer 枚举
dz> run app.package.attacksurface com.target.app
# 输出: X activities exported, Y services exported, ...
Activity のセキュリティ
Exported Activity 测试?
├─ 直接启动 → adb shell am start -n com.target.app/.SensitiveActivity
├─ 是否绕过认证直接访问敏感页面?
│ ├─ 是 → 认证绕过漏洞
│ └─ 否 → 检查 Intent 参数注入
├─ Activity 是否返回敏感数据? → setResult() 泄露
└─ Tapjacking 测试 → filterTouchesWhenObscured / onFilterTouchEventForSecurity / overlay 遮挡触摸处理
Content Provider のセキュリティ
# 枚举 Provider
dz> run app.provider.info -a com.target.app
# SQL 注入测试
dz> run app.provider.query content://com.target.app.provider/users --projection "* FROM sqlite_master--"
# 路径穿越测试
dz> run app.provider.read content://com.target.app.provider/../../../../etc/hosts
# 文件 Provider 检查
dz> run scanner.provider.traversal -a com.target.app
Service/Broadcast Receiver
# Service 枚举与交互
dz> run app.service.info -a com.target.app
dz> run app.service.start --action com.target.app.ACTION --component com.target.app/.MyService
# Broadcast 测试
dz> run app.broadcast.info -a com.target.app
dz> run app.broadcast.send --action com.target.app.CUSTOM_ACTION --extra string data "test"
Deep Link/URL Scheme
# 枚举 scheme
grep -rn "android:scheme" apktool_output/AndroidManifest.xml
# 触发 deep link
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value"
# 检查点:
# 1. 参数是否接受路径穿越 → ../../unwanted-endpoint
# 2. 是否传递敏感数据(密码/token)通过 URL 参数
# 3. 是否存在 Open Redirect
Phase 4: データストレージのセキュリティ
チェックリスト
数据存储位置?
├─ SharedPreferences → /data/data/pkg/shared_prefs/*.xml
│ └─ 是否存储明文密码/token?
├─ SQLite 数据库 → /data/data/pkg/databases/*.db
│ └─ 是否加密? 密钥是否硬编码?
├─ 内部存储 → /data/data/pkg/files/
│ └─ MODE_WORLD_READABLE/WRITABLE?
├─ 外部存储 → /sdcard/ (全局可读写)
│ └─ 是否存储敏感数据?
├─ Keystore → Android Keystore System
│ └─ 密钥是否绑定设备? 是否需要认证?
└─ 后台截图 → /data/system_ce/0/snapshots/
└─ FLAG_SECURE 是否设置?
# 检查 SharedPreferences
adb shell run-as com.target.app cat /data/data/com.target.app/shared_prefs/*.xml
# 检查数据库
adb shell run-as com.target.app ls /data/data/com.target.app/databases/
# 拉取并用 sqlite3 检查
adb pull /data/data/com.target.app/databases/app.db
sqlite3 app.db ".tables"
sqlite3 app.db ".schema users"
sqlite3 app.db "SELECT * FROM users;"
# 检查文件权限
adb shell run-as com.target.app ls -la /data/data/com.target.app/files/
Phase 5: ネットワーク通信のセキュリティ
トラフィックキャプチャの設定
流量抓取方案?
├─ 应用 targetSdkVersion < 24 → 默认信任用户安装的 CA,可直接设置 WiFi 代理到 Burp
├─ 应用 targetSdkVersion >= 24 → 默认不信任用户 CA,需检查/修改 Network Security Config
│ ├─ 修改 network_security_config.xml 信任 user certificates
│ └─ 重打包签名安装,或把 Burp CA 装入系统证书区(需 root)
├─ Flutter 应用 → 可能使用独立 TLS/CA 逻辑,需额外处理
│ └─ 参考 flutter SSL pinning bypass
└─ 非 HTTP 流量 → tcpdump / iptables 转发
# 安装 Burp CA 到系统(需 root)
# 导出 Burp CA → DER 格式 → 转 PEM
openssl x509 -inform DER -in cacert.der -out cacert.pem
# 计算 hash
HASH=$(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1)
cp cacert.pem /system/etc/security/cacerts/${HASH}.0
chmod 644 /system/etc/security/cacerts/${HASH}.0
# 修改 network_security_config.xml(targetSdkVersion >= 24 时常见)
# 在 res/xml/network_security_config.xml 中添加:
# <trust-anchors><certificates src="user" /></trust-anchors>
SSL Pinning の検出と回避
SSL Pinning 类型?
├─ OkHttp CertificatePinner → Frida Hook
├─ 自定义 TrustManager → Frida Hook
├─ Network Security Config → 修改 XML 重打包
├─ WebView SSL 处理 → Hook WebViewClient
└─ 未知实现 → SSLPinDetect 静态扫描定位
# 静态检测 Pinning 实现
python sslpindetect.py -f target.apk -a apktool.jar
# apk-mitm 自动绕过(无需 root)
npx apk-mitm target.apk
# objection 绕过
objection --gadget com.target.app explore --startup-command "android sslpinning disable"
# Frida 绕过(通用脚本)
frida -U -f com.target.app -l ssl-pinning-bypass.js
Phase 6: 保護機構の回避
Root 検出の回避
Root 检测机制?
├─ 文件检查 (/su, /system/xbin/su, Cydia 等)
│ └─ Magisk DenyList 隐藏
├─ SafetyNet / Play Integrity
│ └─ 硬件级别 attestation 难以绕过
│ └─ 基本 attestation → Play Integrity Fix (Zygisk 模块)
├─ RootBeer / 自定义检测库
│ └─ Frida Hook 返回值
└─ 系统属性检查 (ro.debuggable, ro.secure)
└─ MagiskHide Props Config
# objection 绕过 root 检测
objection --gadget com.target.app explore --startup-command "android root disable"
# Frida Hook 通用 root 检测绕过
frida -U -f com.target.app -l anti-root.js
エミュレーター検出の回避
# 检测点: Build.FINGERPRINT, Build.MODEL, CPU_ABI, /dev/qemu_pipe
# Frida Hook Build 类属性
アンチデバッグ/アンチ Frida の回避
反 Frida 检测方式?
├─ 检查 frida-server 端口 (27042)
│ └─ 更改监听端口: frida-server -l 0.0.0.0:1234
├─ 检查 /proc/self/maps 中的 frida 库
│ └─ 使用 linjector 注入(无 ptrace)
├─ 检查 D-Bus 协议特征
│ └─ 使用自编译 Frida gadget
└─ 自杀式 kill(getpid()) 反分析
└─ Hook Process.killProcess / exit
スクリーンショット/画面録画の保護の回避
# 关闭 FLAG_SECURE,便于截图、录屏和动态分析记录
objection --gadget com.target.app explore -s "android ui FLAG_SECURE false"
生体認証の回避
# Frida 绕过指纹
frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f com.target.app
Phase 7: クライアントインジェクションの脆弱性
WebView のセキュリティ
WebView 配置检查?
├─ JavaScript 启用 → setJavaScriptEnabled(true) → XSS 风险
├─ File 协议访问 → setAllowFileAccess(true) → LFI 风险
├─ addJavascriptInterface → RCE(API < 17)
└─ WebViewClient 证书处理 → 忽略 SSL 错误?
SQL インジェクション
- Content Provider の query/insert/update/delete メソッド
- カスタムデータベース操作がパラメーター化されているか
Intent インジェクション
- プロキシ Activity/Service が Intent を受け取った後、そのまま
startActivity()を呼び出す - WebView の URL を
Intent.parseUri()で解析 → 悪意のある Intent の構築
自動解析ツール早見表
| ツール | 種類 | 使用方法 |
|---|---|---|
| MobSF | 静的 + 動的 | Docker でデプロイ、Web UI |
| Qark | 静的 | qark --apk target.apk |
| AndroBugs | 静的 | python androbugs.py -f target.apk |
| SUPER | 静的 | super-analyzer target.apk |
| Androwarn | 静的(動作) | python androwarn.py -i target.apk -r html |
| mariana-trench | 静的(データフロー) | mariana-trench --apk-path target.apk |
| ReverseAPK | 静的 | reverse-apk target.apk |
マルウェア解析のポイント
侵入テストではなく、疑わしい APK を解析する場合は、次の点にも注意してください。
- ネイティブ so ライブラリーの読み込みチェーン:
System.loadLibrary→ 第 2 層の ELF を復号 →InMemoryDexClassLoaderによるファイルを介さない DEX の読み込み InMemoryDexClassLoaderの使用 → メモリ上での DEX 読み込み(Frida Hook でダンプ)AccessibilityServiceの悪用 → オーバーレイ攻撃/ACTION_SET_TEXT の乗っ取り- C2 チャネルとしての FCM → Firebase メッセージのトリガー条件を確認
- フォアグラウンド Service + MediaPlayer による永続化 → プロセスの維持