Multiple Vulnerabilities including Account Takeover, Bypass OTP, etc.
Let me introduce myself first. It’s Farjaal Ahmad here. I am new to Bug Bounties and it’s my First write-up so Forgive my mistakes and sorry for bad English :P
So, I’ve got a project to pentest and report the Vulnerabilities and help them to patch the vulnerabilities.
Let’s call the project site site.com and it was the trading site, including cryptocurrency, etc. As I tested Most of the Functionalities of the website, so, It’s a Long Write-up. Hang on Guys :D
Some Mentioned Bugs in this Write-up are,
- Email Verification Confirmation without having Access to the Email account.
- Account Takeover via Reset Password Functionality by Leaking Token in Response.
- Abuse the RateLimit Functionality to Bruteforce password.
- Abuse the RateLimit Functionality to Bruteforce OTP.
- Bypass OTP with Response Tampering.
- Transfer Money without Transaction fee (Parameter Tampering).
At first sight on the index page of site.com, there was a login page and signup page which caught my attention. I opened my mailbox and put my mail into the “forget password” field and submitted it.
Tip: Always check your unregistered email by putting it into the forget password field. Sometimes, Webapp sends the mail anyway and leaking some information which may help us to understand the workflow.
Back to Point, I didn’t receive the mail. I got the registration page and signed up myself. Without confirming the mail, site.com was not letting me sign in. I again got into my mailbox and check the confirmation link, It was like,
https://site.com/email-verification/[EMAIL_HERE_IN_BASE64_ENCODED]/[USERNAME_HERE_IN_BASE64_ENCODED]
This caught my Attention, after decoding the fields, I came to know that developers only confirming the mail by just base64 encoding the email and my username. After pasting the link in the browser, it returned that “You have successfully confirmed the mail. Now you can log in”, Woah!
This was the First Bug, “Email Verification Confirmation without having Access to Email account”
Next, I was shocked at the developers, how they coded the web app. Anyway, I came back to the forget password page. I put my registered mail there and submitted it. I received a link which was like,
https://site.com/reset-password/[ENTER_EMAIL_HERE]/[ENTER_TOKEN_HERE]
My eyes were stuck there at the Email. I was be a link, what’s the point of putting the mail into the URL? I got the reset password page and changed my password. The “Token” field took my attention. I was like, what if I can reuse this token on the same email. I reopened the URL and surprised to see that the “Reset Password” page opened. I reentered the new password and submitted but there was a message that this token is expired. I got very upset at that moment. I generated another token by “Forget Password” functionality. Another Idea hit on my mind that what if I make another account and put the 2nd email in the field and put the token of the first email account?
I got up and created another account. I entered the mail of the 2nd account and token of the 1st account into the above link. I was really Shocked this time that the “Reset Password” page opened. I entered the password and submitted but that was my bad luck. A message “Token does not match” appeared on the website. I was about to leave testing this functionality. After some time, I retested this and forget the password of the 2nd mail. This time, I was looking at the Intercepting the Request/Response. When the message appeared that, email send successfully, there was a Token value in the Response which caught my attention. I entered the mail of the 2nd account and token value from the response into the URL and opened it. Again, the Reset page was opened but this time my expressions didn’t change. I reentered the password and clicked on Submit. A message “Password Changed Successfully” appeared. Here I got Shocked. All I need is the emails of the users of that organization and I can easily take over their accounts easily.
This was the 2nd Bug, “Account Takeover via Reset Password Functionality by Leaking Token in Response”
Here I’m in the Account to test the Internal functionality. But before that, I was thinking to test the rate limit on the login page. I fired up the Burp Intruder and loaded a wordlist and started the attack. Here I’ve seen 2 new Headers which were never there.
The first one was “X-RateLimit-Limit: 1000” and the other was “X-RateLimit-Remaining: 996”. The intruder was firing the passwords from the wordlist but I was also looking at the header “X-RateLimit-Remaining”. It was decreasing by the requests of intruder was making. At last, It reached 0, and the response status code was 429 “Too Many Request”. I was really tired at this point. I turned off my laptop and didn’t touch it in 2–3 days.
After that, Another thing hit on my mind. What if I can abuse this “X-RateLimit-Remaining” header and bypass it to Bruteforce the password? I turned on the laptop and started everything where I left before. I, Again, fired the Burp Intruder and loaded the wordlist, and started the attack. When the ratelimit-remaining got 0 and the response code become 429, this time I didn’t stop the Intruder. I got up for Smoking, when I came back, I was shocked to see that the status code is again 200 and “X-RateLimit-Remaining” is again started from 1000. Here I was shocked to see the 200 status code. I scrolled up and checked the 429 status code response, there was another header “Try-After: 336”. Seems so Spicy. So the web app suspended us for a couple of seconds (Under 10 Minutes).
Here the Fun begins, I fired up my Sublime-Text and started to code a script in Python. I Automated the entire process. When the response.status_code becomes 200, the script starts firing the passwords and when the response.status_code becomes 429, the script just waits for the 200s.
In this way, I bypassed the rate limit. This was the 3rd bug, “Abuse the RateLimit Functionality to Bruteforce password”
Again, I’m in! Now I was Surfing the site. There was everywhere a popup asking 4-Digit OTP which was sent on the email by mentioning “Email Verification Code”. Every time, I do anything, I have to put the OTP from my mailbox. This really Pissed me off. I tried the Bruteforcing the OTP but same as above, there was a rate limit header. I have to put OPTs from 0000 to 9999 and after every thousand, I’ve to wait for a couple of minutes, but I bypassed that somehow.
This is how I “Abused the RateLimit Functionality to Bruteforce OTP”
This was really time-consuming and I’ve to wait at least half an hour to get the OTP. This again really Pissed me off. So, I started to looking at the response while it sends an OTP but there was nothing there. I turned off the Laptop again. The next day, I retested it again. I entered random numbers into the OTP field and intercepted the request at https://site.com/api/v1/verifycode. The response was
{“data”:{“error”: true,” message”:” Your given code is not matched!”}}
I started to get headaches but suddenly, my eyes stuck on error: true. I changed it to “success: true”. Guess what? OTP Bypassed :v
This was another bug, “Bypass OTP with Response Tampering”.
Now, I got the feature of transfer money from one account to another account. I deposited $100 into the site and transferred $5 to my other account. There was a Transaction fee of approximately 1% of the amount being transferred. :|
I intercepted the request and response and there was a Parameter “fee” which includes the fee on the transaction. I changed it to zero. The amount transferred without any transaction fee. Here was the OTP again but I bypassed with Response Tampering.
So, Here’s another bug, “Transfer Money without Transaction fee (Parameter Tampering)”
Impact: From Account Takeover, we can bypass OTP and Steal the Balance of other Users, all we need is the email of the victim.
That’s all for today, Thanks for reading it at all ❤
Love you all Guys. #KnowledgeShouldBeFree #ServeCyberSecCommunity
Insha Allah, I’ll back with another amazing Write-up. Until then, Take care guys ❤