AndroidManifest.xml

Extraer AndroidManifest.xml

Apktool

apktool d application.apk -o app-decompiled --match-original --no-assets --no-src
more app-decompiled/AndroidManifest.xml

android4me

cp application.apk application.zip
unzip application.zip -d app-unpacked
cd app-unpacked
java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest.xml.txt
more AndroidManifest.xml.txt

Análisis de AndroidManifest.xml

Nombre del paquete

En el atributo package del elemento raíz del archivo de manifiesto se determina el nombre del paquete de la aplicación.

<manifest package="com.example.app">
    ...
</manifest>
grep "package=" app-decompiled/AndroidManifest.xml 

Versiones de Android compatibles

El valor del atributo android:minSdkVersion determina el nivel de API mínimo que se requiere para que se ejecute la aplicación. Android impide que el usuario instale la aplicación si el nivel de API es inferior al valor especificado en este atributo. Se recomienda declarar siempre este atributo, si no declara se adopta el valor predeterminado igual a "1", el cual indica que la aplicación es compatible con todas las versiones de Android.

En el caso que el valor del atributo android:minSdkVersion sea igual o inferior a 15, correspondiente a la versión de Android 4 (Ice Cream Sandwich), una aplicación maliciosa podría potencialmente acceder a los registros (logs) de cualquier otra aplicación, sin requerir privilegios de root. Esta circunstancia podría poner en riesgo información confidencial almacenada en dichos registros, lo que podría dar lugar a accesos no autorizados a datos sensibles.

grep -Eo "android:minSdkVersion=\"[0-9]+\"" app-decompiled/AndroidManifest.xml

Depuración

Determina si es posible o no depurar la aplicación, incluso cuando se ejecuta en un dispositivo en modo de usuario. El valor predeterminado es false.

  • true = depuración activada.

  • false = depuración desactivada.

<application android:debuggable="false">
    ...
</application>
grep "android:debuggable" app-decompiled/AndroidManifest.xml 

Copia de seguridad

Determina si es posible respaldar y restaurar los datos de la aplicación. Si se establece en true, se permite realizar una copia de seguridad de los datos de la aplicación a través de Android Debug Bridge (adb), incluso si el dispositivo no está rooteado. Por lo tanto, las aplicaciones que manejan y almacenan información confidencial deben establecer esta configuración explícitamente en false, debido a que el valor predeterminado es true.

  • true = copia de seguridad permitida.

  • false = copia de seguridad no permitida

<application android:allowBackup="false">
    ...
</application>
grep "android:allowBackup" app-decompiled/AndroidManifest.xml

Realizar copia de seguridad desde Android Debug Bridge (adb).

adb backup <app-package-name>

Descomprimir copia de seguridad.

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) | tar xfvz -

Permisos

Las aplicaciones deben solicitar permiso para acceder a datos sensibles del usuario (como contactos y SMS) o a determinadas funciones del sistema (como la cámara y el acceso a Internet). A partir de Android 6.0 (nivel de API 23), el usuario puede aprobar o rechazar algunos permisos de las aplicaciones durante el tiempo de ejecución. No obstante, sin importar qué versión de Android admita la aplicación, se deben declarar todas las solicitudes de permisos con el elemento <uses-permission>. Si se otorga el permiso, la aplicación podrá usar las funciones protegidas. De lo contrario, los intentos de acceder a esas funciones fallarán.

  • Antes de Android 6.0 (nivel de API 23): todos los permisos son otorgados durante la instalación.

  • Después de Android 6.0 (nivel de API 23): algunos permisos se otorgan en tiempo de ejecución, después de que el usuario lo solicite.

Las aplicaciones también puede definir sus propios permisos con el elemento <permission>.

grep "<uses-permission" app-decompiled/AndroidManifest.xml
grep "<android:uses-permission" app-decompiled/AndroidManifest.xml
grep "<permission" app-decompiled/AndroidManifest.xml
grep -E "<uses-permission|<android:uses-permission|<permission" app-decompiled/AndroidManifest.xml

Activities

Exported

Establece si otras aplicaciones pueden iniciar la activity.

  • true = cualquier aplicación puede iniciar la activity.

  • false = la activity solo se puede iniciar con componentes de la misma aplicación, aplicaciones con el mismo ID de usuario o componentes del sistema con privilegios. Este es el valor predeterminado cuando no hay filtros de intents.

<activity android:exported="false" />
# Búsqueda de activities
grep "<activity" app-decompiled/AndroidManifest.xml

# Búsqueda de activities con exportación habilitada
## explícitamente
grep "<activity" app-decompiled/AndroidManifest.xml | grep "android:exported=\"true\""
## implícitamente
grep "<intent-filter" -B 1 app-decompiled/AndroidManifest.xml | grep "<activity" | grep --invert-match "android:exported=\"true\""

Broadcast receivers

Los broadcast receivers permiten que las aplicaciones reciban intents que el sistema u otras aplicaciones difunden, incluso cuando otros componentes de la aplicación no se están ejecutando.

