1 ago 2016

HTTPoxy: 15 años de exposición

Esta semana hemos tenido un nuevo caso de vulnerabilidad mediática. HTTPoxy fue detectada por primera vez hace 15 años, por lo que no podemos decir que sea nueva, pero sí que es hoy cuando se ha tomado realmente en serio. El problema es profundo, ya que se encuentra en librerías de código que son utilizadas para realizar peticiones HTTP dentro de una aplicación. En el caso de HTTPoxy todas las conexiones podrían ser espiadas y modificadas. 

HTTPoxy ha retomado el escenario a través de aplicaciones basadas en CGI, escritas en PHP, Python o Go. Han habilitado un Github dónde podemos encontrar diferentes pruebas de concepto, las cuales utilizan docker para montarlas, por lo que simplifica el escenario y aplicaciones a instalar.  

La vulnerabilidad reside en cómo se procesan las cabeceras proxy. En el año 2001, el fallo fue identificado en curl, en el año 2012 en Ruby y en el año 2013 en Nginx. Esta vez les ha tocado el turno a los lenguajes PHP, Python y Go. La vulnerabilidad tiene un CVSS, en base score, de 8,1. Para mayor detalle se puede encontrar más información en los siguientes CVE:
CVE-2016-5385, correspondiente a PHP.
CVE-2016-5386, correspondiente a Go.
CVE-2016-5387, correspondiente a Apache HTTP Server. 
CVE-2016-1000110, correspondiente a Python.

¿Cómo funciona?

Cuando un atacante quiere explotar la vulnerabilidad necesita forzar que las aplicaciones web del servidor se crean que el header que obtienen con valor Proxy es la nueva dirección del Proxy al que se tienen que conectar. En otras palabras, es un abuso de la cabecera proxy. Todo esto es provocado por un conflicto de nombres. 

En otras palabras, si nosotros como clientes malintencionados del servidor enviamos una cabecera “Proxy”, puede suceder que algunas implementaciones CGI creen una variable de entorno HTTP_PROXY, lo cual provoca que se anule la variable real, la cual tiene el mismo nombre. Por esta razón decimos que la vulnerabilidad, realmente, es un conflicto de nombres. 


Entonces, si sobrescribimos la variable de entorno HTTP_PROXY por una dirección bajo nuestro control podremos colocarnos en medio de la comunicación del servidor y cualquier punto con el que se comunique. Es decir, estamos realizando un Man in the Middle remoto. ¿Qué podemos hacer? En al PoC viene una pequeña demostración del robo de un Secret de una API, es decir, se muestra como se modifica el Proxy del servidor web en remoto y se consigue redirigir las peticiones que hace el servidor contra una API y capturamos el “secreto”. 

Nuestra PoC

Mi compañero Ioseba y yo montamos un entorno para probar esto y, posteriormente, añadir un plugin en nuestro sistema de pentesting persistente Faast para detectar esta vulnerabilidad. Como se dijo anteriormente utilizaremos docker para tener los contenedores de lo necesario. Para instalar docker solo tenemos que ejecutar apt-get install docker docker.io. Una vez tengamos instalado docker, debemos construir el dock. Para ello descargamos el código desde Github. Una vez tengamos descargado el código ejecutamos docker build -t fpm-guzzle-proxy, tal y como se puede ver en la imagen.


Una vez se descarga y crea el dock debemos ejecutarlo. Para ello utilizamos la instrucción docker run -d -p 80:80 –name fpm-test-instance fpm-guzzle-proxy. La sentencia -p 80:80 nos indica el puerto externo de docker y con qué puerto interno se mapea, en ambos casos es el puerto 80. El resultado tras la ejecución se puede ver en la siguiente imagen.


Ya tenemos el entorno vulnerable montado, por lo que vamos utilizar la herramienta curl para generar una petición al servidor web y aplicación montada. La instrucción es curl -H ‘Proxy: [ip]:[puerto]’ [ip del servidor]. Es muy sencillo de entender lo que estamos haciendo. Nosotros somos el cliente y le estamos diciendo al servidor web que el proxy es el que nos interese. Si la aplicación web es vulnerable ocurrirá lo comentado anteriormente, se sobrescribe la variable de entorno y cuando el servidor web realice peticiones la enviará al proxy, es decir, a nosotros en este caso.


Para poder entender que todo esto está funcionando, hemos habilitado un netcat en el puerto 12345, que coincide con la dirección y puerto dónde le dijimos al servidor vulnerable que estaría su proxy. Como se puede ver en la imagen nos llega una petición POST dirigida a Facebook y que envía algo “secreto”. 


Hemos modificado el código del cliente PHP que utiliza el servidor vulnerable, ya que como podéis ver en la imagen en los datos que se envían por POST aparece el parámetro ‘secret’. Para realmente ver los datos del POST, debemos cambiar el parámetro ‘secret’ por ‘body’, y posteriormente construir el dock y ejecutarlo de nuevo. Es un pequeño bug que tiene la prueba de concepto.


La mitigación es obligada si eres vulnerable a HTTPoxy. Para llevar a cabo la mitigación se debe bloquear el uso de la cabecera Proxy cuanto antes. Como se ha visto es realmente sencillo caer en esta vulnerabilidad y el impacto y potencial de ésta es muy alto afectando a dos dimensiones de la seguridad como son la confidencialidad y la integridad de la información.

ioseba palop
pablo gonzález

No hay comentarios:

Publicar un comentario