06 febrero 2013

Revisando las últimas vulnerabilidades en pfsense 2.0.1


pfSense es una distribución libre, de código abierto, y personalizada de FreeBSD, adaptada para ser utilizada como firewall y router. Incluye una larga lista de funcionalidades incorporadas, y otras tantas que se pueden agregar fácilmente a través de componentes instalables.

Como su rendimiento es muy elevado, pfSense es utilizado en muchísimas organizaciones como firewall perimetral, como terminador de VPNs, y como servidor interno multipropósito (dhcp, proxy, etc.).

El filtrado de paquetes de pfSense se basa en reglas de pfctl; digamos, el "iptables" de freeBSD. El proyecto se inció en el año 2004, basándose en la distribución m0n0wall; pero si bien pfSense puede instalarse en algunos sistemas embebidos, apunta a instalaciones en computadoras personales de 32 y 64 bits.

pfSense tuvo un cambio de versión grande hace poco más de un año. La última versión estable anterior era la 1.2.3, y si bien no tenía tantas funcionalidades como la rama 2.x.x, era un producto robusto, fiable, y no le faltaba nada para reemplazar a muchos UTMs y firewalls comerciales.

La historia de las últimas versiones:
  • 1.2.3 -> 6/12/2009
  • 2.0.0 -> 17/9/2011
  • 2.0.1 -> 20/12/2011
  • 2.0.2 -> 21/12/2012

Nuevas vulnerabilidades

El 4 de enero se hicieron públicas 3 vulnerabilidades presentes en la versión 2.0.1, junto con pruebas de concepto y demo en video: http://www.exploit-db.com/exploits/23901/

Vamos a ver de qué se tratan.


1) La primera es un XSS en el archivo /usr/local/www/progress.php



En primera medida hay que comentar que este archivo no es utilizado realmente, según se puede ver al evaluar el código PHP, y según lo que se indica en :
http://www.freshbsd.org/commit/pfsense/aca65de524027e9aedfa38f83665907b41abce58

Se puede ver en la línea 24, que si el parámetro HTTP GET "e" es enviado (no importa con qué valor), entonces PHP devuelve en la línea 25 el valor del parámetro GET "UPLOAD_IDENTIFIER" que proviene del usuario, sin darle ningún tratamiento.

En la línea 28, se devuelve una variable llamada $url, la cual contiene también al parámetro "UPLOAD_IDENTIFIER", pero en este caso es sanitizado con CSRFMagic (http://csrf.htmlpurifier.org/)

De todos modos, esta debilidad no es explotable, ya que si se invoca al archivo de manera directa, la ejecución falla en la línea 21 debido a que la función "upload_progress_meter_get_info" no se encuentra definida en ninguna parte. De esta manera PHP arroja un FATAL ERROR, y el código inseguro no llega a ejecutarse.

Si cambiamos la asignación en la línea 21 de la siguiente manera:

$X = 0; // upload_progress_meter_get_info( $_GET["UPLOAD_IDENTIFIER"] );

podemos ver que el XSS sí sería explotable.




2) La segunda es un XSS en la línea 166 del archivo /usr/local/www/pkg_mgr_install.php


Nuevamente, el parámetro GET "pkg" es devuelto por PHP tal como es enviado por el navegador, sin ningún tratamiento.

Nada que agregar.


3) La tercera es una vulnerabilidad en la línea 118 del archivo /usr/local/www/system_firmware.php que permite la ejecución remota de código.



Esta vulnerabilidad es muy importante, ya que permitiría a un atacante ejecutar código con permisos totales en el sistema operativo.
El uso correcto que espera darle pfsense a este código es ejecutar:

echo SMP > /boot/kernel/pfsense_kernel.txt

pero un atacante podría enviar una petición POST con el parámetro "kerneltype" modificado, y lograr que la sentencia que se ejecuta sea otra, por ejemplo:

echo lo_que_el_atacante_desee > /boot/kernel/pfsense_kernel.txt

Vamos a modificar lo_que_el_atacante_desee por algo que nos convenga más, por ejemplo:

cualquiercosa ; echo "Me parece haber visto un lindo gatito" > /root/Evidencia_CSRF.txt ; echo SMP

Así, la sentencia completa que se ejecutaría sería:

echo cualquiercosa ; echo "Me parece haber visto un lindo gatito" > /root/Evidencia_CSRF.txt ; echo SMP > /boot/kernel/pfsense_kernel.txt

Creamos un archivo html que contenga el formulario con el valor que queremos, y que al cargarse haga la petición POST


Listamos el directorio /root del pfsense para ver qué hay:

En en navegador abrimos el archivo HTML que creamos, y luego vemos qué pasó en el directorio /root:



Como se puede ver, se creó el archivo que queríamos, en el directorio /root, y su dueño también es root. De mas está mencionar la potencialidad de explotar esta vulnerabilidad.

Estas debilidades se solucionaron en la versión 2.0.2 del producto, y en el detalle de cambio, se mencionan estos (y quizás otros?) fixes:
  • Fix a few potential XSS/CSRF vectors.
Es necesario mencionar que estas debilidades sólo podrían ser explotadas con una sesión iniciada en la consola de administración; Si no hay sesión abierta, no hay exposición.

Adicionalmente, esta última versión se basa en la versión 8.1-RELEASE-p13, que corrige algunas cuestiones de seguridad inherentes al mismo FreeBSD.

Soy un fanático de pfSense, sé que tiene algunas cuantas cosas por mejorar y refinar; personalmente me encontré con algunos casos más de validación de entrada del lado del cliente (por javascript), que no eran chequeados del lado del servidor. Pese a todo esto, creo que es un producto noble, y en muchos casos es la mejor opción.



Contribución por cortesía de Leonardo Brugues (@lbrug)



2 comments :

dani dijo...

aunque me vaya un poco del tema....

En estos tiempos que corren y como no estan las cosas para gastar muchos
euros estoy planteando la posibilidad de instalar una distro linux del
tipo ipfire o pfSense para proteger una red interna de una pequeña empresa.

Basicamente las necesidades son:

bloqueo de puertos
filtrar trafico a determinadas webs
bloquear las palicaciones p2p
proteger de ataques externos

yo entiendo que con ipfire o pfSense (por ejemplo) podria cubrir esas necesidades,
la idea seria instalarla en un pequeño equipo dedicado con 2 o 3
tarjetas de red

¿¿es viable mi idea o voy muy mal encaminado???

javcasta dijo...

Con pfSense y un equipo "viejete" y con al menos 2 nic (tarjetas de red) tendras uno de los mejores firewalls free & open.

Por cierto, pfsense esta basado en freeBSD.
Salu2