This month marks 2 years of formal Bug Bounty hunting for me, with my first report submitted to a program on Bugcrowd on July 27, 2019. That report was marked Not Applicable
and to this day I’m genuinely bewildered the company hasn’t fixed it. I followed that up with a report marked P4 / Informational
for a subdomain with an exposed web.config
file. Exciting stuff (not really). My first 10 reports had an average severity rating of 3.7 with 1 N/A, 5 Informational, and the remaining 4 accepted.
Today, I’ve made it into the top 200 in Bugcrowd’s all time ranking with 134 accepted vulnerabilities including 20 P1’s. Looking back on my first reports I’m amazed at how much I’ve grown both in finding hard hitting vulnerabilities AND writing compelling reports to drive home the impact (or why the company should care). In my still relatively short experience, I’ve found impact drives severity as much as or sometimes more than the class of vulnerability. With that in mind, I decided to share high level write-ups of all of the Critical severity bugs I’ve submitted to Bug Bounty programs over the last two years with the goal of helping you take your hunt to the next level.
This was my first P1 and it was a classic bug taught in many CTFs. I’m obviously always excited when I set a vulnerability rating that automatically suggests P1, but I believe I may have been shaking with nervous excitement for this one — my first. This was a private program that had JUST opened up, one of a few I had been invited to at that point. I had submitted 17 reports prior to this with just 10 accepted — all as either P3/Medium or P4/Low.
I was testing the authentication, password reset, and user profile flows when I discovered this bug, which allowed an attacker to reset a victim user’s security question and answer through parameter tampering. Rather than rely on the session, the application included the username in the POST similar to security_question=hacked&security_answer=hacked&username=victim_account
. This wasn’t a Cross Site Request Forgery (CSRF) to trick a user into changing their own question and answer — ANY user could submit a new security question and answer for ANY OTHER USER. Worse, the password reset flow only required you to provide the security answer before prompting you to set a new password — meaning once you had completed the exploit to reset the victim’s question and answer, you could log out and reset the victim’s password, completing the account takeover.
Date: November 7, 2019
Vulnerability: Broken Authentication and Session Management > Authentication Bypass
The second P1 came hunting on the same private program as the first. This application is a Business to Business site, where a business can establish an account and have various users granted access within that account. New users are able to self register but are required to provide the business’s account number and the associated zip code. Using a previously identified Insecure Direct Object Reference (IDOR) vulnerability on completed orders, I was able to enumerate valid account numbers and the associated business’s name — but not their address.
Luckily it’s easy enough to find a business on Google which provided the needed zip code, but I also identified a lack of rate limiting allowing me to use Burp Intruder to submit the form repeatedly, ultimately brute forcing the answer using the roughly 42,000 valid US zip codes. Once the form returned successfully, I could log in and access the business’s full account details, submit orders on their behalf, and more.
Date: November 14, 2019
Vulnerability: Broken Authentication and Session Management > Authentication Bypass
My first critical on HackerOne! For whatever reason I don’t spend much time there, but a program got my attention for using Adobe Experience Manager (AEM) and 0ang3el hadn’t been there to show them the error in their ways. Thanks to his scanner, I quickly identified an OS Command Injection vulnerability and executed the various Proof of Concept commands whoami
and cat /etc/passwd
. I had spent quite a bit of time following 0ang3el’s research on AEM, and while this was a non-paying program, it’s to this day one of the easiest bugs I’ve reported. This is also the first time I’ve seen a company implement the fix before the Triage team even reviewed the finding.
Date: July 31, 2020
Vulnerability: OS Command Injection
On programs with a large scope, where there’s one finding there’s often more. My scanner’s picked up a second instance with the same vulnerability.
Date: July 31, 2020
Vulnerability: OS Command Injection
Although I had been moderately successful in the first half of 2020, things really picked up in late July into early August. This bug was the first of 4 P1s, among 31 total submissions, in a large scope private program of a Fortune 500 company and a program where I really started to hit my stride as a Bug Bounty hunter.
This company had various unauthenticated workflows that required semi-private user information, such as a user’s phone number and date of birth. I myself was not a customer of the company but have a good friend who agreed to let me use his information. His phone number and date of birth exposed a third key piece of information, we’ll call them widgets. Using his first name, last name, phone number, date of birth, and information about the widgets enabled me to access a request form. In the background, this form interacted with a JSON based REST API similar to https://domain.com/api/v1/widget/123456
. Conveniently, when the client side Javascript triggered the request it appended an API key into a custom header (since the user isn’t authenticated the application can’t rely on a session). From there a simple parameter tampering to increment the URL exposed the IDOR — and it was a big one returning full customer information equivalent to what you might find accessing their database.
Date: August 5, 2020
Vulnerability: Broken Access Control (BAC) > Insecure Direct Object References (IDOR)
It took me over a year to get 5 Critical submissions across Bugcrowd and HackerOne combined. While two were identified through simply running a scanner, two others required chaining lesser vulnerabilities to expose the necessary data needed to access and accomplish the ultimate exploit. None of the vulnerabilities were overly technical but the 3 logic bugs did each take a bit of testing and ultimately knowing where to look.
Look for parts 2, 3, and 4 in the coming weeks that will each cover another 5 critical vulnerabilities as I work through recounting all twenty critical submissions to date.