My absolute favourite functionality to attack when bug bounty hunting is 2FA implementations. Something about being faced with a difficult, but simple challenge consisting of nothing more than a simple 2FA code input field brings me back to the HackThis!! challenges that I used to spend hours on back in the day.
2FA codes usually consists of either 4 or 6 digits, making them inherently vulnerable to brute force attacks unless proper rate limiting is implemented. Unfortunately for us bounty hunters, the 2FA functionality on bug bounty program web applications are usually well-protected by rate limiting. This is the story of a business logic error that enabled me to bypass the rate limiting on a private program’s 2FA implementation, effectively making it possible to bypass 2FA.
After logging in, the site would redirect the user to a 2FA security check page. I tried to brute force it, but after 10 incorrect 2FA authentication attempts, the site would lock the user account. Annoyed that my attack had failed, I pressed the “Unlock Account” link to continue my testing.
I was asked to provide an email address and a reset link was sent to my email inbox. Now, if you think like me, you may already have spotted the potential vulnerability. I tested if the “Unlock Account” functionality was rate limited. It was not.
I did some additional research and I discovered the following misfeatures:
- There was no rate limiting on the login page if the submitted credentials were valid.
- Unlock Account links could be requested by an account that wasn’t locked and the links would remain valid.
Now was the time for exploitation. I wrote a quick script that would
- Send a Unlock Account request email.
- Submit valid victim credentials.
- Attempt to randomly guess the 2FA code 10 times.
- Read my email inbox and find the Unlock Account link using Gmail API.
- Send a GET request to the endpoint to unlock the account.
- Repeat until the correct code is guessed.
The account unlocking request is sent at first to minimise time wasted waiting for the email to arrive to the inbox.
I submitted the report to the program including the PoC script. The Bugcrowd triager seemed a bit sceptical initially due to the email inbox access required, but luckily the security team quickly accepted the report and even praised me for my creativity. I was rewarded handsomely with a $500 bounty.
Unlike many bounty hunters, I’m not a professional penetration tester or security engineer. I find it’s pretty much impossible to compete when hunting classical vulnerabilities such as XSS and SQLi due to amount of extremely skilled hunters and advanced automated vulnerability scanning. In my experience, I have way more success when trying to cheat the system and searching for logical bugs. Also, it’s really fun.