智能合约中的重入攻击

2025 年 5 月 29 日 | 阅读 7 分钟

引言

Solidity 的重入攻击会持续地从智能合约中取出资金并进行转移。本教程重点介绍智能合约中的重入攻击。当一个函数从外部调用一个不受信任的合约时,就会发生这种情况。

什么是重入攻击?

允许在合约内部执行不受信任的外部代码的智能合约容易受到重入攻击。 当一个智能合约调用一个外部合约,而该外部合约又调用原始合约时,就有可能出现无限循环。重入攻击是一种利用智能合约中的缺陷,使攻击者能够反复执行合约中的函数,从而造成无限循环并可能窃取资金。

  1. 一个允许用户存入资金并在之后提取的合约是重入攻击的一个基本例子。假设合约未能适当地验证重入。攻击者可能会在调用提款函数之前反复执行存款方法,从而从合约中窃取资金。
  2. 使用互斥锁(mutual exclusion lock)来防止对同一函数的多个调用同时发生,是抵御重入攻击的一种方法。另一种方法是使用防护条件(guard condition),它在调用外部函数之前设置一个标志,并在之后进行检查。

重入攻击的例子

攻击者可能会通过反复调用合约中的一个函数来窃取资金,这被称为典型的重入攻击。为了存入资金,用户与易受攻击的智能合约进行交互。

  • 之后,恶意合约会不断调用易受攻击的智能合约的存款函数,将资金存入攻击者的个人账户。
  • 然后,恶意合约通过易受攻击的智能合约的提款功能提取已存入的资金。
  • 由于存款函数没有充分防范重入,攻击者可以反复调用易受攻击的智能合约的存款函数,然后再使用提款函数。这实际上允许攻击者从合约中窃取资金。

重入攻击的过程是怎样的?

以下是重入攻击工作原理的例子

  1. 攻击者发现了一个允许用户存入资金并在之后提取资金的智能合约。
  2. 为了将资金存入自己的账户,攻击者构建了一个名为合约 B 的恶意合约,该合约会不断调用易受攻击的合约 A 的存款函数。
  3. 然后,攻击者通过调用易受攻击的合约的提款函数来提取已存入的资金。
  4. 由于易受攻击的合约的存款函数没有充分防范重入,攻击者可以反复调用存款函数,然后再调用提款方法,从而从合约中窃取资金。
  5. 攻击者会不断重复攻击,直到他们提取了想要的全部资金。

重入攻击的类型

重入攻击有几种形式,例如:

  1. 抢跑攻击(Frontrunning attack): 抢跑攻击发生在一个黑客在区块链中搜索将触发易受攻击的合约的交易,然后在原始交易完成之前迅速发出一个触发相同合约的交易。
  2. 时间戳依赖攻击(Timestamp dependency attack): 操纵区块时间戳的攻击者可能会迫使易受攻击的合约以有利于自己的方式执行。这种类型的攻击称为时间戳依赖攻击。
  3. 递归调用攻击(Recursive call attack): 递归调用攻击发生在黑客反复调用易受攻击的合约,迫使其执行一个出乎意料的函数或相同的函数。
  4. 跨函数调用攻击(Cross-function call attack): 这种类型的攻击涉及攻击者以特定顺序调用易受攻击的合约中的多个函数,以产生意外行为。

如前所述,互斥锁或防护条件是可用于阻止所有这些类型攻击的两种方法。

