Check Point Research descubre vulnerabilidades en SQLite que permiten hackear un iPhone




Check Point Research descubre vulnerabilidades en SQLite que permiten hackear un iPhone
Check Point Research descubre vulnerabilidades en SQLite que permiten hackear un iPhone

Check Point Research descubre vulnerabilidades en SQLite que permiten hackear un iPhone.

  • SQLite es el sistema de gestión de bases de datos en el que se guardan los contactos del iPhone
  • Otros sistemas que utilizan SQLite son Windows 10, MacOS, Chrome, Safari, Firefox y Android

Check Point® Software Technologies Ltd. (NASDAQ: CHKP), proveedor líder especializado en ciberseguridad a nivel mundial, ha descubierto vulnerabilidades que afectan a SQLite, el sistema de gestión de bases de datos más utilizado a nivel global. A través de estas vulnerabilidades, un cibercriminal podría obtener el control de un iPhone, dado que los contactos de estos dispositivos se almacenan en este tipo de bases de datos.

“A pesar de la extendida creencia de que los iPhone eran dispositivos más seguros, estas vulnerabilidades demuestran que también podrían ser hackeados. Es importante que el usuario tenga en cuenta la seguridad de sus ordenadores y teléfonos móviles, dado que un usuario podría tomar el control y robar toda la información almacenada”, señala Eusebio Nieva, director técnico de Check Point para España y Portugal.

SQLite es un sistema de gestión de bases de datos que está disponible en todos los sistemas operativos, ordenadores y teléfonos móviles. Por ejemplo, Windows 10, MacOS, iOS, Chrome, Safari, Firefox y Android son usuarios populares de SQLite. Al ser uno de los software más utilizados del mundo, muchos programas lo incluyen para diferentes propósitos. Por ejemplo, además del caso de los iPhone, los Mac también guardan algunas de las contraseñas en este sistema. A través de estas vulnerabilidades, sería posible controlar cualquier sistema que consultara una base de datos controlada por SQLite.

Dado el hecho de que SQLite es tan popular, hay un sinfín de posibilidades para la explotación de estas vulnerabilidades. Check Point ha creado una demo para demostrarlo en el iOS de un iPhone, que ha presentado en el evento Def Con 2019. Aprovechando estas vulnerabilidades, sería posible evadir el mecanismo de arranque seguro de Apple y obtener permisos de administrador en el último iPhone. Check Point ha sido pionero a la hora de demostrar una vulnerabilidad de SQLite que no depende del navegador.

“Hasta ahora, consultar una base de datos nunca se había considerado peligroso, pero nuestras investigaciones han demostrado que sí podría llegar a serlo. Debido a que SQLite es tan popular, estas vulnerabilidades se han convertido en una gran oportunidad para su explotación. Un error grave en SQLite es un error grave en algunas de las tecnologías más utilizadas en el mundo, como iPhone, Dropbox, Adobe o Skype”, finaliza Nieva.

Check Point incluye en sus soluciones de seguridad sistemas de prevención de intrusiones (IPS) que aseguran al usuario para no verse afectado por este tipo de brechas en el software.

Para más información sobre estas vulnerabilidades, por favor visite: https://research.checkpoint.com/select-code_execution-from-using-sqlite/ 

Os dejamos la entrada traducida.

SELECT code_execution FROM* USING SQLite;

Obtener ejecución de código usando una base de datos SQLite maliciosa Investigación por: Omer Gull

SQLite es uno de los software más implementados en el mundo. Sin embargo, desde una perspectiva de seguridad, solo se ha examinado a través de la lente de WebSQL y la explotación del navegador. Creemos que esto es solo la punta del iceberg.

En nuestra investigación a largo plazo, experimentamos con la explotación de problemas de corrupción de memoria dentro de SQLite sin depender de ningún entorno que no sea el lenguaje SQL. Usando nuestras técnicas innovadoras de Secuestro de consultas y Programación orientada a consultas, demostramos que es posible explotar de manera confiable los problemas de corrupción de memoria en el motor SQLite. Demostramos estas técnicas en un par de escenarios del mundo real: crear un servidor backend de robo de contraseñas y lograr la persistencia de iOS con mayores privilegios.

