Hello, This is Samip Aryal from Nepal writing about my highest-paid report. This writeup describes rate-limiting issue in a specific endpoint of Facebook’s password reset flow that could’ve allowed the takeover of any Facebook account by bruteforcing a particular type of nonce.
Background
So basically, I wasn’t searching for any unique bugs for several months. It started when one day; during my Engineering board exam, I was like… Let’s search for Account Takeover; like literally! out of the blue; still not sure where it came from lol. Now, I needed a fresh untouched/hidden/unnoticed endpoint to look for. And when it’s about an “untouched endpoint”; i thought looking on the web is like nah.. Everybody looks on the web. So I started my Android Studio setup, jumped into Facebook’s main login page, and tried looking for one, uninstallation-installation of several versions of Facebook took place but nothing seemed new/interesting. Then I was like what if we try with different user-agents to see the server’s responses on each of the login pages?
and somewhere this poped-up in the password reset flow:
wait what! I’ve seen this option during the reset flow in one of my other accounts (in my default settings). But anyway, this shortly looked interesting for me to quickly jump to testing it. There were three reasons:
- The nonce sent to the user is active for longer than I expected (≈ 2 hrs)
- The same nonce code was sent every time for the period.
- I didn’t see any sort of code invalidation after entering the correct code but with multiple previous invalid tries (unlike in the SMS reset functionality).
This resulted me in eyeing a brute-force attack.
Technical Details
- Choosing any Facebook user account, go to its password reset flow.
2. Simply, Choose the following from the reset options:
This sends a POST request to:
POST /ajax/recover/initiate/ HTTP/1.1
with the parameter; recover_method=send_push_to_session_login
3. Send with a dummy 6-digit code ‘000000’.
This creates a POST request to the vulnerable endpoint:
POST /recover/code/rm=send_push_to_session_login&spc=0&fl=default_recover&wsr=0 HTTP/1.1
4. The “n” parameter holds the nonce.
5. Bruteforce this 6-digit value from 000000 to 999999. This can be done in multiple ways. Using web proxies like Burp Suite,
a) Send the above request to the Intruder and insert $$ placeholder in the ’n’ in order to bruteforce the nonce code and, make 10 sets/tabs of concurrent payload requests each with 10,000 possibilities (000000 to 111111, 111111 to 222222, and so on).
b) Or, automatically through the Burp’s resource pool, maximum concurrent requests can be set between 10–15, which should be sufficient to go through the entire search space in about 1 hrs.
6. Yes, there was no rate limiting on this endpoint, thus the matching code was responded back with a 302 status code. Use this code to log in/reset the FB account password for the user account.
7. Also, In my case, the option ‘Send code via Facebook notification’ got hidden from UI at my end, which might be due to some sort of protection but it could be easily bypassed by changing the IP address.
This a 0-click Account Takeover right?
Well, turns out that;
→ For some set of users, the nonce code would be rendered on the notification itself.
→ For the other set, the notification that is sent with the nonce would need to be opened and the code would be rendered on a separate screen.
Here, in this second case, according to Facebook — One tap of the victim is needed for the nonce to generate.
* Facebook replied that “While this did require user interaction, we consider clicking a notification to be a much lower bar than clicking a link sent to you by an attacker, therefore we decided to deduct from the 0-click ATO, rather than basing the bounty off the 1-click ATO”.
This vulnerability had a huge impact since it enabled the full takeover of Facebook accounts. It also helped me to rank 1 in Facebook’s Hall of Fame 2024 (currently)
Timeline:
Jan 30, 2024 — Report Sent
Feb 1, 2024— Pre-Triaged
Feb 1, 2024 — Clarification Requested by Facebook | Unreproducible
Feb 2, 2024 — Clarification sent that the issue seems fixed today
Feb 9, 2024 — Got an Invitation for BountyCon2024 (South Africa) in the same email thread of the issue; got confused.
Feb 22, 2024 — Rewarded with a clarification message that it was fixed after somebody else’s report that came after mine but I was the first to report (after investigation)
…
Thank you for reading this write-up, If you have any queries/suggestions, I’m available on Facebook/ Instagram/Twitter (X).
…