¿Qué es el almacén de claves de Android?

Android proporciona una serie de mecanismos para proteger los datos de los usuarios.

Los datos casi siempre se cifran en reposo mediante esquemas como el cifrado de disco completo o basado en archivos. Funciones como las pantallas de bloqueo de usuarios y la zona de pruebas de aplicaciones también sirven para proteger los datos de los usuarios contenidos en las aplicaciones contra el acceso o la extracción no autorizados. Sin embargo, todas estas protecciones pueden anularse en determinadas circunstancias y los desarrolladores de aplicaciones pueden optar por agregar una capa de seguridad en la capa de la aplicación.

Desafíos del cifrado de Android

Un ejemplo de esto es cuando los desarrolladores optan por implementar el cifrado de los datos de sus aplicaciones. Este cifrado puede proteger una variedad de tipos de datos almacenados en el dispositivo, como mensajes, medios u otros datos confidenciales, como credenciales. El desafío para los desarrolladores es cómo implementar esta capa adicional de cifrado.

La implementación de un esquema de cifrado que almacena claves de cifrado en el sistema de archivos de Android, utiliza valores codificados para derivar claves o incluso derivar claves a partir de la entrada del usuario sigue siendo algo inseguro:

  • Si las claves o los valores utilizados para derivarlas se pueden extraer del sistema de archivos de Android, entonces es trivial realizar ingeniería inversa en la aplicación y usar estos valores para descifrar los datos.
  • Incluso si las claves se derivan de una entrada del usuario, como una contraseña o un código PIN, los esquemas siguen siendo vulnerables a métodos de recuperación de contraseñas como diccionario o ataques de fuerza bruta.

Para resolver este problema, Android pone a disposición una API que permite a los desarrolladores de aplicaciones almacenar claves de cifrado en un área segura que no forma parte del sistema de archivos de Android y no es accesible para Android incluso si el sistema operativo Android está comprometido. Esto ofrece un grado de protección similar al que el cifrado a nivel de dispositivo Android utilizado para proteger la partición de datos del usuario puede estar “respaldado por hardware” si el dispositivo lo admite; que hacen la mayoría de los dispositivos modernos. El subsistema de Android utilizado para esto se llama Keystore y lo utilizan varias aplicaciones populares como Briar, Wickr, Signal y la aplicación Element, por nombrar algunas.

Finding Keystore keys

Las claves del almacén de claves se almacenan en la partición de datos del usuario en la siguiente ubicación: /misc/keystore/ pero normalmente se almacenan en un formato cifrado.

  • Hasta Android 11, cada usuario de Android en el dispositivo tiene un subdirectorio separado y las entradas del almacén de claves se almacenan en un archivo dedicado por entrada, junto con un archivo asociado que contiene solo las “características” (metadatos asociados) de la entrada del almacén de claves.
  • En Android 12 y versiones posteriores, las entradas del almacén de claves y los metadatos asociados para todos los usuarios se almacenan en una base de datos SQLite ubicada en: /misc/keystore/persistent.sql

Clave de cifrado de clave (KEK)

Aunque las aplicaciones pueden solicitar el uso de sus claves asociadas a través del subsistema Keystore y recibir los resultados, Android impide su acceso directo. Para evitar que un atacante que ha comprometido el sistema operativo Android extraiga estas claves, las propias claves suelen cifrarse con una clave de cifrado de clave (KEK) adicional.

Este KEK generalmente está respaldado por hardware; es decir, se deriva de algunos valores fijos mantenidos en hardware seguro. Android no debería tener acceso a estos valores seguros retenidos por el hardware y, una vez que se inicia un dispositivo, solo debería ser accesible para un sistema operativo confiable (TOS) que se ejecute en paralelo a Android. Es el TOS el que utiliza los valores guardados en hardware seguro para derivar en cada arranque la KEK utilizada para descifrar las entradas del almacén de claves.

Es importante tener en cuenta que los TOS son un sistema operativo autónomo y Android no tiene acceso a las claves descifradas del almacén de claves, que solo las descifran los TOS dentro de un “mundo seguro”. Aunque existe efectivamente un “cortafuegos” entre el mundo seguro y el mundo normal (en el que se ejecuta Android), existen mecanismos de comunicación que permiten a Android solicitar operaciones criptográficas utilizando claves de almacén de claves realizadas por los TOS y luego recibir los resultados de esas operaciones.

Uso común por parte de los desarrolladores del almacén de claves de Android

