17 junio 2009

Bypasseando mod_security mediante HPP

Días atrás analizamos los nuevos conceptos de ataque web basados en lo que se llama HPP (HTTP Parameter Pollution). Dicho nuevo tipo de ataque se podía producir a la hora de "jugar" asignando diferentes valores a una misma variable en una petición web.

Recientemente, ha publicado un paper Lavakumar Kuppan, en el cuál demuestra las aplicaciones de este ataque un paso más allá de lo que comentamos en su momento desde aquí (en los comentarios del referido post hicimos una breve explicación de cómo podría utilizarse este tipo de ataque para vulnerar determinados Web Application Firewalls).

En el caso analizado por Lavakumar Kuppan, se explica de una forma bastante clara, el comportamiento de un servidor web IIS con aplicaciones .ASP y .ASP.NET corriendo en él, así como el efecto de aplicar este ataque asignando valores diferentes a una misma variable,. En el post anterior veíamos que IIS encadenaba los diferentes valores mediante comas. Dependiendo del tipo de la función .ASP que se utilice para interpretar los valores: Request.Params, Request.QueryString y Request.Form y depende además de si es ASP o ASP.NET para que el valor final de la variable sea lo que viene en la URI (de un GET o un POST), lo establecido en una Cookie o en el cuerpo de una petición POST.

En el caso de Lavakumar, utiliza mod_security configurado "by default" para proteger la aplicación web. El WAF lo que hace es analizar cada variable de forma independiente y busca ataques en cada parámetro. En el caso de un ataque HPP, se analizan las variables de una en una,.. y si sueltas no resultan un ataque, lo permitirán pasar.

El problema viene cuando el IIS ensambla todas esas variables (con el mismo nombre)... de manera que pueda unir diferentes valores de manera que queden cosas como "select name, password from users" poniendo un valor "select name" y otro "password from users" en una variable del mismo nombre. Se puede llegar a pensar que es poco potente este ataque puesto que un valor "password from users" algún WAF podría llegar a bloquearla y ya está. No podemos pasar cada palabra en una instancia de variable porque quedarían cosas como "select,name,password,from,users" -> lo cual sería completamente inútil puesto que sintácticamente fallaría en su procesamiento.

Uno de los grandes aportes del análisis de Lavakumar es la utilización de los caracteres para introducir comentarios en código SQL. Presupone, que un IIS suele llevar como servidor de base de datos de backend un Microsoft SQL Server, de manera que para poner algo "entre comentarios" (no procesable por el motor de base de datos) se utiliza estructuras como esta: /*esto es un comentario*/. Además el comportamiento del servidor de base de datos ante un comentario es sustituirlo por un espacio.

¿Cómo aprovechamos esto? Muy sencillo, aquellos campos donde necesitemos espacios pondremos caracteres de inicio y fin de comentario, así:

http://www.miweb.com/index.aspx?a=select/*&a=*/name&a=password/*&a=*/from/*&a=*/users

será interpretado finalmente como "select name,password from users" habiendo vulnerado las comprobaciones de seguridad "por defecto" de mod_security.

Para mitigar este tipo de ataque habría que configurar mod_security para no permitir muchas ocurrencias de la misma variable en una sola petición web.

6 comments :

ChEnChO dijo...

Esto
http://www.miweb.com/index.aspx?a=select/*&a=*/name&a=password/*&a=*/from/*&*/a=users

no sería esto?
http://www.miweb.com/index.aspx?a=select/*&a=*/name&a=password/*&a=*/from/*&a=*/users

Lorenzo Martínez dijo...

@Chencho -> Tienes toda la razón... me he liado al rehacerlo yo, ya está corregido. Muchas gracias por el apunte :D

Anónimo dijo...

Buena información!

Newlog

Zerial dijo...

Suelen suceder cosas asi cuando se usan configuraciones por defecto, mas aun cuando de esa configuracion depende la seguridad de la aplicacion.

eduardo abril dijo...

Mod_security no es la panacea. Lo ideal (risas de fondo xD) sería que los desarrolladores web tuvieran cuidado de validar que cada campo de entrada salida contiene lo que tiene que contener (básicamente, limitar la longitud y el tipo de dato sería un buen principio)

Sin embargo, la gente deja mod_security "por defecto" y se olvida del asunto. Luego sale un exploit para el propio mod_security y fin ...

Aparte, mod_security no es exactamente "free". La versión gratis tiene limitaciones, a no ser que haya cambiado, en su consola de administración, sino recuerdo mal. Eso sí, sigue siendo más barato que los productos comerciales.

Los IDS/IPS llevan MUCHO tiempo de seleccionar + instalar actualizaciones y estar al tanto de las alertas. Configurar mod_security lleva un ratito ...

Muy bueno el artículo!

Saludos,
Eduardo.

Lorenzo Martínez dijo...

@Zerial y @Eduardo -> Efectivamente ambos decís que si dejamos en manos de mod_security la seguridad de la aplicación ante un posible problema en el propio mod_security, la puerta está abierta. Estoy de acuerdo con ambos, pero sin embargo, el problema al que nos enfrentamos aquí es un tipo de ataque nuevo. Un ataque para en el que entra en juego la implementación de cada servidor web a la hora de interpretar una variable repetida. Evidentemente que la programación segura es la mejor de las soluciones, pero es que dados los tiempos que corremos en que todo ha de estar hecho para ayer, sub-sub-sub-sub-contratando el trabajo a empresas mediante un montón de intermediarios, al final quien desarrolla no siempre está bien cualificado en las artes de la programación segura.
En cuanto a mod_security, no he sido capaz de encontrar una interfaz gráfica más allá de la utilización de ficheros, de manera hace que la configuración efectiva de la herramienta esté destinada a unos pocos que son capaces de entender claramente qué hace cada directiva.
Por otro lado, los ficheros de lista negra con los que viene, dada la publicación diaria de vulnerabilidades web encontradas, no te permite estar "al día" a no ser mediante suscripciones de pago (como muy bien apuntaba Eduardo).

En conclusión, la programación segura está bien, pero creo que añadir una segunda capa de protección previa como puede ser un WAF nunca está de más y determinados sitios que protegen información extremadamente sensible (bancos, servicios de salud, seguros, administración pública) deberían contar con cuantas más medidas puedan para proteger los datos y el dinero de sus clientes.