How I hacked Bitcoin Mining Pool
Hey! I decided to write here about some my hacking cases. I think it will be useful for both developers and bug-hunters. And also interesting for users. So let’s start.
Bitcoin exchanges and other sites working with crypto-currencies today are a very tasty target for hackers. It seems that their safety should be at a high level. But it is not always the case. You can be sure of this by visiting BlockChain Graveiard for example. Or just read my story.
So I specifically visited https://pool.viabtc.com - one of the big mining pool - to find some vulnerabilities.
After I had registered account, I attached the phone and connected two-factor authentication via Google Authenticator. Also option “Authenticate When Sign In ViaBTC” (2fa on login) was enabled.
Now let’s talk about what I discovered!
1. The site is not protected against CSRF attacks.
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.
In this case it was found that the attacker can change the email of any user who will go to his site. When the victim enters the attacker’s website, a request will be sent on its behalf.
1) The victim comes to a malicious site.
2) The victim does not suspect anything, but at that moment a request was sent to change the email address on the https://pool.viabtc.com/:
3) The attacker receives an e-mail for confirmation:
4) Then the attacker goes on the link and sees:
The email was successfully changed and the attacker automatically logged in to the victim’s account!
But after a few seconds, it will be redirected to “Home” and a window of the second step of the authentication will be appeared (2fa on login, do you remember?):
Thus, at this stage, the attacker managed to bind his email to the victim’s account. But the account is still protected by two-factor authorization.
2. Bypassing Two-factor Authentication on login.
A critical error in the implementation of two-factor authentication was discovered. In some web-application functions, the second authentication step is required only in the frontend. If the request is sent directly to the backend, it will be executed successfully without the second step of authentication.
Thus, an attacker can send a direct request to disable two-factor authentication when he is logging in
1) The attacker uses the request below to disable authentication on login:
As you see the request was successfully performed.
2) The attacker goes to “Home”, but now authorization is not requested!
What other functions are covered by this method of bypassing authentication? Let’s recall the first point, where the victim sent a request to change the email. If you want to change the email in the frontend, then you will need to perform the second authentication step for this. But if you send the request directly, then authentication is not required. Due to this lack of security, an attacker could change the email using CSRF.
Thus, at this stage, the attacker stole the user’s account and access to his confidential information. But significant operation requires confirmation by two-factor authorization. The attacker can not change the password, for example.
3. Bypassing Two-factor Authentication
The web-application allows you to use two methods of confirmation: SMS-code or Google Authenticator code. But I discovered another undocumented method — email-code.
How? I drew attention to confirm the action via SMS-code. See how it looks:
And then I thought. What if you replace “sms” with “email” in the first request? And what if you replace “sms_code” with “email_code” in the second? As you have already known, it was worked successfully!
The attacker can not control the mobile phone and Google Authenticator, but he can control email (he linked his email to the victim’s account).
So the final steps
- The attacker sends a request below to obtain a confirmation code and change Google Authenticator account:
2. Then he receives the code in the mail:
3. Now the attacker can send a request with confirmation by email-code instead of verifying via SMS-code or Google Authenticator:
4. Since the request was successful, the attacker is able to сhange Google Authenticator account to its own:
Thus, the attacker had the opportunity to steal any account. The victim need only to visit his page.
Сonclusions
Vulnerability chain led to account takeover, which is certainly critical. And this is not very difficult to fix:
- Implement CSRF-tokens.
- Perform server-side checks.
- Disable confirmation function via email.
But looking deeper, these vulnerabilities are just the symptoms by which we can diagnose:
- Developers do not have a basic knowledge of the security of Web-applications. At least knowledge of the bored “OWASP TOP TEN” would rule out the appearance of such a banal vulnerability as CSRF.
- Developers consider their frontend to be the only one source of data for the backend and trust its too much. But this is not true: we can send requests directly to the backend.
- There is no strict policy regarding the functionality. Developers allow the debugging feature in the production version of the web application.
The main thing is not just mitigate those couple of vulnerabilities that I found. It is important to look at the key of the problem. The technical team must draw conclusions and improve their knowledge of security.
Timeline
- 13.12.2017 — Reported.
- 14.12.2017 — Accepted.
- 15.12.2017 — Fixed. Received a bounty.