diff --git a/src/mobile-pentesting/android-app-pentesting/react-native-application.md b/src/mobile-pentesting/android-app-pentesting/react-native-application.md index d7e034307..006a7f9d8 100644 --- a/src/mobile-pentesting/android-app-pentesting/react-native-application.md +++ b/src/mobile-pentesting/android-app-pentesting/react-native-application.md @@ -1,7 +1,7 @@ -{{#include ../../banners/hacktricks-training.md}} - # Análise de Aplicações React Native +{{#include ../../banners/hacktricks-training.md}} + Para confirmar se a aplicação foi construída no framework React Native, siga estes passos: 1. Renomeie o arquivo APK com uma extensão zip e extraia-o para uma nova pasta usando o comando `cp com.example.apk example-apk.zip` e `unzip -qq example-apk.zip -d ReactNative`. @@ -10,6 +10,20 @@ Para confirmar se a aplicação foi construída no framework React Native, siga 3. Use o comando `find . -print | grep -i ".bundle$"` para procurar o arquivo JavaScript. +Nota: Se você receber um Android App Bundle (.aab) em vez de um APK, gere um APK universal primeiro e depois extraia o 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/ +``` ## Código Javascript Se ao verificar o conteúdo do `index.android.bundle` você encontrar o código JavaScript da aplicação (mesmo que minificado), você pode **analisá-lo para encontrar informações sensíveis e vulnerabilidades**. @@ -32,7 +46,7 @@ Para analisar ainda mais o código JavaScript, você pode fazer o upload do arqu Se você encontrar um arquivo chamado `index.android.bundle.map`, poderá analisar o código-fonte em um formato não minificado. Os arquivos de mapa contêm mapeamento de origem, que permite mapear identificadores minificados. -Para procurar credenciais e endpoints sensíveis, siga estas etapas: +Para procurar credenciais sensíveis e endpoints, siga estas etapas: 1. Identifique palavras-chave sensíveis para analisar o código JavaScript. Aplicações React Native costumam usar serviços de terceiros como Firebase, endpoints de serviço AWS S3, chaves privadas, etc. @@ -40,42 +54,142 @@ Para procurar credenciais e endpoints sensíveis, siga estas etapas: 3. Foi uma sorte que credenciais sensíveis codificadas foram encontradas no código JavaScript durante o processo de reconhecimento. +### Caça rápida a segredos/endpoints em pacotes + +Esses greps simples frequentemente revelam indicadores interessantes mesmo em JS minificado: +```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*:)" +``` +Se você suspeitar de frameworks de atualização Over-The-Air, também procure por: +- Chaves de implantação do Microsoft App Center / CodePush +- Configuração de Atualizações do Expo EAS (`expo-updates`, `expo\.io`, certificados de assinatura) + ### Mudar o código JS e reconstruir Neste caso, mudar o código é fácil. Você só precisa renomear o aplicativo para usar a extensão `.zip` e extraí-lo. Então você pode **modificar o código JS dentro deste pacote e reconstruir o aplicativo**. Isso deve ser suficiente para permitir que você **injete código** no aplicativo para fins de teste. -## Hermes bytecode +## Código de bytes Hermes -Se o pacote contiver **Hermes bytecode**, você **não poderá acessar o código Javascript** do aplicativo (nem mesmo a versão minificada). +Se o pacote contiver **código de bytes Hermes**, você **não poderá acessar o código Javascript** do aplicativo (nem mesmo a versão minificada). -Você pode verificar se o pacote contém Hermes bytecode executando o seguinte comando: +Você pode verificar se o pacote contém código de bytes Hermes executando o seguinte comando: ```bash file index.android.bundle index.android.bundle: Hermes JavaScript bytecode, version 96 ``` -No entanto, você pode usar as ferramentas **[hbctool](https://github.com/bongtrop/hbctool)**, **[hermes-dec](https://github.com/P1sec/hermes-dec)** ou **[hermes_rs](https://github.com/Pilfer/hermes_rs)** para **desmontar o bytecode** e também para **decompilá-lo para algum código JS pseudo**. Para fazer isso, por exemplo, esses comandos: +No entanto, você pode usar as ferramentas **[hbctool](https://github.com/bongtrop/hbctool)**, forks atualizados do hbctool que suportam versões mais novas de bytecode, **[hasmer](https://github.com/lucasbaizer2/hasmer)**, **[hermes_rs](https://github.com/Pilfer/hermes_rs)** (biblioteca/APIs Rust), ou **[hermes-dec](https://github.com/P1sec/hermes-dec)** para **desmontar o bytecode** e também para **decompilá-lo em algum código pseudo JS**. Por exemplo: ```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 ``` -### Mudar código e reconstruir +Dica: O projeto open-source Hermes também fornece ferramentas de desenvolvedor como `hbcdump` em lançamentos específicos do Hermes. Se você compilar a versão correspondente do Hermes usada para produzir o pacote, `hbcdump` pode despejar funções, tabelas de strings e bytecode para uma análise mais profunda. -Idealmente, você deve ser capaz de modificar o código desmontado (mudando uma comparação, ou um valor ou qualquer coisa que você precise modificar) e então **reconstruir o bytecode** e depois reconstruir o aplicativo. +### Mudar código e recompilar (Hermes) -A ferramenta **[hbctool](https://github.com/bongtrop/hbctool)** suporta a desmontagem do pacote e a reconstrução após as alterações serem realizadas, no entanto, ela **suporta apenas versões antigas** do bytecode Hermes. +Idealmente, você deve ser capaz de modificar o código desmontado (mudando uma comparação, ou um valor ou qualquer coisa que você precise modificar) e então **recompilar o bytecode** e recompilar o aplicativo. -A ferramenta **[hermes-dec](https://github.com/P1sec/hermes-dec)** não suporta a reconstrução do bytecode. +- O **[hbctool](https://github.com/bongtrop/hbctool)** original suporta desmontar o pacote e reconstruí-lo após as alterações, mas historicamente suportou apenas versões mais antigas de bytecode. Forks mantidos pela comunidade estendem o suporte a versões mais novas do Hermes (incluindo meados dos anos 80–96) e muitas vezes são a opção mais prática para corrigir aplicativos RN modernos. +- A ferramenta **[hermes-dec](https://github.com/P1sec/hermes-dec)** não suporta a recompilação do bytecode (apenas descompilador/desmontador), mas é muito útil para navegar na lógica e despejar strings. +- A ferramenta **[hasmer](https://github.com/lucasbaizer2/hasmer)** visa suportar tanto a desmontagem quanto a montagem para várias versões do Hermes; a montagem ainda está se desenvolvendo, mas vale a pena tentar em bytecode recente. -A ferramenta **[hermes_rs](https://github.com/Pilfer/hermes_rs)** suporta a reconstrução do bytecode, mas na verdade é uma biblioteca e não uma ferramenta CLI. +Um fluxo de trabalho mínimo com montadores semelhantes ao 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) +``` +Note que o formato de bytecode do Hermes é versionado e o montador deve corresponder exatamente ao formato em disco. Se você receber erros de formato, mude para um fork/alternativa atualizado ou reconstrua as ferramentas Hermes correspondentes. ## Análise Dinâmica -Você pode tentar analisar dinamicamente o aplicativo usando o Frida para habilitar o modo de desenvolvedor do aplicativo React e usar **`react-native-debugger`** para se conectar a ele. No entanto, para isso, você aparentemente precisa do código-fonte do aplicativo. Você pode encontrar mais informações sobre isso em [https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/](https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/). +Você pode tentar analisar dinamicamente o aplicativo usando Frida para habilitar o modo de desenvolvedor do aplicativo React e usar **`react-native-debugger`** para se conectar a ele. No entanto, para isso, você aparentemente precisa do código-fonte do aplicativo. Você pode encontrar mais informações sobre isso em [https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/](https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/). +### Habilitando o Suporte ao Desenvolvedor em release com Frida (advertências) + +Alguns aplicativos acidentalmente enviam classes que tornam o Suporte ao Desenvolvedor alternável. Se presente, você pode tentar forçar `getUseDeveloperSupport()` a retornar 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); +} +}); +``` +Atenção: Em builds de release corretamente construídos, `DevSupportManagerImpl` e classes relacionadas apenas para depuração são removidas e mudar esta flag pode fazer o app travar ou não ter efeito. Quando isso funciona, você pode tipicamente expor o menu de desenvolvedor e anexar depuradores/inspetores. + +### Interceptação de rede em apps RN + +React Native Android geralmente depende do OkHttp por baixo dos panos (via o módulo nativo `Networking`). Para interceptar/observar tráfego em um dispositivo não enraizado durante testes dinâmicos: +- Use proxy do sistema + confie no CA do usuário ou use outras técnicas genéricas de bypass de TLS do Android. +- Dica específica do RN: se o app incluir Flipper na release por engano (ferramentas de depuração), o plugin de Rede do Flipper pode expor requisições/respostas. + +Para técnicas genéricas de interceptação e bypass de pinning do Android, consulte: + +{{#ref}} +make-apk-accept-ca-certificate.md +{{#endref}} + +{{#ref}} +frida-tutorial/objection-tutorial.md +{{#endref}} + +## Problemas recentes em bibliotecas populares do RN (o que procurar) + +Ao auditar módulos de terceiros visíveis no bundle JS ou libs nativas, verifique por vulnerabilidades conhecidas e verifique versões em `package.json`/`yarn.lock`. + +- react-native-mmkv (Android): versões anteriores a 2.11.0 registravam a chave de criptografia opcional nos logs do Android. Se ADB/logcat estiver disponível, segredos poderiam ser recuperados. Assegure-se de usar >= 2.11.0. Indicadores: uso de `react-native-mmkv`, declarações de log mencionando a inicialização do MMKV com criptografia. CVE-2024-21668. +- react-native-document-picker: versões < 9.1.1 eram vulneráveis a travessia de caminho no Android (seleção de arquivo), corrigido na 9.1.1. Valide entradas e versão da biblioteca. + +Verificações rápidas: +```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 +``` ## Referências - [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 registra a chave de criptografia dos logs no Android, corrigido na v2.11.0 (NVD): https://nvd.nist.gov/vuln/detail/CVE-2024-21668 +- hbctool (e forks) para montar/desmontar Hermes: https://github.com/bongtrop/hbctool {{#include ../../banners/hacktricks-training.md}}