Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ The companion XML defines how the fake dialog will look like:
android:canRetrieveWindowContent="true"/>
```

### Two-app sideload chain + staged loader handoff

FvncBot shows a reusable **banking-trojan installation pattern**: a visible lure app first asks for **Install unknown apps**, then installs a second APK disguised as a system/update component, and finally deep-links the victim into that second app's setup flow to obtain Accessibility.

Useful implementation details to hunt for during reversing:

1. **Stage-0 lure** keeps operator strings and pre-wires the second package in `AndroidManifest.xml` via `<queries>` and provider lookups.
2. **Stage-1 loader** decodes bytes into an app-private path such as `/data/user/0/<pkg>/app_<dir>/<payload>.txt` and instantiates them with `DexClassLoader`, so the malicious logic is absent from the main `classes.dex`.
3. The runtime-loaded installer **drops an embedded APK from `assets/` to cache**, launches the package installer, then opens a deep link such as `core://setup` with `Intent.ACTION_VIEW` to continue the victim-guided flow.
4. Before re-prompting, the installer may query a **content provider** exposed by the second stage and wait for a value such as `"enabled"` to confirm that Accessibility was granted.
5. The visible second-stage APK can still be another loader: FvncBot stored the final payload inside `assets/qkcCg.jpg`, then applied an **RC4-like transform** to recover a ZIP containing the real `classes.dex`.

Minimal patterns:

```java
DexClassLoader cl = new DexClassLoader(
"/data/user/0/<pkg>/app_tell/tWyWeG.txt",
"/data/user/0/<pkg>/app_tell",
null,
getClassLoader());
```

```java
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("core://setup"));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
```

This chaining separates the **lure**, **installer**, **Accessibility shell**, and **final RAT** into different runtime stages, which reduces static detections and makes the malicious behavior appear only after several victim-driven UI steps.

---

## Remote UI automation primitives
Expand Down Expand Up @@ -147,6 +177,16 @@ ClayRat upgrades the usual MediaProjection trick into a remote desktop stack:

The result is a VNC-like feed delivered entirely through sanctioned APIs—no root or kernel exploits—yet it hands the attacker live situational awareness with millisecond latency.

### 3.b Text-mode VNC: UI-tree capture + rich text interception
FvncBot highlights a common evolution from "simple ATS bot" to **text-mode VNC**:

- Serialize the active Accessibility tree to JSON, including **text**, `viewIdResourceName`, `contentDescription`, bounds, class name, role, and child hierarchy.
- Ship screen metadata (`timestamp`, width, height) so the operator can align taps and overlays remotely.
- Treat `TYPE_VIEW_TEXT_CHANGED` as a keylogging source and keep the full event context: previous text, current text, added/removed counts, indexes, input type, package/class, and `isPassword()`.
- Mix **broadcast / FCM / WebSocket** control channels so high-level commands can trigger `dispatchGesture`, `performGlobalAction`, overlay rendering, clipboard injection, app launch, or session teardown.

This is more reliable than raw video-only remote control because the attacker can search nodes by ID/text/description, render precise phishing overlays, and recover secrets from editable fields even when no full screen stream is active.

### 4. Lock-screen credential theft & auto-unlock
ClayRat subscribes to `TYPE_WINDOW_CONTENT_CHANGED` / `TYPE_VIEW_TEXT_CHANGED` events emitted by `com.android.systemui` (`Keyguard`). It reconstructs whatever guard is active:

Expand Down Expand Up @@ -208,6 +248,8 @@ The **AccessibilityService** is the local engine that turns those cloud commands
* `adb shell settings get secure enabled_accessibility_services`
* Settings → Accessibility → *Downloaded services* – look for apps that are **not** from Google Play.
* MDM / EMM solutions can enforce `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) to block sideloaded services.
* Treat the sequence **Install unknown apps** → **new APK install** → **deep link into setup** → **Accessibility enablement** as a high-signal dropper pattern.
* During malware triage, grep for `DexClassLoader` reading from **app-private directories** or from files with misleading extensions (`.txt`, `.jpg`, `.dat`) and for staged APKs extracted from `assets/`.
* Analyse running services:
```bash
adb shell dumpsys accessibility | grep "Accessibility Service"
Expand Down Expand Up @@ -327,5 +369,6 @@ Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-t
* [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)
* [Analysis of FvncBot campaign](https://cert.pl/en/posts/2026/03/fvncbot-analysis/)

{{#include ../../banners/hacktricks-training.md}}
{{#include ../../banners/hacktricks-training.md}}