Una forma común en que los desarrolladores de aplicaciones utilizan el almacén de claves de Android no es necesariamente para cifrar/descifrar directamente los datos de su aplicación, sino para proteger otras claves generadas dentro de la propia aplicación y almacenadas en el sistema de archivos de Android, generalmente en el directorio de datos dedicado de las aplicaciones. A continuación se muestra un diagrama simplificado de este tipo de implementación:

Extracción de almacén de claves

Puede extraer claves del almacén de claves en forma descifrada utilizando una de dos metodologías. El primero es a través de los métodos físicos Android Debug Bridge (ADB), Full File System Extraction (FFS) o ADB y es específico para aplicaciones particulares para las cuales admitimos la extracción de Keystore. En realidad, este método no extrae las claves descifradas del almacén de claves, sino que solicita a través del sistema operativo Android que los TOS utilicen esas claves para descifrar las claves específicas de la aplicación utilizadas para cosas como el cifrado de bases de datos. Una vez descifradas, estas son las claves que extraemos usando este método para descifrar los datos de la aplicación.

Segundo método de extracción de almacén de claves

El segundo método consiste en realizar el descifrado sin conexión de las claves del almacén de claves y es posible mediante los métodos MTK, Unisoc, Qualcomm, Huawei Qualcomm y Huawei Kirin.

Este enfoque es posible porque a través de estos métodos podemos extraer los valores almacenados en hardware seguro y usarlos para descifrar esas claves “sin procesar” del almacén de claves.

Una ventaja de usar este método es que todas las claves del almacén de claves deben descifrarse y podemos usarlas para descifrar datos de aplicaciones que aún no son compatibles específicamente con nuestro software, o aquellas que pueden ser compatibles en el futuro sin necesidad de realizar otra operación. extracción.

Ventaja: descifra y analiza aplicaciones automáticamente

Para aquellas aplicaciones que son explícitamente compatibles, como Wickr, Signal y Briar (por nombrar algunas), Se encargará del descifrado y el análisis automáticamente.

Una ventaja adicional es que algunas aplicaciones pueden proteger aún más el uso de las claves del almacén de claves agregando un paso de autenticación biométrico o basado en PIN/contraseña antes de que la aplicación pueda hacer uso de las claves (su eliminación puede invalidar las claves permanentemente).

Este proceso no está directamente relacionado con el cifrado y el descifrado fuera de línea pasa por alto este mecanismo de seguridad, lo que puede presentar un problema si se extraen las claves del almacén de claves a nivel del sistema operativo mediante un método “en vivo”.

Algunas aplicaciones, como Briar, pueden optar por implementar su propia pantalla de ingreso de contraseña, lo que les permite vincular el descifrado de los datos de la aplicación a una contraseña de usuario, así como a la clave del almacén de claves, pero estas aplicaciones parecen ser una minoría. La recuperación de contraseña para Briar mediante métodos como fuerza bruta o ataques de diccionario es posible.

Cómo realizar una extracción de almacén de claves

La versión de Android de la aplicación Element es una que no admitimos (todavía, pero observe este espacio) para el análisis, aunque actualmente sí admitimos las versiones de escritorio. Con acceso a las claves del almacén de claves, es posible descifrarlas manualmente.

Element es una aplicación de mensajería de código abierto centrada en la seguridad. Almacena datos en el dispositivo, como mensajes, en una base de datos cifrada de Realm. Utiliza un modelo bastante estándar para almacenar y proteger la clave de cifrado de la base de datos con una clave Keystore, y es el mismo modelo que se muestra en el diagrama anterior de esta publicación.

  • La clave de cifrado de la base de datos se almacena en un archivo XML llamado “im.vector.matrix.android.keys.xml” ubicado en el directorio de preferencias compartidas de la aplicación (/data/data/im.vector.app/shared_prefs) y está cifrado con una clave de almacén de claves.
  • La base de datos también se almacena en el directorio de datos de las aplicaciones y se llama “disk_store.realm“. Esta aplicación es de código abierto, por lo que podemos leer más fácilmente las partes relevantes del código fuente para comprender cómo se implementó el esquema de cifrado; Los detalles son los siguientes:
  • vector.matrix.android.keys.xml contiene más de una clave, pero la relevante comenzará con “REALM_ENCRYPTED_KEY_session_db“. Está codificado en Base64 y cuando se decodifica y se convierte a hexadecimal, sigue el siguiente formato:
  • Byte 0: versión de formato utilizada para determinar el tipo de cifrado
  • Byte 1 – Longitud IV (vector de inicialización)
  • Bytes [2 – longitud IV] – IV
  • Bytes desde el final del IV hasta el inicio de la etiqueta GCM: clave de base de datos cifrada, codificada en Base64
  • 16 bytes finales: etiqueta GCM

