martes, 7 de octubre de 2014

The Walking WordPress [I]: defeating security plugins

¡Saludos!

   Tal y como adelanté en el congreso Navaja Negra iré esta semana ampliando y/o aclarando puntos de la ponencia y soltando por aquí todo el código para que podais hacer pruebas en local. Las slides las publicaré hoy o mañana, según  me vaya el internet (estoy teniendo problemas con WiMax). El orden de publicación va a diferir del cómo fue expuesto en la charla.

  Para aquellos despistados que no estuvieron en el Navaja Negra: esta serie de posts trata de cómo crear malware en PHP orientado a WordPress con capacidad autoreplicativa (es decir, que un WordPress infectado pueda infectar otro que esté sano) a través de la explotación de vulnerabilidades en plugins. Todos los WordPress infectados conformarán una botnet controlada desde un panel central desde el cual podremos dirigir ataques organizados.

   Introducción


    El worm que vamos a generar necesitará editar archivos del core y al plugin Akismet. Los plugins más famosos de seguridad (iThemes Security, WordFence...) implementan una característica que ellos denominan como "Monitorización de la integridad de los ficheros", que en resumidas cuentas consiste en comprobar si algún fichero ha sido modificado. En caso de que se detecte tal variación -que puede ser indicativo de backdoorización- se emite una alerta al administrador.

  El problema de utilizar plugins del propio WordPress para realizar esta tarea radica en que cualquier archivo PHP puede modificar el comportamiento de un plugin, así como la base de datos. Por lo tanto:

-Si un archivo del core ha sido modificado es porque el atacante tenía permisos de escritura.
-Si tiene permisos de escritura, puede editar el PHP del plugin de seguridad
-Además puede editar la DB.


Veamos más en profundidad cómo trabajan los principales plugins (ordenados por descargas totales)

iThemes Security (3 Millones)


     iThemes Security (anteriormente conocido como Better WP Security) es de largo el plugin de seguridad más usado y recomendado para WordPress. De entre sus multiples características, una de ellas es la de comprobación de que no ha habido modificación en ningún archivo.

    Para realizar la comprobación de si un archivo ha sido modificado o no, iThemes guarda un listado de hashes, nombres y fechas de todos los archivos del WordPress cada vez que se realiza un escaneo. En cada escaneo se compruebe si ha habido alguna variación con respecto al anterior. Para bypassear este plugin existen dos métodos: el ninja (consistente en editar el campo de la base de datos donde se sitúan esos hashes con el nuevo hash generado al editar un fichero) o el método rápido.


  Observando el panel de administración de iThemes Security (en concreto el apartado dedicado a la monitorización de archivos) nos damos cuenta de que tanto las alertas mostradas en el dashboard del admin como las alertas al e-mail pueden desactivarse



  Esta configuración se encuentra almacenada en un campo llamado "itsec_file_change" en la tabla wp_options, cuyo valor (dependiendo de la configuración que tengamos) es:

a:9:{s:7:"enabled";b:1;s:6:"method";b:1;s:9:"file_list";a:1:{i:0;s:0:"";}s:5:"types";a:7:{i:0;s:4:".jpg";i:1;s:5:".jpeg";i:2;s:4:".png";i:3;s:4:".log";i:4;s:3:".mo";i:5;s:3:".po";i:6;s:4:".php";}s:5:"email";b:1;s:12:"notify_admin";b:1;s:5:"split";b:0;s:10:"last_chunk";b:0;s:8:"last_run";i:1410341351;}
   Como se puede observar, tenemos dos campos interesantes: "email" y "notify_admin". Echando rápidamente un ojo al código de iThemesse nos damos cuenta de que estos dos campos hacen referencia a las notificaciones por e-mail y a las alertas en el dashboard. Entonces la cosa queda fácil, tan sólo tendremos que modificar esos campos y ponerlos como "false" (bool 0).

    Una de las cosas mágicas de WordPress es que podemos utilizar su propia API (tan sólo debemos de localizar el archivo wp-load.php y hacerle un require() ) para acceder rápidamente a la tabla wp_options y editar las opciones. Incluyendo estas pocas líneas en el malware podremos conseguirlo:

//Para usar get_option deberemos de hacer un require() a wp-load primero
$o = get_option("itsec_file_change");
$o['email'] = FALSE;
$o['notify_admin'] = FALSE;
update_option("itsec_file_change",$o);


WordFence (3 Millones) y Acunetix (2 Millones)

     El plugin por excelencia para la monitorización de los archivos. En este caso la comparación de los ficheros se realiza con respecto a los checksums que provee una API online de WordPress. Al analizar el funcionamiento vemos que se trata de un método muy robusto y que a diferencia de iThemes no podríamos bypassear usando el "método ninja" (no podemos modificar los checksums contra los que comrpueba ya que -en principio- no podemos editar la respuesta que le devuelve la API) por lo que debemos de buscar alguna debilidad en la lógica de funcionamiento.

    Si no puedo evitar que el plugin detecte que hay una discrepancia en el source de algún archivo, al menos puedo evitar que muestre las alertas y hacer que siempre diga que todo va bien. WordFence guarda todas los errores encontrados en una tabla llamada llamada wp_wfissues (lógicamente "wp_" variará según el prefijo designado en wp-config.php).

  Lo que deberemos de hacer en este caso es tan simple como vaciar esta tabla cada vez que un visitante entre en la página, de tal forma que el admin nunca pueda ver el mensaje de alerta:

//Do a require() to include wp-config.php first$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);mysql_select_db(DB_NAME);$query = "truncate ". $prefix ."wfissues;";mysql_query($query);


  Para que se ejecute cada vez que alguien visite la web podemos acoplarlo a un hook (wp_footer, por ejemplo) de tal forma que contínuamente se vacíe la tabla y el admin nunca pueda verlo.

  Esta misma técnica funciona con acunetix, tan sólo se debería de cambiar el nombre de la tabla.


Sucuri (450 Mil)

  Actualmente Sucuri es mi plugin de seguridad preferido (desconozco porqué tiene tan pocas descargas) y realmente realiza muy bien todas las tareas. Aquí debemos de embarrarnos, teniendo que editar una línea de código.

  La porción de código encargada de obtener los checksums que provee la API online de WordPress es este:

    public static function get_official_checksums( $version=0 ){        $url = 'http://api.wordpress.org/core/checksums/1.0/';        $response = self::api_call( $url, 'GET', array(            'version' => $version,            'locale' => 'en_US',        ));

   El problema radica en que si nosotros en el parámetro "version" le prefijamos un valor inexistente (999999), el API nos devolverá un "false" y sucuri en vez de indicarnos que la versión es inexistente, símplemente nos mostrará el mensaje de que ningún archivo ha sido modificado:



   Para ello podemos copiar el código actual del .php en un archivo temporal, editando con un regex para modificar 'version' => $version por 'version' => 999999, y después sustituirlo por el original.




Byt3z



5 0verl0ad Labs: The Walking WordPress [I]: defeating security plugins ¡Saludos!    Tal y como adelanté en el congreso Navaja Negra iré esta semana ampliando y/o aclarando puntos de la ponencia y soltando por ...

No hay comentarios:

< >