Inyección SQL Parte 2

Hola de nuevo! En esta entrada vamos a continuar mostrando conceptos de inyección SQL.
Si no has leído la primera entrada, te recomiendo que lo hagas antes de continuar con esta.
Lo último que vimos es como extraer información de unas columnas y una tabla que previamente nos habían proporcionado.
Veamos como podemos ver que columnas y tablas hay en la base de datos.

Enumerando la base de datos

Para poder trabajar bien con las consultas que vayamos a hacer debemos saber primero que tipo de base de datos tenemos delante, esto será otro paso importantísimo a la hora de explotar exitosamente la vulnerabilidad, ya que la sintaxis de las consultas puede variar dependiendo de la base de datos.
Aquí tenemos una cheat sheet que nos irá bien para trabajar con los diferentes tipos de base de datos:

https://portswigger.net/web-security/sql-injection/cheat-sheet

Lab: SQL injection attack, querying the database type and version on Oracle

Volvemos a PortSwigger! En este laboratorio tenemos que extraer y mostrar la versión de la base de datos Oracle. La vulnerabilidad SQLi reside en el mismo sitio que en los laboratorios anteriores.

Lo primero es encontrar cuantas columnas devuelve la consulta. Haciendo las pruebas previamente explicadas, vemos que devuelve dos columnas.

https://acb81fc01ea8d7e2c07782eb002e0063.web-security-academy.net/filter?category=%27%20order%20by%202--

Vamos a seleccionar los dos nulls.

https://acb81fc01ea8d7e2c07782eb002e0063.web-security-academy.net/filter?category=%27%20union%20select%20null,null--

Error? Por qué nos da ese error? Las base de datos Oracle necesitan que en los SELECT siempre haya especificada una tabla. Existe una tabla llamada dual que nos serviría, pero en este caso haremos uso de la tabla v$version, que es donde está almacenada la versión.

https://acb81fc01ea8d7e2c07782eb002e0063.web-security-academy.net/filter?category=%27%20union%20select%20null,null%20from%20v$version--

Especificando la tabla vemos que la consulta ya no nos devuelve ningún error. Ahora para solucionar el laboratorio debemos sustituir cualquiera de los null por banner que nos devolverá el tipo y versión.

https://acb81fc01ea8d7e2c07782eb002e0063.web-security-academy.net/filter?category=%27%20union%20select%20banner,null%20from%20v$version--

Listando tablas y columnas de las bases de datos

La mayoría de las base de datos contienen un esquema con el contenido de la base de datos. Qué quiere decir esto? Pues que podemos hacer consultas a ese esquema para ver que bases de datos hay, que tablas hay en ellas y finalmente que columnas hay en cada tabla. Esto es bastante útil de cara a un atacante, ya que este no conocerá previamente que contenido tiene. Vamos a verlo con ejemplos prácticos.

Lab: SQL injection attack, listing the database contents on non-Oracle databases

El objetivo de este laboratorio es iniciar sesión con el usuario Administrator. Para ello tendremos que encontrar la tabla que almacena los usuarios y luego encontrar el nombre apropiado de las columnas.

Primero…ya sabéis…encontrar el número de columnas, en este caso son 2.

https://ac041f271f1684b6c004f5e000650063.web-security-academy.net/filter?category=Gifts%27%20order%20by%202--%20-

Comprobamos si ambas columnas se muestran en pantalla y si soportan texto.

https://ac041f271f1684b6c004f5e000650063.web-security-academy.net/filter?category=Gifts%27%20union%20select%20%27a%27,%27b%27--%20-

Perfecto, las dos columnas se muestran y soportan texto, ahora vamos a extraer las diferentes tablas que hay en el esquema de la base de datos en uso. Para ello extraemos la información de information_schema.tables.

https://ac041f271f1684b6c004f5e000650063.web-security-academy.net/filter?category=Gifts%27%20union%20select%20table_name,null%20from%20information_schema.tables--

Nos saca todas las tablas, vamos a filtrar por “users”…

Encontrada! Vamos a ver que columnas contiene esa tabla. Para ello, ahora vamos a buscar información en information_schema.columns indicando la tabla encontrada.

Nota: He ido haciendo las consultas con la categoría seleccionada Gifts. Como no provocamos error, si recupera datos los va a mostrar, por eso en la siguiente parte vamos a retirar el nombre de la categoría. Así podremos visualizar más limpio el contenido deseado.

https://ac041f271f1684b6c004f5e000650063.web-security-academy.net/filter?category=%20%27union%20select%20column_name,null%20from%20information_schema.columns%20WHERE%20table_name=%27users_nbaxwq%27--

Ya tenemos el nombre de la tabla y los nombres de las columnas…lo siguiente está hecho.

https://ac041f271f1684b6c004f5e000650063.web-security-academy.net/filter?category=%27%20union%20select%20username_oczbki,password_ahodsy%20from%20users_nbaxwq--

Perfecto! Hemos conseguido extraer tablas y columnas con nombres aleatorios. Hay que estar atentos a que tipo de base de datos tenemos delante, ya que dependiendo de uno u otro puede variar un poco las consultas, pero la metodología es la misma. Por ejemplo, en oracle los nombres de las tablas para extraer información del esquema son diferentes.

SQLi a ciegas

