Atacando la vulnerabilidad SQLi
Enumerando la DB
Cuando tenemos una SQLi, podemos enumerar la DB, pero para lograr esto, necesitamos la informacion de las columnas y nombres de las tablas si es que queremos extraer informacion de estos.
Enumeración del número de columnas
Podemos usar un order by
para hacer una enumeración simple. Esto le dice a la DB que ordene los resultados de la query por el valor del resultado en una o más columnas. Se puede usar el nombre de las columnas o el index en la query:
Esta query le indica a la DB que ordene los resultados en base al valor de la primera columna. Si se tiene al menos una columna, se enviará la información sin errores:
Entendiendo el layout de la salida
Podemos usar la declaración UNION
para extraer data, en base a la cantidad de columnas de la tabla. UNION
permite agregar una segunda declaración select
a la query original, extendiendo nuestra capacidad (cada declaración debe retornar la misma cantidad de columnas).
Lo primero es validar qué columnas son mostradas en la página.
Como ya sabemos la cantidad de columnas que se tienen, es necesario chequear cuales se muestran usando la declaración union all select 1, 2, 3
:
La columna 1 no se muestra, la 2 muestra el campo del nombre, y la 3 corresponde a los comentarios (el campo Comentario tiene más espacio, por lo que este es un lugar lógico para la salida de nuestro futuro exploit).
Extrayendo data desde la DB (MariaDB)
Validamos la versión de la DB reemplazando el campo 3 con lo siguiente @@version
:
Ahora lo reemplazamos con user()
para obtener el usuario actual de la DB:
Podemos enumerar tablas y columnas de la DB a través de information_schema
. Este almacena informacion sobre la DB, como el nombre de las tablas y columnas. Si queremos obtener el nombre de las tablas, se debe usar el siguiente payload table_name from information_schema.tables
:
Ahora que tenemos el nombre de las tablas, podemos usar el siguiente payload para obtener los nombres de las columnas column_name from information_schema.columns where table_name='users'
:
Con esta información podemos llamar las columnas username
y password
desde la tabla users
:
Ejecución de código usando SQLi
Lo primero que se puede intentar al ejecutar código desde la base de datos, es leer archivos usando la función load_file
:
Ahora, usando la función INTO OUTFILE
, creamos un archivo PHP malicioso, con el cual, podremos ejecutar código:
Con el siguiente payload, obtenemos una full shell:
SQLi en la cláusula WHERE, permitiendo obtener datos ocultos
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos.
El ejemplo de la query que se realiza a la DB es la siguiente:
En este caso, debemos desplegar todos los productos de cualquier categoría.
Validamos que nos despliega la aplicación cuando seleccionamos una categoría:
Ahora, modificamos el valor de la categoría por una comilla simple ('
):
Al modificar este valor, se presenta un error en la aplicación. Esto se puede deber a que modificamos la query a algo similar a lo siguiente:
Usamos el siguiente payload '-- -
para validar si aún se presenta el mismo error:
Si queremos obtener todos los productos, debemos crear una query donde, se valide algún parámetro como verdadero, por lo tanto, usaremos el siguiente payload ' or 1=1 -- -
:
Para poder automatizar esto, podemos usar el siguiente script, el cual, valida si se refleja algún producto que no aparece en el catálogo en producción:
SQLi que permita realizar bypass de login
Se tiene la vulnerabilidad en la funcionalidad de login, en la cual, debemos acceder a la aplicación usando el usuario administrator
.
Se validan usuarios de prueba, como admin
y password admin
:
Vemos que el error no nos permite enumerar usuarios.
Inyectamos una comilla simple ('
) en las casillas de usuario y en la de password, y vemos que la aplicación responde con un error en ambos casos:
En este caso podemos asumir que la query es la siguiente:
Intentamos ingresar usando el siguiente payload admin' -- -
:
Como el usuario admin
no existe, no podemos ingresar, por lo tanto, lo modificamos ingresando el usuario administrator
:
Ahora, automatizamos este proceso usando el siguiente script, donde, lo primero es validar como se envían los datos. Esto se puede corroborar usando Burp Suite.
Ya sabiendo como se envían los datos, necesitamos obtener el valor del token CSRF:
El script valida que se tenga en la respuesta el texto Log out
:
Ataque de SQLi usando UNION para determinar las columnas retornadas por la query
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe determinar la cantidad de columnas retornadas por la DB.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Ahora, al payload le agregamos un comentario para evitar el error ' -- -
:
Para este ataque, podemos usar formas para obtener la cantidad de columnas, poder usar valores NULL, u ORDER BY.
Primero validamos usando valores NULL, donde, tendremos el número de columnas cuando la aplicación deje de mostrar error:
Payloads:
Vemos que se retornan 3 columnas. Esto se puede obtener usando ORDER BY, donde, cuando se nos presente un error, significa que nos pasamos de la cantidad de columnas de la respuesta:
Payloads:
Esto lo podemos automatizar usando el siguiente script, el cual, valida la cantidad de columnas usando ORDER BY
:
Ataque de SQLi usando UNION para encontrar la columna que contiene texto
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe determinar cuál columna retornada por la DB tiene string como tipo de datos.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Vemos que la segunda columna usa el tipo de datos string.
Esto lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION para obtener información de otras tablas
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la tabla users
, columnas username
y password
.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada una de las columnas, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
En este caso, ambas columnas usan strings.
Por último, obtenemos los datos solicitados, y accedemos usando la cuenta del usuario administrator
:
La obtención de la contraseña del usuario administrator lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION, recuperando múltiples valores en una sola columna
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la tabla users
, columnas username
y password
.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Ahora debemos saber la versión de la DB para poder determinar qué tipo de concatenación podemos usar:
Ya sabemos que usa una DB en PostgreSQL, por lo tanto, podemos concatenar los datos que necesitamos usando el siguiente payload:
Esto lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION, consultando el tipo y la versión de la base de datos en Oracle
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la versión de la DB.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Vemos que no funciona de la forma habitual, y esto se debe a que la DB en uso es Oracle (basado en los requerimientos del lab). Para esto, debemos especificar la tabla que queremos consumir, y para esto, usamos la tabla DUAL:
Con esto ya podemos obtener información de la versión de la DB:
Esto lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION, consultando el tipo y la versión de la base de datos en MySQL
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la versión de la DB.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Con esto ya podemos obtener información de la versión de la DB:
Esto lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION, listando el contenido de la DB en base de datos no Oracle
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la tabla que contiane los usuarios y contraseñas.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Con el siguiente payload obtenemos la versión de la DB:
Ahora, obtenemos las tablas de la DB:
Sabemos que el nombre de la tabla que contiene los usuarios es users_vvdspp
, por lo tanto, podemos obtener las columnas de esta tabla:
Con estos datos, podemos extraer la información que necesitamos:
Esto lo podemos automatizar usando el siguiente script:
Ataque de SQLi usando UNION, listando el contenido de la DB en base de datos Oracle
Se tiene una aplicación con una vulnerabilidad de SQLi en el filtro de la categoría de productos, en la cual, se debe obtener información de la tabla que contiane los usuarios y contraseñas.
Si modificamos la categoría con una comilla simple ('
), se nos muestra el siguiente error:
Debemos determinar la cantidad de columnas, esto lo podemos usar con ORDER BY
:
Payloads:
Ahora, debemos identificar el tipo de datos de cada uno de ellos, usando las siguientes combinaciones de payloads. Cuando se detecte el valor correcto, no se presentará un error en la respuesta:
Con el siguiente payload obtenemos las tablas de la DB:
Sabemos que el nombre de la tabla que contiene los usuarios es USERS_YHDUDN
, por lo tanto, podemos obtener las columnas de esta tabla:
Con estos datos, podemos extraer la información que necesitamos:
Esto lo podemos automatizar usando el siguiente script:
Ataque de Blind SQLi con respuestas condicionales
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
El resultado de la query no es retornada, y no muestra un mensaje de error, pero, la aplicación incluye un mensaje Welcome back
en la página si la query retorna alguna fila.
Debemos obtener el usuario y contraseña del usuario administrator
, el cual, se encuentra en la tabla users
.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingID
y session
:
Ingresamos una comilla simple en el valor de la cookie TrackingID
para validar si nos presenta un error:
Ahora, validamos como se comporta con un payload condicional:
Cuando el condicional es TRUE
, vemos el mensaje Welcome back
:
Validamos que existe la tabla users
:
Podemos usar los siguientes payloads para corroborar que exista el usuario administrator:
Si queremos saber la longitud de la password, podemos usar el siguiente payload, el cual, si nos responde con un Welcome back
, es la longitud que tiene esta:
Para esto, usamos Intruder:
Ahora buscamos los carácteres de la password:
En este caso, toma el primer carácter y lo iguala a lo que le indiquemos. Si queremos cambiar de carácter a validar, modificamos el primer número.
Esto lo automatizamos usando el ataque de Intruder Cluster bomb:
Con el siguiente script, se puede obtener el mismo resultado:
Ataque de Blind SQLi con errores condicionales
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
El resultado de la query no es retornada, y solo se muestra un error modificado cuando la query causa alguno.
Debemos obtener el usuario y contraseña del usuario administrator
, el cual, se encuentra en la tabla users
.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingId
y session
:
Si agregamos una comilla simple, vemos un error, mientras que al agregar una segunda, este ya no se muestra:
Validamos si concatenando el siguiente payload, se presenta el error:
Vemos que se presenta un error en una query bien formada, por lo tanto, podemos asumir que es una DB Oracle. Por este motivo, usamos el siguiente payload:
Con esto identificamos que es una DB Oracle.
Ahora, validamos que la tabla users
exista en la DB:
Se presenta un error, y esto se puede deber a que estamos pasando un input vacío, y este se puede esta aplicando a las distintas filas de la tabla, por lo tanto, modificamos el payload para que solo valide solo una entrada:
Sabemos que existe la tabla, ahora corroboramos que exista el usuario administrator
:
Como no se presenta un error, sabemos que existe el usuario.
Lo anterior lo podemos obtener usando un payload más complejo, en el cual, se valida la sección del FROM
, donde, si el usuario a validar existe, realiza lo que se indica en CASE
. Si nos muestra un error, significa que el usuario existe, de lo contrario, no existe:
Ya que sabemos que el usuario existe, ahora obtenemos el largo de su contraseña:
La contraseña del usuario administrator
es de 20 carácteres.
Ahora enumeramos la contraseña:
Esto lo podemos automatizar usando el siguiente script:
Ataque de Blind SQLi con tiempos de delay
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
El resultado de la query no es retornada, sin embargo, la query se ejecuta de forma sincróna, por lo tanto, es posible gatillar una condicional de tiempo con delay para inferir la información.
Para resolver el laboratorio, se debe causar un delay de 10 segundos.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingId
y session
:
Inyectamos una comilla simple para validar que sucede con la aplicación:
No presenta errores, por lo tanto, validamos con los siguientes payloads para ver cual tarda 10 segundos en responder:
Vemos que es una DB PostgreSQL.
Esto lo podemos automatizar usando el siguiente script:
Ataque de Blind SQLi con tiempos de delay y obtención de información
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
El resultado de la query no es retornada, sin embargo, la query se ejecuta de forma sincróna, por lo tanto, es posible gatillar una condicional de tiempo con delay para inferir la información.
Debemos obtener el usuario y contraseña del usuario administrator
, el cual, se encuentra en la tabla users
.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingId
y session
:
Validamos que la cookie es vulnerable:
Tiempo con payload:
Tiempo sin payload:
Confirmamos si existe tabla users
en la DB:
Corroboramos que la tabla tenga el usuario administrator
:
Enumeramos la longitud de la password:
Para evitar errores, es necesario usar un hilo a la vez.
Ahora, enumeramos la password del usuario administrator
:
Esto lo podemos automatizar usando el siguiente script:
Ataque de Blind SQLi con interacción fuera de banda
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
La query se ejecuta de forma asíncrona y no tiene efecto en la respuesta de la aplicación. Por lo tanto, se debe gatillar una interacción fuera de banda con algún dominio externo.
Para esto, se debe lograr que se realice un lookup DNS a Burp Collaborator.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingId
y session
:
Abrimos el cliente de Collaborator, y copiamos el dominio a usar:
Usamos el siguiente payload para hacer el lookup DNS:
Ataque de Blind SQLi con exfiltración de datos fuera de banda
Se tiene una aplicación con una vulnerabilidad de Blind SQLi. Usa una cookie de tracking para análisis, y realiza una query con el valor que esta tenga.
La query se ejecuta de forma asíncrona y no tiene efecto en la respuesta de la aplicación. Por lo tanto, se debe gatillar una interacción fuera de banda con algún dominio externo.
Para esto, se debe obtener la password del usuario administrator
, que se encuentra en la tabla users
.
Capturamos el request usando Burp Suite, y vemos que tiene las cookies TrackingId
y session
:
Abrimos el cliente de Collaborator, y copiamos el dominio a usar:
Usamos el siguiente payload para exfiltrar los datos solicitados:
Ataque de SQLi con bypass de filtros a través de codificación XML
Se tiene una aplicación con una vulnerabilidad de SQLi en la característica de validación de stock. El resultado de la query es devuelta en la respuesta de la aplicación.
Para esto, se debe obtener la password del usuario admin
, que se encuentra en la tabla users
.
Dentro de las recomendaciones, se indica que el WAF bloqueará ciertos ataques, y por esto, usar la extensión Hackvertos.
Vemos que al seleccionar un producto, aparece un botón que permite validar el stock de este:
Validamos las columnas de la tabla usando el payload UNION SELECT NULL
:
Este payload fue detectado, por lo tanto, debemos codificar esta consulta. Usando la extensión Hackvertor, codificamos con hex_entities
:
Con esto podemos determinar que se tiene solo una columna.
Para obtener los datos solicitados, usamos el siguiente payload:
Last updated