mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/react-native-a
This commit is contained in:
parent
6f3e15e839
commit
c959b8089e
@ -1,24 +1,38 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# 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`.
|
||||
1. Zmień nazwę pliku APK na plik zip i wypakuj 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. W tym folderze powinieneś znaleźć plik `index.android.bundle`, który zawiera React JavaScript w zminifikowanym formacie.
|
||||
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.
|
||||
|
||||
## Kod Javascript
|
||||
Uwaga: Jeśli otrzymasz Android App Bundle (.aab) zamiast APK, najpierw wygeneruj uniwersalne APK, a następnie wypakuj 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
|
||||
|
||||
Jeśli sprawdzając zawartość `index.android.bundle` znajdziesz kod JavaScript aplikacji (nawet jeśli jest zminifikowany), możesz **analizować go w celu znalezienia wrażliwych informacji i luk w zabezpieczeniach**.
|
||||
# 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
|
||||
|
||||
Ponieważ bundle zawiera właściwie cały kod JS aplikacji, możliwe jest **podzielenie go na różne pliki** (co potencjalnie ułatwia jego inżynierię wsteczną) przy użyciu **narzędzia [react-native-decompiler](https://github.com/numandev1/react-native-decompiler)**.
|
||||
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ę odwrotną) 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 wykonać następujące kroki:
|
||||
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
|
||||
@ -26,11 +40,11 @@ Aby dalej analizować kod JavaScript, możesz przesłać plik do [https://spacer
|
||||
```
|
||||
2. Otwórz plik `index.html` w Google Chrome.
|
||||
|
||||
3. Otwórz Narzędzie dewelopera, naciskając **Command+Option+J dla OS X** lub **Control+Shift+J dla Windows**.
|
||||
3. Otwórz Narzędzie Dewelopera, naciskając **Command+Option+J dla OS X** lub **Control+Shift+J dla Windows**.
|
||||
|
||||
4. Kliknij na "Sources" w Narzędziu dewelopera. Powinieneś zobaczyć plik JavaScript podzielony na foldery i pliki, tworzące główny pakiet.
|
||||
4. Kliknij na "Sources" w Narzędziu 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 niezmienionej formie. Pliki map zawierają mapowanie źródła, co pozwala na mapowanie zminimalizowanych identyfikatorów.
|
||||
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:
|
||||
|
||||
@ -38,44 +52,144 @@ Aby wyszukać wrażliwe dane uwierzytelniające i punkty końcowe, wykonaj nast
|
||||
|
||||
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.
|
||||
3. Miałeś szczęście, że wrażliwe dane uwierzytelniające zakodowane na stałe 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 ramy 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ć ci **wstrzyknięcie kodu** do aplikacji w celach testowych.
|
||||
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
|
||||
## Hermes bytecode
|
||||
|
||||
Jeśli pakiet zawiera **Hermes bytecode**, **nie będziesz mógł uzyskać dostępu do kodu Javascript** aplikacji (nawet do wersji zminimalizowanej).
|
||||
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
|
||||
```
|
||||
Możesz jednak użyć narzędzi **[hbctool](https://github.com/bongtrop/hbctool)**, **[hermes-dec](https://github.com/P1sec/hermes-dec)** lub **[hermes_rs](https://github.com/Pilfer/hermes_rs)**, aby **zdekompilować bajtkod** i również **zdekompilować go do pseudo kodu JS**. Aby to zrobić, na przykład te polecenia:
|
||||
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 **zdekompilować bajtowy kod** i również **zdekompilować 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
|
||||
hbc-decompiler ./index.android.bundle /tmp/my_output_file.js
|
||||
```
|
||||
### Zmiana kodu i odbudowa
|
||||
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.
|
||||
|
||||
Idealnie powinieneś być w stanie zmodyfikować zdisasemblerowany kod (zmieniając porównanie, wartość lub cokolwiek, co musisz zmodyfikować), a następnie **odbudować bajtkod** i odbudować aplikację.
|
||||
### Zmień kod i odbuduj (Hermes)
|
||||
|
||||
Narzędzie **[hbctool](https://github.com/bongtrop/hbctool)** wspiera disasemblerowanie pakietu i ponowne budowanie go po wprowadzeniu zmian, jednak **obsługuje tylko stare wersje** bajtkodu 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ę.
|
||||
|
||||
Narzędzie **[hermes-dec](https://github.com/P1sec/hermes-dec)** nie wspiera odbudowy bajtkodu.
|
||||
- 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-80s–96) 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 niedawno zbudowanym bajtowym kodzie.
|
||||
|
||||
Narzędzie **[hermes_rs](https://github.com/Pilfer/hermes_rs)** wspiera odbudowę bajtkodu, ale jest to w rzeczywistości biblioteka, a nie narzędzie CLI.
|
||||
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 zewnętrznych 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 wersję >= 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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user