Hey Hackers!! Have you ever seen the importance of different roles in an organization? Well, if not, imagine you need a freelance marketer and you gave him access as an editor to your facebook page having 1 Million following. What if he has the power to remove you from adminship? Worst case scenario, what if he can use the attached payment details of your account to run ads or buy/sell on Facebook?
Scary? Right. Ok you can stop imagining now.
Here is the story of the same kind of scary bug but on another private bug bounty program at Hackerone. It was very easy to exploit but it took me quite a while to find.
Let’s call the target target.com. Target.com is a premium service and one has to pay in order to get into it and start using it. The one who pays for this premium product is called paying admin which is the same as super admin. There is a feature of a team where you can invite other team members as an admin. Let’s call the other admin as invited admins. The invited admins could literally do anything in the product console. The only thing I noticed they can’t do, was to remove the paying admin. They couldn’t remove the paying admin
Yeah, from the invited admin account, I started looking deep into it and tried various ways to remove the paying admin but in vain. They have adopted every kind of validation to avoid privilege escalation. This was the only single thing the invited admin couldn’t do. When you try to remove the paying admin, it gives an error of “ Error: Deleting admin; Status Failed. Delete paying admin not allowed“.
After a while, I found, the only way to remove the paying admin is to Edit the payment details, put in your own banking details and now you get charged for the subscription of the product. This way you become the paying admin now and can perform any action including removing all others admins. But this is just a feature through which the product is making sure that somebody in the team is paying for their product subscription.
I closed my burp suite and just started playing around from the invited admin account. The goal was to remove the paying admin without attaching my own payment details. I went to the payment section, and clicked on “cancel subscription”. The subscription got cancelled but we have some days remaining in the subscription and we can use the product till then. Now I went back to the team portion and tried removing the paying admin.
And guess what? I can remove the paying admin from the team and use his remaining subscription without attaching my own payment details. Yayyy!!! But how did this all happen?
Take this piece of dummy code to understand the logic behind the bug.
When you try to remove the paying admin, you can’t because he is paying admin and one can’t bypass that logic. But when the invited admin cancelled the subscription the authority of paying admin became as equal as invited admins. And hence the ELSE statement executed. If someone tries to remove him, they can, because the above logic (IF) is no longer true.
But I could use the remaining subscription till it’s last date, not more than that. If I want to use more, I have to attach my own payment details, which quite saddened me. Now that I have removed the paying admin, I was looking for something interesting which could save me from paying for an upcoming monthly subscription and make this low severity bug into high severity.
I went to the billing section and saw a feature called “Reactivate Your subscription”. Well, I was sure, if I clicked on that, it would ask me for payment details in order to have a future subscription. But a good hacker is someone who tries everything. I clicked on it and just saw my page get refreshed. Well that’s strange, I opened up my burp suite and retried this because it was totally unusual behavior. It was supposed to ask for my payment details in order to continue for future subscriptions but It didn’t. I clicked on “Reactivate Subscription” with burp interception on. I saw a request was generated to stripe API. I clicked on “Do Intercept Response” in my burp to see what the STRIPE was saying in the http response. I forwarded the request and waited for the response. The response from the stripe api was something like this”
No way!! The subscription got reactivated with the old paying admin payment details? Because I could see his details in http response. I couldn’t believe it and waited for this current subscription to expire, so I could see who would get charged for the next subscription. I was pretty sure it would be the removed paying admin because the invited admin haven’t attached his payment details.
When the remaining interval in the current subscription expired, my subscription got renewed by itself but with whom money? I went to the invoice portion and saw the new subscription details and yeah, I was right. It was the removed admin who paid for my new subscription and will do so in future as well. (haha)
It all happens due to the above programming logic. As you can’t remove the paying admin until you add your payment details. This way the stripe api updates the payment info and charges you for the next subscription. But when you bypass that logic and remove the paying admin, the STRIPE API still operates on the old details. It wasn’t ready for such behavior (case)
Inshort, all you need to exploit this bug is to cancel the subscription, which can let you remove the paying admin (even as an invited admin) and then reactivate the subscription. Now enjoy using the product without paying a penny.
As mentioned in the title, it went informative but still one of my favorites because of the simplicity of exploitation. The triager gives some unusual logic which I am still puzzled at but that’s the part of a game.
The reason for writing a blog on this was not to showcase my bounty amount but to preach an idea of how logical bugs can be simple sometimes. The essence is “You must try things which may not work”. Thanks Muzzamil for proof reading this writeup.
Let’s get connected on Twitter: