Jason chen

Posted on Jun 08, 2022Read on Mirror.xyz

深度解析Optimism被盗2000万来龙去脉!真tm精彩!

很抱歉由于昨天发这篇文章时的研究不够深入,与专业度还是不足,在关于黑客如何生成一样的合约地址的作案手法部分描述错误,黑客先使用了重放攻击在optimism中部署了factory合约,再使用该合约创建了持有资产的合约地址。很感谢各位朋友的反馈与错误指出,对于研究不够深入表示歉意,欢迎各位随时交流探讨,互相学习进步

https://jason.mirror.xyz/x1pVL_Gd11SppFFYgnr3LvFx4TrHch4yRZZBMypCZ20

以下为正文,作为web3信仰者,我遵循web3不可篡改的精神,所以我就不修改本文中的错误,而是如开头重新发了一篇更正补充文章。

—————————————————————————————————————————

未经允许,严禁任何一家媒体私自转载,本文共耗时6小时,请尊重作者不要白嫖,一旦发现将断绝所有合作,并将你们挂在网上警示其他创作者,就是这么硬。

关于这件事大家应该已经在网上看了很多零碎的信息,不少媒体也把外网twitter生搬硬套翻译过来,实际上根本说不通也看不懂,如果你不懂技术也没关系,本文你一定能看得懂。

今天睡起来看到各大媒体都在发Optimism被盗2000万OP的消息,朋友圈和读者群也在热议,毕竟Optimism之前刚完成一轮空投,利益相关方很多,且Optimism的地位也被捧的很高被誉为最有影响力的Layer2方案,所以发生这种事情恐慌情绪蔓延的很快。

说实话我在看到这个信息的时候,也比较吃力,涉及到的知识盲区比较多包括跨链、多签等,所以研究梳理起来相比于之前发的文章困难不少,目前也在twitter以及群聊等渠道看到一些信息,但是比较零散,且背景不全对我来说理解也很困难,更何况读者们了,所以这篇文章我会把背景也讲的详细点,帮助大家建立起更全面的知识体系。

首先要介绍本事件的主角Optimism,它是一种以太坊扩容解决方案,我在读研时恰好当时的研究课题就是区块链扩容并发过一篇SCI一区,所以这里比较拿手给大家多介绍一下,以太坊扩容大体分为两种方案Layer1与Layer2。

Layer1是硬扩容,即直接更改以太坊的架构,比如以前是2车道,然后喊施工队过来把它扩成4车道。

Layer2是软扩容,将一些交易和计算从以太坊挪出来到外面来进行,比如以前是2车道,现在在上面修了高架桥,下面挖了地铁。

Optimism的原理是从以太坊接收交易数据,然后把它发送到Layer2层计算,再接收回计算结果,从而极大的节省了gas费提升交易速度。

这件事的起因是Optimism因为发了token要做市从而提供流动性,所以聘请了专业的做市商Wintermute与其合作,并向Wintermute提供了2000万枚OP用于启动做市。

Wintermute也非等闲之辈,被誉为做市商中的超级巨星,币安、Coinbase、火币等一系列主流交易所都在使用它。

所以这次Optimism和Wintermute这两个分别在扩容和做市领域独占鳌头的公司本应是天作之合,但两家顶级公司强强联手却依然出现了这么大额的漏洞损失,是咋回事呢?这时候引入第三者:Gnosis Safe。

Gnosis Safe是一款多签钱包,这个概念大家应该已经很熟悉了,普通钱包掌握私钥后会拥有全部权限,多签钱包则是可以自定义该钱包的管理规则,比如多人同时签署才可以进行资产转移等行为,一般企业都会使用,毕竟相对更安全,为啥说相对呢?这次不就出事了...

好了Optimism、Wintermute和Gnosis Safe三个演员都出场了,接下来梳理他们之间到底发生了什么故事,使得给了黑客可乘之机。

