196 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Analiza aplikacji React Native
{{#include ../../banners/hacktricks-training.md}}
Aby potwierdzić, czy aplikacja została zbudowana na frameworku React Native, wykonaj następujące kroki:
1. Zmień nazwę pliku APK na plik zip i rozpakuj go do nowego folderu, używając polecenia `cp com.example.apk example-apk.zip` oraz `unzip -qq example-apk.zip -d ReactNative`.
2. Przejdź do nowo utworzonego folderu ReactNative i zlokalizuj folder assets. Wewnątrz tego folderu powinieneś znaleźć plik `index.android.bundle`, który zawiera React JavaScript w zminimalizowanym formacie.
3. Użyj polecenia `find . -print | grep -i ".bundle$"` aby wyszukać plik JavaScript.
Uwaga: Jeśli otrzymasz Android App Bundle (.aab) zamiast APK, najpierw wygeneruj uniwersalne APK, a następnie rozpakuj pakiet:
```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
Jeśli sprawdzając zawartość `index.android.bundle` znajdziesz kod JavaScript aplikacji (nawet jeśli jest zminimalizowany), możesz **analizować go w celu znalezienia wrażliwych informacji i luk w zabezpieczeniach**.
Ponieważ pakiet zawiera właściwie cały kod JS aplikacji, możliwe jest **podzielenie go na różne pliki** (potencjalnie ułatwiając jego inżynierię wsteczną) przy użyciu **narzędzia [react-native-decompiler](https://github.com/numandev1/react-native-decompiler)**.
### Webpack
Aby dalej analizować kod JavaScript, możesz przesłać plik do [https://spaceraccoon.github.io/webpack-exploder/](https://spaceraccoon.github.io/webpack-exploder/) lub postępować zgodnie z tymi krokami:
1. Utwórz plik o nazwie `index.html` w tym samym katalogu z następującym kodem:
```html
<script src="./index.android.bundle"></script>
```
2. Otwórz plik `index.html` w Google Chrome.
3. Otwórz Pasek Narzędzi Dewelopera, naciskając **Command+Option+J dla OS X** lub **Control+Shift+J dla Windows**.
4. Kliknij na "Sources" w Pasie Narzędzi Dewelopera. Powinieneś zobaczyć plik JavaScript podzielony na foldery i pliki, tworzące główny pakiet.
Jeśli znajdziesz plik o nazwie `index.android.bundle.map`, będziesz mógł analizować kod źródłowy w formacie niezmienionym. Pliki map zawierają mapowanie źródła, co pozwala na mapowanie zminifikowanych identyfikatorów.
Aby wyszukać wrażliwe dane uwierzytelniające i punkty końcowe, wykonaj następujące kroki:
1. Zidentyfikuj wrażliwe słowa kluczowe do analizy kodu JavaScript. Aplikacje React Native często korzystają z usług stron trzecich, takich jak Firebase, punkty końcowe usługi AWS S3, klucze prywatne itp.
2. W tym konkretnym przypadku zaobserwowano, że aplikacja korzysta z usługi Dialogflow. Wyszukaj wzór związany z jej konfiguracją.
3. Miałeś szczęście, że wrażliwe dane uwierzytelniające zakodowane na sztywno zostały znalezione w kodzie JavaScript podczas procesu rekonesansu.
### Szybkie polowanie na sekrety/punkty końcowe w pakietach
Te proste grepy często ujawniają interesujące wskaźniki nawet w zminifikowanym JS:
```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*:)"
```
Jeśli podejrzewasz frameworki aktualizacji Over-The-Air, poszukaj również:
- kluczy wdrożeniowych Microsoft App Center / CodePush
- konfiguracji Expo EAS Updates (`expo-updates`, `expo\.io`, certyfikaty podpisujące)
### Zmień kod JS i odbuduj
W tym przypadku zmiana kodu jest łatwa. Musisz tylko zmienić nazwę aplikacji, aby używała rozszerzenia `.zip` i wyodrębnić ją. Następnie możesz **zmodyfikować kod JS wewnątrz tego pakietu i odbudować aplikację**. To powinno wystarczyć, aby umożliwić **wstrzyknięcie kodu** do aplikacji w celach testowych.
## Hermes bytecode
Jeśli pakiet zawiera **Hermes bytecode**, **nie będziesz w stanie uzyskać dostępu do kodu Javascript** aplikacji (nawet do wersji zminimalizowanej).
Możesz sprawdzić, czy pakiet zawiera Hermes bytecode, uruchamiając następujące polecenie:
```bash
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96
```
Jednak możesz użyć narzędzi **[hbctool](https://github.com/bongtrop/hbctool)**, zaktualizowanych forków hbctool, które obsługują nowsze wersje bajtowego kodu, **[hasmer](https://github.com/lucasbaizer2/hasmer)**, **[hermes_rs](https://github.com/Pilfer/hermes_rs)** (biblioteka/API w Rust), lub **[hermes-dec](https://github.com/P1sec/hermes-dec)**, aby **rozłożyć bajtowy kod** i także **dekompilować go do pewnego kodu JS**. Na przykład:
```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
```
Tip: Projekt open-source Hermes dostarcza również narzędzia deweloperskie, takie jak `hbcdump`, w określonych wersjach Hermes. Jeśli zbudujesz odpowiadającą wersję Hermes używaną do produkcji pakietu, `hbcdump` może zrzucić funkcje, tabele ciągów i bajtowy kod do głębszej analizy.
### Zmień kod i odbuduj (Hermes)
Idealnie powinieneś być w stanie zmodyfikować zdisassemblowany kod (zmieniając porównanie, wartość lub cokolwiek, co musisz zmodyfikować), a następnie **odbudować bajtowy kod** i odbudować aplikację.
- Oryginalne **[hbctool](https://github.com/bongtrop/hbctool)** wspiera zdisassemblowanie pakietu i odbudowę po zmianach, ale historycznie wspierało tylko starsze wersje bajtowego kodu. Forki utrzymywane przez społeczność rozszerzają wsparcie na nowsze wersje Hermes (w tym mid-80s96) i często są najbardziej praktyczną opcją do łatania nowoczesnych aplikacji RN.
- Narzędzie **[hermes-dec](https://github.com/P1sec/hermes-dec)** nie wspiera odbudowy bajtowego kodu (tylko dekompilator/zdisassembler), ale jest bardzo pomocne w nawigacji po logice i zrzucaniu ciągów.
- Narzędzie **[hasmer](https://github.com/lucasbaizer2/hasmer)** ma na celu wspieranie zarówno zdisassembly, jak i assembly dla wielu wersji Hermes; assembly wciąż się rozwija, ale warto spróbować na niedawnym bajtowym kodzie.
Minimalny workflow z assemblerami podobnymi do hbctool:
```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)
```
Zauważ, że format bajtów Hermes jest wersjonowany, a assembler musi odpowiadać dokładnemu formatowi na dysku. Jeśli otrzymasz błędy formatu, przełącz się na zaktualizowany fork/alternatywę lub odbuduj odpowiadające narzędzia Hermes.
## Analiza dynamiczna
Możesz spróbować dynamicznie analizować aplikację, używając Frida, aby włączyć tryb dewelopera aplikacji React i użyć **`react-native-debugger`**, aby się do niej podłączyć. Jednak do tego potrzebujesz źródła aplikacji. Więcej informacji na ten temat znajdziesz w [https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/](https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/).
### Włączanie wsparcia dewelopera w wersji release z Frida (ostrzeżenia)
Niektóre aplikacje przypadkowo dostarczają klasy, które umożliwiają przełączanie wsparcia dewelopera. Jeśli są obecne, możesz spróbować wymusić, aby `getUseDeveloperSupport()` zwracało true:
```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);
}
});
```
Ostrzeżenie: W poprawnie zbudowanych wersjach release, `DevSupportManagerImpl` i pokrewne klasy tylko do debugowania są usuwane, a przełączanie tej flagi może spowodować awarię aplikacji lub nie mieć żadnego efektu. Gdy to działa, zazwyczaj możesz wywołać menu dewelopera i podłączyć debugery/inspektory.
### Przechwytywanie sieci w aplikacjach RN
React Native Android zazwyczaj polega na OkHttp w tle (poprzez natywny moduł `Networking`). Aby przechwycić/obserwować ruch na urządzeniu bez roota podczas testów dynamicznych:
- Użyj proxy systemowego + zaufaj użytkownikowi CA lub użyj innych ogólnych technik omijania TLS w Androidzie.
- Wskazówka specyficzna dla RN: jeśli aplikacja przypadkowo pakuje Flipper w wersji release (narzędzia debugowania), wtyczka Flipper Network może ujawniać żądania/odpowiedzi.
Aby uzyskać ogólne techniki przechwytywania i omijania pinów w Androidzie, zapoznaj się z:
{{#ref}}
make-apk-accept-ca-certificate.md
{{#endref}}
{{#ref}}
frida-tutorial/objection-tutorial.md
{{#endref}}
## Ostatnie problemy w popularnych bibliotekach RN (na co zwrócić uwagę)
Podczas audytowania modułów stron trzecich widocznych w pakiecie JS lub bibliotekach natywnych, sprawdź znane luki i zweryfikuj wersje w `package.json`/`yarn.lock`.
- react-native-mmkv (Android): wersje przed 2.11.0 rejestrowały opcjonalny klucz szyfrowania w logach Androida. Jeśli ADB/logcat jest dostępny, sekrety mogą być odzyskane. Upewnij się, że masz >= 2.11.0. Wskaźniki: użycie `react-native-mmkv`, komunikaty logów wspominające o inicjalizacji MMKV z szyfrowaniem. CVE-2024-21668.
- react-native-document-picker: wersje < 9.1.1 były podatne na przejście ścieżki w Androidzie (wybór pliku), naprawione w 9.1.1. Waliduj dane wejściowe i wersję biblioteki.
Szybkie kontrole:
```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
```
## Odniesienia
- [https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7](https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7)
- [https://www.assetnote.io/resources/research/expanding-the-attack-surface-react-native-android-applications](https://www.assetnote.io/resources/research/expanding-the-attack-surface-react-native-android-applications)
- [https://payatu.com/wp-content/uploads/2023/02/Mastering-React-Native-Application-Pentesting-A-Practical-Guide-2.pdf](https://payatu.com/wp-content/uploads/2023/02/Mastering-React-Native-Application-Pentesting-A-Practical-Guide-2.pdf)
- CVE-2024-21668: react-native-mmkv loguje klucz szyfrowania na Androidzie, naprawione w v2.11.0 (NVD): https://nvd.nist.gov/vuln/detail/CVE-2024-21668
- hbctool (i forki) do Hermes assemble/disassemble: https://github.com/bongtrop/hbctool
{{#include ../../banners/hacktricks-training.md}}