El visor de archivos de Oxygen Forensic® Detective incluye una serie de visores útiles para poder ver formatos de datos como XML en una vista deserializada. La herramienta de conversión de datos incorporada también es extremadamente conveniente para la conversión automática de datos seleccionados desde formatos como la codificación Base64.

En este ejemplo, la versión del formato (resaltada en amarillo) es 0; esto rige el tipo de clave del almacén de claves generada y el cifrado utilizado cuando se instala la aplicación por primera vez.

Se decide según la versión de Android.

  • La longitud del IV (resaltada en violeta) es 0x0C, que es 0d12, por lo que el IV son los siguientes 12 bytes.
  • Los últimos 16 bytes son la etiqueta GCM (resaltada en gris) y todo lo que se encuentra entre el IV y la etiqueta GCM es la clave de cifrado de la base de datos cifrada y codificada en Base64 (resaltada en verde).

Seleccionando de la llave correcta

A continuación, necesitamos la clave del almacén de claves correspondiente para descifrar la clave de cifrado de la base de datos. Las claves del almacén de claves, que se han descifrado sin conexión, están disponibles para ver en la sección “Almacén de claves” de la categoría de datos “Cuentas y contraseñas”. Podemos seleccionar la clave correcta mirando la columna “Etiqueta” que se relaciona con el “alias” utilizado por la aplicación para acceder a las entradas del almacén de claves. El alias lo elige el desarrollador de la aplicación y puede tener cualquier valor. Para Element, la clave correcta tiene un alias que comienza con “session_db“.

Cómo resolver conflictos de nombres de alias

En caso de que haya un conflicto de nombres de alias entre aplicaciones, o varias instancias de la misma aplicación en un dispositivo, podemos asegurarnos de elegir la correcta prestando también atención a los campos “Cuenta” y “Servicio” en los detalles. cristal. Estos se relacionan con el ID de usuario de Android y el ID de usuario de la aplicación, respectivamente. Podemos encontrar el ID de usuario de la aplicación (10283 en este ejemplo) buscando dentro del archivo “packages.xml” ubicado en: /data/system el nombre del paquete im.vector.app y verificando que coincida con nuestra entrada de clave descifrada del almacén de claves.

Descifrando la clave de cifrado de la base de datos

Ahora que tenemos la clave del almacén de claves relevante y conocemos la estructura de la entrada de la clave de la base de datos almacenada en “im.vector.matrix.android.keys.xml”, podemos usar una herramienta como Python o la siempre útil, gratuita y abierta. -Herramienta Cyberchef de origen (consulte: https://github.com/gchq/CyberChef para obtener más información) para intentar descifrar la clave de cifrado de la base de datos.

Para esta tarea utilicé Cyberchef. La primera etapa de la receta que utilicé es una operación de descifrado AES, completada con la clave del almacén de claves correspondiente, así como las etiquetas IV y GCM tomadas del archivo XML. Luego, la operación se ejecuta en el segmento de clave de cifrado de la base de datos cifrada (también tomado del archivo XML). Recuerde que esta clave también se almacena en formato Base64, por lo que después del descifrado ejecutamos una operación de decodificación de Base64. Finalmente, como las claves de cifrado de la base de datos de Realm están en formato hexadecimal, utilizamos una operación final para convertir la salida a hexadecimal.

La operación fue exitosa y ahora tenemos una cadena hexadecimal de 128 caracteres como resultado, lo cual es prometedor. Podemos usar esto para intentar descifrar la base de datos de Element dentro de la herramienta.

Después de aplicar la clave, podemos ver que la base de datos se ha descifrado y abierto correctamente en el visor de bases de datos nativo. Ahora podemos comenzar a investigarlo manualmente en busca de datos útiles.

Resumen de descifrado del almacén de claves

El descifrado del almacén de claves sin conexión es una capacidad extremadamente poderosa. En un mundo ideal, una herramienta forense digital permitiría el análisis de cada aplicación, pero en realidad este nunca será el caso y, en ocasiones, se requiere un análisis manual.

Aunque siempre damos la bienvenida a las solicitudes de soporte para nuevas aplicaciones y nos esforzamos por agregarlas, es posible que una investigación requiera demasiado tiempo para esperar. En estos casos, tener acceso a todas las claves del almacén de claves en forma descifrada garantiza que los examinadores siempre tendrán lo que necesitan para descifrar la mayor cantidad de datos posible, incluso si ya no tienen acceso al dispositivo físico.