Esperamos que al lanzar nuestra investigación y metodología, la comunidad de investigación de seguridad se inspire para continuar examinando SQLite en los innumerables escenarios donde está disponible. Dado el hecho de que SQLite está prácticamente integrado en todos los principales sistemas operativos, computadoras de escritorio o dispositivos móviles, el panorama y las oportunidades son infinitas. Además, muchas de las primitivas presentadas aquí no son exclusivas de SQLite y pueden ser portadas a otros motores SQL. Bienvenido al valiente mundo nuevo del uso del familiar lenguaje de consulta estructurado para las primitivas de explotación.

Motivación

Esta investigación comenzó cuando omriher y yo estábamos mirando el código fuente filtrado de algunos ladrones de contraseñas notorios. Si bien hay muchos ladrones de contraseñas ( Azorult , Loki Bot y Pony, por nombrar algunos), su modus operandi es casi el mismo:

Una computadora se infecta y el malware captura las credenciales a medida que se usan o recoge las credenciales almacenadas mantenidas por varios clientes. 
No es raro que el software del cliente utilice bases de datos SQLite para tales fines. 
Después de que el malware recopila estos archivos SQLite, los envía a su servidor C2 donde se analizan mediante PHP y se almacenan en una base de datos colectiva que contiene todas las credenciales robadas.

Leyendo el código fuente filtrado de tales ladrones de contraseñas, comenzamos a especular sobre la superficie de ataque descrita anteriormente. 
¿Podemos aprovechar la carga y consulta de una base de datos no confiable para nuestro beneficio? 
Dichas capacidades podrían tener implicaciones mucho mayores en innumerables escenarios, ya que SQLite es una de las piezas de software más ampliamente implementadas .

Una base de código sorprendentemente compleja, disponible en casi cualquier dispositivo imaginable. es toda la motivación que necesitábamos, y así comenzó nuestro viaje.

Introducción a SQLite

Hay muchas posibilidades de que esté utilizando SQLite actualmente, incluso si no lo sabe. 
Para citar a sus autores:

SQLite es una biblioteca en lenguaje C que implementa un motor de base de datos SQL pequeño, rápido, autónomo, de alta confiabilidad y con todas las funciones. SQLite es el motor de base de datos más utilizado en el mundo. SQLite está integrado en todos los teléfonos móviles y la mayoría de las computadoras y viene incluido en innumerables aplicaciones que la gente usa todos los días.

A diferencia de la mayoría de las otras bases de datos SQL, SQLite no tiene un proceso de servidor separado. SQLite lee y escribe directamente en archivos de disco normales. Una base de datos SQL completa con múltiples tablas, índices, disparadores y vistas está contenida dentro de un solo archivo de disco.

Superficie de ataque

El siguiente fragmento es un ejemplo bastante genérico de un backend de robo de contraseñas.

Dado que controlamos la base de datos y su contenido, la superficie de ataque disponible para nosotros se puede dividir en dos partes: la carga y el análisis inicial de nuestra base de datos, y la consulta SELECT realizada contra ella.

La carga inicial realizada por sqlite3_open es en realidad una superficie muy limitada; Básicamente es una gran cantidad de código de instalación y configuración para abrir la base de datos. Nuestra superficie es principalmente el análisis del encabezado que se prueba en batalla contra AFL.

Las cosas se ponen más interesantes a medida que comenzamos a consultar la base de datos. 
Usando las palabras de los autores SQLite:

«La instrucción SELECT es el comando más complicado en el lenguaje SQL».

Aunque no tenemos control sobre la consulta en sí (ya que está codificada en nuestro objetivo), estudiar el proceso SELECCIONAR cuidadosamente resultará beneficioso en nuestra búsqueda de explotación.