# Búsqueda de broadcast receivers
grep "<receiver" app-decompiled/AndroidManifest.xml

# Búsqueda de broadcast receivers con exportación habilitada
## explícitamente
grep "<receiver" app-decompiled/AndroidManifest.xml | grep "android:exported=\"true\""
## implícitamente
grep "<intent-filter" -B 1 app-decompiled/AndroidManifest.xml | grep "<receiver" | grep --invert-match "android:exported=\"true\""

# Ejecutar broadcast receiver desde Android Debug Bridge (adb)
adb shell am broadcast -a <action> --es <parameter> "<string-value>" --ei <parameter> <numerical-value>
adb shell am broadcast -a <action> -n <app-package-name>/.<broadcast-receiver> --es <parameter> "<string-value>" --ei <parameter> <numerical-value>

# Ejecutar broadcast receiver desde Drozer
run app.broadcast.send --action <action> --component <app-package-name> <broadcast-receiver> --extra string <parameter> <numerical-value> --extra string <parameter> "<string-value>"

Content providers

Los content providers ayudan a una aplicación a administrar el acceso a los datos almacenados por ella misma, almacenados por otras aplicaciones y proporcionar una forma de compartir datos con otras aplicaciones.

# Búsqueda de content providers
grep "<provider" app-decompiled/AndroidManifest.xml

# Búsqueda de content providers con exportación habilitada
## explícitamente
grep "<provider" app-decompiled/AndroidManifest.xml | grep "android:exported=\"true\""
## implícitamente
grep "<intent-filter" -B 1 app-decompiled/AndroidManifest.xml | grep "<provider" | grep --invert-match "android:exported=\"true\""

Exported

Establece si el content provider está disponible para que lo usen otras aplicaciones:

  • true = está disponible para otras aplicaciones. Cualquier aplicación puede acceder a él, sujeto a los permisos especificados.

  • false = no está disponible para otras aplicaciones. Solo las aplicaciones que tienen el mismo ID de usuario (UID) que el provider, o las aplicaciones a las que se les ha otorgado acceso temporal al provider a través de android:grantUriPermissions, tienen acceso a él.

<provider android:exported="false" />

Este atributo se introdujo en el nivel de API 17, todos los dispositivos que ejecutan la API nivel 16 o versiones anteriores se comportan como si este atributo estuviera configurado en true. Si configuras android:targetSdkVersion en 17 o una versión posterior, el valor predeterminado es false para los dispositivos que ejecutan el nivel de API 17 o superior.

Los content providers se pueden consultar con éxito desde un contexto privilegiado (un shell ADB se considera un contexto privilegiado) en dispositivos que ejecutan los niveles de API 8 a 23, incluso si el atributo android:exported está configurado como false. A partir del nivel de API 24 en adelante, los content providers no se pueden consultar desde ADB.

Services

A diferencia de las activities, los services no cuentan con una interfaz de usuario visual. Permiten implementar operaciones de ejecución prolongada en segundo plano o una API de comunicaciones enriquecida a la que pueden llamar las otras aplicaciones.

# Búsqueda de services
grep "<service" app-decompiled/AndroidManifest.xml

# Búsqueda de services con exportación habilitada
## explícitamente
grep "<service" app-decompiled/AndroidManifest.xml | grep "android:exported=\"true\""
## implícitamente
grep "<intent-filter" -B 1 app-decompiled/AndroidManifest.xml | grep "<service" | grep --invert-match "android:exported=\"true\""

Exported

Indica si los componentes de otras aplicaciones pueden invocar o no el servicio, o interactuar con él: true si pueden y false no pueden. Cuando el valor es false, solo los componentes de la misma aplicación o las aplicaciones con el mismo ID de usuario pueden iniciar el servicio o vincularse con él.

El valor predeterminado variará de acuerdo con los intent filters que tenga el servicio. La ausencia de intent filters significa que solo se puede invocar el servicio si se especifica el nombre exacto de la clase. Esto quiere decir que el servicio solo está destinado al uso interno de la aplicación (dado que otras entidades no conocerían el nombre de la clase). Por lo tanto, en este caso, el valor predeterminado es false. Por otro lado, la presencia de al menos un intent filter implica que el servicio está destinado para uso externo, por lo que la configuración es true.

Este atributo no es la única forma de limitar la exposición de un servicio ante otras aplicaciones. También es posible usar un permiso para limitar las entidades externas que pueden invocar al servicio (atributo permission).

<service android:exported="false" />

Funcionalidades exportadas

  • Explícitamente: la etiqueta contiene explícitamente el atributo android:exported="true".

  • Implícitamente: la funcionalidad tiene una etiqueta de <intent-filter> en su interior, que exporta implícitamente la funcionalidad.

# Funcionalidades exportadas explícitamente
grep "android:exported=\"true\"" app-decompiled/AndroidManifest.xml | sort

# Funcionalidades exportadas implícitamente
grep "<intent-filter" -B 1 app-decompiled/AndroidManifest.xml | grep --invert-match "android:exported=\"true\"" | grep -E "<activity|<receiver|<provider|<service" | sort

Última actualización