Detailed explanation of Ethereum smart contract vulnerabilities
— — On-chain vulnerability recurrence(reentrancy vulnerability)
Detailed explanation of Ethereum smart contract vulnerabilities — On-chain vulnerability recurrence(reentrancy vulnerability)
Welcome to follow and discuss with us
Author: support@lunaray.co
0x01 Introduction
Reentrancy means that contract A calls contract B, and contract B recursively calls back the function in contract A through fallback().
0x02 Vulnerable contract
Take the current latest version of Solidity 0.8 as an example:
contract
The EtherStore contract uses the <address>.call{}() function in the transfer function withdraw(), which allows hackers to use the fallback() function to recursively call the withdraw() function, thereby transferring all the money on the EtherStore contract.
0x03 attack contract
We continue to write the attack code following the above contract:
attack
The attack code first creates a constructor to receive the contract address of the vulnerable code, and then writes the attack function: after depositing the money deposit(), call the reentrant function withdraw(), and then write the fallback() function to recursively call the reentrant function.
0x04 Vulnerability reoccurrence
We deploy our first contract, depositing 0.1 ether:
Next, we switch accounts in metamask to deploy the second contract. When deploying, you need to pass in the address of the first contract. Then deposit 0.01 Ether into the contract to attack:
Among them, 1 to 7 are the attack process, and 8 and 9 are the confirmation attack results. We can see that 110000000000000000 is exactly 0.1 ether + 0.01 ether, indicating that the attack was successful.
We can query the transaction records on the chain by attacking the address of the contract:
https://kovan.etherscan.io/tx/0x20e72a9a84f336be320c58e7e5e7f0ac6d8947a450668c3414c7cc0a1da7200f
It can be seen that the transaction has a recursive function call, which is the record of the reentrancy vulnerability on the chain.
0x05 Security advice
Developers can choose to lock to prevent reentrancy:
If the attack code is also written as before, when the above function is called a second time from the callback() function, the check of require will not pass. This prevents reentrancy.