El equipo Project Zero de Google ha verificado una serie de vulnerabilidades que permiten atacar los teléfonos Samsung que utilizan la suite de seguridad supuestamente segura Samsung Knox. El blog señala que todas las vulnerabilidades han sido transmitidas a Samsung, que ha publicado correcciones para ellas en una actualización de software de enero.


Fondo

Como parte del paquete de software de seguridad Samsung Knox presentado por Samsung, hay un software que se encuentra entre las aplicaciones de Android y el núcleo llamadohipervisor. Este se puede utilizar como una capa adicional para proteger aún más los dispositivos Android. El hipervisor Samsung Knox se llama "Protección del núcleo en tiempo real" o RKP para abreviar, como haré referencia a él en el resto de este artículo.

El kernel se encuentra debajo de RKP en la pila de software de Android, y las aplicaciones que se ejecutan en el dispositivo se encuentran en la parte superior. La idea detrás de RKP es proporcionar una capa adicional de seguridad para el dispositivo, ya que todas las solicitudes (de memoria y otros recursos) que realizan las aplicaciones al kernel deben pasar primero por Knox, que intenta detectar si una aplicación está haciendo algo que no debería. RKP también proporciona seguridad a través de la oscuridad con una capa adicional para ocultar información confidencial que una aplicación podría usar para comprometer el dispositivo.

La entrada del blog profundiza bastante en cómo funcionan la memoria de Android, el RKP y los sistemas operativos en general, por lo que la he condensado y simplificado para ofrecer una descripción general rápida de lo que se descubrió. Sin embargo, te recomiendo que leas el artículo completo si tienes tiempo, ya que es muy esclarecedor.


Exploit #1:

KASLRo Kernel Address Space Layout Randomization es el proceso de cambiar la ubicación del código del núcleo en la memoria en una cantidad aleatoria durante el arranque. Cada vez que se arranca el dispositivo, el núcleo se carga en un espacio de direcciones diferente (área de la memoria). La idea es dificultar la búsqueda de la ubicación del código del núcleo para atacarlo, ya que después de cada arranque el código del núcleo "se desplaza" en una cantidad aleatoria en la memoria. Esto parece un gran paso para prevenir posibles atacantes, peroinvestigacionesrecientes han demostrado que en realidad se puede evitar sin necesidad de un error de software o vulnerabilidad, ya que KASLR es realmente muy difícil de implementar de forma robusta contra atacantes locales.

En el caso del software RKP, la capacidad de eludir KASLR es en realidad más sencilla que la investigación a la que se hace referencia anteriormente. La memoria de todos los dispositivos Android está referenciada por punteros y, para proteger los dispositivos de ataques, siempre que los dispositivos Android imprimen o generan datos (ya sea en la pantalla o en un archivo para registros o depuración), las referencias de los punteros se anonimizan, lo que hace imposible averiguar a dónde apunta realmente el puntero al leer el resultado.

Piense en los punteros de memoria como una señal de calle que señala una ubicación y piense en la anonimización como desdibujarla. Al igual que la televisión, la anonimización se realiza después de la filmación, Android también aplica esta anonimización en el momento de la salida y solo si la anonimización está configurada correctamente, y el autor afirmaque todos los dispositivos [que] encontró han tenido la anonimización del puntero configurada correctamente. Esto puede parecer muy difícil de descifrar, pero todo lo que necesita hacer es encontrar un solo puntero (piense en una señal de calle) que no haya sido anonimizado (difuminado) por el desarrollador del kernel (tenga cuidado, este no es el desarrollador promedio de aplicaciones de Android) cuando el puntero se escribe en los registros u otra ubicación, por ejemplo, la pantalla o un archivo.

