网工干货知识

超全学习笔记
当前位置:首页 > 干货知识

智能合约中的再进入攻击

更新时间:2026年03月27日   作者:spoto   标签(Tag):

在 Solidity 中,重入攻击指的是攻击者不断从智能合约中提取资金并将其转移出去。本文主要讨论了智能合约中的重入攻击现象。这种攻击发生在某个函数向另一个不可信的合约发起外部调用时。本文重点探讨了智能合约中的重入攻击问题。

接下来将讨论以下主题:

  1. 什么是重入攻击?
  2. 再入攻击的例子
  3. 重入攻击是如何进行的呢?
  4. 重复入侵攻击的类型
  5. 重复利用智能合约的攻击示例
  6. 再入侵攻击是否仍然是一个严重的问题?
  7. 如何保护智能合约免受重复攻击?

让我们先详细讨论一下这些话题吧。

什么是重入攻击?

再入攻击是一种可能发生在智能合约中的攻击方式,这种攻击会导致不可信的外部代码能够在合约内部被执行。 这种情况可能发生在智能合约调用了外部合约的情况下,而外部合约又再次调用了原始合约。这样一来,就可能出现无限循环的情况。 再入侵攻击是一种利用智能合约中的漏洞的方法。攻击者可以通过反复调用合约中的函数来引发无限循环,从而窃取资金。

  • 一个典型的重复入侵攻击的例子就是那种允许用户存入资金,之后再提取这些资金的合约。假设该合约没有正确检查重复入侵的情况。在这种情况下,攻击者可以在调用取款功能之前,多次调用存款功能,从而从合约中窃取资金。
  • 防止重入攻击的一种方法是使用互斥锁,这样就能避免多个线程同时调用同一个函数的情况发生。另一种方法是使用保护条件机制,即在调用外部函数之前设置一个标志位,而在调用之后再检查该标志位的状态。

再入式攻击的例子

标准的再入侵攻击是指攻击者反复调用合同中的某个函数,从而导致无限循环,甚至可能窃取资金。用户通过与易受攻击的智能合约交互来存入资金。

  • 该恶意合约会反复调用易受攻击的智能合约的存款功能,将资金存入攻击者的账户中。
  • 随后,该恶意合约调用了易受攻击的智能合约的取款功能,从而提取了存入的资金。
  • 由于易受攻击的智能合约的存款功能没有得到有效的保护,攻击者可以在调用取款功能之前,多次调用存款功能,从而从合约中窃取资金。

重入攻击是如何进行的呢?

以下是关于重入式攻击工作原理的示例:

  • 攻击者找到了一种智能合约,该合约允许用户存入资金,并在之后随时提取这些资金。
  • 攻击者创建了一个名为“Contract B”的恶意合约。该合约会不断调用易受攻击的合约“Contract A”中的存款功能,从而将资金存入攻击者的账户中。
  • 之后,攻击者会调用该易受攻击合约中的取款功能,从而取出存入的资金。
  • 由于易受攻击的合约的存款功能并未得到有效的保护,攻击者可以在调用取款功能之前,多次调用存款功能,从而从合约中窃取资金。
  • 攻击者会不断重复这种攻击行为,直到他们成功窃取了他们想要的那么多资金为止。
 

下面是一个简单的智能合约示例,该合约容易受到重复执行攻击的影响:

Solidity
// SPDX许可标识:GPL-3.0pragma 索莱维>=0.4.22<0.9.0;/// @标题 用于演示支付功能及地址的合约/// @作者:Jitendra Kumar/// @注意:目前,这个合约只是展示了如何让支付功能以及地址能够将以太币输入到合约中。合同再入式{映射(地址=>整数类型的数据)公共的balance;功能/作用存款()公共的可支付{balance[msg.sender]+=msg.value;}功能/作用撤回/退出()公开的可支付{需要(balance[msg.sender]>=msg.value);可支付(msg.sender).transfer(msg.value);balance[msg.sender]-=msg.value;}}


