Detailed explanation of Ethereum smart contract vulnerabilities
— — On-chain vulnerability recurrence :hide malicious code with external contracts
Detailed explanation of Ethereum smart contract vulnerabilities — On-chain vulnerability hide malicious code with external contract
Welcome to follow and discuss with us
Author: support@lunaray.co
0x01 Vulnerable contract
The exploit contract is based on the solidity ^0.8.10 version:
The vulnerability is that the Bar of the constructor is passed in the address, which allows someone to forge a fake Bar deployment contract.
0x02 attack contract
The attack contract is in another file, deliberately hidden or obfuscated, so that auditors and users cannot see this file.
0x03 Attack idea
Suppose A can see the code for Foo and Bar but not Mal. Apparently A can use Foo.callBar() to execute the code in Bar.log() . However, Li Si actually deploys Foo using Mal’s address, so A actually executes the code in Mal.log()
0x04 Attack process
- A deploy Mal
- A deploys Foo using Mal’s address
- B After reading the code, judge that it is safe to call Bar.log() through Foo.callBar()
- B expects Bar.log() to be executed, but Mal.log() is actually executed
0x05 On-chain recurrence
Execute the above attack steps and get the result:
As you can see, the address of the Foo contract starts with 0xF8D, and the address of the Mal contract starts with 0x683.
Copy the transaction hash to the test chain transaction address:
https://kovan.etherscan.io/tx/0x21ba7cc7008c56af094f23eb205c15ba7d06dc9d5e1942f0f92945fb38d3ae91
As you can see, the address of the Foo contract starts with 0xF8D, and the address of the Mal contract starts with 0x683.
Copy the transaction hash to the test chain transaction address:
It can be clearly seen that the address of the 0x683 contract is actually called, which is the address of the Mal contract.
0x06 Means of defense
Key point: do not initialize the contract by passing in an address through the constructor
- Initialize the specified contract directly in the constructor
- Or initialize and assign values directly when the variable is declared
In this way, the Foo contract does not need to pass in the address of the specified contract during deployment, but directly initializes the specified contract, avoiding the fake contract address being passed in when the contract is deployed, and preventing the occurrence of loopholes.
0x07 Summarize
In Solidity, any address can be converted to a specific contract, even if the contract on that address is not the converted contract, thus leading to this vulnerability.Developers should avoid dragging things that can be determined at compile time to runtime, and should make the code as explicit as possible to reduce program uncertainty.
Auditors should pay attention to this vulnerability when auditing contracts