Español | English
rss facebook linkedin Twitter

Bypassing SQL injection Filters

Cada vez son más las empresas que utilizan algún tipo de IPS o Firewall de aplicación (WAF) para proteger sus servidores Web. Esto complica la tarea de explotar ciertas de vulnerabilidades. Por ejemplo las inyecciones de SQL.

Antiguamente las reglas de filtrado que aplicaban estos dispositivos solían ser muy burdas y fáciles de evadir.

Por ejemplo utilizaban patrones basados en expresiones regulares del tipo: "UNION SELECT .* FROM"

Que eran fácilmente evitables sustituyendo el carácter espacio " " por algún equivalente. Por ejemplo: “\t” (tabulador), “%09” (tabulador uri-encoded) o “/*xxx*/” (comentario). O incluso construyendo la sentencia SQL sin espacios.

De forma similar se podían codificar los parámetros HTTP de diversas formas para intentar ocultar la inyección.

Esto sigue siendo posible con muchos IPS comerciales. Curiosamente iniciativas libres como mod_security fueron de los primeros en tenerlo en cuenta.

Pero las nuevas generaciones de IPS/WAF ya controlan este tipo de trucos y son mucho más estrictos. Con patrones basados en expresiones regulares del tipo: "SELECT.*FROM"

De forma que una inocente URL de este estilo es detectada como un ataque:
http://www.ejemplo.com/test.php?var=SELECTxFROM ___-> DETECTADO

Ni que decir que esto (que podría ser un ataque real), no colaría tampoco:
http://www.ejemplo.com/test.php?var=1 UNION SELECT campo FROM tabla ___-> DETECTADO

Y por mucho que intentemos codificar la inyección, el IPS/WAF la sigue detectando.

Para evitar este tipo de firmas podemos utilizar varias técnicas, por ejemplo:

Insertar caracteres ignorados


Algunos conectores de bases de datos ignoran algunos caracteres incluidos en una petición SQL de forma que podemos incluirlos en la inyección para confundir al IPS. Por ejemplo:
http://www.ejemplo.com/test.php?var=1 UNION SEL%2500%2500ECT campo FR%2500%2500OM tabla ___-> NO DETECTADO

La pega es que esto solo funciona con determinados caracteres y con ciertas versiones de algunas bases de datos. Una alternativa más genérica es la siguiente:

Separar la inyección

Esta técnica consiste en separar la cadena SQL del ataque en varias partes. Como es lógico, esto solo funciona en inyecciones en las que tenemos más de 1 punto de inyección, por ejemplo: http://www.ejemplo.com/sucursal.php?provincia=MURCIA&ciudad=LORCA

Que en SQL seria:
SELECT direccion FROM sucursales WHERE prov=MURCIA AND city=LORCA

Si intentamos lo siguiente el IDS/WAF lo detectara:
http://www.ejemplo.com/sucursal.php?provincia=MURCIA&ciudad=LORCA UNION SELECT user FROM mysql.user ___-> DETECTADO

Ya que el patrón "SELECT.*FROM" se cumple claramente. Pero si separamos la inyección en 2 y cambiamos el orden de la inyección (ponemos el FROM antes que el SELECT), el patrón no se cumplirá y el ataque pasara inadvertido.

Por ejemplo:
http://www.ejemplo.com/sucursal.php?ciudad=LORCA */ FROM mysql.user &provincia=MURCIA UNION SELECT user /* ___-> NO DETECTADO

Que en SQL quedaría:
SELECT direccion FROM sucursales WHERE prov=MURCIA UNION SELECT user /* AND city=LORCA */ FROM mysql.user

Siendo válido y pasando el filtro...

Ramón Pinuaga
Dpto. Auditoria S21SEC

(+34 902 222 521)


24 horas / 7 días a la semana



© Copyright S21sec 2013 - Todos los derechos reservados


login