说明:在该合同中,存款功能允许用户将资金存入自己的账户,而取款功能则允许用户提取已存入的资金。不过,该合同并没有对重复调用这些功能的情况进行有效的检查。因此,攻击者可以创建一种恶意合约,该合约会反复调用存款功能,然后再调用取款功能,从而从合约中窃取资金。

以下是如何修改合同以防止再入攻击的例子:

Solidity
// SPDX许可证标识:GPL-3.0pragma 斯利普尼迪>=0.4.22<0.9.0;/// @标题 用于演示重入攻击的契约/// @作者:Jitendra Kumar/// @注意:目前,这个合约只是展示了如何保护智能合约免受重复执行攻击的影响。合同再入式{映射(地址=>整数类型的数据)公共的balance;布尔值公开的重新进入锁;功能/作用存款()公共的可支付{需要(!reentrancyLock);reentrancyLock=真的/正确的;balance[msg.sender]+=msg.value;reentrancyLock=错误的/不正确的;}功能/作用撤回/取消()公开的可支付{要求/需要(balance[msg.sender]>=msg.value);可支付(msg.sender).transfer(msg.value);balance[msg.sender]-=msg.value;}}


说明:在这个例子中,我们在合约中添加了一个名为“reentrancyLock”的变量。现在,存款功能在允许进行存款之前,会先检查“reentrancyLock”这个变量的值是否为真。如果该变量的值为真,那么就不会进行存款操作,这样攻击者就无法窃取资金了。在存款之前,“reentrancyLock”这个变量会被设置为真,而在存款之后则会被重新设置为假。通过这种方式,合约一次只能被调用一次。
需要注意的是,这只是一个简化的例子。在现实世界中,合同需要由专家进行审计和全面测试,以确保其安全性。

重复入侵攻击的类型

存在多种类型的再入侵攻击,包括:

  • 领先攻击:这是一种攻击方式:攻击者会监控区块链上那些会调用某个易受攻击合约的交易。然后,他们会在原始交易被处理之前,迅速提交一个同样调用该合约的交易。
  • 时间戳依赖攻击:这是一种攻击方式,攻击者会操纵某个区块的时间戳,从而让那些存在漏洞的合约以对攻击者有利的方式执行。
  • 递归调用攻击:这是一种攻击方式,攻击者会连续多次调用存在漏洞的合约,从而导致合约执行一些非预期的操作,或者重复执行相同的功能。
  • 跨职能呼叫攻击:在这种攻击中,攻击者会按照特定的顺序调用脆弱合约中的多个函数,从而导致不预期的行为发生。

所有这些类型的攻击都可以通过使用不同的技术来预防,比如我之前提到的互斥锁或保护条件等机制。

