sábado, 5 de enero de 2013

Ataques SSRF en servicios de conexión online

Actualización 17/01/2013: La empresa ha dado de baja el servicio afectado por el fallo de seguridad. Nunca obtuve una respuesta reconociendo el reporte.

Antes de nada, quiero decir que la empresa afectada por la vulnerabilidad que se va a exponer en este post fue avisada en dos ocasiones. En la primera, obtuve la respuesta de un técnico de soporte invitándome a explicar mejor "mi problema", a pesar de facilitar ejemplos en los que se accedía con un click a ficheros internos del servidor. En el segundo aviso hice incapié en la gravedad del fallo, indicando que la información debía ser redirigida al equipo de desarrolladores o sysadmins. No volví a obtener respuesta.

El término SSRF (Server Side Request Forgery), sin confundirlo con CSRF, hace referencia de forma genérica a una serie de ataques con unas características comunes. Un servidor vulnerable a SSRF permite a un atacante redirigir paquetes a hosts o puertos de manera que se puedan eludir restricciones impuestas inicialmente a los usuarios y realizar acciones no previstas, abusando de la confianza que el sistema tiene en el propio servidor.
Un ejemplo claro de un servicio susceptible a este tipo de ataques es una web que incluya un campo para introducir una URL a la que el servidor vaya a conectar para realizar una tarea. Una de las preguntas que debe surgirnos siempre como pentesters en esta situación es, ¿el servidor conectará a cualquier host y puerto que facilitemos en la URL incluyendo a él mismo o a hosts de la Intranet?. Si la respuesta es sí, estamos ante un posible grave fallo de seguridad.

La empresa Zoho dispone de una gran cantidad de servicios en la nube, con más de 7 millones de usuarios. Uno de los servicios gratuitos que ofrece es un visor de archivos online en https://viewer.zoho.com. Dispone de dos modos para visualizar documentos. El primero, subiendo un archivo desde local y, el segundo, el que nos interesa, indicando una URL donde se encuentre el archivo que queremos que nos muestre.

https://viewer.zoho.com

A su vez, la modalidad de URL puede usarse a través del formulario o a través de una API. Como el formulario incluye algunas validaciones javascript (esto ya iba dando mala espina), nos centraremos en la API por comodidad. Su forma de uso es la siguiente:

http://viewer.zoho.com/api/urlview.do?url=url_de_su_documento

Lo primero que detecté fue que mediante esta API podía introducir una URL del tipo file:///archivo y que el servidor devolvía páginas de error distintas para archivos UNIX conocidos y para archivos inventados:

https://viewer.zoho.com/api/urlview.do?url=file:///etc/passwd


https://viewer.zoho.com/api/urlview.do?url=file:///etc/sdferg

Después de la primera prueba, pensé que quizá algún tipo de WAF podría estar restringiendo el acceso a ciertas rutas como /etc/passwd, pero tras intentarlo con un  número mayor de archivos  "menos usuales" comprobé que el comportamiento era el mismo: si el archivo existe en el sistema, obtenemos un error del tipo "Ocurrió un error en el servidor al procesar su solicitud", con lo que de alguna manera sí que se está accediendo al sistema de archivos interno.
Lo siguiente que pensé fue que quizá el visor basaba su comportamiento en la extensión del archivo, y el problema para que no apareciera su contenido era que los ficheros pasados como parámetro no tenían extensión. Así que, ¿qué tal si probamos a añadir al final de la URL un "?.txt"? ¡Bingo!

https://viewer.zoho.com/api/urlview.do?url=file:///etc/passwd?.txt

No sólo se puede acceder a los ficheros, también se puede navegar por las rutas del sistema usando URLs del tipo 
https://viewer.zoho.com/api/urlview.do?url=file:///etc/?.txt
https://viewer.zoho.com/api/urlview.do?url=file:///usr/?.txt
...
etc.


Aunque las formas y el resultado del ataque son parecidos a un LFI, no se considera como tal, ya que no se está haciendo una inclusión mediante código fuente del archivo indicado en el parámetro, sino que se está procesando en el funcionamiento normal del servicio una URL interna que debería estar restringida. Con la misma idea, se puede por ejemplo intentar conectar a IPs de la Intranet, probar distintos puertos analizando los distintos mensajes de error o, incluso, provocar una denegación de servicio mediante /dev/random. Las posibilidades del SSRF son muy amplias.

Saludos!