Como SQLite3 es una máquina virtual, cada instrucción SQL primero debe compilarse en un programa de código de bytes utilizando una de las rutinas sqlite3_prepare * . 
Entre otras operaciones, la función de preparación recorre y expande todas las subconsultas SELECT. Parte de este proceso es verificar que todos los objetos relevantes (como tablas o vistas) realmente existen y ubicarlos en el esquema maestro.

sqlite_master y DDL

Cada base de datos SQLite tiene una sqlite_mastertabla que define el esquema para la base de datos y todos sus objetos (como tablas, vistas, índices, etc.). 
La tabla sqlite_master se define como:

La parte que es de especial interés para nosotros es la columna sql. 
Este campo es el DDL (lenguaje de definición de datos) utilizado para describir el objeto. 
En cierto sentido, los comandos DDL son similares a los archivos de encabezado C. Los comandos DDL se utilizan para definir la estructura, los nombres y los tipos de contenedores de datos dentro de una base de datos, del mismo modo que un archivo de encabezado generalmente define definiciones de tipos, estructuras, clases y otras estructuras de datos.

Estas declaraciones DDL realmente aparecen en texto sin formato si inspeccionamos el archivo de base de datos:

Durante la preparación de la consulta, sqlite3LocateTable () intenta encontrar la estructura en memoria que describe la tabla que nos interesa consultar.

sqlite3LocateTable () lee el esquema disponible en sqlite_master, y si es la primera vez que lo hace, también tiene una devolución de llamada para cada resultado que verifica que la declaración DDL es válida y crea las estructuras de datos internos necesarios que describen el objeto en cuestión.

Parches DDL

Nos preguntamos si aprendimos sobre este proceso de preparación, ¿podemos simplemente reemplazar el DDL que aparece en texto plano dentro del archivo? Si pudiéramos inyectar nuestro propio SQL en el archivo, tal vez podamos afectar su comportamiento.

Según el fragmento de código anterior, parece que las instrucciones DDL deben comenzar con «crear». 
Con esta limitación en mente, necesitábamos evaluar nuestra superficie. 
La comprobación de la documentación de SQLite reveló que estos son los posibles objetos que podemos crear:

El comando CREATE VIEW nos dio una idea interesante. Para decirlo de manera muy simple, las VIEW son solo declaraciones SELECT preempaquetadas. Si reemplazamos la tabla esperada por el software objetivo con una VISTA compatible, se revelan oportunidades interesantes.

Secuestrar cualquier consulta

Imagine el siguiente escenario: 
la base de datos original tiene una TABLA única llamada dummy que se define como:

El software de destino lo consulta con lo siguiente:

De hecho, podemos secuestrar esta consulta si creamos un ficticio como una VISTA:

Esta VISTA «trampa» nos permite secuestrar la consulta, lo que significa que generamos una consulta completamente nueva que controlamos totalmente.

Este matiz amplía enormemente nuestra superficie de ataque, desde el análisis muy mínimo del encabezado y una consulta incontrolable realizada por el software de carga, hasta el punto en el que ahora podemos interactuar con vastas partes del intérprete SQLite parcheando el DDL y creando nuestras propias vistas. con subconsultas.

Ahora que podemos interactuar con el intérprete de SQLite, nuestra siguiente pregunta fue ¿qué primitivas de explotación están integradas en SQLite? ¿Permite algún comando del sistema, leer o escribir en el sistema de archivos?

Como no somos los primeros en notar el enorme potencial de SQLite desde una perspectiva de explotación, tiene sentido revisar el trabajo previo realizado en el campo. Comenzamos desde lo más básico.

Inyecciones SQL

Como investigadores, es difícil para nosotros incluso deletrear SQL sin la «i», por lo que parece un lugar razonable para comenzar. Después de todo, queremos familiarizarnos con las primitivas internas que ofrece SQLite. ¿Hay algún comando del sistema? ¿Podemos cargar bibliotecas arbitrarias?

Parece que el truco más sencillo consiste en adjuntar un nuevo archivo de base de datos y escribir en él usando algo como:

