lunaray
3 min readFeb 15, 2022

Detailed explanation of Ethereum smart contract vulnerabilities

— On-chain vulnerability recurrencecall and delegatecall

Detailed explanation of Ethereum smart contract vulnerabilities — On-chain vulnerability recurrencecall and delegatecall

Welcome to follow and discuss with us

Author: support@lunaray.co

0x01 Introduction

Let’s briefly introduce call and delegatecall

  • call: When calling functions of other contracts, the code is executed in the environment of the called contract, and the value of the built-in variable msg will be modified to the caller after the call.
  • delegatecall: When calling functions of other contracts, the code is executed in the environment of the contract that called the function.

delegatecall is tricky to use, and misuse or incorrect understanding can lead to devastating results.

0x02 Notice

  1. delegatecall saves the context (store, caller, etc…)
  2. The storage layout of the contract calling delegatecall and the called contract must be the same

0x03 Vulnerability example

The following is an example of a vulnerable contract and attack:

there are the following 5 steps:

  1. Account A deploys Lib
  2. Account A uses the Lib address to deploy HackMe
  3. Account B uses the HackMe address to deploy Attack
  4. Account B calls Attack.attack()
  5. Attack is now the owner of HackMe

When the attack function is finally called, if the transaction fee is insufficient, such as:

Then you can try to increase the upper limit of the transaction fee in the transaction confirmation step:

We can see on-chain whether the transaction was successful or not:

https://kovan.etherscan.io/tx/0xbaa58712740181a425852e492dfaac62ab44fd2285c8b342b2f2ea8882fcb72a

what happened?

  1. Account B calls Attack.attack()
  2. 2. Attack the function selector that calls HackMe’s fallback function to send pwn()
  3. HackMe uses delegatecall to forward calls to Lib
  4. msg.data contains the function selector for pwn()
  5. This tells Solidity to call the function pwn() in Lib
  6. The function pwn() updates the owner to msg.sender
  7. Delegatecall uses HackMe’s context to run Lib’s code
  8. So HackMe’s store is updated to msg.sender, where msg.sender is the caller of HackMe, in this case Attack

0x04 more complex vulnerabilities

The operation process is exactly the same as before:

0x05 On-chain transaction information:

https://kovan.etherscan.io/tx/0x712863d4a3720ab6617573dfd6a2129ed501533df35e8581c7c2cc2064a3bd8b

so what happened?

Note that state variables are defined differently in Lib and HackMe. This means that calling Lib.doSomething() will change the first state variable inside HackMe, which happens to be the address of lib.

Inside attack() , the first call to doSomething() changes the address where lib is stored in HackMe. The address of lib is now set to Attack. The second call to doSomething() calls Attack.doSomething() , where we change the owner.

0x06 Defense method

Currently, stateless libraries are recommended for this vulnerability.

lunaray
lunaray

Written by lunaray

Lunaray takes a leading position in smart contract auditing and consulting service for blockchain security.

No responses yet