Mobius项目由于智能合约中的一个漏洞,攻击者通过该漏洞增发了价值215万美元的MBU代币。该漏洞位于deposit函数中,计算代币数量时的一个乘法运算缺少了除以10^18的步骤,导致攻击者能够铸造天文数字般的代币。攻击者利用此漏洞,从零地址铸造了大量的MBU,并通过一系列操作将资金转移。
Mobius 是一家 Stellar 生态系统中的区块链公司,旨在“弥合”传统互联网与去中心化应用程序世界之间的差距。 他们的 MOBI 代币为生态系统内的支付提供支持,并支撑着一系列服务:
根据 Cyvers Alerts 在 2025 年 5 月 11 日的报告,攻击者设法从 Mobius 智能合约中抽取了大约 215 万美元。
让我们来分析一下该项目的智能合约以及漏洞的核心。
首先,我们将确定关键地址和交易:
现在让我们在 Tenderly 中检查此交易的详细信息。
代币流动
让我们分解一下此交易的关键步骤:
将 1 BNB 兑换为 stablecoin(稳定币):
–1 BNB → +≈ 2 157 126 BSC-USD
大规模 MBU 铸造:
从零地址 (0x000…000) 铸造了天文数量的代币:+9 731 099 540 720 980 659 843 835 099 042 677 MBU
通过零地址发行:
零地址充当“minter(铸币者)”。
Proxy(代理)合约收到铸造的 WBNB:
作为 BNB 包装流程的一部分,+0.001 WBNB 落在代理上。
Dust-size(小额) MBU 分配给 EOAs:
几个外部账户收到少量 MBU:400 005 MBU、266 670 MBU、333 330 MBU、333 330 MBU、166 665 MBU
限制范围内的合法铸造:
第二次 mint(铸造)调用发行 +28 500 000 MBU 以换取 –2 157 126 BSC-USD。
将 WBNB 解包回 BNB
代理/路由器转换 0.001 WBNB 并返回几乎所有原始 BNB:+0.001 WBNB 和 +0.999 BNB
该交易由地址 0xB32A53Af96F7735D47F4b76C525BD5Eb02B42600 发起,该地址首先在 0x631adFF068D484Ce531Fb519Cda4042805521641 上调用了该函数。与 Mobius 协议的所有交互都通过该合约进行。为了揭示其内部运作方式,我从 BscScan 获取了它的 bytecode(字节码)并通过 Dedaub 反编译器运行它。
结果,很明显该合约公开了三个关键函数:
withdrawERC20(address tokenAddress, address to): 一个通用的“sweep(清扫)”函数,用于合约持有的任何 ERC-20 代币:
withdrawERC20
用于漏洞利用的函数
从 BscScan 我们知道攻击期间使用的 calldata 是:
0xcd60b03d
00000000000000000000000095e92b09b89cf31fa9f1eca4109a85f88eb08531
0000000000000000000000000dfb6ac3a8ea88d058be219066931db2bee9a581
这解码为:
核心逻辑按以下步骤展开:
包装 BNB → WBNB
利用 Vulnerable(有漏洞的)合约:
交换铸造的 MBU
排干剩余的 BNB
换句话说,这个 helper(辅助)合约本身所做的仅仅是编排调用——漏洞利用并不存在于此。接下来,我们将深入研究处理 deposit(存款)的实际 Mobius implementation(实现)合约。
Proxy(代理)合约地址: 0x95e92B09b89cF31Fa9F1Eca4109A85F88EB08531
在撰写本文时,它已经切换了其实现。为了发现哪些参数在部署时传递给 proxy(代理),我找到了合约创建交易并提取了其 calldata。
在 proxy(代理)创建 calldata 的最末尾 — 在标准 bytecode(字节码)前缀和 metadata(元数据)之后 — 出现了 constructor(构造函数)参数:
...000000000000000000000000637d8ce897bb653cb83ba436cdf76bbe158f05b100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000004cbbb1b6ab63b6b01f9309b0aa53a05962a4a66b00000000000000000000000036b7ec863c846d6050e489db1985e7f21a6c90d40000000000000000000000002a8f6052263ef761109d1cae051e9f4f49cffaf200000000000000000000000000000000000000000000000000000000
在最开始,我们看到了我们需要的 implementation(实现)地址:0x637d8Ce897bb653Cb83Ba436CDf76bBe158f05B1
我从 BscScan 获取了这个 implementation(实现)合约的运行时 bytecode(字节码),并通过 Dedaub 反编译器运行它。输出是可读的 pseudocode(伪代码) — 这就是漏洞隐藏的地方。
让我们仔细看看 deposit(存款)函数:
deposite 函数
deposit(存款)函数非常简洁,你可以清楚地看到 mint(msg.sender, v4) 处的代币 mint(铸造)。
我们可以注意到,在私有调用 0x3039 之后,v4 的值再也不会改变,这表明 v4 的计算方式存在错误。有两个函数处理此计算 — 0x3039 和 0x371b。让我们首先检查 0x3039。
0x3039
在快速审查中,我没有发现任何问题 — 0x3039 在逻辑上看起来不错。所以我立即将注意力转向 0x371b 函数。
0x371b
在这里,很明显该函数只是将代币数量乘以它们的价格:
v3 = v1 * varg1;
并且永远不会将结果除以 10**18 以调整小数位数。请记住,代币的价格和代币数量都使用它们自己的 decimal(小数)缩放。因此,v3 最终会被精确地膨胀 1⁰¹⁸ — 这正是使攻击者能够铸造天文数量的代币的原因。
感谢你的关注!😊
P.S. 在区块链中,没有 floating-point numbers(浮点数):所有值都通过乘以 10**(decimals) 来缩放。在进行算术运算时,你必须始终记得除以(或乘以)相同的 10**(decimals) 以使结果保持在正确的缩放比例中。在这种情况下,缺少除以 10¹⁸ 是关键的 vulnerability(漏洞)。
P.P.S. 我自己得出这些结论 — 直接分析交易和合约 — 然后对照外部来源进行交叉检查以完成整个过程。
- 原文链接: coinsbench.com/explosive...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!