El ataque de eu2010.es en otra web de la administración

Mucho revuelo se ha armado con el ataque a la web de la presidencia europea de turno. Llegó incluso a estar en la portada de El Mundo (edición impresa).

Por su parte, desde la Secretaría de Estado de Comunicación reiteraron que la página no ha sido alterada por ningún intruso, ya que la imagen mostrada en el engaño ha sido cargada desde un servidor remoto y no es posible acceder a ella usando normalmente la web.

Y la verdad es que, aunque 11,9 millones por adaptar un OpenCMS y darle mantenimiento y “seguridad” es el robo del siglo, hay que admitir que el error era del propio OpenCMS (el gestor de contenidos que utilizan… que no es PHP :-P ), y además un XSS, si no se utiliza para robar cookies o hijacking es prácticamente inofensivo.

No obstante, este error de principiante no es el único pecado de Telefónica (o de la cárnica que haya subcontratado para el proyecto). Santi Saez nos desvela que la web fue alojada en un servidor con un sistema operativo obsoleto (Debian 4), el panel de control Plesk accesible públicamente, el SSH accesible públicamente y permitiendo el login a root y un BIND (servidor de DNS) vulnerable. Además, el servidor de nombres no era dedicado. Ahora han intentado arreglarlo externalizando el hosting en Akamai.

Pero no nos desviemos del tema, que es explicar cómo funciona esta vulnerabilidad, y cómo explotarla en otra web de la administración que todavía no ha parcheado el OpenCMS.

Qué es XSS

Un ataque XSS o cross-site scripting es una vulnerabilidad de aplicaciones web que consiste básicamente en conseguir que en la página víctima se cargue un script de otro sitio. Como sabemos que los scripts (casi siempre JavaScript) se ejecutan en el navegador del cliente, es evidente que este ataque no va a alterar el servidor en nada.

Pero ¿cómo hacer que una página cargue un script? Para buscar vulnerabilidades XSS y cualquier otra vulnerabilidad web es esencial que encontrar puntos de entrada de datos por parte del usuario. Estas puertas por las que introducimos datos suelen ser:

  • URL (casi siempre parámetros): la dirección de una página la introducimos nosotros y la interpreta el servidor. Habitualmente suelen dar más juego los parámetros (en PHP, lo que se obtiene con $_GET[]). Es el que usaremos en nuestro caso práctico.
  • Formularios: en los formularios de login, búsqueda, etc se nos piden datos que después el servidor interpreta. Por aquí se suelen colar las inyecciones SQL, otro ataque que veremos en futuros posts y que puede llegar a ser muuuuy peligroso, a la vez que sencillo.
  • Cabeceras: son manejadas por los servidores. No suelen dar problemas, porque los desarrolladores web no suelen tocar ahí ;-)
  • Cookies: más complejas y difíciles de atacar, aunque pueden llegar a ser también muy peligrosas (autenticación falsa, etc). Es un tema interesante para un futuro post.

Pues bien, entremos en materia. Imagina un formulario de búsqueda de una web cualquiera. Hay un cuadro de texto en el que tú introduces una palabra, por ejemplo, ‘normativas calidad’ porque quieres buscar las normativas de calidad de un organismo público. Cuando pulsas “buscar”, aparece una página de resultados en el que arriba dice “se han encontrado x resultados para ‘normativas calidad’”. Es decir, repite lo que le has dicho. Ha puesto en la página lo que tú habías introducido en el cajetín de búsqueda.

Vale, pero ¿y si en lugar de ‘normativas calidad’ pones ‘<img src=”http://bean.com/mister-bean.jpg”>’? En teoría la página debe repetir lo que has escrito. Si la web no está protegida, entonces verás una linda foto de Míster Bean en la página de resultados, ya que el navegador interpreta el HTML que has introducido y el buscador ha repetido. Acabas de inyectar HTML, pero no has manipulado el servidor. Esa foto de Míster Bean la ves tú en tu navegador y nadie más.

Si en lugar de HTML plano introduces un script (bien por invocación bien por introducción directa del código), ese script se ejecutará en el navegador, y podrás manipular los elementos de la página, hacer redirecciones… lo que quieras, pero siempre sabiendo que eso se está ocurriendo en tu navegador y sólo en tu navegador.

En los formularios de búsqueda —como ocurrió con eu2010.es— esto no constituye un peligro real para la página (aunque si el sitio es famoso o asociado a política no te dará muy buena imagen), pero si esta inyección la introduces en un cuadro de texto para publicación (un foro, un comentario en un blog, etc), entonces las manipulaciones que hagas las verán todos los que accedan a esa página, y eso ya empieza a ser peligroso.

Tutorial para ser hacker en 5 minutos

