miércoles, 29 de julio de 2015

Android Stagefright Exploit / POC (II)

Pero ¿Qué vectores podemos/debemos seguir para localizar este tipo de vulnerabilidades?


A priori, yo me decantaría principalmente por dos vectores muy distintos y, para los cuales se tendrán que emplear técnicas muy diferentes.


VECTOR de búsqueda 1


Ante todo hay que tener en cuenta que Android es un proyecto Open Source, lo que significa que tenemos acceso a su código fuente. Así, un claro vector de búsqueda sería por esta vía, es decir, analizando el código fuente en busca de aquellos 'Bugs', descuidos y metodologías, técnicas y funciones inseguras utilizadas por los ingenieros del software.

Por tanto, un poco para empezar a buscar es el repositorio del código fuente de Android, el cual podemos encontrar en la siguiente URL:


Como podemos ver en dicho repositorio, la cantidad de código fuente con la que tendremos que lidiar es claramente INMENSA, entonces ¿por qué camino debemos ir? En el caso que nos ocupa sobre StageFright, una vía clara de búsqueda, es la ruta que nos lleva directamente al framework de audio y video nativo del StageFright, el cual está ubicado aquí (para android-5.1.1 r8):


En caso de querer tener acceso al framework de otra reléase, podemos entrar desde esta otra URL:


Por ejemplo, para ir directos al código fuente en C++ de parte de Stagefright podríamos comenzar por aquí:



VECTOR de búsqueda 2

En este caso, como digo, las cosas serán muy diferentes. Ahora no se trata de analizar el código fuente en búsqueda de funciones 'sensibles' o estructuras mal definidas, etc. Aquí de lo que se trata es de utilizar un dispositivo "vivo", es decir, actuar sobre un dispositivo Android en tiempo real.

Nuevamente, en el caso que nos ocupa de StageFright y, en concreto en las vulnerabilidades que hacen referencia a la recepción de MMS, la técnica que se utilizará será la "Fuzzy Data Mining", básicamente el envío de datos mal-formados al dispositivo, con el fin de provocar algún tipo de error.

Está claro que el envío/recepción de mensajes de tipo MMS debe regirse por algún tipo de estándar con su correspondiente especificación, la cual se encarga de definir entre otras cosas las características, formatos de los datos, de las cabeceras, etc. que deben tener dichos mensajes.

Y entre otras cosas, algo que diferencia a un MMS de un SMS común, es que el MMS precisamente soporta el envío/recepción de archivos multimedia (audio y video). Archivos que pueden ser de diversos formatos y, los cuales nuevamente se deben regir por una especificación de formato, en la mayoría de los casos claramente definida.

Por ejemplo, para que os hagáis una idea StageFright, a priori es capaz de identificar las siguientes extensiones de archivos:

".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac", ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota", ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf", ".avi", ".mpeg", ".mpg", ".awb", ".mpga"

Esto, que de entrada podría no significar gran cosa, ya nos está dando una idea aproximada de la cantidad de CODECs con los que tiene que lidiar Android y su complejo framework multimedia.

Por lo tanto y dicho esto, ¿qué pasaría si en lugar de enviar un MMS como el dispositivo Android espera recibir, le enviamos un MMS mal-formado o erróneo? Pues la respuesta es sencilla, si el software no está correctamente diseñado para la detección de este tipo de situaciones tipo excepciones no controladas y demás, se producirá algún error.

Esos errores serán precisamente los que convertirán en vulnerable al dispositivo, pudiendo permitir la ejecución de código remoto no deseado o mal intencionado.


martes, 28 de julio de 2015

Android Stagefright Exploit / POC (I)

Antes incluso de hablar sobre la existencia o no, de los exploits/POC correspondientes, que sin duda a estas alturas ya los hay, sería interesante saber que es exactamente "Stragefright".

Pues bien, Stragefright es básicamente el motor de reproducción de medios digitales que incorpora Android de forma nativa. Este componente software, incorpora ya una serie de codecs de-facto para la reproducción de la gran mayoría de los formatos multimedia más populares y generalizados.

En el siguiente digrama (cortesía de Google), se puede ver como interactuan las aplicaciones de reproducción o gestión de medios, con el framework multimedia nativo de Android (Stragefright).

Se distinguen las siguientes partes o capas en dicha arquitectura, a saber:

- El framework de aplicación, es donde se encontraría el codigo en si de la aplicación de usuario, la cual, haciendo uso de las APIs correspondientes (android.media) pueden interactuar con el hardware multimedia.

- Binder IPC Proxies, se trata de la capa encargada de facilitar la comunicación entre procesos. Estos proxies, se encuentran alojados en el directorio 'frameworks/av/media/libmedia' y comienzan con la letra 'I'

- Native Multimedia Framework, ya a un nivel nativo, Android proporciona un framework multimedia que hace uso del motor Stragefright para la grabación y reproducción de audio y video. Stragefright ya viene con varios codecs por software, pero además se podrían implementar nuevos codecs hardware a través del estandar de OpenMax.