重入智能合约攻击的例子

  1. DAO 黑客事件: DAO(去中心化自治组织)智能合约是基于以太坊区块链的去中心化投资基金。由于攻击者发现了 DAO 智能合约中的一个漏洞,该漏洞允许他们反复使用“split”函数,因此投资者能够在合约有机会修改内部余额之前提取他们的资金。该漏洞允许攻击者反复调用 split 函数,耗尽了 DAO 约 5000 万美元的以太(ETH)。
  2. Lendf.me Protocol: Lendf.me 是一个基于以太坊区块链的去中心化借贷网络。在 2019 年,一名攻击者发现了一个智能合约漏洞,允许他们同时借入和偿还同一笔贷款,并影响标的资产的价格以提高贷款金额。通过利用这一弱点借款并多次偿还一笔贷款,攻击者从该平台窃取了价值超过 350,000 美元的比特币资产。
  3. Cream Finance: 这是一个 DeFi 平台,支持资产借贷。在 2020 年,一名攻击者发现了一个智能合约漏洞,该漏洞允许他们同时借入和偿还同一笔贷款,并影响标的资产的价格以提高贷款金额。通过利用这一缺陷,攻击者能够反复借入和偿还一笔贷款,从而从该平台窃取了价值超过 3000 万美元的比特币资产。
  4. BurgerSwap: 该去中心化交易所基于币安智能链。在 2021 年,一名攻击者发现了一个智能合约漏洞,该漏洞允许他们同时借入和偿还同一笔贷款,并影响标的资产的价格以提高贷款金额。通过利用这一缺陷,攻击者能够反复借入和偿还一笔贷款,从而从该平台窃取了价值超过 200 万美元的比特币资产。
  5. Surge BNB: SurgeBNB 是一个基于币安智能链的去中心化交易所。在 2021 年,一名攻击者发现了一个智能合约漏洞,该漏洞使他们能够反复借入和偿还同一笔贷款,同时影响标的资产的价格以提高贷款金额。通过利用这一缺陷,攻击者能够反复借入和偿还一笔贷款,从而从该平台窃取了超过 3000 万美元的比特币资产。
  6. Siren Protocol: 以太坊区块链是 Siren Protocol 这个去中心化金融平台的根基。在 2021 年,一名攻击者发现了一个智能合约缺陷,该缺陷使他们能够反复借入和偿还同一笔贷款,同时影响标的资产的价格以提高贷款金额。通过利用这一缺陷,攻击者能够反复借入和偿还一笔贷款,从而从该平台窃取了超过 3000 万美元的比特币资产。

重入攻击仍然是一个棘手的问题吗?

重入攻击仍然对智能合约生态系统构成严重威胁。尽管大多数智能合约生态系统和开发框架都具有内置的防护措施,但重入仍然是智能合约安全的一个威胁。为了确保其合约能够抵御重入攻击,新的智能合约和去中心化应用程序的开发者应该广泛测试和审计他们的创作。

如何在智能合约中预防重入攻击?

  • 使用互斥锁: 为了防止同一函数被同时调用,请使用互斥锁,也称为共享拒绝锁。调用函数时会设置互斥锁,并且在锁被释放之前,不会允许对同一函数进行后续调用。
  • 使用防护条件: 使用防护条件,它是一个在调用外部函数之前设置并在之后检查的标志。如果标志已设置,合约将不会执行外部调用,从而阻止重入。
  • 验证调用堆栈深度: 为了确保合约没有被递归调用,请验证调用堆栈的深度。当调用堆栈深度达到某个点时,合约将停止运行。
  • 使用“require”语句: 在允许函数执行之前,可以使用“require”语句来断言合约的当前状态。
  • 持续评估和更新: 密切关注智能合约中的漏洞并在发现时进行更新至关重要。
  • 值得注意的是,这些是保护智能合约免受重入攻击的几种框架;为了完全安全,智能合约应由专家进行测试和审计。
  • 可以使用 call 方法来为交易设定 gas 限制。
  • 在调用外部合约或函数之前,对智能合约的状态变量进行更改。

结论

总而言之,重入攻击一直是智能合约开发中的一个严重问题,因为它们可能导致经济损失,危害智能合约的完整性,并引发系统性故障。因此,识别潜在漏洞并采取防护措施至关重要,例如使用前面讨论的策略,如防护条件或互斥锁。


下一主题区块链结构