零時科技 || WET 攻擊事件分析
金色財經
背景介紹
2025年9⽉17⽇,我們監控到 BNB Smart Chain 上針對 WET Token 的攻擊事件:
https://bscscan.com/tx/0xf92539acf7eadfd4a98925927a52af5349cb13c2a250908373a5baf8ea4b49ad
攻擊共造成 40k USD 的損失。
攻擊及事件分析
攻擊者⾸先從 Moolah 平台利⽤ flashloan 貸了 5,000,000 BUSD,
在 flashloan 的回調函數 onMoolahFlashLoan 中實現真正的攻擊流程。攻擊者⾸先使⽤ 5,000,000 BUSD 兌換了 19,432,567WETToken,
接着,攻擊者調⽤受害者合約 0x0A4085F8a587af76936Ac6368DFc161e5C875882 的函數 0x6a154c56 。
完成了 332 WETToken 兌換 2,234 WUSD。
隨後⼜利⽤剩下的 19,432,234 WETToken 兌換了 4,999,040 BUSD,
然後,⼜調⽤受害者合約 0x0A4085F8a587af76936Ac6368DFc161e5C875882 的函數 0xa6ff54ad 。將之前兌換的 2,234 WUSD 兌換了 223, 800 WETToken 。
整理的流程如下:
1. 花費 5,000,000 BUSD ,得到 19,432,567 WETToken
2. 花費 332 WETToken ,得到 2,234 WUSD
3. 花費 2,234 WUSD ,得到 223, 800 WETToken
所以,受害者合約 0x0A4085F8a587af76936Ac6368DFc161e5C875882 的函數 0x6a154c56 本質上是完成了 WETToken 兌換 WUSD 的操作,函數 0xa6ff54ad 完成的是 WUSD 兌換 WETToken 的操作。具體的兌換邏輯我們可以看⼀下函數的實現,由於函數沒有開源,只能看反編譯後的內容。
函數 0x6a154c56 的實現如下:
function 0x6a154c56(uint256 varg0) public nonPayable { find similar
require(msg.data.length - 4 >= 32);
v0, /* bool */ v1 = _wet.transferFrom(msg.sender, address(this), varg0).gas(msg.gas);
require(bool(v0), 0, RETURNDATASIZE()); // checks call status, propagates error data on error
require(MEM[64] + RETURNDATASIZE() - MEM[64] >= 32);
require(v1 == bool(v1));
require(v1, Error("failed"));
v2 = 0x235f(varg0); // WET amount to WUSD amount
v3, /* bool */ v4 = _wusd.transfer(msg.sender, v2).gas(msg.gas);
require(bool(v3), 0, RETURNDATASIZE()); // checks call status, propagates error data on error
require(MEM[64] + RETURNDATASIZE() - MEM[64] >= 32);
require(v4 == bool(v4));
emit 0x23266bed0cd8b71bf4eea333265915d69df9cc6cd109a7f5978ff864bdac5c48(msg.sender, varg0, v2);
}
邏輯很簡單,輸入的 varg0 為輸入 WET Token 數量,通過函數 0x235f 轉化為 WUSD 數量,再轉給⽤戶。
0x235f 的主要邏輯如下:
function 0x235f(uint256 varg0) private {
if (varg0 > 0) {
v0 = new address[](2);
CALLDATACOPY(v0.data, msg.data.length, 64);
require(v0.length, Panic(50)); // access an out-of-bounds or negative index of bytesN array or
slice
v1 = v0.data;
v0[0] = _wet;
require(1 v0.length, Panic(50)); // access an out-of-bounds or negative index of bytesN array
or slice
v0[1] = _usdt;
v2 = new address[](v0.length);
v3 = v4 = v2.data;
v5 = v6 = v0.data;
v7 = v8 = 0;
while (v7 v0.length) {
MEM[v3] = address(MEM[v5]);
v3 += 32;
v5 += 32;
v7 += 1;
}
v9, /* uint256 */ v10 = _uniswapV2Router.getAmountsOut(varg0, v2, v11, _wet).gas(msg.gas);
//pancakeswap
require(bool(v9), 0, RETURNDATASIZE()); // checks call status, propagates error data on error
RETURNDATACOPY(MEM[64], 0, RETURNDATASIZE());
MEM[64] = MEM[64] + (0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0 &
RETURNDATASIZE() + 31);
require(MEM[64] + RETURNDATASIZE() - MEM[64] >= 32);
require(MEM[MEM[64]]
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與加密貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 佈局加密資產,台北台中鉅亨買幣實體授課!
- 掌握全球財經資訊點我下載APP
延伸閱讀
- 講座
- 公告
上一篇
下一篇