Hace algún tiempo me encontré con una situación interesante mientras auditaba una aplicación web conectada a un servidor de base de datos Microsoft SQL Server que provocaba que ninguna de las herramientas que utilizo habitualmente para la explotación de Blind SQL Injection funcionara correctamente.
La aplicación web presentaba una vulnerabilidad de Inyección SQL en uno de sus parámetros. Evidentemente no puedo mostrar la aplicación real que contenía el fallo, pero pongamos que la aplicación tenía un código como el siguiente:
Evidentemente, la aplicación es vulnerable a Inyección SQL, y ni siquiera Inyección SQL Ciega, pero vamos a usarlo como ejemplo.
Si lanzamos la herramienta SQLMap para la detección y explotación del parámetro "id", obtenemos lo siguiente:
# ./sqlmap.py -u "http://172.16.24.151/?id=1" -p id
Perfecto! SQLMap detecta correctamente que el parámetro "id" es vulnerable, y nos muestra el fingerprint del servidor de base de datos. Ahora, como un posible segundo paso, veríamos las bases de datos contenidas en el servidor:
# ./sqlmap.py -u "http://172.16.24.151/?id=1" -p id --dbs
Cuando llegué a este punto en la auditoría, intenté ir accediendo a la información contenida en las bases de datos, pero cuando le tocó a "test-db" me encontré con algo así:
# ./sqlmap.py -u "http://172.16.24.151/?id=1" -p id -D "test-db" --tables
Parece que por algún motivo no puedo recuperar las tablas de la base de datos. No hubo manera de hacerlo funciona cambiando las opciones, ni tampoco era por un tema de permisos, puesto que era la base de datos utilizada por la aplicación web. Probé otras herramientas y nada, todas me devolvían el mismo resultado.
Al final, lancé SQLMap con la opción "-v 2", para así poder ver con algo más de detalle que estaba pasando, y obtuve lo siguiente:
# ./sqlmap.py -u "http://172.16.24.151/?id=1" -p id -D "test-db" --tables -v 2
La SQL, a mis ojos, parecía correcta, pero por si acaso me la llevé a una maqueta de Microsoft SQL Server y la lancé, con lo que obtuve un "bonito" error de sintaxis:
"Sintaxis incorrecta cerca de -", y el único "-" que hay en la SQL es el del nombre de la base de datos, así que... no puede ser que el guión (hyphen) sea un carácter no permitido para nombres de tablas en Microsoft SQL Server, porque de hecho la tabla existe, pero parece tratarse de algún tipo de carácter especial en SQL que deberá ser escapado de alguna manera.
Revisando la documentación del SQL Server y referencias varias en Internet, me encontré con que es posible definir el nombre de una tabla entre corchetes, y que eso podría evitar que ese guión fuera interpretado como lenguaje SQL. Veamos que pasa si cambiamos la SQL anterior incluyendo esos corchetes:
Bueno, parece que SÍ que era ese el problema, así que solo necesitamos decirle a SQLMap que el nombre de nuestra base de datos es "[test-db]" en lugar de "test-db" para poder seguir extrayendo la información.
Tras extraer el nombre de las tablas (opción --tables), vemos una llamada "usuarios", así que aprovechamos lo que acabamos de aprender para obtener todo el contenido de la tabla:
# ./sqlmap.py -u "http://172.16.24.151/?id=1" -p id -D "[test-db]" -T usuarios --dump
Hay otra manera de corregir este problema para que no nos vuelva a suceder ni ahora ni nunca, independientemente del nombre que tengan las bases de datos. SQLMap contiene las sentencias SQL dentro de un fichero llamado queries.xml (en el directorio "xml" del sqlmap), con lo que podemos realizar pequeñas (o grandes si nos atrevemos) modificaciones sobre ellas, entre las cuales podemos incluir corchetes en las referencias a nombre de tablas, que serán del tipo %s..loquesea, y que tras la modificación pasarán a ser [%s]..loquesea, o de tipo [DB]..loquesea que pasará a ser [[DB]]..loquesea, solo para la zona de sentencias para SQL Server, por supuesto:
Una vez hecho esto podemos lanzar la herramienta de una forma totalmente normal, y no volveremos a encontrarnos este problema.
Cualquiera de las dos formas nos vale para solucionar nuestro problemilla, aunque a mi me gusta más la segunda. No será la primera vez que toca modificar algo en el código de sqlmap para adaptarlo alguna situación concreta, como por ejemplo WAFs que filtran algunas palabras y que fastidian un poco.
Pero eso ya para otro post.