首先一个非常重要的背景是地址分为合约地址和钱包地址,钱包地址就是你自己小狐狸的地址,它是归属于你个人所有的,只用于收付款等行为,合约地址则是通过智能合约代码部署生成的地址,除了具备收付款能力以外,因为有智能合约的存在可以实现更多业务逻辑,比如多签钱包。

对于钱包地址不论在哪个网络进行切换,钱包地址和钱包拥有权即私钥都是不会变的,变的只是对应的网络不同,即我在以太坊的钱包,切换到polygon还是我的钱包。

但是合约地址不一样,它产生的过程是先编写智能合约代码,再将其选择一条链进行部署,说到这里老粉一定会激动起来,如果你现在不激动,那你就不是我的老粉,还记得我之前写的那篇跨链文章吗《那个可以跨链的Gh0stlyGh0sts会成为下一个Azuki吗?》,还记得这篇文章是这么讲到它跨链的原理吗?这玩意直接简单粗暴的在7条链部署了7遍一摸一样的合约,从而实现了跨链,因为我从A链跨到B链,B链得有东西能够接住它,于是我需要在B链也部署一套和A链一摸一样的智能合约。

所以到这里你应该意识到了,哦,如果是我个人的钱包地址,不管在哪个链,这个钱包都是我的,如果是合约地址,只有部署的链才是我的,没部署的就和我没关系。

那么我们来试着看一下一个在以太坊中完成部署的合约地址,在其他的链中是什么样子呢?我们猜测一下,有两种可能,要么是不存在这个地址,要么是存在但是无人认领。

下图是无聊猿在以太坊的合约地址,正常的对吧。

下图是该地址在Optimism中的状态,地址存在,但是没有创建人,没有合约,没有交易,什么都没有,所以这是一个无人认领的地址。

这里快破案了,精彩的地方来了,下面图是Gnosis Safe为‍Wintermute在以太坊创建的的一个多签钱包地址,虽然这里叫钱包地址,但是它的本质是合约地址,所以怎么样?它在以太坊部署了,就只在以太坊有用,它没在Optimism部署,那Optimism就是一个无人认领的地址。

下图是Optimism里与Wintermute在以太坊网中一摸一样的地址,你们会疑惑,哎不对啊这不是有交易记录,也有创建人吗?

别急,我们来看看这个地址都做了些什么。

它的第一条交易记录是0x25这个地址(也是Gnosis Safe生成的多签地址)给它转移了1OP,1天后分两次又转了2000万OP。

我们看一下Optimism是怎么解释的,为方便读者阅读我网页翻译为中文,它说先给Wintermute发送了两次测试交易,让Wintermute确认它是否收到,然后对方说我收到啦,因为我打开这个地址看了下发现多出来了1个OP,于是Optimism放心的又转了2000万过去。但是等转完后Wintermute突然发现自己无法操作这些token,因为tmd我忘了把合约部署到这个地址了!这地址现在就压根不是我的啊!

其实这个时候可能的剧情是这2000万个token因为转入一个不存在的地址而被永久锁定了,因为这个地址也压根不属于Wintermute,不属于任何一个人的黑洞地址。

所以到这里其实Optimism与Wintermute的败局已经定了,即使没有后来这个黑客的出现,已经产生了如此严重的失误将钱转入一个不存在的地址。

那么既然这个地址是不归属于任何一个人的地址,为啥后面这个黑客又可以把钱转走呢?从这里开始会稍微复杂,但是一定要认真理解阅读下去。

我们再回顾一下《那个可以跨链的Gh0stlyGh0sts会成为下一个Azuki吗?》这篇文章,里面提到它跨了7个链,于是部署了7个合约,但是这7个合约的地址都是不一样的,而并不是1个地址对7条链都有效,这里稍微有点绕,一定要理解清楚,我再详细解释一下。

首先我在A链部署了一个地址为123的合约,这时在B链也有个不属于任何人的123地址。

然后我在B链部署了一个新的合约,此时它的地址是456,并不是123。

因为合约部署后产生的地址是有一个算法规则的,不是说在不同的链中,同样的人部署同样的合约代码,就对应着同样的地址。

