WRITEUP · MOBILE · RCE · 2026 · @YNSMROZTAS

DEX from a writable path

● liveclk --:--:--module · runtime

The process loaded a DEX after a write the app did not sign. That is in-process code execution. Not a second APK on this page.

rce // loadobserve
radar--:--:--
AndroScopeRCE classDexClassLoaderlab only

The trick

Split APKs, feature modules, and “update the plugin” paths all end the same way: bytes land under the app's data dir, then DexClassLoader / PathClassLoader maps them into the process. If that file is writable by someone other than a verified pack — world-writable cache, unzip without path checks, overlay from an exported provider — the next cold start runs their code as the app.

Play-style extractors have shipped this class when the unzip target was the same directory the loader trusted. Lab target is lab.sample.app. No extractor name, no payload DEX.

01 write cache / unzip / download 02 trust no signature on the file 03 load DexClassLoader(path) UID of the host code runs inside the instrumented package. that is the RCE class. public note stops at path + loader. no replace recipe.
D  NATIVE & RUNTIME
44  JNI / loader observer

session — lab.sample.app
[load] DexClassLoader
[load] path under app files — writable after extract
[load] no APK signature check on that file
[load] bytes not dumped on this page

mitsec@lab.sample.app:

What AndroScope is allowed to say

The runtime observer prints the loader class and whether the path sits in a writable tree. It does not drop a replacement DEX. Persistence after reboot is a second finding only if the same file is loaded again — write that as two rows, not as a kit.

Class: dynamic load from an unsigned, writable path. Same family as feature-module extract bugs. No Play Core pack on this site.

Fix

YUNUS EMRE ÖZTAŞ · MITSEC · LAB BUILD ONLY