mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
204 lines
9.1 KiB
Markdown
204 lines
9.1 KiB
Markdown
# Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
このページでは、インスツルメンテーションを検出/ブロックしたり、TLSピンニングを強制するAndroidアプリに対して動的分析を再取得するための実用的なワークフローを提供します。迅速なトリアージ、一般的な検出、および再パッキングなしでバイパスするためのコピー&ペースト可能なフック/戦術に焦点を当てています。
|
||
|
||
## Detection Surface (アプリがチェックするもの)
|
||
|
||
- ルートチェック: suバイナリ、Magiskパス、getprop値、一般的なルートパッケージ
|
||
- Frida/デバッガーチェック (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), /procのスキャン、クラスパス、ロードされたライブラリ
|
||
- ネイティブアンチデバッグ: ptrace(), システムコール、アンチアタッチ、ブレークポイント、インラインフック
|
||
- 初期化チェック: Application.onCreate()またはプロセス開始フックがインスツルメンテーションが存在する場合にクラッシュする
|
||
- TLSピンニング: カスタムTrustManager/HostnameVerifier、OkHttp CertificatePinner、Conscryptピンニング、ネイティブピン
|
||
|
||
## Step 1 — Quick win: hide root with Magisk DenyList
|
||
|
||
- MagiskでZygiskを有効にする
|
||
- DenyListを有効にし、ターゲットパッケージを追加
|
||
- 再起動して再テスト
|
||
|
||
多くのアプリは明白な指標(su/Magiskパス/getprop)を探すだけです。DenyListはしばしば単純なチェックを無効化します。
|
||
|
||
References:
|
||
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
||
|
||
## Step 2 — 30‑second Frida Codeshare tests
|
||
|
||
深く掘り下げる前に、一般的なドロップインスクリプトを試してください:
|
||
|
||
- anti-root-bypass.js
|
||
- anti-frida-detection.js
|
||
- hide_frida_gum.js
|
||
|
||
Example:
|
||
```bash
|
||
frida -U -f com.example.app -l anti-frida-detection.js
|
||
```
|
||
これらは通常、Javaのroot/debugチェック、プロセス/サービススキャン、およびネイティブptrace()をスタブします。軽く保護されたアプリに役立ちます; 強化されたターゲットにはカスタマイズされたフックが必要な場合があります。
|
||
|
||
- Codeshare: https://codeshare.frida.re/
|
||
|
||
## ステップ3 — 遅れてアタッチすることでinit-time検出をバイパス
|
||
|
||
多くの検出はプロセスの生成/onCreate()中にのみ実行されます。生成時のインジェクション(-f)やガジェットは捕まります; UIが読み込まれた後にアタッチすることで回避できます。
|
||
```bash
|
||
# Launch the app normally (launcher/adb), wait for UI, then attach
|
||
frida -U -n com.example.app
|
||
# Or with Objection to attach to running process
|
||
aobjection --gadget com.example.app explore # if using gadget
|
||
```
|
||
もしこれが機能すれば、セッションを安定させ、マッピングとスタブチェックを進めます。
|
||
|
||
## ステップ 4 — Jadxを使用して検出ロジックをマッピングし、文字列をハントする
|
||
|
||
Jadxでの静的トリアージキーワード:
|
||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||
|
||
典型的なJavaパターン:
|
||
```java
|
||
public boolean isFridaDetected() {
|
||
return getRunningServices().contains("frida");
|
||
}
|
||
```
|
||
一般的なAPIのレビュー/フック:
|
||
- android.os.Debug.isDebuggerConnected
|
||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||
- java.lang.System.loadLibrary / System.load (ネイティブブリッジ)
|
||
- java.lang.Runtime.exec / ProcessBuilder (コマンドのプロービング)
|
||
- android.os.SystemProperties.get (root/emulator ヒューリスティック)
|
||
|
||
## ステップ5 — Fridaを使用したランタイムスタブ (Java)
|
||
|
||
カスタムガードをオーバーライドして、安全な値を返すようにし、再パッキングを行わない:
|
||
```js
|
||
Java.perform(() => {
|
||
const Checks = Java.use('com.example.security.Checks');
|
||
Checks.isFridaDetected.implementation = function () { return false; };
|
||
|
||
// Neutralize debugger checks
|
||
const Debug = Java.use('android.os.Debug');
|
||
Debug.isDebuggerConnected.implementation = function () { return false; };
|
||
|
||
// Example: kill ActivityManager scans
|
||
const AM = Java.use('android.app.ActivityManager');
|
||
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
||
});
|
||
```
|
||
初期クラッシュのトリアージ?クラッシュする直前にクラスをダンプして、検出される可能性のある名前空間を特定します:
|
||
```js
|
||
Java.perform(() => {
|
||
Java.enumerateLoadedClasses({
|
||
onMatch: n => console.log(n),
|
||
onComplete: () => console.log('Done')
|
||
});
|
||
});
|
||
```
|
||
疑わしいメソッドをログに記録し、無効化して実行フローを確認します:
|
||
```js
|
||
Java.perform(() => {
|
||
const Det = Java.use('com.example.security.DetectionManager');
|
||
Det.checkFrida.implementation = function () {
|
||
console.log('checkFrida() called');
|
||
return false;
|
||
};
|
||
});
|
||
```
|
||
## ステップ 6 — Java フックが失敗した場合は JNI/ネイティブのトレイルをたどる
|
||
|
||
JNI エントリポイントをトレースして、ネイティブローダーと検出初期化を特定します:
|
||
```bash
|
||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||
```
|
||
バンドルされた .so ファイルの迅速なネイティブトリアージ:
|
||
```bash
|
||
# List exported symbols & JNI
|
||
nm -D libfoo.so | head
|
||
objdump -T libfoo.so | grep Java_
|
||
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
||
```
|
||
インタラクティブ/ネイティブリバース:
|
||
- Ghidra: https://ghidra-sre.org/
|
||
- r2frida: https://github.com/nowsecure/r2frida
|
||
|
||
例: libcのシンプルなアンチデバッグを打破するためにptraceを無効化する:
|
||
```js
|
||
const ptrace = Module.findExportByName(null, 'ptrace');
|
||
if (ptrace) {
|
||
Interceptor.replace(ptrace, new NativeCallback(function () {
|
||
return -1; // pretend failure
|
||
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
||
}
|
||
```
|
||
See also: {{#ref}}
|
||
reversing-native-libraries.md
|
||
{{#endref}}
|
||
|
||
## ステップ 7 — Objection パッチング (埋め込みガジェット / 基本のストリップ)
|
||
|
||
ランタイムフックよりもリパッキングを好む場合は、次を試してください:
|
||
```bash
|
||
objection patchapk --source app.apk
|
||
```
|
||
ノート:
|
||
- apktoolが必要です。ビルドの問題を避けるために、公式ガイドから最新バージョンを確認してください: https://apktool.org/docs/install
|
||
- Gadget injectionはrootなしでのインスツルメンテーションを可能にしますが、より強力なinit時チェックに捕まる可能性があります。
|
||
|
||
参考文献:
|
||
- Objection: https://github.com/sensepost/objection
|
||
|
||
## ステップ8 — フォールバック: ネットワークの可視性のためにTLSピンニングをパッチする
|
||
|
||
インスツルメンテーションがブロックされている場合でも、ピンニングを静的に削除することでトラフィックを検査できます:
|
||
```bash
|
||
apk-mitm app.apk
|
||
# Then install the patched APK and proxy via Burp/mitmproxy
|
||
```
|
||
- ツール: https://github.com/shroudedcode/apk-mitm
|
||
- ネットワーク設定のCAトラストトリック(およびAndroid 7+のユーザーCAトラスト)については、次を参照してください:
|
||
{{#ref}}
|
||
make-apk-accept-ca-certificate.md
|
||
{{#endref}}
|
||
{{#ref}}
|
||
install-burp-certificate.md
|
||
{{#endref}}
|
||
|
||
## 便利なコマンドチートシート
|
||
```bash
|
||
# List processes and attach
|
||
frida-ps -Uai
|
||
frida -U -n com.example.app
|
||
|
||
# Spawn with a script (may trigger detectors)
|
||
frida -U -f com.example.app -l anti-frida-detection.js
|
||
|
||
# Trace native init
|
||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||
|
||
# Objection runtime
|
||
objection --gadget com.example.app explore
|
||
|
||
# Static TLS pinning removal
|
||
apk-mitm app.apk
|
||
```
|
||
## ヒントと注意点
|
||
|
||
- アプリが起動時にクラッシュする場合は、スパウンするよりも遅延接続を優先する
|
||
- 一部の検出は重要なフロー(例:支払い、認証)で再実行される — ナビゲーション中はフックをアクティブに保つ
|
||
- 静的と動的を組み合わせる:Jadxで文字列を検索してクラスを絞り込み、その後メソッドをフックしてランタイムで検証する
|
||
- ハード化されたアプリはパッカーやネイティブTLSピンニングを使用する場合がある — ネイティブコードのリバースを期待する
|
||
|
||
## 参考文献
|
||
|
||
- [Reversing Android Apps: Bypassing Detection Like a Pro](https://www.kayssel.com/newsletter/issue-12/)
|
||
- [Frida Codeshare](https://codeshare.frida.re/)
|
||
- [Objection](https://github.com/sensepost/objection)
|
||
- [apk-mitm](https://github.com/shroudedcode/apk-mitm)
|
||
- [Jadx](https://github.com/skylot/jadx)
|
||
- [Ghidra](https://ghidra-sre.org/)
|
||
- [r2frida](https://github.com/nowsecure/r2frida)
|
||
- [Apktool install guide](https://apktool.org/docs/install)
|
||
- [Magisk](https://github.com/topjohnwu/Magisk)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|