Adjuntamos una nueva base de datos, creamos una sola tabla e insertamos una sola línea de texto. La nueva base de datos crea un nuevo archivo (ya que las bases de datos son archivos en SQLite) con nuestro shell web dentro. 
La naturaleza indulgente del intérprete PHP analiza nuestra base de datos hasta que alcanza la etiqueta abierta PHP de «<?». 
Escribir un shell web definitivamente es una victoria en nuestro escenario de ladrones de contraseñas, sin embargo, como recordará, DDL no puede comenzar con «ATTACH»

Otra opción relevante es la función load_extension . Si bien esta función debería permitirnos cargar un objeto compartido arbitrario, está deshabilitada de manera predeterminada.

Daños en la memoria en SQLite

Al igual que cualquier otro software escrito en C, los problemas de seguridad de la memoria son definitivamente algo a tener en cuenta al evaluar la seguridad de SQLite. 
En su gran publicación de blog , Michał Zalewski describió cómo unió SQLite con AFL para lograr algunos resultados impresionantes: 22 errores en solo 30 minutos de fuzzing.

Curiosamente, SQLite ha comenzado a usar AFL como parte integral de su notable conjunto de pruebas.

Estas corrupciones de memoria fueron tratadas con la gravedad esperada (Richard Hip y su equipo merecen mucho respeto). Sin embargo, desde la perspectiva del atacante, estos errores resultarían ser un camino difícil de explotación sin un marco decente para aprovecharlos. 
Las mitigaciones modernas representan un obstáculo importante para explotar los problemas de corrupción de memoria y los atacantes necesitan encontrar un entorno más flexible.

¡La comunidad de Security Research pronto encontrará el objetivo perfecto!

SQL web

Web SQL Database es una API de página web para almacenar datos en bases de datos que pueden consultarse utilizando una variante de SQL a través de JavaScript. El Grupo de Trabajo de Aplicaciones Web W3C dejó de trabajar en la especificación en noviembre de 2010, citando la falta de implementaciones independientes que no sean SQLite.

Actualmente, la API todavía es compatible con Google Chrome, Opera y Safari. 
Todos ellos usan SQLite como el back-end de esta API.

La entrada no confiable en SQLite, accesible desde cualquier sitio web dentro de algunos de los navegadores más populares, llamó la atención de la comunidad de seguridad y, como resultado, el número de vulnerabilidades comenzó a aumentar. 
De repente, los errores en SQLite podrían ser aprovechados por el intérprete de JavaScript para lograr una explotación confiable del navegador.

Se han publicado varios informes de investigación impresionantes:

Un patrón claro en investigaciones anteriores de WebSQL revela que un módulo de tabla virtual llamado «FTS» podría ser un objetivo interesante para nuestra investigación.

FTS

La búsqueda de texto completo (FTS) es un módulo de tabla virtual que permite búsquedas de texto en un conjunto de documentos. 
Desde la perspectiva de una instrucción SQL, el objeto de la tabla virtual se parece a cualquier otra tabla o vista. Pero detrás de escena, las consultas en una tabla virtual invocan métodos de devolución de llamada en tablas de sombra en lugar de la lectura y escritura habitual en el archivo de base de datos.

Algunas implementaciones de tablas virtuales, como FTS, utilizan tablas de bases de datos reales (no virtuales) para almacenar contenido.

Por ejemplo, cuando se inserta una cadena en la tabla virtual FTS3, se deben generar algunos metadatos para permitir una búsqueda textual eficiente. Estos metadatos se almacenan en tablas reales llamadas «% _segdir» y «% _segments», mientras que el contenido en sí se almacena en «»% _content «donde»% «es el nombre de la tabla virtual original. 
Estas tablas reales auxiliares que contienen datos para una tabla virtual se denominan «tablas de sombra»

Debido a su naturaleza de confianza, las interfaces que pasan datos entre tablas de sombra proporcionan un terreno fértil para los errores. CVE-2019-8457, – una nueva vulnerabilidad de lectura OOB que encontramos en el módulo de tabla virtual RTREE, lo demuestra bien.

