SQL Injection
¿Qué es y cómo funciona?
la inyección SQL es una técnica de inyección de código que se utiliza para atacar aplicaciones basadas en datos, en las que se insertan declaraciones SQL maliciosas en un campo de entrada para su ejecución (por ejemplo, para volcar el contenido de la base de datos al atacante).
Comandos básicos de SQL
SELECT
Se utiliza para seleccionar las columnas que se desean mostrar en la consulta.
FROM
Se utiliza para especificar la tabla o tablas de las que se desean recuperar los datos.
WHERE
Se utiliza para establecer una condición que deben cumplir los datos que se desean recuperar.
GROUP BY
Se utiliza para agrupar los datos por una o varias columnas.
HAVING
Se utiliza para establecer una condición que deben cumplir los grupos que se desean recuperar.
ORDER BY
Se utiliza para ordenar los datos por una o varias columnas.
LIMIT
Se utiliza para limitar el número de filas que se desean recuperar.
OFFSET
Se utiliza para establecer el número de filas que se deben saltar antes de empezar a recuperar datos.
DISTINCT
Se utiliza para eliminar las filas duplicadas de los resultados de la consulta.
IN
Se utiliza para especificar una lista de valores que deben cumplir una condición.
BETWEEN
Se utiliza para especificar un rango de valores que deben cumplir una condición.
LIKE
Se utiliza para buscar valores que contengan una cadena de caracteres determinada.
IS NULL
Se utiliza para buscar valores que sean nulos.
IS NOT NULL
Se utiliza para buscar valores que no sean nulos.
La tabla que se presenta a continuación enumera las posibilidades de las vistas de metadatos del sistema en diferentes bases de datos comunes:
MySQL
information_schema.SCHEMATA
Contiene una fila por cada base de datos en el servidor MySQL.
MySQL
information_schema.TABLES
Contiene información sobre cada tabla en cada base de datos en el servidor MySQL.
MySQL
information_schema.COLUMNS
Contiene información sobre cada columna en cada tabla en cada base de datos en el servidor MySQL.
MySQL
information_schema.INDEXES
Contiene información sobre cada índice en cada tabla en cada base de datos en el servidor MySQL.
PostgreSQL
pg_catalog.pg_namespace
Contiene información sobre cada esquema en la base de datos de PostgreSQL.
PostgreSQL
pg_catalog.pg_tables
Contiene información sobre cada tabla en cada esquema en la base de datos de PostgreSQL.
PostgreSQL
pg_catalog.pg_columns
Contiene información sobre cada columna en cada tabla en cada esquema en la base de datos de PostgreSQL.
PostgreSQL
pg_catalog.pg_indexes
Contiene información sobre cada índice en cada tabla en cada esquema en la base de datos de PostgreSQL.
SQL Server
sys.schemas
Contiene información sobre cada esquema en la base de datos de SQL Server.
SQL Server
sys.tables
Contiene información sobre cada tabla en cada esquema en la base de datos de SQL Server.
SQL Server
sys.columns
Contiene información sobre cada columna en cada tabla en cada esquema en la base de datos de SQL Server.
SQL Server
sys.indexes
Contiene información sobre cada índice en cada tabla en cada esquema en la base de datos de SQL Server.
Check List
Strings como ' or ""
SQL Comandos SELECT, UNION y otros.
Comandos # o --
También puede haber el caso que este sanitizado pero mal, y sin ponerle ' o "" ya funciona el comando (id=1 order by 2)
Tipos de SQL Injection
SQL In-Band
Tenemos que saber que esto:
Es lo mismo que esto:
Así que podemos hacer después del id=2 mas consultas basadas en error, una vez entendido esto, vamos a las comandos:
Test si hay sql injection
Error based - ORDER BY
Este proceso es para determinar cuantas columnas existen en la base de datos a la que estamos intentando de sacar información. Cuando hayamos hecho por ejemplo order by 10 -- -
y no salga información solo hace falta ir bajando hasta que salga y así sabremos cuantas columnas tiene la bbdd.
Nota importante: El caso es que a veces puede pasar que no sale el error, lo que hay que hacer es lo de siempre order by 100-- -
hasta que te salga información, cuando te salga información por ejemplo cuando has hecho order by 4-- -
significa que hay 4 columnas. Y ya puedes seguir con la inyección.
Recordar que para que muestre la info tenemos que poner el primer parametro que sea erroneo porque sino no funcionará. Si existe el id=2
al hacer la query id=2 union select 1,2,3,database() -- -
no saldrá información por que es correcto el id, habría que poner id=-1
o id=23123
para que funcione.
UNION
A veces puede pasar que filtramos por (username y password) y puede que no aparezcan las contraseñas, eso es por que a veces suele estar en la columna "authentication_string"
Así que deberíamos añadir el campo en la syntaxis
Test en buscador
A veces podemos sacar información en un buscador de la web mediante sqlinjection.
Test en Login
veces con este tipo de sql injectio podemos bypassear el login de un panel.
SQL Blind/Boolean-based
Cuando hablamos de una SQL Injection la cuál no podemos ver el resultado de la petición se le llama a ciegas, y dentro de esta misma variable hay de 2 tipos:
Basada en tiempo
Basada en condiciones
Tiempo
Una SQL Injection de tiempo son cuando enviamos una petición y le ponemos el parámetro sleep y dependiendo de lo que tarde en responder podriamos determinar si los datos son correctos o no.
Ejemplo de como sería por detrás
Ahora pondré un ejemplo de si la base de datos con la que estamos trabajando actualmente empieza por 'a' tarda 5 segundos en responder:
Primera petición
Segunda petición
Como podemos ver en la segunda petición no nos da ningún resultado, eso nos da a entender que el primer carácter de la base de datos empieza por j. Y en la primera obviamente sería el resultado de una petición no correcta ya que no empieza por a.
Este proceso es un poco tedioso a la hora de hacerlo manual, por eso os traigo un script en python que estuve haciendo en un curso de s4vitar el cuál te automatiza todo el proceso:
Solamente tenemos que cambiar 2 parámetros que cambian dependiendo de a lo que nos enfrentemos:
main_url
sql_url
SQL-URL Examples
Script python para SQL Injection en GET
Resultado del script
Script python para SQL Injection en POST
Condiciones
Una SQL Injection condicional es cuando enviamos la petición y le ponemos la condición true o false.
Si ponemos al final de la query esto ' OR 1=1-- -
nos aparecera de nuevo toda la tabla ya que le estamos diciendo que obvie todo lo de atrás y que muestre todo ya que 1=1 es true.
O por ejemplo imaginemos que estamos enfrentandonos a una tabla de usuarios y queremos descubrir si el primer carácter empieza por a.
Cómo el primer usuario es jack, la condición te dice que es 0 que es false. Pero si le ponemos ='j' veremos que pone 1.
Otro ejemplo que lo estaré haciendo con curl es el siguiente:
El id 9 no existe pero como despues hacemos un OR 1=1
pues lo detecta como true que le decimos que obvie lo de atrás y muestre todo
Pero si ponemos 1=2 que es false nos dará un 404
Script de python para condicones
Ejemplo SQL Injection - Error Based
Este ejemplo lo he realizado con un laboratorio que puedes instalarte en docker, aquí el link
Primero tenemos que saber cuantas columnas tiene la base de datos actual, con BurpSuite interceptamos la petición y la mandamos al Repeater para hacer las pruebas.
Vemos que con 5 ya no nos da error
Empecemos con lo bueno, vamos a realizar unas pruebas para ver si poniendo con UNION unos datos se representa en la tabla
Ahora vamos a listar todas las bases de datos existentes del servidor
En el siguiente comando listaremos las tablas de la base de datos sqlitraining
Seguidamente listaremos todas las columnas de la tabla users
Nos interesan los campos username y password
Si cambiamos la respuesta a Pretty podemos seleccionar todos los datos
También podemos ver estos datos de una manera más ordenada poniendo el campo username y password en las columnas
SQL Map
Sintaxis principal
Sqlmap en buscador
Cuando hayamos conseguido el payload del sql map para inyectarlo manualmente, al final poner siempre %23.
Sqlmap en Login
Sqlmap -r
Primero hay que interceptar la petición y después guardarla en un fichero y entonces decirle al sqlmap que parámetro tiene que consultar
El parámetro al que queremos que compruebe si es vulnerable es `searchitem=test`
En /usr/share/sqlmap/output/<target> encontramos todos los logs de los comandos y info que hemos hecho. Si no hay nada ejecuta la siguiente comanda: sqlmap -r <URL file> -p user --technique=B --banner -v3 --flush-session
SQL Map cheat sheet
Aquí encontrarás todos los comandos de sqlmap: Cheat sheet
Last updated