How I Got My First Bounty: The Exciting Story of My Bug Bounty Breakthrough

6 months ago 51
BOOK THIS SPACE FOR AD
ARTICLE AD

whit3ros3

Long time no see! I’ve been a bit preoccupied with other tasks besides bug bounty hunting, so I haven’t had the chance to post any blogs. But setting all that aside, today I want to share how I achieved every beginner bug hunter’s dream: scoring that first bounty. Still gives me chills just thinking about it!

So, without further ado, let’s dive into the details of this exhilarating experience.

Let’s get Started

The most important takeaway from this blog is simple:

Keep learning about different vulnerabilities and, more importantly, put that newly gained knowledge into practice. There are hundreds and thousands of websites out there waiting to be hunted, with millions of vulnerabilities just waiting to be discovered by someone.

Further Details

Here’s how it all went down. The bug that landed me my first bounty was actually a combination of two bugs:

GraphQL API key leak & cache poisoning.

The target? A private one I stumbled upon using some good ol’ Google dorking. (Psst, here’s a handy repo for some similar Google Dorks.)

Exploration

The scope of my program was massive, which was great because it meant more things to poke at. I started by hunting down the main domain and, as some of you might know from my previous blogs, I have a thing for starting with finding JavaScript files — they’re like treasure chests sometimes, just sitting there with API keys waiting to be exploited.
So, I ran my trusty one-liner commands to extract those JS files and extract the API keys in them, one after the other.

cat domains.txt | waybackurls | grep '.js' | httpx -mc 200 >> js.txtnuclei -l js.txt -t /home/kali/.local/nuclei-templates/http/exposures -o potential_secrets.txt

(Hey you!! Confused about where these commands came from? Check out my last blog.)

While these were running in the background, I used the ‘dirb’ tool to discover all directories related to the target.

A ray of light

After letting both processes run overnight, I woke up to some promising results. Nuclei didn’t disappoint, flagging a JS file containing a GraphQL API key. To verify, I opened the JS file and found this:

And dirb did its job too, giving out a bunch of URLs but one which quickly grabbed my eye after finding that API key

https://www.redacted.com/graphql

Lesgoooooo!!!!

But then came the moment of truth: “You don’t know squat about GraphQL, bro.” Just this line kept running through my mind.

Collecting the arsenal

So, Determined to overcome this hurdle, I immersed myself in learning about it. Shoutout to PortSwigger Academy — that place is gold for learning about vulnerabilities, my go-to resource for mastering vulnerabilities.
So, my next couple of days went solely into researching, learning, and collecting all my arsenal against this new enemy of mine.

So, I stumbled upon something called an introspection query, which basically lets you peek into the GraphQL schema. It’s like a special query that clients can use to ask a GraphQL service about its structure. With this query, you can get info about types, fields, directives, and more.
(Psst, wanna know more about it?? Here you go.)

Result of introspection query

But let me tell you, when I first got this response from using the query, it was a bit overwhelming. It just kept going and going, and as a newbie to GraphQL, it was like trying to make sense of a maze.

Then came the lifesaver: the “InQL Burp extension.” It helped me visualize the schema in a way that even a total beginner like me could understand. All I had to do was copy-paste that chaotic response into a text file and feed it to the extension, and bam! Everything suddenly became much clearer. Easy peasy, right?

Exploring the Schema

After using the InQL Burp extension, I got a beautifully visualized version of the GraphQL schema, all nicely structured and organized. It was a relief to see everything laid out so clearly.

Then, it hit me: I remembered finding two API keys in the JavaScript file.😈

So, here I had the schemas for both of these keys. But wait a sec… the schema from the private key had two extra queries: “tags” and “users”.

First, I checked out the “tags” info, but nothing interesting popped up there. Then, it was time to dig into the “users” field. Fingers crossed, I used some queries to see what this “users” field was all about.

And guess what? Voilà!

Got the data of different users, and let me tell you, it was like hitting the jackpot!

The Unexpected Twist

I was all set with all the data in hand, ready to start writing up my report. Description, check. Steps to reproduce, check. And then, it was time for the POC (Proof of Concept).
So, I started sending different Burp requests to take screenshots, something caught my attention! After a few requests, I realized that I had forgotten to include the auth header containing the API key. But here’s the twist— I was still getting responses. Bro, what?!

And just like that, I stumbled upon something unexpected: another bug!

Understanding Cache Poisoning

Luckily, I already knew what it was because right before diving into hunting on this target, I had finished learning about a new vulnerability that was new to me: “Cache Poisoning”.
In simple words it’s when a hacker messes with the information stored in a cache (a temporary storage) to make a website or network give out wrong or harmful data to users. It’s a way to trick systems into doing things they shouldn’t like giving unauthorized access.

So, the same thing was happening in this case: the auth header containing the API key was getting cached!
That means once the key is cached, anyone can query from the GraphQL.

Closing the Deal

Now, with everything in hand and a bonus vulnerability to add to my report, I completed it and marked the vulnerability as “High”. Then, all there was left to do was wait.

So, I waited and waited for what felt like ages, but no response came from the program. After a while, I kind of forgot about it.

Then, one day, a few months later, I got this email.
A good thing and a bad thing happened.

The good thing? I got a response. But the bad thing? They marked it as a low-level bug.

I tried really hard to explain that this vulnerability was more serious than they thought, but they didn’t see it my way. It was frustrating, but I knew I had to let it go and keep hunting for more bugs.

Then, after a few days, another email came and… Goosebumps!!!

I finally got my first bounty, and it was $700! (Maybe it’s less for some hunters.) But hey, this being my first bounty and on a ‘low’ severity bug, I was dancing like crazy!

Conclusion

Finally, it all came together, shining brightly! Oh man, what a wonderful feeling that was.

Just a little reminder for my fellow hunters who are still striving for their first bug or first bounty: keep doing what you’re doing. You’ll get there soon, and let me tell you, when you do, it will all be worth it!

Read Entire Article