BlackBerry – Análisis estático de código y detección de vulnerabilidades

07/05/12 by Rubén Garrote García | hacking, programación segura, programming, secure programming | No Comments »

Introducción

Cuando RIM desarrolló BlackBerry, lejos de lo que se haya dado a entender o la imagen que pueda tener, uno de los aspectos más importantes que tuvieron en cuenta, fue sin duda la seguridad. Ello les llevó a desarrollar las partes principales del sistema operativo en lenguajes de bajo nivel y adaptaron, el interprete de Java para su sistema operativo.

Tras introducir los procesadores ARM, adaptaron su JVM para aceptar el estándar de instrucciones J2ME. Esta máquina virtual está desarrollada íntegramente en C/C++ y ensamblador. El resto de aplicaciones están íntegramente desarrolladas en Java.

Además diseñaron unas políticas muy restrictivas en cuanto a seguridad para terceros desarrolladores. Este interprete, no permite la inserción de código nativo mediante JNI (Java Native Interface), evitando la inserción de vulnerabilidades de corrupción de memoria por parte de aplicaciones de terceros, pudiendo comprometer así el dispositivo. Esta decisión, disminuye la superficie de ataque disponible para atacar al dispositivo.

A la hora de compilar un programa, el entorno de desarrollo de BlackBerry, JDE, convierte el código en un fichero .jar. Tras este paso, verifica que no se hayan utilizado librerías o utilidades no permitidas en J2ME, uso de JNI, por ejemplo y marca como verificadas las diferentes clases. Una vez verificado se procede a eliminar información y símbolos de compilación, además de modificar determinados opcodes para aumentar le velocidad y el rendimiento. Tras este paso, se finaliza troceando dicho fichero en varias partes con extensión .codfirmadas digitalmente para su correcto despliegue.

Analizando el código fuente

Para asegurarnos que el código fuente que estamos desarrollando es totalmente seguro, debemos realizar auditorías de código y en este caso vamos a comentar el análisis estático de código, con el que poder detectar código con potenciales vulnerabilidades.