再进入式智能合约攻击示例

  • DAO攻击:DAO(去中心化自治组织)的智能合约,是一种建立在以太坊区块链上的去中心化投资基金。 攻击者发现了DAO智能合约中的一个漏洞,他们可以利用这个漏洞反复调用“分割”功能。这样一来,投资者就可以在合约尚未更新内部余额之前,提取自己的资金。 攻击者利用这一漏洞,反复调用了“split”函数,从而从DAO中窃取了价值约5000万美元的Ether。
  • Lendf.me协议:Lendf.me是一个基于以太坊区块链构建的去中心化借贷平台。 在2019年,一名攻击者发现了智能合约中的漏洞。利用这一漏洞,他们可以反复借入和偿还同一笔贷款,同时还能操纵相关资产的价格,从而增加贷款的金额。 攻击者利用这一漏洞,多次借款并还款,从而从平台上窃取了价值超过35万美元的加密货币资产。
  • Cream FinanceCream Finance是一个DeFi平台,它允许用户进行资产的借贷操作。 在2020年,一名攻击者发现了智能合约中的漏洞。利用这一漏洞,他们可以反复借入和偿还同一笔贷款,同时操纵相关资产的价格,从而增加贷款的金额。 攻击者利用这一漏洞,多次借款并偿还贷款。最终,他们从平台上窃取了价值超过3000万美元的加密货币资产。
  • BurgerSwapBurgerSwap是一款基于Binance Smart Chain构建的去中心化交易所。 在2021年,一名攻击者发现了智能合约中的漏洞。利用这一漏洞,他们可以反复借入和偿还同一笔贷款,同时操纵相关资产的价格,从而增加贷款的金额。 攻击者利用这一漏洞,多次借款并偿还贷款。最终,他们从平台上窃取了价值超过200万美元的加密货币资产。
  • SurgeBNBSurgeBNB是一种基于Binance Smart Chain构建的去中心化交易所。 在2021年,一名攻击者发现了智能合约中的漏洞。利用这一漏洞,他们可以反复借入和偿还相同的贷款,同时操纵相关资产的价格,从而增加贷款的金额。 攻击者利用这一漏洞,多次借款并还款,从而从平台上窃取了价值超过3000万美元的加密货币资产。
  • Siren Protocol:Siren Protocol是一个基于Ethereum区块链构建的去中心化金融平台。 在2021年,一名攻击者发现了智能合约中的漏洞。利用这一漏洞,他们可以反复借入和偿还同一笔贷款,同时还能操纵相关资产的价格,从而增加贷款的金额。 攻击者利用这一漏洞,多次借款并偿还贷款,从而从平台上窃取了价值超过3000万美元的加密货币资产。

再入攻击是否仍然是一个严重的问题?

再进入攻击仍然是智能合约生态系统中的一个严重问题。虽然许多智能合约平台和开发框架都配备了防止再进入攻击的防护措施,但这一威胁仍然持续存在。随着新的智能合约和去中心化应用程序的不断发展,开发者们必须彻底测试并审查这些合约,以确保它们能够免受再进入攻击的侵害。

如何保护智能合约免受重复攻击?

  • 使用互斥锁或排他锁:互斥锁用于防止同一个函数被多次调用。当某个函数被调用时,互斥锁会被激活,其他对该函数的调用则会被阻塞,直到互斥锁被释放为止。
  • 使用防护条件:“Guard条件”是一种在调用外部函数之前被设置的标志,该标志会在调用之后被检查。如果此标志被设置,那么合约就不会执行该外部函数的调用,从而避免了重复执行的情况。
  • 请检查调用栈的深度:检查调用栈的深度是一种确保合约不会被递归调用的方式。如果调用栈的深度超过某个阈值,那么合约就会停止执行。
  • 使用“require”语句:可以使用“require”语句来在允许某个函数执行之前,检查合同的状态。
  • 持续监控与更新:智能合约应被持续监控,以发现任何潜在的安全漏洞。一旦发现新的漏洞,应立即对智能合约进行更新。
  • 需要注意的是,这些只是保护智能合约免受重复入侵攻击的一些方法而已。为了确保智能合约的安全性,必须由专家进行严格的审计和测试。
  • 为了为这些交易设定Gas限制,你可以使用“call”方法来实现这一目的。该方法允许你设置Gas的限制。
  • 在调用外部函数或外部合约之前,需要更新智能合约中的状态变量。

结论

总而言之,再进入攻击在智能合约的开发过程中是一个极其重要的问题。这种攻击可能导致资金损失、智能合约的完整性受到破坏,甚至引发系统级故障。因此,必须意识到这些潜在的漏洞,并采取措施来预防它们。比如,可以使用我之前提到的那些技术,比如互斥锁或保护条件等。

              马上抢免费试听资格
意向课程:*必选
姓名:*必填
联系方式:*必填
QQ:
思博SPOTO在线咨询

相关资讯

即刻预约

免费试听-咨询课程-获取免费资料