Se espera que las tablas virtuales RTREE, utilizadas para la indexación geográfica, comiencen con una columna entera. Por lo tanto, otras interfaces RTREE esperan que la primera columna de un RTREE sea un número entero. Sin embargo, si creamos una tabla donde la primera columna es una cadena, como se muestra en la figura siguiente, y la pasamos a la interfaz rtreenode () , se produce una lectura OOB.

Ahora que podemos usar el secuestro de consultas para obtener el control sobre una consulta y saber dónde encontrar vulnerabilidades, es hora de pasar a explotar el desarrollo.

SQLite Internals para desarrollo de exploits

Publicaciones anteriores sobre la explotación de SQLite muestran claramente que siempre ha sido necesario un entorno de envoltura, ya sea el intérprete PHP visto en esta increíble publicación de blog sobre el abuso de los tokenizadores SQLite o el trabajo más reciente en Web SQL desde la comodidad de un intérprete de JavaScript .

Como SQLite está prácticamente en todas partes, limitarnos a su potencial de explotación nos pareció poco convincente y comenzamos a explorar el uso de componentes internos de SQLite para fines de explotación. 
La comunidad de investigación se volvió bastante buena en la utilización de JavaScript para el desarrollo de exploits. ¿Podemos lograr primitivas similares con SQL?

Teniendo en cuenta que SQL está Turing completo ([ 1 ], [ 2 ]), comenzamos a crear una lista de deseos primitiva para el desarrollo de exploits basada en nuestra experiencia pwning. 
Un exploit moderno escrito exclusivamente en SQL tiene las siguientes capacidades:

  • Pérdida de memoria.
  • Empaque y desempaquetado de enteros a punteros de 64 bits.
  • Puntero aritmética.
  • Elaboración de objetos falsos complejos en la memoria.
  • Heap Spray.

Uno por uno, abordaremos estas primitivas y las implementaremos utilizando nada más que SQL.

Con el fin de lograr RCE en PHP7, utilizaremos el 1 día aún sin arreglar de  CVE-2015-7036 .

¿Esperar lo? ¿Cómo es que nunca se ha solucionado un error de 4 años? En realidad es una historia interesante y un gran ejemplo de nuestro argumento. 
Esta característica solo se consideró vulnerable en el contexto de un programa que permite SQL arbitrario de una fuente no confiable (Web SQL), por lo que se mitigó en consecuencia. 
Sin embargo, el uso de SQLite es tan versátil que aún podemos activarlo en muchos escenarios many

Plan de juego de explotación

CVE-2015-7036 es un error muy conveniente para trabajar. 
En pocas palabras, la función fts3_tokenizer () vulnerable devuelve la dirección del tokenizador cuando se llama con un solo argumento (como «simple», «porter» o cualquier otro tokenizer registrado).

Cuando se llama con 2 argumentos, fts3_tokenizer anula la dirección del tokenizer en el primer argumento con la dirección proporcionada por un blob en el segundo argumento. 
Después de que cierto tokenizer ha sido anulado, cualquier nueva instancia de la tabla fts que use este tokenizer nos permite secuestrar el flujo del programa.

Nuestro plan de juego de explotación:

  • Fuga de una dirección de tokenizer
  • Calcule la dirección base
  • Falsifique un tokenizador falso que ejecutará nuestro código malicioso
  • Anula uno de los tokenizadores con nuestro tokenizer malicioso
  • Instanciar una tabla fts3 para activar nuestro código malicioso

Ahora volvamos a nuestro desarrollo de exploits.

Programación orientada a consultas ©

Estamos orgullosos de presentar nuestro propio enfoque único para el desarrollo de exploits utilizando el lenguaje de consulta estructurado familiar. Compartimos QOP con la comunidad con la esperanza de alentar a los investigadores a buscar las infinitas posibilidades de explotación de motores de bases de datos. 
Cada una de las siguientes primitivas va acompañada de un ejemplo del shell sqlite3.

Si bien esto le dará una pista de lo que quiere lograr, tenga en cuenta que nuestro objetivo final es plantar todas esas primitivas en la tabla sqlite_master y secuestrar las consultas emitidas por el software de destino que carga y consulta nuestro archivo db SQLite malicioso