- OpenMAX Integration Layer (IL), como he mencionado anteriormente, se trata de una estandarización para el uso de codecs multimedia basados en hardware. Digamos que son una especie de componentes o plugins en forma de librería compartida.

Bueno, ahora que ya tenemos una ligera idea sobre que es Stagefright, es momento de hablar sobre el/los bugs que están apareciendo recientemente en los dispositivos Android y, que pueden permitir a determinadas personas sin escrúpulos, acceder a dichos dispositivos para tomar el control de los mismos, haciendo uso de la cámara de fotos/video, el micrófono, tarjeta SD, y demás información que pulula por nuestros cacharros.

Según parece, ya hay una serie de identificadores asignados a tales vulnerabilidades:

CVE-2015-1538, CVE-2015-1539, CVE-2015-3824, CVE-2015-3826, CVE-2015-3827, CVE-2015-3828, CVE-2015-3829

Y volviendo al hilo del título, ¿cuánto pensáis que van a tardar en aparecer los correspondientes exploits?

Si como dicen con enviar un MMS manipulado adecuadamente, ya es posible conseguir la ejecución de código remoto y, como es lógico con los privilegios de ejecución de los procesos de StageFriht, parece bastante lógico pensar que los problemas estén en los codecs oportunos. ¿Será una decodificación de cabeceras? ¿Desbordamientos? o por ejemplo ¿Guardará Stagefriht algún tipo de archivo temporal con parte de los datos extraídos, para proceder posteriormente a su interpretación?

Yo por el momento, ya dispongo de un dispositivo Android listo para ser investigado.

jueves, 11 de junio de 2015

¿Qué tiene dentro? El Condensador Electrolítico

Aquí uno de esos post que sirven para saciar la curiosidad de los "mente-inquieta", que gustan de conocer las interioridades de todo aquello que les rodea.

En esta ocasión algo pequeñito y sencillo a la vez, pero de vital importancia en la tecnología que nos acompaña cada a día en nuestro entorno, el condensador electrolítico.









Diagrama de Transición para números en Notación Científica (1.5e-10)

Si en el anterior post mostraba la expresión regular necesaria para representar patrones correspondientes a números expresados en notación científica, en esta ocasión quiero mostrar como sería el diagrama de transición necesario, para que un autómata sea capaz de analizarlo.

En la imagen siguiente podéis ver tanto el diagrama de transición como la expresión regular correspondiente:


Podríamos expresarlo con alguna variante, pero para entender el concepto general del diagrama de transición creo que es más que suficiente.

Expresión Regular para números en Notación Científica (1.5e-10)

No cabe duda que las expresiones regulares tienen un potencial de mucho valor a la hora de analizar textos, ya sea para marcado, búsqueda de patrones, o incluso la programación de un compilador, un analizador de frases, de expresiones matemáticas, etc.
 
En esta ocasión he tenido que echar mano de ellas para el análisis de textos matemáticos en los cuales aparecen números en Notación Científica (con exponentes del tipo 1.5E-10). Pues bien, una expresión regular que me está funcionando bastante bien es la siguiente:
 