Entonces, si puedes encontrar un puntero que no esté anonimizado, puedes calcular el cambio de dirección aleatorio del núcleo como la diferencia entre los dos. Curiosamente, el autor no pudo encontrar un puntero explotable en el núcleo, pero sí lo encontró dentro del RPK, donde los desarrolladores olvidaron anonimizar un puntero en la salida de depuración (registro), lo que se produjo por un error tipográfico. Para anonimizar los punteros en Android, debes usar un código especial y resulta que los desarrolladores de RPK usaron por error una"k" minúsculaen lugar de una"K" mayúscula. Por lo tanto, fue relativamente simple averiguar la cantidad de cambio aleatorio del código del núcleo y atacarlo.


Exploit #2:

El siguiente exploit es un poco más complejo: Samsung Knox protege tu dispositivo aplicando un conjunto de reglas a la memoria del dispositivo para detener el código malicioso. Las reglas son las siguientes:

  1. Todas las páginas (código en memoria), con excepción del código del núcleo, están marcadas como "Ejecución privilegiada nunca" (lo que significa que el código aquí nunca puede ejecutarse)
  2. Las páginas de datos del núcleo (datos utilizados por el programa en la memoria) nunca se marcan como ejecutables (por lo que el código aquí nunca puede ejecutarse)
  3. Las páginas de códigos del núcleo (código en la memoria) nunca se marcan como escribibles (por lo que ningún código malicioso puede cambiarlas)
  4. Todas las páginas del kernel están marcadas como de solo lectura en la tabla de traducción de la etapa 2 (la tabla que se encuentra entre la aplicación y el kernel para evitar aún más que las aplicaciones conozcan las ubicaciones de memoria reales).
  5. Todas las entradas de traducción de memoria están marcadas como de solo lectura para las aplicaciones.

Nos centraremos en la regla 3, ya que aquí es donde el autor encontró un problema con la implementación de las reglas anteriores. De hecho, RPK marca la memoria para el núcleo como de solo lectura, sin embargo, como un descuido del KASL, se descubrió un agujero, lo que llevó aescribir código en la sección supuestamente "de solo lectura". Para ofuscar la ubicación del núcleo en el momento del arranque, se asigna memoria al núcleo, pero esta cantidad de memoria es mucho mayor que el segmento de texto del núcleo. Al asignar una mayor cantidad de memoria, es mucho más difícil encontrar el código real del núcleo, que podría estar en cualquier lugar y, como vimos anteriormente, se mueve aleatoriamente en cada arranque del dispositivo.

Imagen de archivo kaslr_rwx ​​(1).png

El autor pudo confirmar que la memoria utilizada por el núcleo estaba marcada como "de solo lectura", sin embargo, el resto de esa gran cantidad de memoria utilizada para ocultar el núcleonoestaba marcada como "de solo lectura". Esto se debe a que RKP solo protege la región que contiene el texto del núcleo después de aplicar la diapositiva KASLR.


Exploit #3

En el tercer exploit, el autor pudo acceder a otra área de la memoria que también debería estar restringida a solo lectura. El RKP protege la memoria y utiliza unRegistro de configuración de hipervisor(HCR) para controlar las operaciones clave del núcleo. El objetivo del HCR es permitir que las operaciones del núcleo válidas y reales accedan a los registros y bloqueen los ataques maliciosos. Para ello, comprueba las llamadas realizadas a los registros que controlan las funciones de virtualización. El HCR está configurado para bloquear operaciones específicas que se gestionarían normalmente, lo que permite a RKP elegir si permite o no una solicitud.

En este exploit, el control HCRno cubría dos registrosque resultaron ser muy importantes. El autor investigó en profundidad el manual de referencia de ARM y descubrió que el primer registro le permitía básicamente desactivar RKP para las aplicaciones. El "Registro de control del sistema para EL1 (SCTLR_EL1) proporciona un control de nivel superior sobre el sistema, incluido el sistema de memoria". En un mundo perfecto, la aplicación utilizaría la memoria que se asignaba a través del RKP para que el RKP pudiera controlar a qué podía acceder la aplicación. Sin embargo, desactivar este registro permitíadesactivar el RKPal devolver efectivamente el dispositivo a cómo se ejecutaba antes de que se instalara RKP, lo que significa que el dispositivo se asigna a la memoria física sin la seguridad adicional proporcionada por RKP. Eso, a su vez, significaba que el autor podía leer y escribir en la memoria que estaba bloqueada originalmente y correctamente por el software RKP.

