36 KiB
Conceptos Básicos de Aplicaciones Android
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si quieres ver a tu empresa anunciada en HackTricks o descargar HackTricks en PDF, consulta los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub de HackTricks y HackTricks Cloud.
Encuentra vulnerabilidades que importan más para poder solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos proactivos de amenazas, encuentra problemas en todo tu stack tecnológico, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Modelo de Seguridad de Android
Hay dos capas:
- El SO, que mantiene las aplicaciones instaladas aisladas unas de otras.
- La aplicación en sí, que permite a los desarrolladores exponer ciertas funcionalidades y configura las capacidades de la aplicación.
Separación de UID
A cada aplicación se le asigna un ID de Usuario específico. Esto se hace durante la instalación de la app para que la app solo pueda interactuar con archivos propiedad de su ID de Usuario o archivos compartidos. Por lo tanto, solo la propia app, ciertos componentes del SO y el usuario root pueden acceder a los datos de la app.
Compartición de UID
Dos aplicaciones pueden configurarse para usar el mismo UID. Esto puede ser útil para compartir información, pero si una de ellas se ve comprometida, los datos de ambas aplicaciones estarán comprometidos. Por eso se desaconseja este comportamiento.
Para compartir el mismo UID, las aplicaciones deben definir el mismo valor android:sharedUserId
en sus manifiestos.
Aislamiento (Sandboxing)
El Sandbox de Aplicaciones Android permite ejecutar cada aplicación como un proceso separado bajo un ID de usuario separado. Cada proceso tiene su propia máquina virtual, por lo que el código de una app se ejecuta aislado de otras apps.
Desde Android 5.0(L) se aplica SELinux. Básicamente, SELinux deniega todas las interacciones de procesos y luego crea políticas para permitir solo las interacciones esperadas entre ellos.
Permisos
Cuando instalas una app y esta pide permisos, la app está solicitando los permisos configurados en los elementos uses-permission
en el archivo AndroidManifest.xml. El elemento uses-permission indica el nombre del permiso solicitado dentro del atributo name. También tiene el atributo maxSdkVersion que deja de pedir permisos en versiones superiores a la especificada.
Nota que las aplicaciones de android no necesitan pedir todos los permisos al principio, también pueden pedir permisos dinámicamente pero todos los permisos deben estar declarados en el manifiesto.
Cuando una app expone funcionalidad, puede limitar el acceso solo a apps que tienen un permiso especificado.
Un elemento de permiso tiene tres atributos:
- El nombre del permiso
- El atributo permission-group, que permite agrupar permisos relacionados.
- El protection-level que indica cómo se otorgan los permisos. Hay cuatro tipos:
- Normal: Usado cuando no hay amenazas conocidas para la app. El usuario no necesita aprobarlo.
- Peligroso (Dangerous): Indica que el permiso otorga a la aplicación solicitante algún acceso elevado. Se solicita a los usuarios que los aprueben.
- Firma (Signature): Solo apps firmadas por el mismo certificado que el que exporta el componente pueden recibir permiso. Este es el tipo de protección más fuerte.
- FirmaOSistema (SignatureOrSystem): Solo apps firmadas por el mismo certificado que el que exporta el componente o apps que se ejecutan con acceso a nivel de sistema pueden recibir permisos
Aplicaciones Preinstaladas
Estas apps generalmente se encuentran en los directorios /system/app
o /system/priv-app
y algunas de ellas están optimizadas (puede que ni siquiera encuentres el archivo classes.dex
). Estas aplicaciones valen la pena revisarlas porque a veces están ejecutándose con demasiados permisos (como root).
- Las que vienen con la ROM del AOSP (Proyecto de Código Abierto de Android)
- Añadidas por el fabricante del dispositivo
- Añadidas por el proveedor de telefonía móvil (si se compró a través de ellos)
Rooting
Para obtener acceso root en un dispositivo android físico generalmente necesitas explotar 1 o 2 vulnerabilidades que suelen ser específicas para el dispositivo y versión.
Una vez que el exploit ha funcionado, generalmente se copia el binario su
de Linux en una ubicación especificada en la variable de entorno PATH del usuario, como /system/xbin
.
Una vez configurado el binario su, se utiliza otra aplicación de Android para interactuar con el binario su
y procesar solicitudes de acceso root como Superuser y SuperSU (disponibles en Google Play store).
{% hint style="danger" %} Nota que el proceso de rooting es muy peligroso y puede dañar severamente el dispositivo {% endhint %}
ROMs
Es posible reemplazar el SO instalando un firmware personalizado. Haciendo esto es posible extender la utilidad de un dispositivo antiguo, eludir restricciones de software o acceder al código más reciente de Android.
OmniROM y LineageOS son dos de los firmwares más populares para usar.
Nota que no siempre es necesario rootear el dispositivo para instalar un firmware personalizado. Algunos fabricantes permiten el desbloqueo de sus gestores de arranque de una manera bien documentada y segura.
Implicaciones
Una vez que un dispositivo está rooteado, cualquier app podría solicitar acceso como root. Si una aplicación maliciosa lo obtiene, tendrá acceso a casi todo y podrá dañar el teléfono.
Fundamentos de la Aplicación Android
Esta introducción está tomada de https://maddiestone.github.io/AndroidAppRE/app_fundamentals.html
Revisión de Fundamentos
- Las aplicaciones Android están en el formato de archivo APK. APK es básicamente un archivo ZIP. (Puedes cambiar la extensión del archivo a .zip y usar unzip para abrirlo y ver su contenido.)
- Contenidos del APK (No exhaustivo)
- AndroidManifest.xml
- resources.arsc/strings.xml
- resources.arsc: un archivo que contiene recursos precompilados, como XML binario, por ejemplo.
- res/xml/files_paths.xml
- META-INF/
- ¡El certificado vive aquí!
- classes.dex
- Bytecode Dalvik para la aplicación en formato de archivo DEX. Este es el código Java (o Kotlin) compilado que la aplicación ejecutará por defecto.
- lib/
- Las bibliotecas nativas para la aplicación, por defecto, ¡viven aquí! Bajo el directorio lib/, están los directorios específicos de la CPU.
armeabi
: código compilado solo para procesadores basados en ARMarmeabi-v7a
: código compilado solo para procesadores basados en ARMv7 y superioresx86
: código compilado para X86mips
: código compilado solo para procesadores MIPS
- assets/
- Cualquier otro archivo que pueda ser necesario para la app.
- Bibliotecas nativas adicionales o archivos DEX pueden estar incluidos aquí. Esto puede suceder especialmente cuando los autores de malware quieren intentar "ocultar" código adicional, nativo o Dalvik, al no incluirlo en las ubicaciones predeterminadas.
- res/
- el directorio que contiene recursos no compilados en resources.arsc
Dalvik & Smali
La mayoría de las aplicaciones Android están escritas en Java. Kotlin también es compatible e interoperable con Java. Para simplificar, por el resto de este taller, cuando me refiera a "Java", puedes asumir que me refiero a "Java o Kotlin". En lugar de que el código Java se ejecute en la Máquina Virtual de Java (JVM) como las aplicaciones de escritorio, en Android, el Java se compila al formato de bytecode _Dalvik Executable (DEX)_**.** Para versiones anteriores de Android, el bytecode era traducido por la máquina virtual Dalvik. Para versiones más recientes de Android, se utiliza el Android Runtime (ART).
Si los desarrolladores escriben en Java y el código se compila a bytecode DEX, para la ingeniería inversa, trabajamos en la dirección opuesta.
\
Smali es la versión legible por humanos del bytecode Dalvik. Técnicamente, Smali y baksmali son los nombres de las herramientas (ensamblador y desensamblador, respectivamente), pero en Android, a menudo usamos el término "Smali" para referirnos a las instrucciones. Si has hecho ingeniería inversa o arquitectura informática en código compilado C/C++. SMALI es como el lenguaje ensamblador: entre el código fuente de alto nivel y el bytecode.
Encuentra vulnerabilidades que importan más para poder solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos proactivos de amenazas, encuentra problemas en todo tu stack tecnológico, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Intents
Los Intents son el principal medio por el cual las aplicaciones Android se comunican entre sus componentes o con otras apps. Estos objetos de mensaje también pueden llevar datos entre apps o componentes, de manera similar a cómo se utilizan las solicitudes GET/POST en las comunicaciones HTTP.
Entonces, un Intent es básicamente un mensaje que se pasa entre componentes. Los Intents pueden dirigirse a componentes o apps específicas, o pueden enviarse sin un destinatario específico.
Para ser simples, los Intents pueden usarse:
- Para iniciar una Actividad, abriendo típicamente una interfaz de usuario para una app
- Como difusiones para informar al sistema y a las apps de cambios
- Para iniciar, detener y comunicarse con un servicio en segundo plano
- Para acceder a datos a través de ContentProviders
- Como callbacks para manejar eventos
Una implementación incorrecta podría resultar en la fuga de datos, funciones restringidas siendo llamadas y la manipulación del flujo del programa.
Intent-Filter
Un Intent Filter especifica los tipos de Intents a los que puede responder una actividad, servicio o Broadcast Receiver. Especifica lo que una actividad o servicio puede hacer y qué tipos de difusiones puede manejar un Receiver. Permite que el componente correspondiente reciba Intents del tipo declarado. Los Intent Filters se definen típicamente a través del archivo AndroidManifest.xml. Para Broadcast Receiver también es posible definirlos en código. Un Intent Filter se define por su categoría, acción y filtros de datos. También puede contener metadatos adicionales.
En Android, una actividad/servicio/content provider/broadcast receiver es público cuando exported
está configurado en true
pero un componente es también público si el manifiesto especifica un Intent filter para él. Sin embargo,
los desarrolladores pueden hacer explícitamente privados los componentes (independientemente de cualquier filtro de intent)
configurando el atributo ** exported
a false
** para cada componente en el archivo del manifiesto.
Los desarrolladores también pueden configurar el atributo permission
para requerir cierto permiso para acceder al componente, restringiendo así el acceso al componente.
Intents Implícitos
Los Intents se crean programáticamente utilizando un constructor de Intent:
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
El Action del intent previamente declarado es ACTION_SEND y el Extra es un Uri mailto (el Extra es la información adicional que el intent espera).
Este intent debe declararse dentro del manifiesto como en el siguiente ejemplo:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Un intent-filter necesita coincidir con la acción, datos y categoría para recibir un mensaje.
El proceso de "Resolución de Intent" determina qué aplicación debe recibir cada mensaje. Este proceso considera el atributo de prioridad, que se puede establecer en la declaración del intent-filter, y se seleccionará el que tenga la mayor prioridad. Esta prioridad se puede establecer entre -1000 y 1000 y las aplicaciones pueden usar el valor SYSTEM_HIGH_PRIORITY
. Si surge un conflicto, aparece una ventana de "elección" para que el usuario pueda decidir.
Intents Explícitos
Un intent explícito especifica el nombre de la clase al que está dirigido:
Intent downloadIntent = new (this, DownloadService.class):
En otras aplicaciones para acceder al intent previamente declarado puedes usar:
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
Pending Intents
Estos permiten que otras aplicaciones realicen acciones en nombre de tu aplicación, utilizando la identidad y permisos de tu app. Al construir un Pending Intent se debe especificar un intent y la acción a realizar. Si el intent declarado no es Explícito (no declara qué intent puede llamarlo) una aplicación maliciosa podría realizar la acción declarada en nombre de la app víctima. Además, si no se especifica una acción, la aplicación maliciosa podrá realizar cualquier acción en nombre de la víctima.
Broadcast Intents
A diferencia de los intents anteriores, que solo son recibidos por una app, los broadcast intents pueden ser recibidos por múltiples aplicaciones. Sin embargo, desde la versión de API 14, es posible especificar la aplicación que debe recibir el mensaje usando Intent.set Package.
Alternativamente, también es posible especificar un permiso al enviar el broadcast. La aplicación receptora necesitará tener ese permiso.
Hay dos tipos de Broadcasts: Normal (asincrónico) y Ordenado (sincrónico). El orden se basa en la prioridad configurada dentro del elemento receptor. Cada app puede procesar, retransmitir o descartar el Broadcast.
Es posible enviar un broadcast utilizando la función sendBroadcast(intent, receiverPermission)
de la clase Context
.
También podrías usar la función sendBroadcast
del LocalBroadCastManager
asegura que el mensaje nunca salga de la app. Usando esto ni siquiera necesitarás exportar un componente receptor.
Sticky Broadcasts
Este tipo de Broadcasts puede ser accedido mucho tiempo después de haber sido enviado.
Fueron obsoletos en el nivel de API 21 y se recomienda no usarlos.
Permiten que cualquier aplicación husmee los datos, pero también los modifique.
Si encuentras funciones que contienen la palabra "sticky" como sendStickyBroadcast
o sendStickyBroadcastAsUser
, verifica el impacto e intenta eliminarlas.
Deep links / Esquemas de URL
Los deep links permiten activar un Intent a través de una URL. Una aplicación puede declarar un esquema de URL dentro de una actividad para que cada vez que el dispositivo Android intente acceder a una dirección usando ese esquema se llame a la actividad de la aplicación:
En este caso el esquema es myapp://
(nota también la categoría BROWSABLE
)
Si dentro del intent-filter
encuentras algo como esto:
Entonces, está esperando algo como http://www.example.com/gizmos
Si encuentras algo como esto:
Significará que está esperando una URL que comience con example://gizmos
En este caso podrías intentar abusar de la funcionalidad creando una web con los siguientes payloads. Intentará navegar a páginas arbitrarias y tratar de ejecutar JS:
<a href="example://gizmos/https://google.com">click here</a>
<a href="example://gizmos/javascript://%250dalert(1)">click here</a>
Para encontrar el código que se ejecutará en la App, ve a la actividad llamada por el deeplink y busca la función onNewIntent
.
Aprende cómo llamar a deep links sin usar páginas HTML.
AIDL - Lenguaje de Definición de Interfaz de Android
El Lenguaje de Definición de Interfaz de Android (AIDL) te permite definir la interfaz de programación que tanto el cliente como el servicio acuerdan para comunicarse entre sí utilizando la comunicación entre procesos (IPC). En Android, un proceso normalmente no puede acceder a la memoria de otro proceso. Por lo tanto, para comunicarse, necesitan descomponer sus objetos en primitivas que el sistema operativo pueda entender y trasladar los objetos a través de ese límite por ti. El código para hacer ese traslado es tedioso de escribir, por lo que Android lo maneja por ti con AIDL.
Los servicios que utilizan AIDL se conocen como Servicios Vinculados. En la clase del Servicio encontrarás el método onBind
. Aquí es donde comienza la interacción, por lo que es la parte inicial del código a revisar en busca de posibles vulnerabilidades.
Un servicio vinculado es el servidor en una interfaz cliente-servidor. Permite que componentes (como actividades) se vinculen al servicio, envíen solicitudes, reciban respuestas y realicen comunicación entre procesos (IPC). Un servicio vinculado normalmente solo existe mientras sirve a otro componente de la aplicación y no se ejecuta en segundo plano indefinidamente.
Messenger
Un Messenger es otro tipo de mecanismo IPC. Dado que el Messenger también es un "Servicio Vinculado", los datos pasados desde la aplicación cliente también se procesan a través del método onBind
. Por lo tanto, la revisión del código debe comenzar en este método y debes buscar la invocación de funcionalidades sensibles o el manejo inseguro de datos.
Binder
Es raro encontrar una clase Binder invocada directamente ya que es mucho más fácil usar AIDL (que abstrae la clase Binder). Sin embargo, es bueno saber que Binder es un controlador a nivel de kernel que mueve datos de la memoria de un proceso a la de otro (https://www.youtube.com/watch?v=O-UHvFjxwZ8).
Componentes
Estos incluyen: Actividades, Servicios, Receptores de Difusión y Proveedores.
Actividad de Inicio y otras actividades
Una actividad de Android es una pantalla de la interfaz de usuario de la app de Android. De esa manera, una actividad de Android es muy similar a las ventanas en una aplicación de escritorio. Una app de Android puede contener una o más actividades, es decir, una o más pantallas.
La actividad de inicio es lo que la mayoría de las personas consideran como el punto de entrada a una aplicación de Android. La actividad de inicio es la actividad que se inicia cuando un usuario hace clic en el ícono de una aplicación. Puedes determinar la actividad de inicio mirando el manifiesto de la aplicación. La actividad de inicio tendrá los siguientes intentos MAIN y LAUNCHER listados.
Ten en cuenta que no todas las aplicaciones tendrán una actividad de inicio, especialmente las aplicaciones sin una UI. Ejemplos de aplicaciones sin UI (y por lo tanto sin actividad de inicio) son aplicaciones preinstaladas que realizan servicios en segundo plano, como el buzón de voz.
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Las Activities pueden ser exportadas permitiendo que otros procesos en el dispositivo inicien la activity. Por defecto, no están exportadas, pero puedes exportarlas configurando:
<service android:name=".ExampleExportedService" android:exported="true"/>
Tenga en cuenta que la capacidad de bypass activity protections no siempre es una vulnerabilidad, necesita verificar a qué datos ha obtenido acceso.
Además, algunas actividades devuelven datos al llamador. En estos escenarios, necesita buscar el método setResult
y verificar los datos que se pasan al parámetro Intent. Si son datos sensibles, podría tener una vulnerabilidad de fuga de información y es explotable con aplicaciones capaces de comunicarse con la Actividad.
El código de una actividad comienza con el método onCreate
.
Subclase de Aplicación
Las aplicaciones Android pueden definir una subclase de Application. Las aplicaciones pueden, pero no tienen que definir una subclase personalizada de Application. Si una aplicación Android define una subclase de Application, esta clase se instancia antes que cualquier otra clase en la aplicación.
Si el método attachBaseContext
está definido en la subclase de Application, se llama primero, antes del método onCreate
.
Servicios
Los Services funcionan en segundo plano sin una interfaz de usuario (UI). Se utilizan para realizar procesos de larga duración, incluso si el usuario comienza a utilizar una aplicación diferente.
Hay una miríada de formas en que se pueden iniciar y, por lo tanto, son un punto de entrada para aplicaciones. La forma predeterminada en que un servicio puede iniciarse como punto de entrada a una aplicación es a través de Intents.
Cuando se llama al método startService
para iniciar un Servicio, se ejecuta el método onStart
en el Servicio. Funcionará indefinidamente hasta que se llame al método stopService
. Si el servicio solo es necesario mientras el cliente está conectado, el cliente debe "vincularse" a él utilizando el método bindService
.
Para un servicio vinculado (ver sección anterior), los datos se pasarán al método onBind
.
Por ejemplo, un servicio podría reproducir música en segundo plano mientras el usuario está en una aplicación diferente, o podría obtener datos a través de la red sin bloquear la interacción del usuario con una actividad.
Un servicio puede ser exportado lo que permite a otros procesos en el dispositivo iniciar el servicio. Por defecto los servicios no se exportan pero se puede configurar en el Manifiesto:
<service android:name=".ExampleExportedService" android:exported="true"/>
Broadcast Receivers
Los Broadcasts pueden considerarse un sistema de mensajería y los receptores de broadcast son los oyentes. Si una aplicación ha registrado un receptor para un broadcast específico, el código en ese receptor se ejecuta cuando el sistema envía el broadcast. Tenga en cuenta que en este caso varias aplicaciones pueden recibir el mismo mensaje.
Hay 2 formas en que una aplicación puede registrar un receptor: en el Manifiesto de la aplicación o registrado dinámicamente en el código de la aplicación utilizando la llamada a la API registerReceiver
. En el manifiesto, puedes limitar los broadcasts que aceptas mediante el uso de permisos dentro del elemento receptor. Cuando se define dinámicamente, puedes pasar el permiso al método registerReceiver
.
En ambos casos, para registrar el receptor, se establecen los filtros de intención para el receptor. Estos filtros de intención son los broadcasts que deben activar el receptor.
Cuando se envían los broadcasts específicos para los que se ha registrado el receptor, se ejecuta onReceive
en la clase BroadcastReceiver.
Una aplicación puede registrar un receptor para el mensaje de batería baja, por ejemplo, y cambiar su comportamiento en base a esa información.
Los Broadcasts pueden ser asincrónicos (todos los receptores lo reciben) o sincrónicos (el broadcast se recibe de manera ordenada en base a la prioridad establecida para recibirlo).
{% hint style="danger" %} Tenga en cuenta que cualquier aplicación puede establecerse como máxima prioridad para recibir un Broadcast. {% endhint %}
Para examinar el código implementado en un BroadcastReceiver, necesita buscar el método onReceive
de la clase del receptor.
Tenga en cuenta que los Broadcasts Ordenados pueden descartar el Intent recibido o incluso modificarlo utilizando uno de los métodos setter. Por lo tanto, los receptores deben validar los datos.
Content Provider
Los Content Providers son la forma en que las aplicaciones comparten datos estructurados, como bases de datos relacionales. Por lo tanto, es muy importante usar permisos y establecer el nivel de protección adecuado para protegerlos.
Los Content Providers pueden usar los atributos readPermission
y writePermission
para especificar qué permisos debe tener una aplicación. Estos permisos tienen prioridad sobre el atributo de permiso.
Además, también pueden permitir excepciones temporales configurando grantUriPermission
en verdadero y luego configurando los parámetros apropiados en el elemento grant-uri-permission
dentro del elemento del proveedor en el archivo del manifiesto.
El grant-uri-permission
tiene tres atributos: path, pathPrefix y pathPattern:
- path: Permite especificar la ruta completa a excluir
- pathPrefix: Permite especificar el comienzo de la ruta
- pathPattern: Permite el uso de comodines y reemplazos simbólicos para obtener un control más granular.
Es importante validar y sanear la entrada recibida para evitar vulnerabilidades potenciales como la inyección SQL.
Características del Content Provider:
- El componente Content Provider suministra datos de una aplicación a otras bajo solicitud.
- Puedes almacenar los datos en el sistema de archivos, una base de datos SQLite, en la web o cualquier otro lugar de almacenamiento persistente al que tu aplicación pueda acceder.
- A través del content provider, otras aplicaciones pueden consultar o incluso modificar los datos (si el content provider lo permite).
- Content Provider es útil en casos en que una aplicación quiere compartir datos con otra aplicación.
- Es muy similar a las bases de datos y tiene cuatro métodos.
- insert()
- update()
- delete()
- query()
FileProvider
Este es un tipo de Content Provider que compartirá archivos desde una carpeta. Puedes declarar un file provider así:
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true" android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
Tenga en cuenta el atributo android:exported
porque si es true
, las aplicaciones externas podrán acceder a las carpetas compartidas.
Observe que la configuración android:resource="@xml/filepaths"
está indicando que el archivo res/xml/filepaths.xml contiene la configuración de qué carpetas este FileProvider va a compartir. Este es un ejemplo de cómo indicar compartir una carpeta en ese archivo:
<paths>
<files-path path="images/" name="myimages" />
</paths>
Compartir algo como path="."
podría ser peligroso incluso si el proveedor no está exportado si hay otra vulnerabilidad en alguna parte del código que intentó acceder a este proveedor.
Podrías acceder a una imagen dentro de esa carpeta con content://com.example.myapp.fileprovider/myimages/default_image.jpg
El elemento <paths>
puede tener múltiples hijos, cada uno especificando un directorio diferente para compartir. Además del elemento <files-path>
, puedes usar el elemento <external-path>
para compartir directorios en almacenamiento externo, y el elemento <cache-path>
para compartir directorios en tu directorio de caché interno.
Para más información sobre atributos específicos de proveedores de archivos, haz clic aquí.
Más información sobre FileProviders aquí.
WebViews
Los WebViews son efectivamente navegadores web incrustados en aplicaciones Android.
El contenido de los WebViews puede provenir de sitios remotos o ser archivos incluidos en la aplicación.
Los WebViews son vulnerables a las mismas vulnerabilidades que afectan a cualquier navegador web. Sin embargo, hay algunas configuraciones que pueden ser útiles para limitar la superficie de ataque.
Hay dos tipos de WebViews en Android:
- El WebViewClient, más adecuado para la renderización simple de HTML. Este no ejecutará la función de alerta JS. Por lo tanto, las pruebas de XSS utilizando esa función serán inválidas.
- El WebChrome client, es un navegador Chrome.
Ten en cuenta que los navegadores WebView no tienen acceso a las cookies del navegador nativo.
Para cargar una URL o archivo es posible usar las funciones loadUrl
, loadData
o loadDataWithBaseURL
. Es importante acceder solo a URLs saneadas.
La seguridad de WebView se puede configurar a través del objeto WebSettings
.
Por ejemplo, la ejecución de código JS se puede deshabilitar usando el método setJavaScriptEnabled
con el valor false
. Esto eliminará la posibilidad de un XSS y otras vulnerabilidades relacionadas con JS.
La funcionalidad "Bridge" de JavaScript inyecta objetos Java en un WebView haciéndolos accesibles a JS. Desde Android 4.2 los métodos deben estar anotados con @JavascriptInterface
para ser accesibles a JavaScript.
Si se pasa true
a setAllowContentAccess
, los WebViews podrán acceder a los Proveedores de Contenido a través del esquema content://
. Esto obviamente representa un riesgo de seguridad. Ten en cuenta que si se otorga este acceso, es muy importante asegurarse de que la URL content://
sea segura.
Por defecto, los archivos locales pueden ser accedidos por WebViews a través de URLs file://, pero hay varias formas de prevenir este comportamiento:
- Pasar
false
asetAllowFileAccess
, previene el acceso al sistema de archivos con la excepción de los activos a través defile:///android_asset
yfile:///android_res
. Estas rutas deben usarse solo para datos no sensibles (como imágenes), por lo que esto debería ser seguro. - El método
setAllowFileAccess
indica si una ruta de una URLfile://
debería poder acceder al contenido de otras URLs del esquema de archivo. - El método
setAllowUniversalAccessFromFileURLs
indica si una ruta de una URLfile://
debería poder acceder al contenido de cualquier origen.
Otros componentes de la aplicación
Firma de Aplicaciones
- Android requiere que todas las aplicaciones estén firmadas digitalmente con un certificado antes de que puedan ser instaladas. Android utiliza este certificado para identificar al autor de una aplicación.
- Para ejecutar la aplicación en el dispositivo, debe estar firmada. Cuando se instala la aplicación en un dispositivo, el gestor de paquetes verifica si la aplicación ha sido correctamente firmada con el certificado en el archivo apk o no.
- La aplicación puede estar autofirmada o puede ser firmada a través de una CA.
- La firma de aplicaciones asegura que una aplicación no pueda acceder a otra aplicación excepto a través de IPC bien definido y también que se pase sin modificaciones al dispositivo.
Verificación de Aplicaciones
- Android 4.2 y versiones posteriores admiten la verificación de aplicaciones. Los usuarios pueden optar por habilitar "Verificar aplicaciones" y tener las aplicaciones evaluadas por un verificador de aplicaciones antes de la instalación.
- La verificación de aplicaciones puede alertar al usuario si intentan instalar una aplicación que podría ser dañina; si una aplicación es especialmente mala, puede bloquear la instalación.
Gestión de Dispositivos Móviles
MDM o Gestión de Dispositivos Móviles son suites de software que se utilizan para asegurar el control y los requisitos de seguridad sobre dispositivos móviles. Estas suites utilizan las características denominadas API de Administración de Dispositivos y requieren que se instale una aplicación Android.
Generalmente, las soluciones MDM realizan funciones como imponer políticas de contraseñas, forzar el cifrado de almacenamiento y habilitar el borrado remoto de datos del dispositivo.
Encuentra vulnerabilidades que importan más para que puedas solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos proactivos de amenazas, encuentra problemas en toda tu pila tecnológica, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si quieres ver a tu empresa anunciada en HackTricks o descargar HackTricks en PDF Consulta los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub HackTricks y HackTricks Cloud.