Vamos a ver este ataque en la práctica. La web del Centro de Investigaciones Sociológicas, construida sobre OpenCMS, tiene un lindo buscador. Si introducimos una palabra clave como “hola mundo”, la página de resultados repetirá nuestras palabras como un loro:

Página de resultados de búsqueda

Aquí tenemos el código fuente:

Primer fallo... no poner comillas para los valores, como exige el estándar HTML. Bueno, más fácil nos lo ponen. Si en lugar de 'hola mundo' ponemos '>hola mundo <', entonces el código generado será
<input class="txt" type="text" size="15" name="query" value=>hola mundo <>

Lo que acabamos de hacer es inyectar código cerrando la tag input con el símbolo '>', y el resultado será que vemos el texto box de búsqueda vacío y nuestro mensaje, 'hola mundo' a su lado. Bien, vamos a divertirnos. Si introducimos '><script>alert("Hola mundo")</script>' inyectamos HTML con un JavaScript (la función alert() muestra un mensaje emergente), que se ejecuta con el siguiente resultado:

XSS con un alert() en JavaScript

Hala, ya somos super-hackers de la CIA —voy corriendo a publicarlo en Meneame :-P —. Ah, no, todavía nos falta el "golpe final", introducir la imagen de Mr. Bean. Ahora simplemente inyectamos una imagen (habiendo cerrado previamente la tag input con el signo '>'):

 ><img src="http://blog.tmcnet.com/blog/tom-keating/images/mr-bean.jpg"> 

Mr. Bean en la web del CIS

Si aparece repetida es porque en la página de resultados se muestra el mensaje de "buscar otra vez" en varios idiomas.

(Lo que viene ahora no es muy importante): hay una particularidad en este caso, y es que, nuestra inyección la podemos hacer tanto con la casilla de búsqueda (es decir, enviando el formulario por POST) como introduciendo el parámetro query —el nombre del campo de texto— en la propia URL (es decir, haciendo petición GET). Esto ocurre porque los servlets—eso que se utiliza en Java para hacer aplicaciones web— mete en el mismo "saco" (el método getParameter()) los parámetros introducidos por formularios y URL. Eso, combinado con la mala práctica de poner doPost en doGet y viceversa —o sea, decirle a Java que haga lo mismo para las peticiones GET y POST— hace que podamos inyectar código no sólo a través del campo de texto de búsqueda, sino también desde la URL. Así podremos distribuir nuestro super-hackeo a nuestros amigos, y al igual que pasó con eu2010.es, decir/tuitear...

¡Mira, mira! ¡Mr. Bean también se fue al CIS! http://is.gd/679lU

¿Cómo prevenir esta vulnerabilidad?

Si eres webmaster o desarrollador, ve y corre a comprobar si tus webs son vulnerables a este ataque. En caso de que hayas recibido una desagradable sorpresa, no tranquilizará saber que prevenirlo es tan sencillo como filtrar con una función la entrada del usuario. Imaginemos que tenemos un buscador en PHP que recibe las palabras clave por un formulario y un campo de texto llamado "busqueda". Si en nuestra página de resultados tenemos algo como

Se han encontrado <?php echo $numero_de_resultados ?&gt; resultados para &lt;?php echo $_POST['busqueda'] ?>

sólo tendremos que sustituirlo por

Se han encontrado &lt;?php echo $numero_de_resultados ?&gt; resultados para &lt;?php echo htmlentities($_POST['busqueda']) ?&gt;

...y estaremos a salvo (más información sobre htmlentities()). Aunque hay métodos más sofisticados y completos, este funciona muy bien, ya que sustituye los caracteres especiales de HTML en sus entidades correspondientes, de tal forma que el atacante no verá su código interpretado, sino mostrado tal y como lo escribió.

Moraleja

¡No te fíes de los usuarios! Filtra todas las entradas (¡todas! formularios, URL, etc). Si esperas un valor numérico en un campo de texto, comprueba que es un número; si esperas una dirección de email, comprueba que es un email (pero con expresiones regulares ¿eh? nada de cosas raras).

Conclusión

Vivimos en la era del ladrillo, y en contra de lo que nuestros torpes políticos digan, el modelo de negocio del ladrillo no sólo no ha muerto, sino que se ha extendido como un cáncer hacia la industria informática. Nuestro negocio está lleno de gente con talento que cobra poco, y políticos corruptos que chupan generosas subvenciones y concursos públicos de una administración a la que no le importa malgastar un dinero que nos pertenece a todos.

Como dice un amigo... en España la ingeniería informática tiene tres principales salidas: por tierra, mar y aire.

Primeras experiencias con WordPress… y muchas nueces ;-)

