React Native-Anwendungsanalyse

Reading time: 10 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Um zu bestätigen, ob die Anwendung auf dem React Native-Framework basiert, befolgen Sie diese Schritte:

  1. Benennen Sie die APK-Datei mit einer Zip-Erweiterung um und extrahieren Sie sie in einen neuen Ordner mit dem Befehl cp com.example.apk example-apk.zip und unzip -qq example-apk.zip -d ReactNative.

  2. Navigieren Sie zum neu erstellten ReactNative-Ordner und suchen Sie den Ordner assets. In diesem Ordner sollten Sie die Datei index.android.bundle finden, die das React JavaScript in einem minifizierten Format enthält.

  3. Verwenden Sie den Befehl find . -print | grep -i ".bundle$", um die JavaScript-Datei zu suchen.

Hinweis: Wenn Ihnen ein Android App Bundle (.aab) anstelle einer APK gegeben wird, generieren Sie zuerst eine universelle APK und extrahieren Sie dann das Bundle:

bash
# Get bundletool.jar and generate a universal APK set
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app.apks \
--mode=universal \
--overwrite

# Extract the APK and then unzip it to find assets/index.android.bundle
unzip -p app.apks universal.apk > universal.apk
unzip -qq universal.apk -d ReactNative
ls ReactNative/assets/

Javascript-Code

Wenn Sie den Inhalt der index.android.bundle überprüfen und den JavaScript-Code der Anwendung finden (auch wenn er minimiert ist), können Sie ihn analysieren, um sensible Informationen und Schwachstellen zu finden.

Da das Bundle tatsächlich den gesamten JS-Code der Anwendung enthält, ist es möglich, ihn in verschiedene Dateien zu unterteilen (was die Rückentwicklung potenziell erleichtert) mit dem Tool react-native-decompiler.

Webpack

Um den JavaScript-Code weiter zu analysieren, können Sie die Datei auf https://spaceraccoon.github.io/webpack-exploder/ hochladen oder diese Schritte befolgen:

  1. Erstellen Sie eine Datei mit dem Namen index.html im selben Verzeichnis mit dem folgenden Code:
html
<script src="./index.android.bundle"></script>
  1. Öffnen Sie die index.html-Datei in Google Chrome.

  2. Öffnen Sie die Entwicklertools, indem Sie Command+Option+J für OS X oder Control+Shift+J für Windows drücken.

  3. Klicken Sie im Entwicklertool auf "Sources". Sie sollten eine JavaScript-Datei sehen, die in Ordner und Dateien unterteilt ist und das Hauptbündel bildet.

Wenn Sie eine Datei namens index.android.bundle.map finden, können Sie den Quellcode in einem unminifizierten Format analysieren. Map-Dateien enthalten Quellzuordnungen, die es Ihnen ermöglichen, minifizierte Bezeichner zuzuordnen.

Um nach sensiblen Anmeldeinformationen und Endpunkten zu suchen, befolgen Sie diese Schritte:

  1. Identifizieren Sie sensible Schlüsselwörter, um den JavaScript-Code zu analysieren. React Native-Anwendungen verwenden häufig Drittanbieterdienste wie Firebase, AWS S3-Dienstendpunkte, private Schlüssel usw.

  2. In diesem speziellen Fall wurde beobachtet, dass die Anwendung den Dialogflow-Dienst verwendet. Suchen Sie nach einem Muster, das mit seiner Konfiguration zusammenhängt.

  3. Es war günstig, dass während des Recon-Prozesses sensible hartcodierte Anmeldeinformationen im JavaScript-Code gefunden wurden.

Schnelles Suchen nach Geheimnissen/Endpunkten in Bündeln

Diese einfachen Greps bringen oft interessante Indikatoren selbst in minifiziertem JS zutage:

bash
# Common backends and crash reporters
strings -n 6 index.android.bundle | grep -Ei "(api\.|graphql|/v1/|/v2/|socket|wss://|sentry\.io|bugsnag|appcenter|codepush|firebaseio\.com|amplify|aws)"

# Firebase / Google keys (heuristics)
strings -n 6 index.android.bundle | grep -Ei "(AIza[0-9A-Za-z_-]{35}|AIzaSy[0-9A-Za-z_-]{33})"

# AWS access key id heuristic
strings -n 6 index.android.bundle | grep -E "AKIA[0-9A-Z]{16}"

