Diario de un exploit contra Joomla/Mambo

joomla_snapshot3.pngNota: llevaba bastante tiempo sin actualizar DiarioLinux.com preparando mis clases y peleándome con un proyecto en el que estoy metido. Así que, entre ayer y hoy me he dedicado a escribir un extenso artículo sobre seguridad informática, exploits, SQL Injection y protección (incluyendo un parche para un exploit recién publicado). Espero que os guste.

No sé si el CMS Mambo sigue existiendo como tal tras el fork que dió origen a Joomla en el 2005. De hecho, si entramos en la web principal de Mambo y pulsamos en «Download Mambo» nos encontramos con este mensaje de error al ser redirigidos a http://mamboxchange.com/frs/?group_id=5:»MamboXchange Could Not Connect to Database:»

En cualquier caso, el exploit al que me voy a referir y que acaba de publicar Milw0rm podría funcionar tranquilamente en una instalación Joomla sin actualizar, dado que afecta al módulo SimpleFAQ 2.11 y este módulo funciona tanto en Mambo como en Joomla. Sólo hay que analizar cómo funciona para hacerlo compatible 🙁 Lógicamente este exploit no debería de tener demasiado impacto dado que SimpleFAQ va ya por la versión 2.40 según la web de sus desarrolladores (aunque la primera corrección SQL Injection que se nombra en el ChangeLog corresponde a esta última versión…) y cualquier administrador que se precie debería de tener actualizado su sistema. Lo que es interesante es el proceso que se sigue para poner en marcha el ataque y las connotaciones que ésto tiene. En concreto, el hecho de que el exploit contenga una sóla línea, que se introduce en la URL del servicio a explotar, puede hacerlo devastador:


http://localhost/mambo/index.php?option=com_simplefaq&task=answer&Itemid=9999&
catid=9999&aid=-1/**/union/**/select/**/0,username,password,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/**/from/**/mos_users/*

El vector de ataque es un SQL Injection típico en dicha versión 2.11 de ese módulo (podría ser que en alguna versión superior también). Cuando se ejecuta con éxito, el servidor nos devuelve una lista de logins y passwords en formato MD5. Un ataque de fuerza bruta o mejor aún, una consulta con suerte a las Rainbow Tables y el password se desvelará ante nuestros ojos.

¿Cómo nos hemos enterado del exploit?
Estoy suscrito a varios feeds RSS con exploits de publicación diaria (sigue leyendo…)

La prinicipal: http://www.milw0rm.com/rss.php . Se ha convertido en una rutina, encender el equipo, abrir las pestañas del día y leer los RSS de seguridad. Si alguno de mis servicios está afectado, buscar el parche e instalar. Si no hay parche, leer el código del exploit y parchear a mano o deshabilitar la parte del servicio vulnerable temporalmente. Tengo copias locales de mis servicios web online (no sólo de los de diariolinux.com). Los exploits los suelo probar en local, ver cómo funcionan y cuál es la debilidad que explotan. Se aprende mucho al respecto. Cuando no tengo copia local de alguna aplicación vulnerable que me interesa es cuando recurro a Google. En el caso del exploit para Mambo la búsqueda no podía ser más fácil, dado que el propio autor nos indica la cadena a buscar:

# Dork : inurl:»index.php?option=com_simplefaq»

Si la ponemos en Google, nos dará 72.500 resultados. Supongamos que sólo un 1% está afectado: 725 webs. Probando al azar nos encontramos con que unos supuestos iraníes ya han dejado algún regalito :

defaced_1.png

En otras ocasiones el exploit no funciona como se esperaba, pero arroja un error que muestra el path absoluto físico donde está instalada la aplicación (Path Disclosure), tal y como se puede ver en el siguiente pantallazo (path-disclosure).

path_disclosure.png

La gente de Google sabe perfectamente que su buscador puede usarse con fines malignos, y además, ha actuado en consecuencia. Si detecta que estamos buscando cadenas sospechosas («Powered by Mambo», SimpleFaq 2.11 o el string dork de unos párrafos atrás) nos dejará hacer algunos click (puede que la búsqueda sea con buenos fines), pero si insistimos, nos mostrará un bonito aviso como el siguiente (Google)

Pantallazo_Google_Espia.png

«Lo sentimos… pero en estos momentos no podemos procesar su solicitud. Un virus de ordenador o software espía nos está mandando solicitudes automáticas y, al parecer, su red o su equipo ha sido infectado. Restauraremos su acceso tan pronto como nos sea posible, de modo que vuélvalo a intentar pronto. Mientras, podría ejecutar un programa para la detección de virus o para la eliminación de software espía para tener la seguridad de que su equipo no tiene virus ni otros tipos de software dañinos. Rogamos disculpe las molestias. Esperamos verle pronto de nuevo en Google. »

Veamos cómo se originó todo. Necesitamos el módulo SimpleFAQ en su versión 2.11. En la web del fabricante me ha sido imposible descargarlo, por lo que he recurrido al oráculo y he encontrado que la comunidad de Joomla Spanish tienen ese módulo disponible para su descarga (en la versión que necesitamos)

Bien, abrimos el zip con VIM y elegimos simplefaq.php (sí, has leído bien, con VIM 7 es posible abrir un .zip y automáticamente te muestra un directorio de contenidos, pulsas sobre el fichero que te interesa y se abre en otro buffer). Para aquellos que no conozcan las delicias de VIM también pueden usar el método lento: descomprimir, buscar el fichero simplefaq.php y abrirlo con su editor preferido. ¿Dónde está la miga? Si nos fijamos en el exploit, el parámetro aid está ‘sobrecargado’


&aid=-1/**/union/**/select/**/0,username,password,0,0,.....

