Skip to content

Commit 0e69388

Browse files
authored
Merge pull request #2739 from HackTricks-wiki/update_MoYu_Malware_Turns_Android_Car_Head_Units_into_P_c599dc5f57afeb22
MoYu Malware Turns Android Car Head Units into Proxy-Botnet ...
2 parents 63b578a + 6ad9f14 commit 0e69388

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

src/mobile-pentesting/android-app-pentesting/insecure-in-app-update-rce.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,34 @@ Also consider stubbing vendor methods such as `PluginVerifier.verifySignature()`
249249
- Split APK / local-testing leftovers: official Play Core testing helpers obtain splits from a specified local directory, and `SplitCompat.install()` immediately exposes code/resources from installed splits. In production builds, any custom equivalent that trusts writable module directories, `split_id`-derived filenames, or leftover local-testing artefacts becomes a plugin-swap primitive. Historically this class of bug already led to Play Core code execution via path traversal (CVE-2020-8913); today you usually find the same idea as app-side misuse rather than the library bug itself.
250250
- React Native / Web-based OTA content: if native bridges execute JS from OTA without strict signing, arbitrary code execution in the app context is possible (e.g., insecure CodePush-like flows). For Expo/EAS-style updaters, look for disabled or bypassable update signing before treating the JS bundle as trusted.
251251

252-
### 5.1 Platform changes that change exploitation
252+
### 5.1 Trusted updater abuse: installing packages that do not exist yet
253+
254+
Do not test only replacement updates. A preinstalled or privileged updater may deserialize a remote Boolean/enum that decides whether the target package must already exist. If the backend can select an “install when absent” branch (for example, `installNotExists=true`), the update channel becomes an **arbitrary new-APK installation primitive**, even if the normal workflow appears limited to maintaining firmware packages. Trace the complete path from MQTT/push-message parsing through the package-existence check, download destination and `PackageInstaller`/PackageManager call.<sup>[[3]](#references)</sup>
255+
256+
Preserve the updater cache and correlate every newly introduced package with its recorded installer. Android's `pm list packages -i` option exposes the installer identity; on a rooted or forensic image, compare this with the APKs staged below the updater's external cache.<sup>[[3]](#references)[[4]](#references)</sup>
257+
258+
```bash
259+
UPDATER=com.vendor.updater; SUSPECT=com.example.suspect
260+
adb shell 'pm list packages -i | sort'
261+
adb shell "find /sdcard/Android/data/$UPDATER/cache/push/apk -type f -ls 2>/dev/null"
262+
adb shell "pm path $SUSPECT; dumpsys package $SUSPECT"
263+
```
264+
265+
Treat the installer identity as provenance, not privilege inheritance: a downloaded APK normally executes under its **own UID and declared/granted permissions**. Do not report execution with the updater's system privileges unless shared UID, platform signing, an exported privileged bridge or another explicit escalation path proves it.<sup>[[3]](#references)</sup>
266+
267+
### 5.2 Recovering staged payload families
268+
269+
A downloaded file's extension is not a reliable type signal. Start from the loader's reads and deserializer: one observed staged format used a one-byte string key, a four-byte floating-point value reused as an XOR key, and then encrypted DEX bytes. Embedded droppers may also split ciphertext into blocks and derive each single-byte key linearly (`key_i = (key_0 + i * step) & 0xff`). Reimplement the exact loop, deserialize the recovered metadata, and validate output with DEX/ZIP magic before decompilation.<sup>[[3]](#references)</sup>
270+
271+
Predictable version strings in payload URLs are also an analysis surface. If a captured path contains a directly editable value such as `dex3.68.png`, enumerate nearby versions **only in an authorized sinkholed/lab copy**, then record HTTP status, hash, decoded magic and entry point. Diff recovered versions for header-layout, decoder, C2, class/method and capability changes; a decoder change in an older payload can reveal a previously unknown intermediate loader.<sup>[[3]](#references)</sup>
272+
273+
### 5.3 Configuration-driven reflective modules
274+
275+
Look beyond hard-coded command handlers. A compact implant can receive integer task IDs, fetch JSON definitions only for unknown or newer timestamped versions, and persist them in `SharedPreferences`; a field such as `tagName` then selects handlers for HTTP, WebView/JavaScript or module loading. During analysis, dump the preferences XML and correlate ID/version changes with descriptor-fetch requests and reflective calls.<sup>[[3]](#references)</sup>
276+
277+
For module loaders, trace attacker-controlled `url`, module name, entry class, factory/virtual method, typed arguments, cleanup list, thread and reload flags. An MD5/SHA value delivered in the **same attacker-controlled task object** as the payload URL detects corruption but does not authenticate code: the operator controls both values. Successful reflection gives replaceable code execution in the implant process and permission context.<sup>[[3]](#references)</sup>
278+
279+
### 5.4 Platform changes that change exploitation
253280

254281
- Apps targeting Android 14 (API 34+) must mark dynamically loaded DEX/JAR/APK files read-only as soon as they are opened and before content is written; otherwise the system throws an exception when the app later tries to load them.<sup>[[2]](#references)</sup>
255282
- Apps targeting Android 17 (API 37+) extend the same Safer Dynamic Code Loading rule to native libraries loaded with `System.load()`; writable copied `.so` files now fail with `UnsatisfiedLinkError`.<sup>[[2]](#references)</sup>
@@ -279,5 +306,7 @@ Also consider stubbing vendor methods such as `PluginVerifier.verifySignature()`
279306

280307
- [1] [NowSecure – Remote Code Execution Discovered in Xtool AnyScan App](https://www.nowsecure.com/blog/2025/07/16/remote-code-execution-discovered-in-xtool-anyscan-app-risks-to-phones-and-vehicles/)
281308
- [2] [Android Developers – Dynamic Code Loading (risks and mitigations)](https://developer.android.com/privacy-and-security/risks/dynamic-code-loading)
309+
- [3] [MoYu Malware Turns Android Car Head Units into Proxy-Botnet Nodes](https://securelist.com/android-head-unit-malware/121106/)
310+
- [4] [Android Debug Bridge – Package manager commands](https://developer.android.com/tools/adb#pm)
282311

283-
{{#include ../../banners/hacktricks-training.md}}
312+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)