06/02/2021

Get Rich Or Die Trying

Introduction



This article is going to focus on "Programmable Money Overflow Attacks" on Ethereum and this is the way hackers can become rich and famous. More specifically we are going to discuss the batchOverflow attack. The batchOverflow Bug was identified in multiple ERC20 Smart Contracts [3] (CVE-2018–10299), back in 2018, when Ethereum was relatively new. [1]  

The batchOverflow attack is a typical integer overflow attack in the batchTransfer function of a smart contract implementation for the Beauty Ecosystem Coin (BEC). The BEC was an Ethereum ERC20 compliant token that allowed attackers to accomplish an unauthorized increase of digital assets by providing two _receivers arguments in conjunction with a large _value argument, as exploited in the wild in April 2018 [2]. But before we move into replicating the attack, it is better if we explain a few Blockchain properties.

The Code Is Law Principle  

The "code is law principle" is the principle that no one has the right to censor the execution of code on the ETH blockchain. In layman's terms this means that as soon as a smart contract is deployed on the ETH blockchain, then the code cannot change. One of the main defining properties of Ethereum Smart Contracts is that their code is immutable. Blockchain immutability means that all the engaging parties agree to the terms or “code” of the Smart Contract, that code can’t be changed by any party unilaterally [4]. And this is the main reason a Smart Contract gets trustworthy.


Well that is not exactly true, a contract, can be a) destroyed or get b) upgraded. Which essentially means that the code:
  • In the first scenario will stop functioning, but wont get deleted (because a blockchain is immutable)
  • In the second scenario the smart contract will get:
    • Upgraded and modify their code, while not preserving their address, state, and balance.
    • Upgraded and modify their code, while preserving their address, state, and balance, by using special tools (e.g. by using tools such as OpenZeppelin Upgrades Plugins, or proxy smart contracts) [7].
Below we can see an Ethereum blockchain [6]:


When the contract is destroyed the state root of the block account is zeroed. Each block has a "state root" which contains accounts. With a Self-destruct function the opcode triggered is used to zero out the block account of the smart contract. The Bitcoin ledger is based on recording transactions and the Ethereum blockchain is based on managing account balances. Why am I giving you all this information? Well, to put it simple, to explain that deleting or upgrading a Smart Contract is not an easy job. And guess what, in order to install a security patch to a smart contract we need either to destroy the old smart contract and create a new one or upgrade the current smart contract. This essentially means that Smart Contract governance is important. In the early stages of the cryptocurrency space, such governance was not something that was carefully designed.

The Money Overflow

Below we can see some vulnerable code for explaining the actual vulnerability. In the following code we are replicating the behavior and the insufficient user input validation code. 

pragma solidity ^0.4.10;

contract TheOverflow {
     
    mapping (address => uint) contractBalances;
  
    function contribute() payable { 
        contractBalances[msg.sender] = msg.value;
    }
  
    function getBalance() constant returns (uint) {
        return contractBalances[msg.sender]; 
    }
    
    function batchTransfer(address[] _receivers, uint _value) { 
    // This is the infamous batchTransfer vulnerable function
    // Overflow line, that caused the hack
        uint totalReceivers = _receivers.length * _value;
        
        require(contractBalances[msg.sender] >= totalReceivers); // Here is the user input validation
        contractBalances[msg.sender] = contractBalances[msg.sender] -totalReceivers;
        
        for(uint counter=0; counter< _receivers.length; counter++) { // Here is the function loop
            contractBalances[_receivers[counter]] = contractBalances[_receivers[counter]] + _value;
        }  
    }
}

The ways the batchTransfer function works is that it accepts as input the receivers addresses and the value to transfer e.g., it will get as an input a list with three or more addresses, along with the value of the ETH to transfer. Then it will get the number of the receivers and check against each receiver the balance e.g. see if the address that withdraws ETH has enough.

The vulnerable function batchTransfer shown in the code above: 
  1. The variable _value accepts the amount to be transferred as a user input (declared as 256 bits integer).
  2. The variable _value was overflowed with zeros and got zeroed out.
  3. When the variable _value is zeroed out the require checks got bypassed.
  4. The require check then became - 0>=0, which is a true condition.

What Is An ERC20 Token And Why Is Relevant

ERC-20 has emerged as a Smart Contract de-facto technical standard; it is used for all Smart Contracts on the Ethereum blockchain for token implementation and provides a list of rules that all Ethereum-based tokens must follow [9]. This means that in order for a token to run on the Ethereum, it has to implement certain functionality, or more specifically an interface. 

As of October 2019, more than 200,000 ERC-20-compatible tokens exist on Ethereum's main network. The ERC-20 defines a common list of rules that all Ethereum tokens must adhere to. Some of these rules include how the tokens can be transferred, how transactions are approved, how users can access data about a token, and the total supply of tokens [9]. Consequently, this particular token empowers developers of all types to accurately predict how new tokens will function within the larger Ethereum system. The same applies also for attackers, a hacker understands that all ERC20 tokens, must implement certain functionality, in order to interface with the Ethereum blockchain. But the implementation details of these functions is going to be handled by the developer, not the standard.  

 How Did exchanges React To The Hack?

Due to lack of coordination between Centralized Exchanges (CEX) and Decentralized Exchanges (DEX) no immediate response took place. This resulted into hacking attacks taking place for a long period of time, even when the hack does not go unnoticed. An extra layer of security must be added that monitors the Smart Contract behavior and takes action accordingly. For example in our attack scenario the suspicious transaction should have been blocked due to excessive withdraw of funds. 

The Impact

The bug was discovered 04/22/2018. The weakness was released 04/23/2018 (Website). The advisory is shared at dasp.co. This vulnerability is uniquely identified as CVE-2018-10299 since 04/22/2018. It is possible to initiate the attack remotely. No form of authentication is needed for exploitation. It demands that the victim is doing some kind of user interaction. Technical details are known, but no exploit is available. The price for an exploit might be around USD $5k-$25k at the moment (estimation calculated on 01/30/2020) [8].

References: