从技术出发深入分析此漏洞,用样例代码复现攻击原理
作者:十四君
封面:Photo by Markus Spiske on Unsplash
被朋友 Q 到近期火热的羊毛事件,来分析本次利用 FTX 交易所免手续费提币的漏洞,结合智能合约回调发起的攻击,截止目前,不仅是始作俑者黑客获利超 10W 刀,更有 15 名同样思路的攻击者部署合约发起攻击。
由于 FTX 已经通过人工审计针对攻击者进行惩罚,该漏洞处于风险可控阶段,所以本文处于科普目的系统的分析攻击的前因后果与链上数据表现,总结对 web3 发展的启发。
背景
XEN 是什么?
是近期大火的一个 XEN 币,到 10-15 为止已有超过 120W 笔交易,其实笔者对这类缺乏长期价值对 Web 毫无建设性意义的项目一直没什么兴趣,因为他的机制就是只要发起的交易消耗了多少的 GAS,就可以铸造出一定数量的 XEN 币,而众所周知 Etherscan 有针对 gas 消耗的排行榜
可以看到真正出色的项目往往由于服务用户多交易量大,所以 gas 消耗高,仿佛成了另一种的应用商店热门榜单,而 XEN 一举通过 “冲票 “成了冠绝以太坊整个生态的 Top1,且等于其他好项目的总和。
受害方 FTX 交易所
本次被攻击的也正是其免费提币的优惠活动,在平台有质押且有一定交易记录后即可发起免费提币,而提币会受制于之前交易量(因此本文仅出于科普分析攻击手法,请勿模仿,易于被 FTX 官方封号没收质押资产)
链上数分结果
其实 mirror 上爆出的还不是最大的攻击者,而此攻击手法最早出现在 10-10 号,截止 10-15 号,合计类似逻辑的攻击地址有 38 个,合计 1.45W 笔攻击(无法判断地址背后是否为相同攻击者)。
计算依据:FTX 热钱包单笔转移 gas 消耗大于 5W,且 to 地址是合约地址的交易。
下图为其中 top10 的攻击者,其交易数占总攻击数的 80%,致使 FTX 手续费损失 86 个 ETH
笔者通过对其交易的 gas 消耗总值核算后,得出 FTX 本次损失总值为:108.19 个 ETh
合计铸造出 XEN 约 24 亿个。按 14 号日常价格估算的话,则黑客总收益在 24W 美金以上
黑客攻击流程
核心原理
智能合约 fallback/receive 可任意执行逻辑。
任何一个合约都有默认的 fallback 函数,典型的功能就是让合约可以接收以太币并对其做出反应,这也是代币型合约用来拒绝转账、发出事件或转发以太币的典型模式。后来更多场景是应用在代理升级模式(合约部署链上本身不可更改,但可以修改指向新的合约,从而实现一定程度上的升级)
总之就是,一笔指向合约地址的交易,如果没有匹配到对应执行的函数,就必然会执行 fallback 函数,而 fallback 可以将输入参数指向另一个合约地址,从而执行对应的逻辑。
参考:https://blog.soliditylang.org/2020/03/26/fallback-receive-split/
攻击流程
其实看完手法核心,已经很明显了
- 黑客先部署了一个攻击合约 0xCba9b1
- 然后利用 FTX 的交易免费提币功能
- 让 FTX 的热钱包 0xc098b2,发起了一笔指向攻击合约的提币
- 导致交易触发指向 XEN 合约的 Mint 函数调用
- 由于 XEN 合约可以设置 Mint 出代币的收益方,从而将代币转入黑客地址
攻击手法还原
其实任意 fallback 非常好触发,咱们通过现场手搓实现下,当然并不是 MintXen,而是临时随意的一个 20token 来示意。
下文便是最简单的一个 ERC20 代币了,任何人均可执行 mint 函数,雷同于 XEN 了
对于 ERC20/721 实现原理可拓展阅读:xx
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract token20 is ERC20 {
constructor() ERC20("Gold", "GLD") {}
function mint(address to,uint256 amount) public {
_mint(to,amount);
}
}
而攻击合约也很简单,设置写死要调用 Mint 的 XEN 合约地址以及黑客收益的地址。
interface IERC20 {function mint(address to,uint256 amout) external ;}
contract attack{
address ERC20Addr = 0xd9145CCE52D386f254917e481eB44e9943F39138;
address myAddr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
receive() external payable {
IERC20(ERC20Addr).mint(myAddr,1e18);
selfdestruct(payable(myAddr));
}
}
可以看到实验中,对此攻击合约发起的任意一笔交易,即会触发了 receive,且 myAddr 的 GLD 余额增加 1e18 个,当然并不能拿着这个代码就去复现黑客的实现了,因为要铸造更多的 GEX 还得增加工厂合约部署的逻辑,即能提高 gas 消耗也吻合 XEG 的 mint 管理。
总结-从攻击事件看” 元交易 “的发展
其实如果不是黑客本身知道 FTX 有免费提币优惠,且其提币的交易的 gasLimit 设置为固定值 50W,则很难发起这样的攻击,因为依据以太坊黄皮书,普通转账也仅仅需要 2.1W 的 gas 即可。
黑暗森林的 web 里知其雄守其雌,这样的攻击从历史进程来看,其实更有警示性意义
笔者想谈谈元交易的发展
元交易是来自于 Christian Lundkvist 教授在 2015 年的一个设想
如今上手 Dapp 实在是太麻烦了,以太坊生态若想普及,就应该允许新用户直接使用其功能,而不是先安排几座大山让用户翻山越岭。这意味着需要为新来的用户垫付 Gas 费用。当前的以太坊协议并没有提供原生方法来实现这一点。然而,得益于公/私密钥对,用户可以通过对元交易 进行签名并证明所有权。
相信未来元交易终会成为应用主流,本次的 FTX 代付 gas 执行免费提币转账还只是元交易的某种小小(伪)实现,但只有安全+无感才能迎接全民低成本上链时代的到来(而非低代币 gas 价格),为此安全与风控都需要特别注意,这也是笔者分析安全案件的初衷。
免责声明:作为区块链信息平台,本站所发布文章仅代表作者及嘉宾个人观点,与 Web3Caff 立场无关。文章内的信息仅供参考,均不构成任何投资建议及要约,并请您遵守所在国家或地区的相关法律法规。