Blind SQL Injection en WP-Forum 1.7.4
¿Ayer os anunciaba una especie de venganza hacia el WoW y hoy os vengo con un fallo de seguridad?
La cosa es que en estos ratos en los que me pongo a investigar y a mirar cositas descubrí un fallo de seguridad (más bien muchos…) en un plugin de wordpress llamado wp-forum. Indagando sobre el tema llegue al blog del creador del plugin de donde puede uno descargarse el código fuente del mismo. Resulta que el tío hace más de un año que no toca su código (a pesar de existir ya otra vulnerabilidad publica) porque tiene toda la pinta que se pasa el día jugando al WoW. Y como se que aunque le escriba un correo avisándole el tío va a pasar, pues os lo cuento por aquí, asi lo pueden leer las mas de 22 mil personas que usan este plugin.
El código en si es bastante malo. No comprueba ningún parámetro y las únicas comprobaciones son en el caso que WordPress las realice. Dando una vuelta se llega al fichero forum_feed.php, que presenta una serie de líneas que os pongo a continuación:
if(isset($_GET['user']))
$posts = $wpdb->get_results("SELECT * FROM $table_posts WHERE thread_id IN ($f) ORDER BY `date` DESC ");
else
$posts = $wpdb->get_results("SELECT * FROM $table_posts WHERE thread_id = $_GET[thread] ORDER BY `date` DESC ");
Este código es claramente vulnerable. ¿Por qué? Pues porque recibe directamente el parámetro thread desde la url y lo introduce en la consulta.
¿Qué podemos hacer con esto? Pues así rápido esta el tema del Blind SQL Injection, con añadir tras la consulta AND 1=0 o AND 1=1 comprobamos que la página que nos devuelve es diferente, y por tanto vulnerable a esta técnica. Evidentemente las preguntas que deberíamos de hacer serian más interesantes que igualdades numéricas, cosas como: AND (SELECT Count(*) FROM wp_users) > 10, lo que nos diría si en el blog existen más de 10 usuarios registrados.
Luego, y aprovechando el bucle foreach que tenemos unas líneas más abajo, podemos ejecutar el clásico SQL Injection mediante el UNION. ¿Cómo se hace esto? Vamos a verlo.
En SQL podemos ejecutar dos SELECTs en la misma sentencia mediante el comando UNION. Para que esto sea válido y el motor de base de datos pueda traerse registros validos tenemos que seleccionar el mismo número de campos en la primera y en la segunda SELECT.
Vamos a saltarnos un poco el proceso de investigación (vosotros, yo no
) y ya sabemos cómo se llama la tabla de los usuarios (wp_users), el campo donde se guarda el nombre del usuario (user_login) y donde se guarda el MD5 (user_pass) de su contraseña. Ahora pensemos como podemos traernos TODOS los usuarios de la aplicación junto a sus respectivos usuarios:
X UNION SELECT user_login,user_pass FROM wp_users/*
Aquí (si sois muy rapidillos) os dará fallo. ¿Y eso? Resulta que en la sentencia contenida en el código se hace un SELECT de todo (*) y nosotros solo hemos especificado dos campos, así que tenemos que probar cuantos campos tiene y sobre todo en qué posición se muestra cada uno. Al final la sentencia quedaría así:
-1 UNION SELECT user_login,user_pass,3,4,5,6,7 FROM wp_users/*
Y nada más… ¡a crackear!
Ahh! Y si alguien juega al WoW y conoce al chaval que lo avise
P.D. El fichero wp-forum-manage.php tiene una pinta exquisita… Pero ese ya os lo dejo para que saqueis nota.
Deberías invitar a la gente a que se parchee o lo elimine, no a hacer el mal.