domingo, 4 de septiembre de 2011

Apache Range Vuln Scanner (CVE-2011-3192)

Hace dos semanas se hizo público un exploit para el popular servidor web Apache que permite realizar una denegación de servicios con relativamente pocas consultas. El exploit aprovecha una vulnerabilidad en Apache que se produce por un inadecuado tratamiento de la cabecera Range. Esta cabecera sirve para pedir segmentos de bytes de un archivo, útil cuando se necesita transferir solamente algunas partes del archivo, por ejemplo, para hacer streaming.


Lo que hace el exploit es generar una consulta que pide la pagina por defecto segmentada en gran cantidad de partes y además cada parte comprimida con gzip. Luego lanza una cantidad arbitraria de hilos que envían simultáneamente esa consulta al servidor. Todo lo anterior dentro de un bucle infinito. Eso provoca que Apache empiece a consumir excesivos recursos (procesamiento y memoria) hasta que finalmente deja de responder.

El código del exploit pueden conseguirlo aquí:

http://www.exploit-db.com/exploits/17696/

Este tema fue abordado en muchos sitios y ya bastante se ha dicho como para repetirlo aquí también. No es el propósito de este post.

Como la vulnerabilidad no lleva mucho tiempo de ser corregida, se me ocurrió que podría encontrar algunos servidores vulnerables en la Universidad. Así que me he pasado toda la tarde del sábado programando un script en java para buscar servidores Apache con la vulnerabilidad del Range. Para los interesados, lo pueden descargar de aquí:

http://www.mediafire.com/?pphnxla0z5o2ig1

El script recibe dos parámetros: el rango de IP's  a scannear (en notación CIDR) y el número de hilos que lanzará.

Para testear si un servidor es vulnerable o no, se envía la siguiente consulta HTTP:

HEAD / HTTP/1.1
Host: [ip_del_host]
Accept-Encoding: gzip
Range: bytes=0-,0-5
Connection: close


El rango de bytes "bytes=0-,0-5" indica que queremos 2 segmentos "0-" y "0-5". El primer segmento comprende desde el byte 0 hasta el final, es decir, el fichero completo. Y el segundo segmento comprende desde el byte 0 hasta el 5 (6 bytes en total).

Según este anunció que hizo Apache sobre como han corregido la vulnerabilidad

http://www.apache.org/dist/httpd/Announcement2.2.html

si la suma del número de bytes de todos los rangos pedidos es mayor que la cantidad de bytes del archivo, entonces se ignora los rangos y se envía el archivo completo.

Ya que la consulta que envía el script pide 6 bytes más que el tamaño del fichero, un servidor que no fuese vulnerable responderá enviando todo el fichero y el código de respuesta será "200 OK". Algo así:

HTTP/1.1 200 OK
Server: Apache/2.2.20 (Unix)
Accept-Ranges: bytes
Content-Encoding: gzip
Content-Length: 44
Content-Type: text/html


Sin embargo un servidor vulnerable seguirá haciendo caso a los rangos y responderá con un código "206 Partial Content" como este:

HTTP/1.1 206 Partial Content
Server: Apache/2.2.19 (Unix)
Accept-Ranges: bytes
Content-Encoding: gzip
Content-Length: 234
Content-Type: multipart/byteranges; boundary=4ac195297a4a74dd0


Eso es lo único que tiene en cuenta el script para determinar si es o no vulnerable un servidor ¿Y que pasa si el servidor responde con otro código como por ejemplo, 302 o 403? Pues nada, simplemente se muestra el código de respuesta xD

Otra cosa que revisa el scanner es si está activado el modulo "mod_deflate" que sirve para que Apache pueda comprimir las páginas antes de enviarlas. Para que funcione el exploit es necesario que este modulo esté activado, la idea es que Apache comprima cada segmento de bytes y de esa forma consuma más memoria y procesador.

Para revisar si mod_deflate está activo, se envía la cabecera "Accept-Encoding: gzip", sugiriendo de esta forma que nos envié el contenido comprimido. Si el servidor responde con una cabecera "Content-Encoding: gzip" entonces significa que el modulo esta activo.

Bueno, probé mi script contra la red de la universidad para ver que encontraba y estos fueron los resultados:

Fig. 1 - Resultados.
He resaltado con verde los servidores que no son vulnerables, con amarillo los que son vulnerables pero que no tienen el mod_deflate activado y con rojo los que son vulnerables y tienen el mod_deflate activo. (lo que no esta resaltado son falsos positivos)

Como verán estamos más o menos mal, solo hay un servidor en rojo pero abundan los amarillos. Y hay 6 en verde, de los cuales 2 son servidores de la FISI ;)

Bueno, es todo por hoy. Saludos.

No hay comentarios:

Publicar un comentario