那么我们来猜测一下这个黑客的可能性,要么是他部署了一套合约并且这个合约地址与Optimism打款过去的无人认领地址恰好一摸一样,要么是黑客用了什么骚操作直接黑进了EVM把这个无人认领的地址资产转移走了?基本上不可能如果能黑进去这v神都得管他叫爸爸。

那么第一种可能性最大,但是刚才已经说过每次部署合约后产生的地址都是不一样的,说明是“随机”的,那这个黑客如何恰好命中了这个地址呢?我们要先了解一下合约地址生成的规则,了解它是怎么随机的。

这篇openzeppelin的文档很清晰的讲解了地址生成规则:https://docs.openzeppelin.com/cli/2.8/deploying-with-create2,我带大家来拆解一下。

总共有两种生成规则CREATE和CREATE2,我们先看CREATE,可以看到合约地址是由发布者地址和一个随机数生成的。

另外一种CREATE2就复杂不少了有很多参数。

我们来看一下Gnosis Safe的合约代码,会发现它在创建合约时传入的参数类型与CREATE一致,所以能够确定如果想创建一个合约地址与Optimism中的地址一样,只需要确保创建者地址与随机数这两个参数与在生成以太坊那个有效地址时的一样就可以了,这里稍微有点复杂要认真理解一下,我使用了X和Y两个参数在以太坊创建了地址123,这时Optimism也有个123无效地址,于是我需要在Optimism中也使用X和Y创建一个合约出来,这个合约的地址就恰好是123。

黑客的地址是:0x60B28637879B5a09D21B68040020FFbf7dbA5107,我们来看看它都做了些什么。

可以看到他使用了合约0xE7145dd6287AE53326347f3A6694fCf2954bcD8A来调用Gnosis Safe用于创建多签钱包的合约:0xE7145dd6287AE53326347f3A6694fCf2954bcD8A,执行了64次交易,这些交易是干嘛的呢?

我们打开其中一个可以看到,每一个交易中都执行了162次创建多签钱包的事件,其中可以看到Address即合约创建者参数它传入的就是当时给Wintermute在以太网创建了多签钱包的地址,那么剩下的那个递增随机数就只需要不断的去创建然后去碰运气,迟早会刚好碰到这个数从而在Optimism生成一个与以太坊一样的地址。

这里我不辞辛劳的一个个点开了这几十个交易并从中查找,终于在0x00a3da68f0f6a69cb067f09c3f7e741a01636cbc27a84c603b468f65271d415b中找到了存着2000万个OP的地址。

当我找到这个地址时,我仿佛能够感受到黑客当时的心情。

以上就是整个Optimism事件的来龙去脉,这篇文章写的还是很辛苦的,主要因为涉及到的知识面比之前以往的都多,不过这里提一下我写过最累的一篇文章还是《深度解析:NBA的16进制合约漏洞是怎么被科学家薅秃噜皮的?

写完之后,我是什么感受呢?首先我很佩服这位黑客,在之前的Venus事件中我也说过,这种攻击手法绝对不是我们普通人能够执行的,它需要的是技术+认知+运气全部拉满后才可能成功攻击,这种Optimism乌龙本身就是小概率事件,需要有极强的运气能够蹲守到,其次它就算出现了你也需要立刻能够意识到意味着什么,这需要极强的认知可以嗅到背后的机会,最后你需要极强的技术能力来结合你的认知去进行攻击获利。

所以他能赚到这钱?我佩服,但是不论如何,黑客行为是绝对不提倡的,毕竟它是极大的损害了他人的正当利益。

最后还是我一开始强调的,请各位媒体不要未经授权就转发,写文不易,我已经被你们嫖怕了,求求了,只要发现私自转发我绝对挂你。

写文不易,看完有收获麻烦打个赏,不少读者说让我发NFT发paas卡,但是我不想被人说割韭菜,所以我个人不会靠发nft来赚钱,所以如果你可以通过打赏来认可我的文章,谢谢。

欢迎大家添加我的微信 cj350306878,一起交流学习,添加时请备注你的姓名、公司、岗位与来意。

往期文章:

Optimism