当前位置:网站首页>Introduction to smart contract security audit delegatecall (2)
Introduction to smart contract security audit delegatecall (2)
2022-06-24 18:50:00 【Slow fog technology】
By: The small white @ Slow fog security team
Background Overview
Last article We learned what is delegatecall Function and a basic vulnerability , The purpose of this article is to deepen our understanding of delegatecall And take everyone to play some exciting , Win an advanced version of the vulnerability contract .
Pre knowledge
Here we will not repeat the previous basic knowledge , Those who don't understand or forget can look at the last article :《 Introduction to smart contract security audit —— delegatecall (1)》.
Vulnerability example
contract Lib { uint public someNumber; function doSomething(uint _num) public { someNumber = _num; }}contract HackMe { address public lib; address public owner; uint public someNumber; constructor(address _lib) { lib = _lib; owner = msg.sender; } function doSomething(uint _num) public { lib.delegatecall(abi.encodeWithSignature("doSomething(uint256)", _num)); }}Vulnerability analysis
The target of this attack is still to gain HackMe In the contract owner jurisdiction , We can see two contracts except HackMe The constructor in the contract can modify the owner Other places have not been modified owner Function of . How do we complete the attack ? Here's a little trick , You can think about it , It can also verify your mastery of previous knowledge and whether your thinking is active .
Do you have any ideas ? It doesn't matter if you don't have any ideas , Let's see how the attack is accomplished :
Attack contracts
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;contract Attack { // Make sure the storage layout is the same as HackMe // This will allow us to correctly update the state variables address public lib; address public owner; uint public someNumber; HackMe public hackMe; constructor(HackMe _hackMe) { hackMe = HackMe(_hackMe); } function attack() public { // override address of lib hackMe.doSomething(uint(uint160(address(this)))); // pass any number as input, the function doSomething() below will // be called hackMe.doSomething(1); } // function signature must match HackMe.doSomething() function doSomething(uint _num) public { owner = msg.sender; }}Let's first look at the attack process :
- Alice Deploy Lib contract ;
- Alice Deploy HackMe Contract and pass... In the constructor Lib The address of the contract ;
- The attacker Eve Deploy Attack Contract and pass... In the constructor HackMe The address of the contract ;
- Attacker calls Attack.attack() Function will HackMe In the contract owner Become yourself .
What's the matter ? In fact, this attack method is cleverly used delegatecall This function modifies storage Characteristics of type variables :delegatecall The execution environment of the function is the caller's environment and for storage The type variable is modified according to the slot position of the called contract variable .
- Attack.attack() Function first converts its own address to uint256 type ( This step is to be compatible with the data types in the target contract ) First call HackMe.doSomething() function ;
- HackMe.doSomething() Function USES delegatecall Function with the passed in Attack The address of the contract calls Lib.doSomething() function ;
- You can see Lib.doSomething() The function stores the contract at slot0 Change the parameter of to the passed in value , So when HackMe The contract uses delegatecall call Lib.doSomething() Function will also change itself in slot0 The value of the variable stored in the location , Also is to lib Parameters ( What's stored here is Lib The address of the contract ) Change to our incoming Attack The address of the contract . Before this time HackMe.lib Parameter Lib The address of the contract is changed to the one we sent in Attack The address of the contract ;
- Attack.attack() Function is called again HackMe.doSomething() function , Because in the last step we have HackMe.lib Change the variable to Attack The address of the contract , At this time HackMe.doSomething() The function will no longer call the previous Lib The contract is to use delegatecall To call Attack.doSomething() function . Now let's look at Attack The writing of the contract , It is found that the storage location of its variables is intentionally and HackMe The contract is consistent , And it's not hard to find Attack.doSomething() The contents of the function are also written as owner = msg.sender, This operation changes the storage location in the contract to slot1 The variable of . therefore HackMe The contract uses delegatecall call Attack.doSomething() The function will store the contract in the location slot1 The variable of owner It is amended as follows msg.sender That is to say Eve The address of , At this point, the attacker completed his attack .
Repair suggestions
As a developer
- In the use of delegatecall It should be noted that the address of the called contract cannot be controllable ;
- In a complex contract environment, you need to pay attention to the declaration order and storage location of variables . Because use delegatecall When making an external call, the contract will be modified according to the data structure of the called contract slot Data stored in , When the data structure changes, this may cause unexpected variable coverage .
As an auditor
- In the process of audit, there is a use in the contract delegatecall Pay attention to whether the called contract address is controllable ;
- When the function in the called contract is modified storage In the case of variables, pay attention to the position of the variable storage slot , Avoid the data stored in this contract due to inconsistent data structure storage The variable is incorrectly overwritten .
notes : This article refers to 《Solidity by Example》
Reference link :
https://solidity-by-example.org/hacks/delegatecall
This article was first published in :https://mp.weixin.qq.com/s/6sAqyjv4gI3c9DzqoYhybA
边栏推荐
- Volcano becomes spark default batch scheduler
- Bisection function template
- Interpreting harmonyos application and service ecology
- Network security database penetration of secondary vocational group in 2022
- JS deep understanding of functions
- JS pre parsing
- Location object
- JS deep understanding of scope
- Introduction and download tutorial of administrative division vector data
- JS picture display and hiding cases
猜你喜欢

2022 network security C module of the secondary vocational group scans the script of the surviving target aircraft (municipal, provincial and national)

okcc呼叫中心数据操作的效率问题
![[leetcode] rotation series (array, matrix, linked list, function, string)](/img/9e/079311df16fa8e28708f4e050e531f.png)
[leetcode] rotation series (array, matrix, linked list, function, string)

Why are life science enterprises on the cloud in succession?

为什么 Nodejs 这么快?

Eight digit

微服务系统设计——数据模型与系统架构设计

Flutter dart regular regexp special characters $, () (IV)

【leetcode】838. Push domino (Analog)

JS deep understanding of scope
随机推荐
696. count binary substring
Spatial simulation model acquisition future land cover tutorial
Monotone stack template
论文解读(SR-GNN)《Shift-Robust GNNs: Overcoming the Limitations of Localized Graph Training Data》
The mixed calculation of rpx and PX in JS by the uniapp applet
Knowledge points in T-SQL
How to use Fisher's least significant difference (LSD) in R
110. balanced binary tree
Introduction and download of nine npp\gpp datasets
Palindrome string (two methods)
Industry Cloud video editing software
Volcano成Spark默认batch调度器
为什么 Nodejs 这么快?
Sentry series satellite introduction and download tutorial
Restful design method
Get the actual name of the method parameter through the parameter
Wechat applet development - Implementation of rotation chart
Mcu-08 interrupt system and external interrupt application
应用程序DDoS攻击原理及防御方法
History object