El segundo registro que se pasó por alto tuvo un efecto más sutil, pero en última instancia igual de devastador para la seguridad. Elregistro de control de traducción para EL1(TCR_EL1) se relaciona directamente con la cantidad de memoria con la que trabaja una aplicación, denominada página. RKP está codificado de forma rígida con un tamaño de página de 4 kb porque los núcleos Linux AARCH64 (como Android) utilizan un tamaño de traducción de 4 KB. El registro en cuestión (TCR_EL1) establece los chipsets ARM en el tamaño de memoria que se debe devolver. Resulta queeste registro no está protegido por el HCRy, por lo tanto, un atacante puede cambiarlo como el autor lo cambió a un tamaño de página de 64 kb.

Esto significa que cuando RKP cumple con la solicitud, la cantidad real de memoria accesible es ahora de 64 kb en lugar de 4 kb. La razón es que el chipset ARM todavía controla el tamaño de la página y el exploit lo estableció en 64 kb. Dado que RKP protege la memoria para que no se escriba en ella, como parte de las reglas enumeradas en el exploit n.° 2, la memoria sigue estando protegida. Pero aquí está el truco: dado que RKP está codificado en 4 kb, no cambia a un tamaño de página de 64 kb cuando se actualiza el registro, por lo quesolo los primeros 4 kb de memoria están protegidos,lo que permite al atacante hacerlo que quiera con los 60 kb restantes.


Explotación #4

El último exploit que muestra el autor hace referencia a la memoria donde se encuentra el software RKP, por lo que el atacante podría atacar el propio software RKP. Un truco para detener este tipo de ataque, que también utilizan los núcleos de Linux, es desasignar el programa del espacio de direcciones de la memoria virtual para que ninguna aplicación pueda atacarlo porque no puede hacer referencia a él.

Recuerde que la memoria se compone de punteros y tablas que asignan la memoria física a la memoria virtual. Según la defensa normal en este tipo de ataque, RKP se desasigna a sí mismo para que no pueda ser atacado. Sin embargo, cuando el núcleo no proporciona tales capacidades, RKP permite que se asigne un fragmento de memoria y se marque como de lectura/escritura. La única comprobación es que no se trata del núcleo subyacente en sí, ya que RKP no realiza comprobaciones para ver si las direcciones que se solicita asignar son el área donde reside el propio RKP en la memoria. Básicamente, RKPse permite volver a asignaral espacio de direcciones al que pueden acceder las aplicaciones y, como efecto secundario, lamemoria se marca automáticamente como de lectura/escritura,de modo que un atacante ahora puede usar la memoria como quiera.


Conclusión

Uno de los mayores problemas con los cuatro exploits enumerados anteriormente es que el autor menciona lo difícil que sería realizarlos debido a la falta de funciones en el kernel básico de Android. Irónicamente, el hipervisor seguro RKP proporcionó todas las herramientas necesarias para llevar a cabo los ataques. Esto demuestra que, a veces, el software bien intencionado causa más problemas de los que resuelve y tenemos suerte de tener personas como Gal Beniamini dispuestas a poner manos a la obra y comprobar que la documentación coincide con lo que realmente hace el software.

Si bien estos exploits parecen aterradores y hacen que Knox parezca muy vulnerable, me gustaría asegurarles a todos que todos estos problemas se hansolucionado en la actualización de enerode Samsung. Además, estos exploits requieren un conocimiento muy profundo de los procesadores ARM y la programación, por lo que la barrera de entrada para su uso es astronómicamente alta.


Fuente: Proyecto Zero