I Earned $3500 and 40 Points for A GraphQL Blind SQL Injection Vulnerability.

nav1n
InfoSec Write-ups
Published in
7 min readMar 10, 2023

--

Thank you for your love and appreciation for my recent blog post on MySQL SQL Injection, which I discovered in a major international retail company.

After my initial post, many of you asked me to continue writing. However, it’s not possible for me to do so as I have a full-time job from 8 AM until 6 PM. By the time I reach home at 7:30 PM and go to the gym, it becomes quite challenging. Nonetheless, I am planning to write something on weekends to assist the community of white-hat hackers.

Image © https://www.invicti.com/blog/web-security/how-blind-sql-injection-works/

Today, being the weekend, I dedicated a couple of hours to writing and I’m back with a new article on another impactful yet straightforward SQL Injection vulnerability that I recently uncovered in a private web application.

Although the target was an invite-only platform, it gained popularity among many white-hat hackers, with numerous attempts already made. Upon receiving the invitation, I noticed that the target had been listed on BugCrowd for over two years, with more than 250 bugs discovered and rewarded thus far.

Clicking on the “Accept Invite” button, I was well aware that finding even a P3 bug would not be easy, let alone a P1 or P2. However, I was determined to approach the challenge with creativity and think outside the box to uncover something that no one else had discovered yet.

SQL Injection In the GraphQL Query

The target had an extensive scope, but excluding subdomains. The scope was defined as “target.*,” encompassing a broad range of ccTLDs (e.g., target.co.uk, target.it, target.ae, target.co.in, target.com, etc.). I found this particularly interesting since it covered various country code top-level domains.

Knowing that the target operated in countries worldwide, I realized that it would be relatively easy to identify the TLDs using certificate transparency (CT) services. To proceed, I opened the main website, target.com, in Firefox, aiming to extract the Organization name from the SSL certificate (as shown in the example screenshot below) and copied it for further analysis.

It is indeed worth noting that many organizations register their SSL certificates under the name of their organization, such as “Twitter, Inc.” Therefore, when conducting searches for subdomains or ccTLD domains, it is crucial to use the Organization name as part of your search criteria. This approach can help ensure more accurate and comprehensive results.

Next, I utilized tools like netlas.io and crt.sh to search for every possible ccTLD domain associated with the identified Organization. By combining the results from both sources, I obtained over 7,000 results, including subdomains.

However, after applying thorough filtering and analysis, I narrowed down the list to approximately 64 endpoints to focus on. This selection process aimed to identify the most relevant and potentially vulnerable targets for further investigation.

HTTP Probing and Parameter Discovery

IAfter copying the list to my Kali VM, I proceeded to send the list of endpoints through httpx to perform probing. Following the probing process, I discovered that 57 endpoints were live and responsive.

To conduct a comprehensive analysis of the endpoints, I employed ParamSpider, using the following command while excluding subdomains by setting the -subs False flag:

cat targets | xargs -n 1 -I {} python3 ~/ParamSpider/paramspider.py --subs False --domain {} --level high | urldedupe >> all-param.txt

This allowed me to gather additional information and potentially identify any vulnerabilities or areas of interest within the targeted endpoints.

UsingParamSpider, I encountered a considerable amount of data, with approximately 20,000 lines of URLs. To refine the list and remove irrelevant or extraneous information, I carefully filtered out the garbage data, resulting in a final list of 12,000 relevant URLs.

Subsequently, I began inspecting the parameters and URLs, only to discover that the majority of them were similar links to product pages. An example of such a URL is: https://www.target.co.xx/en/xxxx/category2/men/t-shirts.xxx?n=xx&s=xx&ww=xxx. Unfortunately, these URLs did not provide any useful information for my investigation, as they contained the same parameter structure across more than 10,000 instances. I performed a few tests for SQL injection and XSS on a subset of these URLs, but found no vulnerabilities.