Inyección SQL a ciegas se da cuando la aplicación web no muestra contenido por pantalla pero aún así sigue siendo vulnerable. Para ello haremos uso de condicionales y de retrasos de tiempo, lo explicamos en breve.

SUBSTRING Y SLEEP

Haremos uso de substring y sleep para explotar las siguientes vulnerabilides. No conoces estas funciones? Te hago un breve resumen.

Substring es una función que extrae una cantidad de caracteres indicados de una cadena de texto. Veamos el siguiente ejemplo.

En el anterior ejemplo, se hace uso de substring con la cadena de texto ‘Administrator’, seguido de la posición dónde quiere empezar, en este caso por el caracter 1 y finalmente le indicamos cuantos caracteres cogemos. Es decir, de la cadena de Administrator empiezame por la A y cógeme 5 caracteres con ella incluida. El resultado es Admin.

La función sleep provocará un retraso de tiempo en la respuesta de la petición. Si a una consulta le indicamos sleep(5), tardará 5 segundos en devolvernos el resultado de la petición.

Lab: Blind SQL injection with conditional responses

El objetivo del laboratorio es extraer la contraseña del usuario Administrator e iniciar sesión. Nos dan un poco de información mencionando que la aplicación web hace uso de “trackeo” de cookies. Para ello, hace una consulta a la base de datos de la cookie proporcionada. Si la cookie está en la base de datos, se muestra un mensaje de “Welcome Back”, de lo contrario no se muestra nada.

Una vez navegamos por la página, se nos proporciona una cookie, esta es almacenada en la base de datos y por lo tanto en la siguiente petición se nos muestra el mensaje de “Welcome back!”.
Lo ideal sería usar Burp ya que facilita mucho la tarea, pero vamos a seguir haciendo solo uso del navegador hasta que tengamos que hacer uso de Python para automatizar las peticiones.

' AND 1=1--

Añadimos el payload ‘ AND 1=1– a la cookie y podemos comprobar que nos sigue mostrando el Welcome back. Eso está bien, ya que la cookie existe y 1 es igual a 1. Pero si ponemos 1=2, provocaremos que no nos devuelva ese mensaje, ya que la primera parte de la cookie es correcta pero la segunda provoca False y por tanto no se cumple la condición AND.

Jugando con condicionales y con el mensaje de “Welcome back” podemos hacer consultas y extraer datos. Vamos a ver si existe la tabla users.

' AND (SELECT 'a' FROM users)='a

Seleccionamos una cadena de texto para comparar, en este caso la letra ‘a‘ pero haciendo uso de la tabla users. Nos muestra el mensaje de bienvenida, por lo tanto la tabla users existe. Vamos a comprobar si existe el user Administrator.

' AND (SELECT 'a' FROM users WHERE username='administrator')='a

Genial, la tabla users y el usuario Administrator existen. La idea ahora es conocer la longitud de la contraseña ya que necesitamos saberla para hacer uso de substring.

' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

A la consulta que tenemos previamente le añadimos otra afirmando que la longitud de la contraseña del Administrator es mayor que 1. Nos muestra el mensaje de bienvenida por lo tanto es mayor que 1. Podríamos ir uno por uno subiendo ese dígito hasta que nos de False, pero vamos a cambiar el mayor que por igual que, automatizando un poco el proceso. Para esta parte haremos uso de python con la idea de recorrer del 1 al 40 la longitud de la contraseña buscando la cadena Welcome en la respuesta.

El script nos devolvió que tiene una longitud de 20. Ahora es cuando entra en acción la función substring. Con ella vamos a ir iterando de uno en uno la contraseña para ir comprobando que caracter coincide. Es decir…cogeremos el primer caracter y lo comprobaremos con todos los caracteres posibles, en el momento que nos muestre el mensaje de Welcome Back sabremos que ese caracter es el correcto.

De nuevo haremos uso de python para esta tarea.

Hemos conseguido sacar la contraseña con éxito! Vamos a comprobarla…

Lab: Blind SQL injection with time delays

El objetivo del laboratorio es conectarse a la cuenta del Administrator. La idea es exactamente la misma… la única diferencia es que esta vez no tenemos mensaje de Welcome Back, la respuesta del servidor es incluso la misma si devuelve algún error. La manera de comprobar las consultas es jugar con sleep.

Por no repetir cada proceso de nuevo…que ya nos lo sabemos, explicaré el concepto y mostraré el script en python.
La idea es preguntar si la contraseña tiene una longitud de 20, si es True me tardas 3 segundos en responder. Por lo tanto, vamos a ir de nuevo uno por uno comprobando la longitud de la contraseña hasta que tarde 3 segundos en responder. Una vez tarde 3 segundos, entrará en el IF, mostrará un mensaje por pantalla y finalizará el script.

Al lanzar el script nos devuelve exitosamente la longitud de la contraseña. Sabiendo la longitud de la contraseña repetimos el método de substring para extraer la contraseña en claro.

El script termina con éxito de nuevo y nos devuelve la contraseña del usuario administrator.

Hasta aquí la entrada de inyecciones manuales. En mi opinión, esta segunda entrada ha sido más entretenida, divertida y laboriosa.
Espero que os haya gustado tanto como me ha gustado a mi hacerla.

Óscar Montoya