以太坊作为全球领先的智能合约平台,其去中心化、不可篡改的特性为DeFi、NFT、DAO等众多创新应用提供了坚实的基础,智能合约一旦部署,代码即法律,任何微小的漏洞都可能被攻击者利用,导致巨额资金损失,深入理解以太坊智能合约的常见攻击手段,对于开发者、审计者以及整个区块链生态的安全至关重要,本文将详细介绍几种主流的以太坊智能合约攻击手段,并探讨相应的防范策略。

重入攻击 (Reentrancy Attack)

  • 原理:重入攻击的核心在于合约在调用外部合约(特别是未知或不受控的外部合约)时,未正确处理状态变量的更新,导致外部合约可以多次“重入”调用原合约的函数,从而重复执行某些操作(如提取资金)。
  • 经典案例:2016年的The DAO事件,攻击者利用DAO合约中取款函数的逻辑漏洞,通过递归调用,不断转移资金,最终导致以太坊社区不得不通过硬分叉来挽回损失。
  • 攻击流程
    1. 攻击者部署恶意合约,并调用目标合约的某个函数(如withdraw)。
    2. 目标合约在处理该函数时,先向恶意合约地址转移资金(调用恶意合约的fallback/receive函数)。
    3. 恶意合约的fallback/receive函数被触发,再次调用目标合约的withdraw函数。
    4. 由于目标合约的状态变量(如记录用户提款金额的userWithdrawnAmount)在转移资金后才被更新,导致恶意合约每次调用都能成功提取资金,而状态检查未通过,形成循环。
  • 防范措施
    • Checks-Effects-Interactions模式:在函数执行中,优先进行所有条件检查(Checks),然后更新状态变量(Effects),最后才进行外部调用(Interactions),确保状态变量在外部调用之前被正确更新。
    • 使用重入锁:引入一个bool类型的锁变量,在函数入口处检查锁状态,若已锁定则 revert;在执行外部调用前锁定,在函数执行结束后解锁。
    • 避免使用低级调用:尽量使用address.call()等更安全的调用方式,并限制外部调用的深度。

整数溢出与下溢 (Integer Overflow and Underflow)

  • 原理:在Solidity早期版本(0.8.0之前)中,整数类型没有内置的溢出检查,当数值超过其类型的最大值(溢出)或低于最小值(下溢)时,它会回绕(wrap around),导致意外的计算结果。
  • 攻击场景
    • 溢出uint8类型的最大值是255,255 + 1会变成0,攻击者可以利用这一点,在铸造代币时,将0 - 1作为数量,导致铸造出大量代币。
    • 下溢uint8类型的最小值是0,0 - 1会变成255,攻击者可以利用这一点,在转账或提取时,使余额看似足够,实则因下溢而允许非法操作。
  • 防范措施随机配图