# Expo/CodePush deployment keys
strings -n 6 index.android.bundle | grep -Ei "(CodePush|codepush:\\/\\/|DeploymentKey)"

# Sentry DSN
strings -n 6 index.android.bundle | grep -Ei "(Sentry\.init|dsn\s*:)"

Wenn Sie Verdacht auf Over-The-Air-Update-Frameworks haben, suchen Sie auch nach:

  • Microsoft App Center / CodePush-Bereitstellungsschlüsseln
  • Expo EAS Updates-Konfiguration (expo-updates, expo\.io, Signaturzertifikate)

Ändern Sie den JS-Code und bauen Sie neu

In diesem Fall ist es einfach, den Code zu ändern. Sie müssen nur die App umbenennen, um die Erweiterung .zip zu verwenden, und sie extrahieren. Dann können Sie den JS-Code in diesem Bundle ändern und die App neu bauen. Das sollte ausreichen, um Ihnen zu ermöglichen, Code in die App zu injizieren, um Tests durchzuführen.

Hermes-Bytecode

Wenn das Bundle Hermes-Bytecode enthält, werden Sie nicht auf den Javascript-Code der App zugreifen können (nicht einmal auf die minimierte Version).

Sie können überprüfen, ob das Bundle Hermes-Bytecode enthält, indem Sie den folgenden Befehl ausführen:

bash
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96

Sie können jedoch die Tools hbctool, aktualisierte Forks von hbctool, die neuere Bytecode-Versionen unterstützen, hasmer, hermes_rs (Rust-Bibliothek/APIs) oder hermes-dec verwenden, um den Bytecode zu disassemblieren und auch ihn in einen pseudo JS-Code zu dekompilieren. Zum Beispiel:

bash
# Disassemble and re-assemble with hbctool (works only for supported HBC versions)
hbctool disasm ./index.android.bundle ./hasm_out
# ...edit ./hasm_out/**/*.hasm (e.g., change comparisons, constants, feature flags)...
hbctool asm   ./hasm_out ./index.android.bundle

# Using hasmer (focus on disassembly; assembler/decompiler are WIP)
hasmer disasm ./index.android.bundle -o hasm_out

# Using hermes-dec to produce pseudo-JS
hbc-disassembler ./index.android.bundle /tmp/my_output_file.hasm
hbc-decompiler   ./index.android.bundle /tmp/my_output_file.js

Tipp: Das Open-Source-Projekt Hermes liefert auch Entwicklerwerkzeuge wie hbcdump in bestimmten Hermes-Versionen. Wenn Sie die passende Hermes-Version, die zur Erstellung des Bundles verwendet wurde, erstellen, kann hbcdump Funktionen, String-Tabellen und Bytecode für eine tiefere Analyse ausgeben.

Code ändern und neu erstellen (Hermes)

Idealerweise sollten Sie in der Lage sein, den disassemblierten Code zu ändern (einen Vergleich, einen Wert oder was auch immer Sie ändern müssen) und dann den Bytecode neu zu erstellen und die App neu zu bauen.

  • Das ursprüngliche hbctool unterstützt das Disassemblieren des Bundles und das Wiederherstellen nach Änderungen, unterstützte jedoch historisch nur ältere Bytecode-Versionen. Von der Community gepflegte Forks erweitern die Unterstützung auf neuere Hermes-Versionen (einschließlich Mid-80s–96) und sind oft die praktischste Option, um moderne RN-Apps zu patchen.
  • Das Tool hermes-dec unterstützt nicht das Neuaufbauen des Bytecodes (nur Decompiler/Disassembler), ist aber sehr hilfreich, um die Logik zu navigieren und Strings auszugeben.
  • Das Tool hasmer zielt darauf ab, sowohl Disassemblierung als auch Assemblierung für mehrere Hermes-Versionen zu unterstützen; die Assemblierung entwickelt sich noch, ist aber einen Versuch mit aktuellem Bytecode wert.

Ein minimaler Workflow mit hbctool-ähnlichen Assemblierern:

bash
# 1) Disassemble to HASM directories
hbctool disasm assets/index.android.bundle ./hasm

# 2) Edit a guard or feature flag (example: force boolean true)
#    In the relevant .hasm, replace a LoadConstUInt8 0 with 1
#    or change a conditional jump target to bypass a check.