Fuga de memoria – Binario

Mitigaciones como ASLR definitivamente elevaron el listón para la explotación de corrupciones de memoria. Una forma común de derrotarlo es aprender algo sobre el diseño de la memoria que nos rodea. 
Esto es ampliamente conocido como Memory Leak. 
Las pérdidas de memoria son su propia subclase de vulnerabilidades, y cada una tiene una configuración ligeramente diferente.

En nuestro caso, la fuga es el retorno de un BLOB por SQLite. 
Estos BLOB son un buen objetivo de fuga, ya que a veces contienen punteros de memoria.

El fts3_tokenizer () vulnerable se llama con un solo argumento y devuelve la dirección de memoria del tokenizador solicitado. hex () lo hace legible por humanos. 
Obviamente obtenemos alguna dirección de memoria, pero se invierte debido a la poca endianidad. 
Seguramente podemos voltearlo usando algunas operaciones de cadena incorporadas de SQLite.

¡substr () parece ser un ajuste perfecto! Podemos leer BLOB little endian, pero esto plantea otra pregunta: ¿cómo almacenamos las cosas?

Cadena QOP

Naturalmente, el almacenamiento de datos en SQL requiere una instrucción INSERT. Debido a la verificación reforzada de sqlite_master, no podemos usar INSERT ya que todas las declaraciones deben comenzar con «CREATE». Nuestro enfoque para este desafío es simplemente almacenar nuestras consultas bajo una VISTA significativa y encadenarlas. 
El siguiente ejemplo lo hace un poco más claro:

Puede que esto no parezca una gran diferencia, pero a medida que nuestra cadena se vuelva más complicada, poder usar pseudovariables seguramente nos facilitará la vida.

Desembalaje de punteros de 64 bits

Si alguna vez ha enfrentado desafíos de pwning, el concepto de empacar y desempacar punteros no debería ser extraño. 
Esta primitiva debería facilitar la conversión de nuestros valores hexadecimales (como la fuga que acabamos de lograr) a enteros. Hacerlo nos permite realizar varios cálculos en estos punteros en los siguientes pasos.

Esta consulta itera una cadena hexadecimal char por char de forma inversa usando substr ().

Se realiza una traducción de este carácter utilizando este ingenioso truco con el ajuste menor de instr () que se basa en 1. 
Todo lo que se necesita ahora es el desplazamiento correcto que está a la derecha del signo *.

Aritmética de puntero

La aritmética de punteros es una tarea bastante fácil con enteros a mano. Por ejemplo, extraer la base de la imagen de nuestro puntero del tokenizador filtrado es tan fácil como:

Embalaje de punteros de 64 bits.

Después de leer los indicadores filtrados y manipularlos a nuestra voluntad, tiene sentido empaquetarlos nuevamente en su forma little endian para que podamos escribirlos en algún lugar. 
SQLite char ()   debería usarse aquí, ya que su documentación indica que «devolverá una cadena compuesta de caracteres que tienen los valores de punto de código Unicode de un entero». 
Resultó funcionar bastante bien, pero solo en un rango limitado de enteros

Los enteros más grandes se tradujeron a sus puntos de código de 2 bytes. 
Después de golpearnos la cabeza contra la documentación de SQLite, de repente tuvimos una extraña epifanía: nuestro exploit es en realidad una base de datos. 
Podemos preparar de antemano una tabla que asigne enteros a sus valores esperados.

Ahora nuestra consulta de empaque de puntero es la siguiente:

Elaboración de objetos falsos complejos en la memoria

Escribir un solo puntero es definitivamente útil, pero aún no es suficiente. Muchos escenarios de explotación de problemas de seguridad de la memoria requieren que los atacantes forjen algún objeto o estructura en la memoria o incluso escriban una cadena ROP.

Esencialmente, conectaremos varios de los bloques de construcción que presentamos anteriormente. 
Por ejemplo, forjemos nuestro propio tokenizador, como se explica aquí . 
Nuestro tokenizer falso debe cumplir con la interfaz esperada por SQLite definido aquí:

Usando los métodos descritos anteriormente y una simple consulta JOIN, podemos falsificar el objeto deseado con bastante facilidad.

Al verificar el resultado en un depurador de bajo nivel, vemos que de hecho se creó un objeto falso de tokenizer.

Spray de montón

Ahora que hemos creado nuestro objeto falso, a veces es útil rociar el montón con él. 
Idealmente, esto debería ser alguna forma repetitiva de este último.

Desafortunadamente, SQLite no implementa la función REPEAT () como MySQL. 
Sin embargo, este hilo nos dio una solución elegante.

La función zeroblob (N) devuelve un BLOB que consta de N bytes mientras usamos replace () para reemplazar esos ceros con nuestro objeto falso.

La búsqueda de esos 0x41 muestra que también logramos una consistencia perfecta. Observe la repetición cada 0x20 bytes.

Fuga de memoria: montón

Mirando nuestro plan de juego de explotación, parece que nos estamos moviendo en la dirección correcta. 
Ya sabemos dónde se encuentra la imagen binaria, pudimos deducir dónde están las funciones necesarias y rociar el montón con nuestro tokenizer malicioso.

Ahora es el momento de anular un tokenizador con uno de nuestros objetos rociados. Sin embargo, como la dirección del montón también es aleatoria, no sabemos dónde está asignada nuestra pulverización. 
Una fuga en el montón requiere que tengamos otra vulnerabilidad.

Nuevamente, apuntaremos a una interfaz de tabla virtual. 
Como las tablas virtuales usan tablas de sombra subyacentes, es bastante común que pasen punteros sin formato entre diferentes interfaces SQL.

Nota: Este tipo exacto de problema se mitigó en SQLite 3.20 . Afortunadamente, PHP7 se compila con una versión anterior. En el caso de una versión actualizada, CVE-2019-8457 también podría usarse aquí.

Para filtrar la dirección del montón, necesitamos generar una tabla fts3 de antemano y abusar de su interfaz MATCH.

Tal como vimos en nuestra primera pérdida de memoria, el puntero es little endian, por lo que debe invertirse. Afortunadamente, ya sabemos cómo hacerlo con SUBSTR (). 
Ahora que conocemos nuestra ubicación de almacenamiento dinámico y podemos rociar correctamente, ¡finalmente podemos anular un tokenizador con nuestro tokenizador malicioso!

Poniendolo todo junto

Con todas las primitivas de explotación deseadas a la mano, es hora de volver a donde comenzamos: explotar un ladrón de contraseñas C2.

Como se explicó anteriormente, necesitamos configurar una VISTA de «trampa» para iniciar nuestro exploit. Por lo tanto, debemos examinar nuestro objetivo y preparar la VISTA correcta.

Como se ve en el fragmento de arriba, nuestro objetivo espera que nuestra base de datos tenga una tabla llamada Notas con una columna llamada BodyRich dentro. Para secuestrar esta consulta, creamos la siguiente VISTA

Después de consultar Notes, se ejecutan 3 cadenas QOP. Analicemos el primero de ellos.

heap_spray

Nuestra primera cadena QOP debería llenar el montón con una gran cantidad de nuestro tokenizer malicioso.

p64_simple_create, p64_simple_destroy y p64_system son esencialmente todas las cadenas logradas con nuestras capacidades de fuga y empaque.

Por ejemplo, p64_simple_create se construye como:

A medida que estas cadenas se ponen muy compleja, muy rápido, y son bastante repetitivo, creamos QOP.py . 
QOP.py simplifica un poco las cosas al generar estas consultas en estilo pwntools. 
Crear las declaraciones anteriores se vuelve tan fácil como:

Manifestación

https://youtu.be/cPfYoxLOi1M

COMETER;

Ahora que hemos establecido un marco para explotar cualquier situación en la que el interrogador no pueda estar seguro de que la base de datos no es maliciosa, exploremos otro caso de uso interesante para la explotación de SQLite.

Persistencia de iOS