En simplefaq.php, vemos que

$answerid = mosGetParam($_REQUEST, 'aid', '0');

Y según la documentación de mosGetParam http://help.joomla.org/content/view/516/155/ al parecer, si magic_quotes_gpc está desactivado, mosGetParam insertará automáticamente contrabarras en las comillas simples, dobles, contrabarras y nulls . Pero en nuestro variable aid no hay ninguno de estos caracteres :-O

$anserid se usa más adelante en la función showAnswers:

function showAnswers($catid, $answerid=0){
[...]
if ($answerid) {
$where[] = " id=$answerid ";
$tableheader = _SIMPLEFAQ_ANSWER ;
}

El $answerid (nuestro parámetro aid) formará parte del where de la consulta SQL que se ejecutará en breve…
Allá vamos:

$dbwhere = (count( $where ) ? ' WHERE '.implode( ' AND ', $where ) : ''); <-- Unimos con AND todas las cláusulas del WHERE // get the total number of records $query1 = " SELECT * FROM #__simplefaq $dbwhere ORDER BY ordering"; <---- buscamos las preguntas/respuestas del FAQ if (!$sf_indexmode) $query1 .= " LIMIT $start,$sf_perpage"; <---- si hay que paginar usar LIMIT x,y $database->setquery($query1); <---- preparar la consulta $result1 = $database->query(); <---- ejecutar (!)

Las pruebas también las he hecho con DVL (Damn Vulnerable Linux) (http://www.damnvulnerablelinux.org), que viene con Joomla 1.0.9 preinstalado (una vieja versión con fallos de seguridad). Como bien sabe el lector DVL es una distro con la misión de enseñar con casos reales problemas de seguridad informática. Estoy terminando un artículo al respecto que publicaré en una revista Linuxera, con detalles de 3 ataques a aplicaciones web. Como podemos ver en la siguiente imagen, Joomla 1.0.9 no es vulnerable al exploit tal cual (preparado para Mambo, no para Joomla).

joomla_snapshot1.png

Sin embargo, si analizamos la consulta generada (ver siguiente imagen) nos damos cuenta de que el exploit no es compatible dado que en Joomla el prefijo de las tablas es jos_ y no mos_.

joomla_snapshot2.png

Cambiando ese prefijo... el exploit se ejecuta correctamente en Joomla (ver siguiente imagen... ah! nos os molestéis en crackear el md5, ya os doy yo el resultado: el password de root en DVL es toor).

joomla_snapshot3.png

Ahora viene la parte que muchos se dejan en el tintero (incluso la web de Metasploit no indica la forma de parchear. Tampoco en SecurityFocus ) : LA SOLUCIÓN.

Si nos fijamos en el código anterior, la solución no es difícil , máxime teniendo en cuenta que _en el propio manual de la función mosGetParams se nos indica que
si queremos asegurarnos de que lo que tratamos es un número entero (y no una cadena SQL tan grande como un elefante) basta con indicarlo así:

$answerid = intval ( mosGetParam($_REQUEST, 'aid', '0') );

De esta forma si lo que hay en la variable aid no es un número, intval lo convertirá en 0, y el exploit deja de funcionar. Una sóla línea, un descuido en la programación, hace que más de 700 webs de todo el mundo se hayan dejado las puertas de administración abiertas de par en par.

Actualización (22/08/2007): acabo de ver que ha salido el exploit para Joomla con la actualización que indico en este artículo. Si usas SimpleFAQ en tu instalación Joomla/Mambo asegúrate de cambiar la línea que he indicado antes o te arriesgas a tener un bonito defacement en menos de lo que canta un gallo.

Actualización (23/08/2007): si este artículo te ha parecido interesante, anímate y menéalo un poco.

6 comentarios en «Diario de un exploit contra Joomla/Mambo»

  1. Pingback: meneame.net
  2. Alucinante 😉 en la primera que he probado me ha devuelto los passwords (encriptados) de admin y de prueba, como soy de gorro blanco no tengo ni idea de desencriptar eso, pero es alucinante como descubren errores esta gente.

    Gracias Juanan por darme la pagina de los exploits, ahora mismo me la pongo en el lector rss.

    Saludos.

  3. La verdad es que es efectivo 100%, lo digo de primera mano. Enhorabuena por el articulo, me ha gustado y sobre todo me gusta el enfoque didactico que le das y el tirón de orejas a los admins. 🙂

  4. Muy buen artítulo de pies a cabeza, lo probé y pude ver la facilidad con que volcaba los passwords.
    Agradezco vuestro aporte, soy un fanático de este sitio.

  5. Que tal… Felicitaciones por el artículo y por el sitio, aquí estoy investigando las situaciones de seguridad y por lo que veo, voy a ser un asiduo lector a tu página para ponerme al corriente y por supuesto seguir aprendiendo.

    Tengo una pregunta que a la fecha nadie me ha podido o no ha querido contestarme, ojala pudieras orientarme.. tengo un sitio con joomla (1.0.12), inicialmente había leído que magic quotes debería estar apagado.. posteriormente que debería estar activado.
    Por lo que he leido entiendo que a la fecha debe estar activado para evitar la inserción de algun código a la base de datos.

    Solo que tengo un problema .. al activarlo he notado que la web se vuelve lenta en algunos ordenadores… tarda a veces mas de 10 segundos en cargar, en otros no es tan lenta pero si tarda un poco.

    Si desactivo las magic quotes, esta bastante rapida.
    La forma de activarlas es por medio del .htacces, habrá alguna otra opción para activarse y que no se alente tanto la web??

    Muchas gracias de antemano.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.