¡Hola a todos! Hoy os traigo una publicación en la que os voy a enseñar cómo he encontrado algunas vulnerabilidades y he obtenido el CVE-2023-24622 en una librería anti-SSRF llamada safeurl-python.
En diciembre, Portswigger hizo una publicación hablando sobre la librería anti-SSRF para Go que había desarrollado Doyensec, una librería que ya conocía porque vi la publicación de la empresa el día que la sacaron y porque estuve revisando el código en busca de alguna vulnerabilidad sin tener suerte.
En el artículo se menciona que habían llevado a cabo el desarrollo porque en otros lenguajes hay librerías con el mismo propósito pero que querían ofrecer una alternativa para Golang y daban como referencia dos librerías que fueron las que les dieron la idea de desarrollar la suya, una era safeCURL para PHP y la otra safeURL para Python, de la que vamos a hablar.
Cuando vi que una de las librerías que habían usado de referencia era en Python y al ser un lenguaje en el que me siento más cómodo que en Go, eché un vistazo al código para ver un poco como funcionaba.
CVE-2023-24622. Bypass del filtro de dominios
Abrí el archivo desde el móvil, que era donde estaba leyendo el artículo, para echar un ojo rápido y empecé a bajar leyendo por encima el código cuando vi una regex que me llamó la atención.
Veo que compara el dominio al que se está intentando hacer la petición con todos los de la lista que define el usuario, pero hay algo raro. La regex tiene el símbolo "^" obligando a que el valor introducido empiece con el dominio que va obteniendo de la lista de la configuración, pero no se define su final (correspondería al símbolo "$" en la expresión regular). Esto hace que se pueda alargar el valor del dominio al que queremos enviar la petición tomando como base uno definido en la lista blanca.
Este error en la expresión regular permite a un atacante hacer pasar un dominio malicioso por el filtro de la lista blanca correctamente.
Imaginad que tenemos dentro de la lista blanca "victim.com", la regex resultante que se ejecuta sería "(?i)^victim.com" y es cierto que "victim.com" haría match con la regex, pero como no se define el final (y como el punto del ".com" no se escapa), otros valores posibles que hacen match con esta regex serían "victimacomattacker.com", o "victim.com.attacker.com" por ejemplo.
Probé la regex en local y vi que se podía explotar como había interpretado.
Mandé un mail a la empresa que creó la librería (Include Security) para reportarles la vulnerabilidad, ya que quería reportarla a MITRE para que asignasen un CVE y primero quería consultarles a ellos por si querían arreglarla aunque pareciese que no mantenían ya la librería ya que su última actualización era hace unos 6 años. Me contestaron muy rápidamente para agradecer el aviso y me dijeron que a la semana siguiente me confirmarían la vulnerabilidad por su parte y darían arreglo.
DNS rebinding
Cuando encontré la primera vulnerabilidad hablé con Rolo (muchas gracias desde aquí por la ayuda siempre <33) para contarle que había estado echando un ojo y había sacado un bypass en la librería y me dió alguna idea por si me ponía a probar ataques.
Una de las ideas que me dió fue probar un ataque de DNS rebinding y como aparte de eso tenía alguna idea más, monté una PoC en local de una web que coge un parámetro llamado "url" para hacer una petición al valor recibido usando safeurl y me puse a probar.
Tras varias pruebas más para saltar el filtro y atacar la librería probé a realizar un DNS rebinding.
DNS rebinding es un ataque que consiste en hacer una petición a un dominio que devuelve como primera resolución DNS una IP autorizada por el servidor para hacer la petición pero que posteriormente cambia esa IP por una no autorizada. Esto hace que la resolución DNS apunte a un sitio autorizado pero que la petición HTTP se dirija a una IP no autorizada.
Para realizar la explotación usé la herramienta rbndr que permite introducir las dos IPs a las que quieres que resuelva el dominio alternativamente.
Una vez que tenemos el dominio configurado para que resuelva a una IP autorizada (8.8.8.8) y a una no autorizada (127.0.0.1), mandamos la petición contra nuestro servidor vulnerable, viendo como hace una petición a 127.0.0.1 correctamente, donde tenemos un servidor web a la escucha en el puerto 80.
Viendo el código se puede comprobar que hay una protección para DNS rebinding implementada, pero que por defecto viene deshabilitada.
Lo comenté con el equipo de Include Security porque creía que esto debería de venir habilitado por defecto o mejor desarrollado en la documentación y aunque no calificaría para CVE, ya que es algo configurable, implementaron una mejor solución para este tipo de ataques, por lo que al menos sirvió para hacer algo más segura la librería.
Conclusiones
Me ha resultado muy entretenido buscar estas vulnerabilidades ya que no estoy acostumbrado a atacar directamente librerías ni a emplear técnicas de bypass de filtros anti-SSRF.
Dado que esta forma de buscar vulnerabilidades me sirve para ver distintos lenguajes de programación, formas de escribirlos y para mejorar en la lectura para encontrar errores, seguramente siga buscando vulnerabilidades en librerías más adelante y os lo contaré por aquí.
Espero que os haya gustado esta entrada y hayáis aprendido algo útil, o bien para bypass de filtros anti-SSRF o para revisar código mejor. ¡Nos vemos en la próxima!
Aquí un resumen de los tiempos de reporte/arreglo/publicación:
- 07/01/2023. Reporte de CVE-2023-24622 a Include Security.
- 07/01/2023. Respuesta de Include Security.
- 11/01/2023. Aviso de vulnerabilidad a DNS rebinding por defecto.
- 11/01/2023. Respuesta de Include Security.
- 17/01/2023. Solución publicada en GitHub para la configuración anti DNS rebinding.
- 18/01/2023. Solución publicada en GitHub para la regex.
- 19/01/2023. Aviso de Include Security de los arreglos realizados.
- 19/01/2023. Arreglos confirmados.
- 28/01/2023. Reporte a MITRE de CVE-2023-24622
- 30/01/2023. CVE asignado.
No hay comentarios:
Publicar un comentario