Web de Nueces San Ignacio
Todo desarrollador web debe saber trabajar con uno o varios sistemas de gestión de contenidos (CMS). Estos programas nos ahorran reinventar la rueda cada vez que tenemos que publicar contenidos en la web, gestionar usuarios y la administración del sitio, organizar nuestro código de acuerdo a un estándar, etc, etc, etc.

Personalmente siempre he sido aficionado a los CMS, pero a nivel de usuario. Me encanta conocer y probar los gestores de contenido, aunque hasta hace poco no había desarrollado proyectos —proyectos de verdad— con una de estas herramientas, por vagancia para afrontar la curva de aprendizaje y por afán de reinventar la rueda (puede ser divertido y muy pedagógico, pero no es práctico si queremos buenos resultados).

El caso es que hace un par de meses comencé un proyecto web para un amigo que cultiva nueces y me animé a probar WordPress, animado por la experiencia de los chicos de Atracciona, que utilizan este gestor de blogs para hacer webs corporativas. Mi proyecto era dar presencia web a la Nueces San Ignacio y captar clientes a través de Internet, por lo que a nivel técnico las exigencias eran mínimas (unas cuantas secciones de texto rico, fotos, un formulario de contacto y poco más).

La experiencia con WordPress ha sido impresionante. A pesar de que no me gustan sus tripas (algunos fragmentos de código son verdadero spaghetti code), diseñar un theme con WordPress es increíblemente fácil y rápido. Una vez tuve el diseño en HTML/CSS, pasarlo a WordPress fue cosa de una noche. No toma más esfuerzo que copiar un tema (por ejemplo, Kubrick) e ir modificando las plantillas, adaptando el CSS y cambiando el marcado que sea necesario.

El resultado, una web corporativa con un panel de administración muy potente, la disponibilidad de miles de plug-ins y el respaldo de un software probado en millones de servidores.

Logo de Nueces San IgnacioMás allá de la programación, también diseñé la web, el logotipo —y las tarjetas de visita, y un dossier comercial, todo ello con software libre e imágenes libres— y todo lo relativo a márketing en redes sociales, SEO y SEM. Y aunque el mercado en el que se mueve la empresa no depende en gran medida de Internet (el objetivo es vender toneladas de nueces, y el público objetivo hoy en día son distribuidores y grandes superficies), poco a poco la estrategia web va dando fruto. La experiencia ha sido gratificante, porque no es lo mismo hacer un proyecto para un cliente (con la exigencia de calidad y la concentración de sólo programar) que para un amigo (he tenido total libertad para diseñar, desplegar, redactar, etc). Te lo tomas con más calma, le dedicas las horas que puedas y el resultado acaba siendo muy satisfactorio, porque de un modo u otro me he involucrado en la empresa.

Conclusión, WordPress es un muy buen gestor de blogs que también puede ser usado como gestor de contenidos genérico para sitios web pequeños, con una rapidez en la creación de themes que nunca antes se había visto. No obstante, cuando tenga tiempo he de revisar otros CMS para sitios web corporativos. Hace algún tiempo probé CMS Made Simple, pero no me convenció. Sin embargo, MODx promete bastante.

Cuestiones todas a resolver en 2010. Feliz Navidad y que el año que se avecina sea el mejor de tu vida :-)

Introducción visual a jQuery

Hace unos días impartí un breve taller de introducción a jQuery a mis amigos del SAW. El taller está pensado para durar unas cuatro o cinco horas, con ejemplos prácticos y casos reales, de forma que el asistente salga conociendo las posibilidades de jQuery y su aplicación en la vida real. Aquí tienes la presentación visual que complementa el taller (hecha con Prezi):

El taller está orientado a diseñadores web y programadores con conocimientos básicos de JavaScript y HTML. Así que si tú y tu equipo queréis aprender jQuery en un día, decidle a vuestro jefe que me contrate ;-)

Qué dice el creador de la Web sobre la “Web 2.0″

Web 1.0 was all about connecting people. It was an interactive space, and I think Web 2.0 is of course a piece of jargon, nobody even knows what it means. If Web 2.0 for you is blogs and wikis, then that is people to people. But that was what the Web was supposed to be all along.

Tim Berners-Lee

Desde luego, el mejor remedio contra la manipulación es la información. El que quiera entender, que entienda.

ACTUALIZACIÓN (16 de diciembre):

Traduzco (libremente y sin garantías) la cita para mayor claridad:

Todo lo que trataba la Web 1.0 era de conectar personas. Era un espacio interactivo, y creo que hablar de Web 2.0 es, por supuesto, una cuestión de jerga, nadie sabe lo que significa. Si Web 2.0 es para ti blogs y wikis, entonces es conectar personas. Pero eso es lo que la web siempre ha sido.