大概两周前(5 月 20 日),知名混币协议 Tornado Cash 遭受到治理攻击,黑客获取到了Tornado Cash的治理合约的控制权(Owner)。 攻击过程是这样的:攻击者先提交了一个“看起来正常”的提案, 待提案通过之后, 销毁了提案要执行的合约地址, 并在该地址上重新创建了一个攻击合约。 攻击过程可以查看 SharkTeam 的 Tornado.Cash提案攻击原理分析[1]。 这里攻击的关键是在同一个地址上部署了不同的合约, 这是如何实现的呢? 背景知识 EVM 中有两个操作码用来创建合约:CREATE 与 CREATE2 。 CREATE 操作码 当使用 new Token() 使用的是 CREATE 操作码 , 创建的合约地址计算函数为: address tokenAddr = bytes20(keccak256(senderAddress, nonce)) 创建的合约地址是通过创建者地址+创建者Nonce(创建合约的数量)来确定的, 由于 Nonce 总是逐步递增的, 当 Nonce 增加时,创建的合约地址总是是不同的。 CREATE2 操作码 当添加一个salt时 new Token{salt: bytes32()}() ,则使用的是 CREATE2 操作码 , 创建的合约地址计算函数为: address tokenAddr = bytes20(keccak256(0xFF, senderAddress, salt, bytecode)) 创建的合约地址是创建者地址+自定义的盐+要部署的智能合约的字节码, 因此 只有相同字节码 和 使用相同的盐值,才可以部署到同一个合约地址上。 那么如何才能在同一地址如何部署不用的合约? 攻击手段 攻击者结合使用 Create2 和 Create 来创建合约, 如图:
先用 Create2 部署一个合约 Deployer , 在 Deployer 使用 Create 创建目标合约 Proposal(用于提案使用)。Deployer 和 Proposal 合约中均有自毁实现(selfdestruct)。 在提案通过后,攻击者把 Deployer 和 Proposal 合约销毁,然后重新用相同的slat创建 Deployer , Deployer 字节码不变,slat 也相同,因此会得到一个和之前相同的 Deployer 合约地址, 但此时 Deployer 合约的状态被清空了, nonce 从 0 开始,因此可以使用该 nonce 创建另一个合约Attack。 攻击代码示例 此代码来自:https://solidity-by-example.org/hacks/deploy-different-contracts-same-address/ // SPDX-License-Identifier: MIT 大家可以使用该代码自己在 Remix 中演练一下。 首先部署 DeployerDeployer , 调用 DeployerDeployer.deploy() 部署 Deployer , 然后调用 Deployer.deployProposal() 部署 Proposal 。 拿到 Proposal 提案合约地址后, 向 DAO 发起提案。 分别调用 Deployer.kill 和 Proposal.emergencyStop 销毁掉 Deployer 和 Proposal 再次调用 DeployerDeployer.deploy() 部署 Deployer , 调用 Deployer.deployAttack() 部署 Attack , Attack 将和之前的 Proposal 一致。 执行 DAO.execute 时,攻击完成 获取到了 DAO 的 Owner 权限。 查看更多 —- 编译者/作者:登链社区 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
解析Tornado治理攻击:如何同一个地址上部署不同的合约
2023-06-02 登链社区 来源:区块链网络
LOADING...
相关阅读:
- 专访Starknet创始人:仰望星空脚踏实地2023-06-02
- RGB协议如何成为比特币第2层解决方案的破局者?2023-06-02
- IOSGVentures:深度解读全链游戏引擎2023-05-30
- NFTFi赛道全景研究:慢就是快NFTfi驱动下一轮牛市2023-05-29
- CoinGPT——突破创新边界Web3的AI革命2023-05-27