# 3) Reassemble into a new bundle
hbctool asm ./hasm assets/index.android.bundle

# 4) Repack the APK and resign
zip -r ../patched.apk *
# Align/sign as usual (see Android signing section in HackTricks)

Beachten Sie, dass das Hermes-Bytecode-Format versioniert ist und der Assembler mit dem exakten On-Disk-Format übereinstimmen muss. Wenn Sie Formatfehler erhalten, wechseln Sie zu einem aktualisierten Fork/Alternativ oder bauen Sie die passenden Hermes-Tools neu auf.

Dynamische Analyse

Sie könnten versuchen, die App dynamisch zu analysieren, indem Sie Frida verwenden, um den Entwicklermodus der React-App zu aktivieren und react-native-debugger zu verwenden, um sich daran anzuhängen. Allerdings benötigen Sie dafür anscheinend den Quellcode der App. Weitere Informationen finden Sie unter https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/.

Aktivieren der Dev-Unterstützung in der Release-Version mit Frida (Einschränkungen)

Einige Apps versenden versehentlich Klassen, die die Dev-Unterstützung umschaltbar machen. Wenn vorhanden, können Sie versuchen, getUseDeveloperSupport() zu zwingen, true zurückzugeben:

javascript
// frida -U -f com.target.app -l enable-dev.js
Java.perform(function(){
try {
var Host = Java.use('com.facebook.react.ReactNativeHost');
Host.getUseDeveloperSupport.implementation = function(){
return true; // force dev support
};
console.log('[+] Patched ReactNativeHost.getUseDeveloperSupport');
} catch (e) {
console.log('[-] Could not patch: ' + e);
}
});

Warnung: In ordnungsgemäß erstellten Release-Bauten werden DevSupportManagerImpl und verwandte Debug-Only-Klassen entfernt, und das Umstellen dieses Flags kann die App zum Absturz bringen oder keine Wirkung haben. Wenn dies funktioniert, können Sie typischerweise das Entwickler-Menü aufrufen und Debugger/Inspektoren anhängen.

Netzwerkinterzeption in RN-Apps

React Native Android verlässt sich typischerweise im Hintergrund auf OkHttp (über das Networking-native Modul). Um den Datenverkehr auf einem nicht gerooteten Gerät während dynamischer Tests abzufangen/beobachten:

  • Verwenden Sie einen Systemproxy + vertrauen Sie dem Benutzer-CA oder verwenden Sie andere generische Android-TLS-Bypass-Techniken.
  • RN-spezifischer Tipp: Wenn die App versehentlich Flipper im Release bündelt (Debug-Tooling), kann das Flipper-Netzwerk-Plugin Anfragen/Antworten offenlegen.

Für generische Android-Interzeption und Pinning-Bypass-Techniken siehe:

Make APK Accept CA Certificate

Objection Tutorial

Aktuelle Probleme in beliebten RN-Bibliotheken (worauf man achten sollte)

Bei der Überprüfung von Drittanbieter-Modulen, die im JS-Bundle oder in nativen Bibliotheken sichtbar sind, prüfen Sie auf bekannte Schwachstellen und verifizieren Sie die Versionen in package.json/yarn.lock.

  • react-native-mmkv (Android): Versionen vor 2.11.0 protokollierten den optionalen Verschlüsselungsschlüssel in den Android-Protokollen. Wenn ADB/logcat verfügbar ist, könnten Geheimnisse wiederhergestellt werden. Stellen Sie sicher, dass >= 2.11.0 verwendet wird. Indikatoren: Verwendung von react-native-mmkv, Protokollanweisungen, die die MMKV-Initialisierung mit Verschlüsselung erwähnen. CVE-2024-21668.
  • react-native-document-picker: Versionen < 9.1.1 waren anfällig für Pfadtraversierung auf Android (Dateiauswahl), behoben in 9.1.1. Validieren Sie Eingaben und Bibliotheksversion.

Schnelle Überprüfungen:

bash
grep -R "react-native-mmkv" -n {index.android.bundle,*.map} 2>/dev/null || true
grep -R "react-native-document-picker" -n {index.android.bundle,*.map} 2>/dev/null || true
# If you also have the node_modules (rare on release): grep -R in package.json / yarn.lock

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks