Attackers can steal all of Ether in ROC (Rasputin Online Coin) token smart contract (CVE-2018–10944)

Jonghyuk Song
Coinmonks
3 min readMay 14, 2018

--

Abstract

I found a vulnerability of a smart contract for ROC (aka Rasputin Online Coin), an Ethereum ERC20 token (CVE-2018–10944)[1]. The request_dividend() function has a critical bug similar to Reentrancy attack. Attackers can call the function in multiple times to steal Ether constantly until all of the contract’s Ether is drained.

Details

Figure 1. Source code of the request_dividend() function

Figure 1 shows the source code of the request_dividend() function [2]. First, this function computes holder_token_balance and holder_profit using balances of token_holder which is an argument of the function. Then, it sends Ether to token_holder as much as holder_profit. However, the balance of token_holder is not decreased after or before the transmission. It means that we can send the same amount of Ether to token_holder again and again until all of the contract’s Ether is drained. Moreover, request_dividend() function is declared as public and there is no permission check, so anyone can call this function and send the contract’s Ether to any address.

What attackers can do?

Attackers can get all of the contract’s Ether by calling request_dividend() function repeatedly. All they have to do is buy some ROC tokens and call request_dividend() function with their account addresses. Attackers can get all of the contract’s Ether by calling the function infinitely.

Why it happened?

I am not sure why they implement the request_dividend() function like this. In my opinion, there are two mistakes in here.

First, the request_dividend() function does not check how much Ether have been transferred to specific address before. Therefore, the request_dividend() functions send same amount of Ether even though it is called with same address in multiple times. It is similar with Reentrancy attack that it became widely known because of The DAO Attack [3]. One way to fix is to decrease the balance of token_holder at somewhere of the function. After The DAO Attack, developers usually insert the code decreasing the balance of accounts before the transmission.

Second, there is no permission check in the request_dividend() function. It is declared as public and also there is no check for msg.sender. Therefore, anyone can call the function with any address.

Figure 2. fallback function of the contract

Figure 2 shows fallback function of the contract. In the fallback function, it executes the request_dividend() function when msg.sender is owner. From this code, I guess that the developers intended to design the request_dividend() function that only owner can call it. However, they forgot function visibility, such as internal, and permission check, so it causes a critical bug.

Damages

Fortunately, this smart contract does not have any Ether, so there is no Ether that attackers can steal. However, attackers continuously monitor the contract and then they can steal the Ether as soon as someone send Ether to the contract. Sadly, but fortunately, ROC token is not promising token (it is not listed on any exchanges yet) so I expect that there will be no users who send Ether to the smart contract of ROC token.

Report

I had tried to report it to admins of Rasputin Online Coin. However, their ICO official site is down, so I can’t find an email address in charge of the smart contract. I found an email livesupport@verotel.com in https://www.rasputinmansion.com/ and sent an email but there is no response. So, I recommend that do not buy this token until it is fixed.

Conclusion

Developers should be careful when they implement functions transferring Ether because a small mistake can lead to a serious problem such as this bug, and The DAO Attack. They should consider who is the callers of the function, and carefully check the balances of the accounts and the possibility of duplicate transmission. Finally, it is dangerous to buy a crypto coin that is not verified completely.

Reference

--

--