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 @@ -860,6 +860,83 @@ struct Header {
- Once verified, the bot sends a `MsgType=0` body carrying the operator-defined **group string** (e.g. `android-postboot-rt`). If the group is enabled, the C2 responds with `MsgType=2 (confirm)`, after which tasking (MsgType 5–12) begins.
- Supported verbs include SOCKS-style TCP/UDP proxying (residential proxy monetization), reverse shell / single command exec, file read/write, and **Mirai-compatible DDoSBody** payloads (same `AtkType`, `Duration`, `Targets[]`, `Flags[]` layout).


## Copybara-style banker / RAT tradecraft: per-app Play Store blackholes, parser differentials, and decoy overlays

### Per-application `VpnService` blackhole against `com.android.vending`

A more targeted installation-coercion pattern is to create a **VPN that only captures Google Play Store traffic** instead of taking the whole device offline. The dropper calls `VpnService.Builder.addAllowedApplication("com.android.vending")`, installs IPv4/IPv6 routes into a local TUN, and then simply discards packets for a short installation window.

Why it matters:
- The victim still has connectivity in most apps, so the outage looks like a transient Play Store / Play Protect problem rather than a device-wide network failure.
- The same dropper can immediately resume the sideloading flow after the user grants `ACTION_MANAGE_UNKNOWN_APP_SOURCES`.
- In one observed case the UI polled the unknown-source permission state every **800 ms**, so installation resumed almost instantly after approval.

Hunting ideas:
- `VpnService` + `addAllowedApplication("com.android.vending")`
- both `addRoute("0.0.0.0", 0)` and `addRoute("::", 0)` with no forwarding path from the TUN reader
- constants such as `240000` near VPN teardown / timers even if nearby strings claim a shorter block
- same code path also invoking `PackageInstaller`, `ACTION_INSTALL_PACKAGE`, or `ACTION_MANAGE_UNKNOWN_APP_SOURCES`

### Hostile APK/ZIP parser differentials

Some droppers intentionally build APKs that Android or tolerant ZIP readers can still process while common analysis tooling disagrees about the file layout.

Interesting anti-analysis shapes:
- **local-header vs central-directory mismatches** (for example different compression methods for the same entry)
- **oversized ZIP extra fields** and random Unicode path components
- **extremely long asset names** used to hide the real payload near the end of a path that desktop tools fail to materialize
- **file-versus-directory collisions** below names normally treated as files, such as `classes.dex/`, `AndroidManifest.xml/`, or `resources.arsc/`

Practical workflow:

```bash
zipinfo -v sample.apk
7z l sample.apk
bsdtar -tf sample.apk
python -m zipfile -l sample.apk
jadx sample.apk -d out-jadx
apktool d sample.apk -o out-apktool
```

If these tools produce different entry lists, or one sees `classes.dex` while another sees children under `classes.dex/`, treat the APK as **parser-differential anti-analysis** rather than a broken download. Tools such as [apkInspector](https://github.com/erev0s/apkInspector/) are useful to diff local headers against the central directory before rebuilding a normalized sample.

### Long-path asset tail loaders + RC4 JAR staging

A useful loader pattern is: **benign-looking outer APK -> hidden JAR at the tail of an abnormally long asset path -> RC4/XOR decrypt -> DEX loader -> embedded payload APK**.

Generic reversing steps:
1. Start from the custom `Application` subclass or the earliest `attachBaseContext()` / `onCreate()` hook.
2. Check whether the loader opens an asset with a suspiciously long name and then seeks to a tail offset instead of treating the whole asset as a normal file.
3. Reimplement the lightweight decryptor (`RC4`, rolling XOR, custom KSA/PRGA) and dump the recovered JAR/ZIP.
4. Inspect the recovered stage for `DexClassLoader`, reflective `pathList` edits, or `PackageManager.getPackageArchiveInfo()` calls used to show the embedded APK label/icon before install.
5. Look for a final `assets/base.apk` (or similarly generic filename) that is installed through the standard `PackageInstaller` flow.

This pattern matters because the visible Java code in the outer APK may only contain UI glue and permission shepherding; the real installer logic lives in the decrypted second stage.

### Context hiding instead of biometric bypass

Accessibility bankers do not always need to break biometric crypto. A full-screen branded loading page or a generic utility **WebView decoy** can hide the real app while Accessibility performs taps underneath. If the victim is tricked into approving a genuine biometric / system prompt whose context is concealed, the attacker gets authorization **without** bypassing the biometric primitive itself.

Operational clues:
- locale-driven HTML decoys such as `pg-en.html`, `pg-it.html`, ... loaded full-screen in a `WebView`
- hard-coded battery / temperature / RAM values used only to make the decoy look alive
- `TYPE_ACCESSIBILITY_OVERLAY` or opaque activity screens shown while `dispatchGesture`, `ACTION_SET_TEXT`, `performGlobalAction`, or notification suppression runs in parallel
- strings / structures indicating **server-defined overlays**, e.g. an `inj` object containing `package` + template filename so new target apps can be added without rebuilding the APK

### Split MQTT control/media channels for Accessibility RATs

Some Android RATs keep low-bandwidth control traffic separate from screen/camera streaming.

A practical pattern to hunt for:
- MQTT topic such as `commands_FromPC` for serialized commands
- separate registration topic such as `RegisterMyDevice`
- one port/channel for command dispatch and a second port/channel for MediaProjection or camera traffic
- Android ID or a similarly stable device identifier substituted into the registration payload before subscription/publish

This split keeps UI automation responsive while heavier screen or camera data uses a different socket/QoS profile.


## References

- [Premium Deception: Uncovering a Global Android Carrier Billing Fraud Campaign](https://zimperium.com/blog/premium-deception-uncovering-a-global-android-carrier-billing-fraud-campaign)
Expand All @@ -882,6 +959,8 @@ struct Header {
- [Rokarolla : Android Banker with Complete Device Takeover Capabilities](https://zimperium.com/blog/rokarolla-android-banker-with-complete-device-takeover-capabilities)
- [Zimperium IOC – Rokarolla commands](https://github.com/Zimperium/IOC/blob/master/2026-06-Rokarolla/commands.md)
- Kimwolf Android TV Botnet: ENS-Based C2 Evasion, TLS+ECDSA C2 Protocol, and Large-Scale Proxy/DDoS Operations - [blog.xlab.qianxin.com](https://blog.xlab.qianxin.com/kimwolf-botnet-en/)
- [Inside an N26 Impersonation Campaign: From Vishing and Fake Control 1.0 to the Copybara Android RAT](https://d3lab.net/inside-an-n26-impersonation-campaign-from-vishing-and-fake-control-1-0-to-the-copybara-android-rat)
- [apkInspector](https://github.com/erev0s/apkInspector/)


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