op代币丢失始末

5月8号早上看到很多关于op 2000万代币丢失的消息。两天过去了 很多大佬已经对整件事有了非常明了的梳理了。我自己再整理一遍给自己看。

涉及地址:

Gnosis Safe: Deployer 3(

0x1aa7451DD11b8cb16AC089ED7fE05eFa00100A6A

Gnosis Safe: Proxy Factory(

0x76E2cFc1F5Fa8F6a5b3fC4c8F4788F0116861F9B

masterCopy

(0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F)

攻击者钱包地址(

0x60B28637879B5a09D21B68040020FFbf7dbA5107

攻击者批量创建多签钱包地址(

0xE7145dd6287AE53326347f3A6694fCf2954bcD8A

Wintermute Exploiter Multisig(

0x4f3a120E72C76c22ae802D129F599BFDbc31cb81

攻击者的另一个地址(

0x8bcfe4f1358e50a1db10025d731c8b3b17f04dbb

先回顾一下 op 项目方给 Wintermute 2000万个op 去做市商 Wintermute 给op项目方提供了Multisig合约地址,op项目方先测试了两笔 地址收到了 就给转了2000万枚。这个过程中Wintermute 并没有在测试的时候检查是否有Multisig合约地址的控制权。那为什么Wintermute 会提供给op项目方Multisig这个地址呢?其实Multisig是Wintermute 在eth上的多签钱包地址,至于为什么他要提供这个地址,是疏忽还是别的什么原因就不得而知。

我们知道合约地址在为创建时就是一个普通eoa地址 只是我们谁也不知道私钥。在Multisig收到2000万op时 它在op链上还是一个没有私钥的普通EOA地址。但是它在eth链上已经是一个合约地址了 由于op链与eth链都是evm兼容的链。很多实现都是一模一样的。于是一个大胆的想法就产出了 是不是可以在op链上创建出这个合约地址来?

在eth链上创建合约 有两个方法 ,分别时create2 与 create

post image
post image

那我们就先去看看eth这个Multisig是怎么创建的吧

创建交易

0xd705178d68551a6a6f65ca74363264b32150857a26dd62c27f3f96b8ec69ca01

post image

Multisig是由一个EOA地址调用了Proxy Factory合约的

createProxy(address masterCopy, bytes data)方法以masterCopy 与data为参数创建的

由于createProxy是在区块浏览器验证的地址 我们就可以去看看它的具体实现

post image

显然它是用create创建的

也就是说我们要创建出与eth链上地址相同的Multisig合约 我们只需要用op链上Proxy Factory不断去创建多签钱包 op链上Proxy Factory的nonce值与eth链上创建Multisig的nonce值相等的时候创建出来的Multisig合约地址就会与eth链上的合约地址相同。

实际上攻击者也确实是这样做的

他首先创建了批量调用op链上Proxy Factory创建多签钱包的合约(0xE7145dd6287AE53326347f3A6694fCf2954bcD8A)

然后批量去创建(eth链上创建出Multisig地址的nonce我们是可以知道的)

post image

终于在交易

0x53ce65948fd07bb012142578fe399ddfe0a0cfab3a941ef56b33cde706ad9b24给创建出来了

到此攻击者就创建出接受2000万op的Multisig合约了 也拥有了合约的看控制权。

拥有控制权后 他通过交易

0x230e17117986f0dc7259db824de1d00c6cf455c925c0c8c6b89bf0b6756a7b7e

给地址0x60B28637879B5a09D21B68040020FFbf7dbA5107转了100万op并立马在inch上获利720个eth。

在9号是我以为这就是事件的整个过程没有想到忽略了最关键的部分。

在攻击者攻击之前Proxy Factory合约在op链上是没有创建的。

那就必须得先创建出Proxy Factory。

那我们再去看看eth上得Proxy Factory合约是如何创建得

0x75a42f240d229518979199f56cd7c82e4fc1f1a20ad9a4864c635354b4a34261
0x75a42f240d229518979199f56cd7c82e4fc1f1a20ad9a4864c635354b4a34261

而Proxy Factory得创建这是一个EOA( Gnosis Safe: Deployer 3)地址,整个地址应该是属于Wintermute 的。怎么办?

那就先去op上看看这个地址( Gnosis Safe: Deployer 3)

此时在op上是没有任何交易的

再看个前置知识。

post image

现在我们知道如果eth链上的Gnosis Safe: Deployer 3 创建Proxy Factory的前几笔交易都是不符合eip155标准我们就可以再op链上重放这些交易 从而再op链上创建出Proxy Factory合约。

重放的过程就直接贴上慢雾的文章了 (不太想写了)

post image
post image
post image

再对比一下两条链的这几笔交易

eth

post image

op

post image

是不是发现交易hash都是一样的啊

第一笔创建了创建Implementation(masterCopy)

第二笔 调用了 0x34F5c67D50d7539B69B743F45B7e24ebBE7202cA 合约的

Function: setImplementation(string contractName, address implementation) 方法

implementation为第一步创建的masterCopy

第三笔 创建了Proxy Factory,后面创建Multisig 传的masterCopy 就是第一步创建的合约是具体的逻辑合约。到此 对上前面就是整个过程