Una de las principales cosas que se deben mirar, es la utilización de funciones potencialmente peligrosas. Como puede ser la utilización de MD5 (net.rim.device.api.crypto.MD5Digest), o el envío de información sensible sin cifrar (javax.microedition.io.HttpConnection). También se debe observar si el programa guarda información potencialmente sensible en dispositivos de acceso no restringido, como pueden ser las tarjetas SD (Connector.open(“file:///SDCard”)).

Hasta aquí es todo muy bonito, pero ¿qué es información sensible? ¿cómo detectar la información sensible? Desde un punto de vista técnico es complicado determinarlo, ya que depende de la naturaleza del programa y la finalidad para la que se ha desarrollado, información sensible, puede ser cualquier cosa. Sin embargo, es posible asegurar que determinada información siempre será sensible. Por ejemplo, la introducción de un valor mediante el interfaz de usuario del programa en un campo del tipo “password” (net.rim.device.api.ui.component.PasswordEditField).

Ya que los programas de BlackBerry están escritos en Java, es posible utilizar analizadores estáticos de código tales como FindBugs. Sin embargo, este software no está especializado en BlackBerry, por lo que no es capaz de interpretar semánticamente las APIs propias de la plataforma. Esto hace que el número de vulnerabilidades reales no detectadas sea extremadamente alto. Para poder detectar vulnerabilidades, es necesario tener conocimiento de las funcionalidades de las distintas APIs y ser capaces de reconocer, de que manera es posible explotar un fallo originado al utilizar indebidamente dichas funciones.

Ejemplo de vulnerabilidades

Para dejar claro los detalles conceptuales anteriormente explicados, vamos a ver algunos ejemplos de código inseguro que debería eliminarse del código fuente de nuestras aplicaciones.

  • Envío de información mediante una conexión sin cifrar:
import javax.microedition.io.HttpConnection;

byte[] data = postParameters.getBytes(); // Contiene “user=…&password=” try {

c = (HttpConnection)Connector.open(url); // Se establece una conexión no cifrada.

// Set the request method and headers c.setRequestMethod(HttpConnection.POST);

data.append(password); // Se detecta información sensible.

output = httpConnection.openDataOutputStream();

// Se detecta el envío de información sensible por una conexión no cifrada

output.write(data, 0 ,data.length);

  • Utilización de funciones criptográficas inseguras:
import net.rim.device.api.crypto.MD5Digest;

MD5Digest digest = new MD5Digest();

digest.update(password, 0, password.length);

// No se debe utilizar MD5 para generar hash de contraseñas.

byte[] md5Password = digest.getDigest();

  • Almacenamiento de información sensible sin cifrar:
import net.rim.device.api.ui.component.PasswordEditField;

javax.microedition.io.file.FileConnection

// Se detecta información sensible.

private PasswordEditField passwordfield;

String password = passwordfield.getText();

FileConnection fc = (FileConnection)Connector.open(“file:///SDCard”);

// Se guarda información sensible en un dispositivo sin cifrar

// y accesible sin autenticación.

fc.write(password);

Conclusión

Como se ha podido ver, es posible detectar determinado tipo de vulnerabilidades en el código fuente de una aplicación, realizando análisis estático de código. Sin embargo, es necesario tener un conocimiento semántico de la arquitectura a auditar, para poder tener información contextual de la misma y poder seguir el flujo de información de manera adecuada. Con este conocimiento, es posible detectar una gran cantidad de vulnerabilidades que de otra forma sería imposible detectar. También es posible eliminar gran cantidad de falsos positivos generados por simples búsquedas con expresiones regulares.

BlackBerry está evolucionando y actualmente, con la adquisición de QNX, ha abierto sus plataformas a dispositivos como tablets no solo smartphones, además de soportar desarrollo de aplicaciones con HTML5 y Adobe AIR. Esto sin duda amplia la superficie de ataque para estos dispositivos y los desarrolladores tienen que estar bien atentos a todos los posibles vectores de ataques, para poder desarrollar código seguro.

— Follow me on Twitter: @Boken_

DNSSnoopy – Herramienta para hacer DNS Cache Snooping

06/26/12 by alejandronolla | hacking, labs, Networking, tools | No Comments »

A la hora de realizar una auditoría de seguridad el primer paso es obtener y recolectar la mayor cantidad de información posible acerca del objetivo que nos pueda ser de utilidad.

Entre dicha información se encuentran los dominios con los que los empleados de la entidad se relacionan de un método u otro, actualizaciones de software, envío de correos electrónicos, visitas a páginas web, etc.

La utilidad que le podemos dar a esta información es diversa dependiendo del tipo de dominio obtenido:

  • Direcciones de actualización para realizar ataques de evilgrade
  • Dominios de malware para saber si algún equipo está contactando con un servidor de malware (existen multitud de dominios de malware, pero puede ser útil para comprobar algunos en concreto)
  • Un atacante con fines lucrativos podría buscar ciertos dominios “para adultos” con el fin de chantajear
  • Búsqueda de redes sociales y profesionales. Por ejemplo, para buscar en ellas más información acerca de los empleados.
  • Para buscar tus propios dominios y saber si la empresa se ha interesado por tí. Por ejemplo, una entidad de gestión visitando páginas p2p o de detectives privados spacer

La metodología para hacer “snooping” de los dominios cacheados en un servidor DNS es muy sencilla. Debido a la topología jerárquica de DNS, si realizamos una consulta DNS y el servidor consultado no tiene la entrada cacheada (esto dependerá de su configuración, obviamente), escalará la petición a un servidor DNS un nivel jerárquico por encima.

Es precisamente este comportamiento el que nos permite hacer el ataque de “snooping”, en la petición DNS podemos indicarle al servidor que no use recursividad, si no tiene la entrada en su tabla de DNS y/o caché no escalará la petición y devolverá una respuesta negativa. Debido a ello, cualquier petición no recursiva contra el servidor DNS y a un dominio del que no es autoritativo indicará que ese dominio se encuentra cacheado.

Para poder explotar esta vulnerabilidad de una forma sencilla y automatizada he desarrollado la herramienta DNSSnoopy (code.google.com/p/dns-snoopy/). El funcionamiento de la herramienta es el siguiente:

  1. Primero obtiene los servidores DNS del dominio solicitado.
  2. Comprueba si alguno de ellos es vulnerable al ataque de snooping, para ello se solicita un listado de los dominios más comunes hasta que se encuentra alguno cacheado o se acaba la lista.
  3. Si se ha obtenido uno o más servidores vulnerables se procede a probar una lista de dominios que se indique para encontrar los cacheados con anterioridad.
  4. Trata de calcular el tiempo que hace que se cacheó en el servidor vulnerable, para ello compara el TTL obtenido del servidor cacheado con el TTL original.

Os dejo un pantallazo de la herramienta en acción:

spacer

Esperamos que os resulte de interés y utilidad en alguna auditoría o simplemente para trastear, además el código está en Python y es open source, por lo que es muy fácil modificarlo para vuestras necesidades.

Podéis contactar con el autor a través de Twitter: https://www.twitter.com/z0mbiehunt3r

Mejorando los resultados de nmap – La bbdd de payloads.

06/21/12 by alejandronolla | hacking, labs, Networking, tools | No Comments »

Seguro que más de una vez, habéis observado la diferencia de tiempo necesario entre un escaneo de tipo UDP y un escaneo de tipo TCP, siendo el primero mucho más lento que el segundo.

Esto se debe a que UDP es un protocolo de transporte no orientado a conexión, al contrario que TCP. Ello quiere decir que en TCP, antes de mandar cualquier información a otro equipo a través de la red (en redes que usen TCP o UDP como protocolos de transporte), se establece un canal previo con el otro extremo, es lo que se conoce como fase de “three-way handshake”:

spacer

En cambio, cuando se usa UDP como protocolo de transporte, la información se manda sin realizar ningún tipo de establecimiento de canal previo, ni llevar ningún tipo de control de la información que se  pueda estar perdiendo por el camino. Se gana velocidad pero se pierde confiabilidad (en caso de que sea necesario hacerlo, será una capa superior del modelo de red, la encargada de ello).

Cuando hacemos un escaneo con nmap, por defecto se incluyen únicamente las cabeceras de los paquetes sin ningún tipo de carga de “aplicación”, esto es así para enviar menos tráfico y hacer el proceso lo más rápido posible. La desventaja que tiene este método de funcionamiento es, que ciertos dispositivos de seguridad, como un IPS o firewall, pueden descartar el paquete TCP si ven que no tiene carga útil, para ello nmap cuenta con la opción “–data-length” para indicar el número de bytes aleatorios que se incluirán en los paquetes.

Si bien, esto nos puede resultar útil para escaneos de tipo TCP, en escaneos UDP es totalmente inútil, además, la mayoría de los servicios UDP no responderán a un datagrama que no contenga carga útil. Para ello, nmap incorpora ciertos “payloads” para servicios UDP conocidos que se establecen en el fichero “nmap-payloads” (nmap.org/svn/nmap-payloads).

Ahora pongamos un caso útil, necesitamos detectar servidores DNS en un rango de red, para ello podríamos hacer algo parecido a lo siguiente:

spacer

Como vemos en la imagen, únicamente el primer servidor ha respondido con un datagrama, el resto aparecen como “abiertos|filtrados” ya que no se ha podido determinar.

En esta prueba, el payload utilizado es el que viene por defecto “\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”.

Ahora, probamos a capturar otro payload mediante Wireshark, para ello capturamos la petición y en la parte de “Domain Name System (query)” seleccionamos “Copy, bytes, hex-stream” y obtendremos algo así “babd010000010000000000000377777706676f6f676c6503636f6d0000010001”, esto lo pasamos a notación hexadecimal y lo insertamos en la base de datos “nmap-payload”:

udp 53 “\x8d\x78\x01\x00\x00\[…]\x63\x6f\x6d\x00\x00\x01\x00\x01″ (Se ha recortado por motivos de espacio, descuadraba demasiado)

Y volvemos a lanzar el mismo escaneo:

spacer

Como podemos observar ahora, tanto el primer servidor como el segundo, han respondido con un datagrama, habiendo obtenido un puerto abierto más.

Todo es cuestión de probar distintas cargas y quedarnos con la que mejor resultados nos dé, espero que os resulte interesante y de utilidad.

Podéis contactar con el autor a través de Twitter: https://www.twitter.com/z0mbiehunt3r

Analizando el malware Trojan-Spy.AndroidOS.Zitmo.a v1.2.8

06/12/12 by agurbanov | forensic, labs | No Comments »

En otro post hemos visto, de que es capaz nuestro “Galletero” con la versión versión 1.2.3 de Android. Esta entrada, la dedicaremos a la misma familia pero a la última versión con la que hemos chocado últimos días, la versión 1.2.8.

El vichaco es distribuido por las mismas vías que hemos comentado en el post anterior, por SMS, y de la misma manera, haciéndose pasar por una aplicación de seguridad y enviada desde una entidad financiera la que utiliza la víctima.

Esta versión, está un poco modificada, obtiene varias funciones nuevas de la hablaremos un poco más adelante, y un punto de defensa que el desarrollador implementa, que también indicaremos en mas adelante. Iremos paso a paso, y empezaremos por la clase “MainActivity”. Aquí se ha introducido un paso extra para obtener la URL y almacenarla temporalmente en una variable, para después seguir ya con el proceso que viene siendo habitual en versiones anteriores y continuar cargando el resto de las funciones.

spacer

En la clase de “SecurityReceiver” se importan nuevas cosillas como:

  • import java.util.zip.CRC32;
  • import java.util.Random;
  • import java.text.SimpleDateFormat; (antes se importaba el java.util.Date)

Como veis, importa CRC32, curioso eh!? A ver dónde lo utiliza….ah sí, aquí está, asigna una variable global con el valor no modificable.

spacer

Luego utiliza la nueva función llamada “SqlCheckLastSend” donde calcula CRC32 de la URL a la que reporta y la compara con esta constante. Parece que comprueba si la URL es correcta.

spacer

Y ya está, parece que no lo utiliza en ningún otro sitio. Le veo muy poco sentido. Bueno, vamos a seguir.

En esta ocasión, el desarrollador decidió que también quería enviar y almacenar en la BBDD la fecha y hora de los mensajes obtenidos.

spacer

spacer

Como ya sabemos del post anterior, este “Galletero” es capaz de recibir órdenes, bien, pues parece que en esta versión le modificaron un poco la función encargada de interpretarlos. Las funciones como tales, se han quedado intactas, sin embargo los símbolos que interpreta se han modificado, veremos. Antes se recibían estos símbolos: “%”, “:”, “*” y “,”, pues ahora recibe esto: “#”, “/”, “!” y “.”. Donde cada uno de ellos recibe esta funcionalidad:

  • Estos son los comandos que nuestro “Galletero” de la versión 1.2.3 es capaz de recibir:
    • “%” – GET INFO, extrae el número del mensaje y envía el reporte.
    • “:” – Report Number Update, extrae el número del mensaje de texto. Guardar el número, para utilizar éste, como un punto de reporte alternativo y envía el reporte
    • “*” – Uninstall, activa el flag de desinstalación de la aplicación, extrae el número del mensaje y envía el reporte.
    • “,” – Fin de control por mensajes, elimina el número de control alternativo, extrae el número de mensaje de texto y envía el reporte
  • Y estos son los que el “Galletero” de la versión 1.2.8 recibirá
    • “#” – GET INFO, extrae el número del mensaje y envía el reporte.
    • “/” – Report Number Update, extrae el número del mensaje de texto, guardaa el numero para utilizar este como un punto de reporte alternativo y envía el informe.
    • “!” – Uninstall, activa el flag de desinstalación de la aplicación, extrae el número del mensaje y envía el informe.
    • “.” – Fin de control por mensajes, elimina el número de control alternativo, extrae el número de mensaje de texto y envía el informe.

Bueno, seguimos, la clase “ValueProvider” obtiene una nueva función llamada “reverseString”, la cual se encarga de cambiar los caracteres de un string al revés. Para que lo usara…

spacer

A si, aquí esta, la función “GetActivationCode” se ha modificado, bien parece que utiliza la función “reverseString”, vamos a ver. El código de activación ahora es el siguiente, se obtiene en “deviceId” utilizando “reverseString” se le da la vuelta y al final se le añade un “3″.

spacer

Lo demás sigue gestionándose de la misma manera como en la versión 1.2.3.

Parece que el desarrollo de nuestro “Galletero” sigue y veremos más variantes, con más implementación y defensas.

Reference: Malware analysis Trojan-Spy.AndroidOS.Zitmo.a version 1.2.3

MD5: e9068f116991b2ee7dcd6f2a4ecdd141

Analizando el malware Trojan-Spy.AndroidOS.Zitmo.a

06/11/12 by agurbanov | forensic, labs | 1 Comment »

Cada día vemos más y más familias de malware para todo tipo de dispositivos móviles. Esta vez nos hemos topado con una familia que se encarga de interceptar el código del segundo factor de autenticación.

Hoy le dedicamos la entrada a un tipo de malware identificado por Kaspersky como “Trojan-Spy.AndroidOS.Zitmo.a“. Para ser exactos la versión 1.2.3.

Este malware se propaga a través de SMS. En dichos SMS intenta saltarse el factor humano para instalar la aplicación. Lo más curioso es que en los mensajes se indica que se envió desde una entidad financiera, claro está, la que utiliza el usuario.

Interesante verdad, tiene toda la pinta de ser un ataque dirigido.

Veremos un par de ejemplos de los que vimos:

  • “De BancoMovil: [Entidad_afectada] informa: Para la instalación de un programa de criptografía gratis en su teléfono, utilice la siguiente dirección [domain].com/seguridad.apk”
  • “[Entidad_afectada]: [domain].net/androidversion2.apk”

Qué curioso, y lo que nunca falta, la lista de los permisos que solicita nuestra aplicación de cifrado. Claro está, que para cifrar la información hace falta mandar SMS, cambiar el estado de red, etc.

spacer

Manos a la obra, al instalarse nos muestra un escudito bonito, indicando que es una aplicación de seguridad “Android Security Suite Premium”, con un código de supuesta activación. Lógicamente, nosotros nos fiamos, como indica que es “Android Security Suite Premium”, tiene que ser legítima, sin duda.

Bien, el código de activación se genera de la siguiente manera, solicitamos el DeviceID del dispositivo y le añadimos un “1″ al principio y un “3″ al final.

spacer

spacer

El siguiente paso que realiza es arrancar un servicio, recorrer todo el dispositivo en busca de la información, etc. (esto me recuerda al Monstruo de las Galletas buscando galletas y cualquiera se encuentra en su camino, se la zampa)

Bueno, vamos a ver qué funciones tiene nuestro querido “Monstruo de las Galletas” y que es lo que puede hacer y de que es capaz.

Crea un servicio llamado “SecurityService”, la cual es encargada de monitorizar el dispositivo en espera de nuevos mensajes de texto, llamadas, etc.

spacer

Nuestro “Monstruo de las galletas” puede crear, modificar y eliminar alarmas en el dispositivo.

spacer

La siguiente cosita que puede solicitar es la información sobre el tiempo de vida de nuestro dispositivo, es decir el tiempo que estuvo encendido y el que estuvo apagado.

spacer

El bicho es capaz de enviar SMS. Aquí sin comentarios, todo claro.

spacer

Puede ocultar los mensajes recibidos y enviados.

spacer

Otro detalle interesante es que puede extraer números de los mensajes.

spacer

Adicionalmente, es capaz de recibir órdenes. Dependiendo de con que empieza el mensaje, nuestro “Galletero” hace esto:

  • “%” – GET INFO, extrae el numero del mensaje y envía el reporte

spacer

  • “:” – Report Number Update, extrae el numero del mensaje de texto, guardar el numero para utilizar este como un punto de reporte alternativo y envía el reporte

spacer

  • “*” – Uninstall, activa el flag de desinstalación de la aplicación, extrae el número del mensaje y envía el reporte. Mola eh?!

spacer

  • “.” – Fin de control por mensajes, elimina el numero de control alternativo, extrae el numero de mensaje de texto y envía el reporte

spacer

Los reports podrían enviarse por 2 vías: SMS o HTTP. Vamos a ver la estructura en la que nuestro “Galletero” envía los reports:

  • Por HTTP los reports se envían de la siguiente manera “?to=%s&i=%s&m=%s&aid=%s&h=%s&v=%s” donde:
    • to = Número de teléfono del usuario
    • i = IMSI
    • m = IMEI
    • aid = Código de activación generado por nuestro “Galletero”
    • h = 1 si esta en modo Hiden (oculto) o 0 si no lo esta
    • v = versión del “Galletero”

spacer

  • Por SMS el report se envía de la siguiente manera “Model:%s AC:%s H:%d AltC:%d V:%s Mf:%s/%s”.

spacer

Vamos a ver el formato con el que se reportan los SMS recopilados en el dispositivo

  • El envío es similar a “&from=%s&text=%s” donde:
    • from = número de teléfono del remitente
    • text = contenido del mensaje
  • Si el mensaje es último de los que tiene pendientes añade un parámetro más a la petición.
    • &last=1

spacer

Por defecto nuestro “Galletero” espera 180 segundos antes de enviar primer report y un delay de 1500 segundos para cada uno de los siguientes.

spacer

spacer

Si la petición ha fallado en el envío (que no es un 200), la petición se guardar en

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.