[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
 

Esta expresión regular se puede descomponer en los siguientes bloques, para poder interpretarla con mayor facilidad: 
  • El primer bloque [-+]? está indicando que el número podría estar precedido opcionalmente de un signo - o un signo +
  • El segundo bloque [0-9]* indica que podría aparecer un número de 0 o más dígitos del 0 al 9 
  • El tercer bloque indica que también de manera opcional podría aparecer un punto decimal
  • El cuarto bloque sugiere la aparición de un número de 1 o más dígitos del 0 al 9 
  • El quinto bloque es precisamente el que indicaría la parte exponencial del número y podría ser totalmente opcional.
Este último bloque se descompone en los siguiente sub-bloques:
  • Un primer bloque que indica la aparición de la letra 'e' o 'E' de exponente.
  • Un segundo bloque que indica la aparición opcional del signo '-' o el signo '+'
  • Un tercer bloque que indica la aparición de un número de 1 o más dígitos del 0 al 9.

sábado, 6 de junio de 2015

Captura de la FSK del Caller-ID

Dado que actualmente estoy trabajando en un nuevo proyecto relacionado con la telefonía, quería mostraros como se ve la FSK, o dicho de otro modo, la trama de datos del CallerID o identificación de llamada entrante.

Supongo que si has llegado hasta aquí es porque ya sabes de que va esto, pero para aquellos de vosotros que sintáis curiosidad y no sepáis de que va, se trata de la señal que llega a nuestros teléfonos fijos cada vez que recibimos una llamada telefónica, así de sencillo.

Dicha señal, contiene los datos que identifican a la llamada entrante, esto es, fecha, hora y número de teléfono entre otras cosas. Ni que decir tiene, que para que dicha señal llegue por la línea de teléfono hasta nuestro terminal, deberemos tener activado dicho servicio con nuestro operador, el cual en algunos casos implica un pequeño coste añadido.

Pues bien, esta señal se transmite por la línea telefónica desde la Oficina Central de nuestro operador hasta nuestro terminal, utilizando lo que se conoce como FSK (Frequency Shift Keying) ó Modulación por Desplazamiento de Frecuencia.

La idea "bijain de escen" es sencilla. Básicamente consiste en utilizar dos señales de distinta frecuencia para representar el 1 y el 0, o lo que se conoce como marca y espacio. De tal forma que, si queremos transmitir un 1 utilizaremos una de las frecuencias y para el 0 utilizaremos la otra.

Bueno al grano, aquí podéis ver una captura realizada con el osciloscopio RIGOL DS2202 de toda la trama completa, además de un par de señales de Ring:



Como podéis comprobar en la imagen, la señal de la trama del Caller-ID se encuentra entre dos señales de tono o Ring. En la imagen siguiente, he hecho una "ampliación" de un pedacito de dicha trama para que veáis la diferencia entre las dos señales empleadas para representar los '0' y '1'. Además he recortado la señal para que lo podáis ver un poco más claro:


Como se ve en la imagen superior, tenemos una valor de 8 bits '11001010', la cual corresponde a una mínima porción de la trama completa, es más, solamente a efectos de sincronización y para que os hagáis una idea de su magnitud, cuenta con unos 300 bits iniciales + otros 150 bits aprox. de sincronismo y finalmente los datos de identificación, pero esto según el estándar que se utilice podría llegar a ser de más de 2000 bits de longitud.

Pues nada, ahora ya sabéis como se ve la trama FSK del Caller-ID o identificación de llamada entrante.



C++11 y constexpr

El estándar de C++ desde su versión 11, incluye el nuevo especificador 'constexpr'. En concreto me voy a centrar en la especificación 11 de C++, ya que en la versión 14 hay algunos cambios muy interesantes, pero el compilador que voy a utilizar (que será Visual C++ de Visual Studio 2015), solo incluye hasta la versión 11.

A estas alturas me imagino que la mayoría de vosotros ya conocereis la existencia de este nuevo especificador, pero para aquellos que no lo sepan y por tanto, no lo hayan utilizado nunca, decir que se trata de un especificador para variables y funciones, que permitirá que éstas puedan ser utilizadas en expresiones constantes, las cuales en principio, podrán ser evaluadas en tiempo de compilación.

Y como una imagen vale más que mil palabras y, para nosostros un pedazo de código vale más que mil párrafos de explicaciones, vamos con un sencillo ejemplo.


Imaginad que definimos una plantilla que recibe un parámetro de tipo constante, y queremos que en el momento de instanciar tal plantilla, podamos pasarle una función como parámetro. Hasta ahora esto no era posible, al obligarnos la plantilla a que dicho parámetro fuese de tipo constante, pero ahora, y gracias al especificador 'constexpr', ya es posible, vamos a verlo.


#include <iostream>
using namespace std;
template<int n>
struct Calculos
{
 Calculos()
 {
  std::cout << "Valor: " << n << '\n';
 }
};
int main()
{
 Calculos<5> Test;
}


Bueno, como veis, lo que va a suceder con este pequeño código, es que se va a crear una instancia de  tipo Calculos y en cuanto se llame a su constructor, se mostrará por pantalla el valor pasado como parámetro a la plantilla, es decir el valor '5'


Pues bien, ¿qué sucede si lo que queremos es incluir como parámetro de la plantilla una llamada a una función que retorne un valor de tipo entero, por ejemplo el factorial de un número, en lugar de codificar directamente el valor '5'?, pues vamos a verlo:


#include <iostream>
using namespace std;
int factorial(int v)
{
 return v <= 1 ? 1 : (v * factorial(v-1));
}
template<int n>
struct Calculos
{
 Calculos()
 {
  std::cout << "Valor: " << n << '\n';
 }
};
int main()
{
 Calculos<factorial(6)> Test;
}

Este pedazo de código, va a lanzar un error en tiempo de compilación, porque al instanciar Test, va a comprobar que la funcion factorial no es constante y la plantilla está esperando un valor constante.

Pues bien, esto lo resolvemos incluyende el especificador 'constexpr' en la declaración de la función factorial. Obviamente, esto nos va a imponer ciertas restricciones en cuanto a que podemos utilizar en la programación de dicha función y que no. Por ejemplo, no podremos declarar variables locales, no podremos utilizar sentencias de iteración tipo For, While, etc. Esto último si que se podrá hacer con la versión del estándar 14 de C++

El siguiente código si que compilará sin ningún tipo de error, ya que el compilador evaluará la función  factorial en tiempo de compilación, consiguiendo de esta manera que el parámetro de la plantilla sea constante.


#include <iostream>
using namespace std;
constexpr int factorial(int v)
{
 return v <= 1 ? 1 : (v * factorial(v-1));
}
template<int n>
struct Calculos
{
 Calculos()
 {
  std::cout << "Valor: " << n << '\n';
 }
};
int main()
{
 Calculos<factorial(6)> Test}


Por último, simplemente decir que según parece, en la RTM de Visual Studio 2015 no estarán implementadas las características de 'constexpr' incluídas en el estándar C++14, tocará esperar a otra versión.


En cualquier caso, si que se pueden ir probando algunas de estas con el compilador GCC en su versión 5. Podeis ver algo de información al respecto aquí: https://isocpp.org/files/papers/N3652.html