🥚
FridaでAndroidの(簡易な)Root検出をバイパスする
※ 2022/06/22:リンク先が間違っていたのを修正
注意事項
- 本記事は、モバイルアプリ診断用のためのTipsであり、悪用厳禁です。
- Root化はメーカーの保証対象外となり、また意図しないセキュリティリスクを引き起こす場合があるため、実機で行う場合は、個人情報などの機微な情報が保存されていない端末での実施を推奨します。
- 本記事では、AVDでのエミュレータで実施します。
概要
- Root化とRoot検出とは
- テストアプリで検証
Root化とRoot検出とは
- Root化:本来ユーザ権限で動作しているAndroidシステムに対して、特権(root権限)を取得すること。
- ユーザ権限だと制限されている行為を制限を迂回して実行できるようになる。
- モバイルアプリ診断だと、アプリとサーバの通信傍受のためのプロキシ証明書をシステムレベルで信頼させる、Fridaなどの診断用ツールのインストールなどの目的で利用する。
- Root検出:アプリを実行している端末が、Root化されていないかをチェックする行為のこと。
- 通常の(Root化されていない)端末では存在しない権限やファイルなどをチェックする場合が多い。
-
Superuser.apk
がインストールされているか -
/sbin/su
ディレクトリが存在するか - システムディレクトリに書き込み権限が付与されているか など
-
- 通常の(Root化されていない)端末では存在しない権限やファイルなどをチェックする場合が多い。
テストアプリで検証
- 今回は、
AndroGoat
というテスト用Appを使用します。- satishpatnayak/AndroGoat: AndroGoat
- AVDのセットアップや、インストール方法については、前回記事を参照ください。
-
AndroGoat
を起動し、「ROOT DETECTION」をタップすると、下記のような画面が表示されます。
- このページでは、「CHECK ROOT」ボタンをタップすると、Root検出メソッドが起動し、このAppを実行している端末がRoot課されているかをチェックします。
- Root化されている場合「Device is rooted」が、そうでない場合は「Device is not rooted」のメッセージが表示されます
-
AndroGoat
を解凍する。$ unzip AndroGoat.apk -d AndroGoat
-
jadx
で、2.で解凍したディレクトリにあるclasses.dex
を開きます。- 開いた後、
owasp.sat.agoat.RootDetectionActivity
を開きます。
RootDetectionActivity.javapublic final boolean isRooted() { // デフォルトでは非Root判定(false) boolean result = false; // Root端末でよく用いられるAPKやコマンドのパスリストに対して、存在するかを確認する for (String files : new String[]{ "/system/app/Superuser/Superuser.apk", "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/data/local/su", "/su/bin/su", "re.robv.android.xposed.installer-1.apk", "/data/app/eu.chainfire.supersu-1/base.apk" }) { // 上記のリストのパスが存在している場合、trueが返される result = new File(files).exists(); if (result) { break; } } // Root判定の結果を返す return result; }
-
実際にAVDに
adb
コマンドで接続し、su
コマンドのパスを確認すると下記のとおりとなるため、上記で検出される状態です。generic_x86:/ $ which su /system/xbin/su
-
→ この関数が
false
を返すようにすれば、実際はRoot端末であってもRoot検出を回避できます。
- 開いた後、
-
Fridaを使用して、この関数(
isRooted
)をフックし、常にfalse
(非Root)を返すようなスクリプトを作成します。Java.perform(function () { send("Start Script"); // AndroGoatのROot DetectionのActivityを指定 var rootDetectionActivity = Java.use("owasp.sat.agoat.RootDetectionActivity"); // isRooted関数をフック rootDetectionActivity.isRooted.implementation = function () { send("Hooking isRooted method"); // 常にfalse(非Root)の結果が返るように変更 return false; } })
- 作成したFridaのJSコードをPythonで実行するためには、拙作の『FirdaでAndroid APKをHookingする』を参考ください。
- 結果として、下記のようにRoot検出を回避できます。
Discussion