This article is about how I found a vulnerability on Instagram that allowed me to hack any Instagram account without consent permission. Facebook and Instagram security team fixed the issue and rewarded me $30000 as a part of their bounty program.

Facebook is working constantly to improve its security controls on all of their platforms. As a part of it, they recently increased reward payouts for all critical vulnerabilities including account takeovers. So I decided to try my luck on Facebook and Instagram. Fortunately, I was able to find one on Instagram.

Also, read 12 ways to hack Facebook account

Instagram forgot password endpoint is the first thing that came to my mind while looking for an account takeover vulnerability. I tried to reset my password on the Instagram web interface. They have a link based password reset mechanism which is pretty strong and I couldn’t find any bugs after a few minutes of testing.

Then switched to their mobile recovery flow, where I was able to find a susceptible behavior. When a user enters his/her mobile number, they will be sent a six-digit passcode to their mobile number. They have to enter it to change their password. Therefore if we are able to try all the one million codes on the verify-code endpoint, we would be able to change the password of any account. But I was pretty sure that there must be some rate limiting against such brute-force attacks. I decided to test it.

My tests did show the presence of rate limiting. I sent around 1000 requests, 250 of them went through and the rest 750 requests were rate limited. Tried another 1000, now many of them got rate limited. So their systems are validating and rate limiting the requests properly.

Two things that struck mind was the number of requests and the absence of blacklisting. I was able to send requests continuously without getting blocked even though the number of requests I can send in a fraction of time is limited.

After a few days of continuous testing, I found two things that allowed me to bypass their rate limiting mechanism.

Race Hazard IP rotation

For those who are unaware of race condition, please read it here. Sending concurrent requests using multiple IPs allowed me to send a large number of requests without getting limited. The number of requests we can send is dependent on concurrency of reqs and the number of IPs we use. Also, I realized that the code expires in 10 minutes, it makes the attack even harder, therefore we need 1000s of IPs to perform the attack.

I reported the vulnerability to the Facebook security team and they were unable to reproduce it initially due to lack of information in my report. After a few emails and solid proof of concept video, I was able to convince them that the attack is feasible.

Also, read how to hack instagram and its prevention measures

Proof of concept:

Requesting passcode

POST /api/v1/users/lookup/ HTTP/1.1

User-Agent: Instagram 92.0.0.11.114 Android (27/8.1.0; 440dpi; 1080×2150; Xiaomi/xiaomi; Redmi Note 6 Pro; tulip; qcom; en_IN; 152830654)

Accept-Language: en-IN, en-US

Content-Type: application/x-www-form- urlencoded; charset=UTF-8

Accept-Encoding: gzip, deflate

Host: i.instagram.com

Connection: keep-alive

q=mobile_number&device_id= android-device-id-here

The victim will receive a passcode and it will expire in 10 minutes.

Verify passcode

POST /api/v1/accounts/account_ recovery_code_verify/ HTTP/1.1

User-Agent: Instagram 92.0.0.11.114 Android (27/8.1.0; 440dpi; 1080×2150; Xiaomi/xiaomi; Redmi Note 6 Pro; tulip; qcom; en_IN; 152830654)

Accept-Language: en-IN, en-US

Content-Type: application/x-www-form- urlencoded; charset=UTF-8

Accept-Encoding: gzip, deflate

Host: i.instagram.com

Connection: keep-alive

recover_code=123456&device_id=android-device-id-here

Now we need to brute-force this endpoint using multiple IPs. Roughly, I was able to send 200 requests from a single IP without hitting rate limit.

I have used 1000 different machines (to achieve concurrency easily) and IPs to send 200k requests (that’s 20 percent of total one million probability) in my tests.

Sending 200k requests

In a real attack scenario, the attacker needs 5000 IPs to hack an account. It sounds big but that’s actually easy if you use a cloud service provider like Amazon or Google. It would cost around 150 dollars to perform the complete attack of one million codes.

The Facebook security team was convinced after providing the above video of sending 200k valid requests. They were also quick in addressing and fixing the issue.

After the patch

I thank Facebook security team for rewarding me through their bug bounty program. Let me know your thoughts in comments 🙂