To further narrow down the list, I filtered out all the product URLs, resulting in a curated list of approximately 1,600 URLs that appeared more promising for further analysis and vulnerability testing.

Nuclei Scanning

With the intention of exploring the technology behind the curated list of URLs, I proceeded to conduct a default scan using Nuclei. Within a matter of seconds, I obtained the scan results.

While there were multiple findings, one particular result immediately caught my attention. It appeared that one of the country-specific top-level domain (TLD) websites was utilizing GraphQL.

However, it seemed that there was a misconfiguration in the GraphQL implementation, indicating a potential security vulnerability. This finding warranted further investigation to better understand the nature and implications of the misconfiguration.

Burp Suite Scan

When there’s a hint, I always confirm it through Burp Scanner.In this case, I used Burp to further investigate the URLs. After initiating an active scan, I received a positive result.

Burp Scanner detected a potential SQL injection vulnerability when a single quote (‘) was submitted in the request body. The server responded with a “500 Internal Server Error,” indicating that the input triggered an unexpected response from the server. This finding strongly suggests the presence of a SQL injection vulnerability that could potentially be exploited.

However, regarding Burp Suite’s findings, the issue remains tentative. Therefore, I’m unsure if there is indeed an SQL Injection vulnerability present or if it might be a false positive.

SQLMAP and Ghauri Couldn't Find The Injection

I proceeded by copying the request and sending it to both SQLMAP and Ghauri for further analysis. However, despite these additional tests, neither tool was able to identify any injections or vulnerabilities.

This outcome indicates that the initial potential SQL injection detected by Burp Scanner may have been a false positive.

I took matters into my own hands and decided to manually investigate the potential SQL injection vulnerability, as I firmly believed in Burp Suite’s ability to identify such vulnerabilities. I disregarded other endpoints for the time being until I could confirm whether SQL injection was possible.

Finding Right GraphQL Query

To begin, I opened Burp Community edition on a separate screen and sent a request to the vulnerable URL. I then started capturing the request to analyze the responses it provided for different types of queries. After dedicating an hour to this task, I finally captured the complete query used to retrieve or modify the “gender” data of a user. The query accepts three keywords: “M” for Male, “F” for Female, and “NA” for Not Applicable.

The example query is as below:

{
"query":
"query ($_key***_0:String!, $_***_0:Int!) {*****
(keyword:$_key***_0, ****:$_***_0){ key***_text, number_of_result,
number_of_uses, ***_id, gender_cd, url }}",
"variables":{
"_key***_0":"M",
"_***_0":"1"
}
}

Finding Blind SQL Injection

With the identified query in hand, I proceeded to experiment with different payloads to test the vulnerability. Based on the information gathered from the Nuclei scan, which revealed that the application uses PHP running on Apache, I focused on sending MySQL Sleep payloads.

The breakthrough came when I sent a specific payload, resulting in a delay in server response for precisely 10.121 seconds. This confirmed the presence of the SQL injection vulnerability, and I further validated it by employing various payloads with different time delays. The successful exploitation of the vulnerability further solidified its existence and potential impact.

XOR(if(now()=sysdate(),sleep(9),0))XOR\"Z

I felt immense relief upon witnessing the server’s delayed response aligned with the query I had sent. At times, I was on the verge of giving up out of frustration when things didn’t initially work as expected. However, determination, focus, and hard work ultimately paid off.

Without delay, I promptly prepared and submitted the report. Additionally, I inquired with the trigger if they wanted me to run SQLMap to gather further details such as the host name, database, or current user. They responded by stating they would consult the client for guidance. Nevertheless, the report was triaged as a Blind SQL injection, and the target acknowledged my efforts by rewarding me with $3500 and 40 points.

Thank you for reading, and stay tuned for my forthcoming discoveries. On another note, I’m considering writing a blog post about my findings on Log4Shell. If you are interested, please let me know.

I’m on Twitter if you wish to follow me :)

--

--