La persistencia es difícil de lograr en iOS, ya que todos los archivos ejecutables deben firmarse como parte del Arranque seguro de Apple. Afortunadamente para nosotros, las bases de datos SQLite no están firmadas.

Utilizando nuestras nuevas capacidades, reemplazaremos una de las bases de datos de uso común con una versión maliciosa. Después de que el dispositivo se reinicia y se consulta nuestra base de datos maliciosa, obtenemos la ejecución del código.

Para demostrar este concepto, reemplazamos la base de datos de contactos «AddressBook.sqlitedb». Como se hizo en nuestro exploit PHP7, creamos dos declaraciones DDL adicionales. Una declaración DDL anula el tokenizador predeterminado «simple», y la otra declaración DDL desencadena el bloqueo al intentar crear una instancia del tokenizador anulado. Ahora, todo lo que tenemos que hacer es volver a escribir cada tabla de la base de datos original como una vista que secuestra cualquier consulta realizada y redirigirla hacia nuestro DDL malicioso.

Reemplazar los contactos db con nuestros contactos maliciosos db y reiniciar los resultados en el siguiente bloqueo de iOS:

Como se esperaba, el proceso de contactos se bloqueó en 0x4141414141414149 donde esperaba encontrar el constructor xCreate de nuestro falso tokenizador.

Además, los contactos db se comparten entre muchos procesos. Contactos, Facetime, Springboard, WhatsApp, Telegram y XPCProxy son solo algunos de los procesos que lo consultan. Algunos de estos procesos son más privilegiados que otros. Una vez que probamos que podemos ejecutar código en el contexto del proceso de consulta, esta técnica también nos permite expandir y elevar nuestros privilegios.

Nuestra investigación y metodología han sido divulgadas de manera responsable a Apple y se les asignaron los siguientes CVE:

  • CVE-2019-8600
  • CVE-2019-8598
  • CVE-2019-8602
  • CVE-2019-8577

Trabajo futuro

Dado el hecho de que SQLite está prácticamente integrado en casi cualquier plataforma, creemos que apenas hemos arañado la punta del iceberg cuando se trata de su potencial de explotación. Esperamos que la comunidad de seguridad tome esta investigación innovadora y las herramientas lanzadas y la impulse aún más. Un par de opciones que creemos que podrían ser interesantes de seguir son

  • Creando hazañas más versátiles. Esto se puede hacer construyendo exploits dinámicamente eligiendo los gadgets QOP relevantes de las tablas prefabricadas utilizando funciones como sqlite_version () o sqlite_compileoption_used () .
  • Lograr primitivas de explotación más fuertes como R / W arbitrario.
  • Busque otros escenarios en los que el interrogador no pueda verificar la confiabilidad de la base de datos.

Conclusión

Establecimos que simplemente consultar una base de datos puede no ser tan seguro como espera. Usando nuestras técnicas innovadoras de Secuestro de consultas y Programación orientada a consultas, demostramos que los problemas de corrupción de memoria en SQLite ahora pueden ser explotados de manera confiable. A medida que nuestras jerarquías de permisos se vuelven más segmentadas que nunca, está claro que debemos repensar los límites de la entrada SQL confiable / no confiable. Para demostrar estos conceptos, logramos la ejecución remota de código en un backend de robo de contraseñas que ejecuta PHP7 y obtuvimos persistencia con mayores privilegios en iOS. Creemos que estos son solo un par de casos de uso en el panorama interminable de SQLite.

El producto Check Point IPS protege contra esta amenaza: «SQLite fts3_tokenizer Ejecución remota de código de puntero no confiable (CVE-2019-8602)».

. Leer artículo completo en Frikipandi Check Point Research descubre vulnerabilidades en SQLite que permiten hackear un iPhone.

Te interesa

Los 3 pasos básicos para convertir tu hogar en una smarthome, según Konyks

Los 3 pasos básicos para convertir tu hogar en una smarthome, según Konyks

Hoy os dejmaos los 3 pasos básicos para convertir tu hogar en una smarthome, según …

Últimas noticias de Frikipandi.com

Las noticias se actualizan cada 15 minutos.