SOLID:Curve这次遭遇的漏洞利用 或许为黑客们打开了新思路

作者:Jaleel,BlockBeats 

随着一场漏洞利用事件的发生,DeFi 行业陷入了一场混乱。Curve Finance,这个 DeFi 行业的巨头,成为了严重「攻击」的目标,诸如 alETH/msETH/pETH 的多个稳定币池岌岌可危。据不完全统计,该漏洞利用事件已造成 Alchemix、JPEG'd、MetronomeDAO、deBridge、Ellipsis 和 CRV/ETH 池累计损失 5200 万美元,整个市场的信心被严重撼动。

Vyper 0.2.15、 0.2.16 和 0.3.0 版本的重入锁失效,Vyper 官方文档安装界面推荐的也是一个错误的版本。其他使用 Vyper 编译器的项目方也赶紧进行了自查,试图确保自己不会成为下一个受害者。随着漏洞利用事件的源头被逐渐揭露,市场逐渐认识到,这次的危机并不仅意味着一次普通的黑客漏洞利用事件,更是展露出整个底层堆栈对整个 DeFi 行业潜在的巨大风险。

和以往相比,前段时间的黑客事件数量越来越少,这与市场的繁荣程度脱不开关系。DeFi summer 和 NFT summer 时期,每周都有新的十亿美元协议推出,相比之下如今的市场十分萎缩。与此同时的,黑客们找到漏洞利用或者制造大笔的攻击事件的市场机会也在逐渐萎缩,这意味着黑客需要更新的、未开发的切入口来探索。

回归「第一性原理」的黑客们在更底层的编译器上找到了一个完美的切入口,去馋食 DeFi 市场上巨大可口的「蛋糕」,更底层的编译器成为了黑客们更「聪明」的选择。就这次事件及其暴露出的相关问题,BlockBeats 采访了智能合约开发者 Box(/img/202386163054/0.jpg">

那在这次攻击事件里,Vyper 的问题究竟出在哪里?重入锁为什么会失效呢?是因为没有进行测试吗?BlockBeats 采访了智能合约开发者 Box 826.eth(/img/202386163054/1.jpg">

在 Box 后续分享出来的这几段 Vyper 代码中,可以明显看出问题。当锁名称第二次出现的时候,storage_slot 的数量会被覆盖,也就是说,在 ret 中,第一次获取锁的 slot 为 0 ,但是再次有函数使用锁后,锁的 slot 被加一。编译后使用错误的 slot,导致重入锁无法生效。

左为被攻击代码,右为修复后代码

「预计错误的测试结果,当然验证不出错误。举个简单的例子,现在我们在做计算题, 1+ 1 = 2 ,但给定的标准答案错了,说 1+ 1 = 3 。而这时做题的同学答错了,回答了 1+ 1 = 3 ,但却和提前给定的标准答案相同,程序就自然没办法判定出测试结果出错。」Box 在和 BlockBeats 的采访中这么说道。

前美CFTC主席将担任Citadel Securities首席法律官:于3月离开美国商品期货交易委员会(CFTC)的前主席Heath Tarbert将于4月5日加入Citadel Securities担任首席法律官。据悉,Citadel Securities是全球最大的做市商之一。该公司传统上保持低调,但最近因其与股票及加密交易平台Robinhood的关系而受到来自监管机构的压力。此前消息,监管文件显示,交易公司们为股票和期权订单流信息向Robinhood支付了近1亿美元的费用。Citadel Securities等高频交易公司在2020年第一季度向该公司支付了9100万美元的费用,以换取各种类型的订单。(the block)[2021/4/3 19:42:07]

在有所记录的史上第一次重入攻击事件中,WETH Attack 韦斯攻击的攻击者,正是为了让开发者重视重入攻击而故意制造攻击的白客,目的是使更多项目免受重入攻击的可能性。在智能合约的情境下,开发者应该采用不同的触发机制,例如调用某个状态改变函数来实现保护。这就要求开发人员在设计合约时充分考虑可能的攻击场景,采取适当的预防措施。

为了深入了解 Vyper 编辑器,BlockBeats 采访了 BTX 研究员 Derek(/img/202386163054/3.jpg">

对于编译器的漏洞,仅通过对合约源码逻辑的审计,是很难发现的。仅仅是研究版本和版本之间的差异也是一个大工程。需要结合特定编译器版本与特定的代码模式共同分析,才能确定智能合约是否受编译器漏洞的影响。

「目前只有两个编译器最佳,Vyper 的代码库更小,更容易阅读,对其历史进行分析的更改也更少,这可能就是黑客从这里下手的原因,Solidity 的代码库要更大一些。」fubuloubu 甚至怀疑国家支持的黑客可能参与这起 Curve 攻击事件:「找到该漏洞需要几周到几个月的时间,考虑到投入的资源,这也许是由一个小团体或团队进行的。」

作为加密行业使用最广泛的编译语言,Solidity 的安全更是被用户所牵挂,毕竟如果这次是 Solidity 编译器出现了重入锁失效的问题,那么整个 DeFi 行业的历史或许都要被改写了。

根据 Solidity 开发团队定期发布的安全预警,在多个不同版本的 Solidity 编译器中也都曾存在过安全漏洞。

最近一次的编译器错误记录是 6 月 26 日,在调查与使用具有副作用的三元表达式的 abi.decode 作为类型参数相关的安全报告时,在 Solidity 编译器的旧代码生成管道中发现了一个错误。旧代码生成器没有评估复杂的表达式,如赋值、函数调用或条件,其 .selector 正在被访问。这会导致此类表达式未执行的副作用,因此使用旧管道编译的合约的行为可能不正确。

我们也可以看到 Solidity 的Github 仓库 中放置着一个文件,上面列出了 Solidity 编译器上一些已知的安全相关的 bug。该列表可以追溯到 0.3.0 版本,只在此版本之前存在的 bug 没有被列入。这里,还有另外一个 bugs_by_version.json 文件。该文件可用于查询特定的某个编译器版本会受哪些 bug 影响。

幸运的是,也正是因为 Solidity 语言的广泛应用,以及以太坊基金会在背后的辅助,许多已存在的问题已经被项目和协议在部署的过程中被指出。因此 Solidity 比 Vyper 更快几步完成了修改和完善,从这个角度看,这也是 Solidity 更规范和更安全的原因之一。

为了帮助 Solidity 开发者进行更好的测试,防止发生同样的事。UnitasProtocol 联合创始人 SunSec(@ 1 nf 0 s 3 cpt)在 Curve 被攻击事件后,发布了一份 DeFiVulnLabs Solidity 安全测试指南,支持 47 种漏洞,其中包括漏洞描述、场景、防御、漏洞代码、缓解措施以及如何测试。

在这起 Curve 事件上,Box 认为所有开发者得到的启示是:不要贪图追随技术潮流选择不成熟的方案;不要在不写测试用例的情况下就认可自己的代码(Vyper 出问题的几个版本上,甚至连测试用例都是错误的);永远不要自己批准自己的代码;有些财富,可能要数年才会被发现;不可升级是对自己的傲慢和对其他人的藐视。

通常开发人员也不会想到这里面有什么坑,随手就选一个版本编译,可能会忽略版本之间的区别所带来的风险。即使是小版本升级也可能引入重大变化,这一点在开发去中心化应用程序时尤其重要。

这起 Curve 事件对开发者的警示有:使用较新版本的编译器语言。保持最新的代码库、应用程序和操作系统非常重要,同时也要全方位搭建自身的安全防御机制。尽管新版本也可能引入新的安全问题,但已知的安全问题通常较旧版本要少。当然也要及时关注社区和官方的版本更新公告。了解每一个版本带来的变化,按需更新自己的代码库和运行环境。采取这些措施或许可以大大减少编译器错误导致的安全事件。

此外,要完善代码的单元测试用例。大部分编译器级别的错误会导致代码执行结果不一致, 这很难仅通过代码 review 发现, 但在测试中就可以暴露出来。提高代码覆盖率有助于避免这类问题。以及要尽量避免使用内联汇编、多维数组编解码等复杂语言特性,除非有明确需求。历史上大多数 Solidity 语言漏洞都与这些高级功能相关。在没有特殊需求的情况下,开发人员应该避免为了炫技而使用实验性语言特性。

对协议层以及安全人员而言,在进行代码审计时,也不能忽视编译器版本可能带来的风险。可以预见的是,黑客们已然打开了新思路,在未来一段时间里,更底层的漏洞被利用事件会越来越多。同时,作为更底层的基础设施,底层堆栈、编程语言、EVM 等更需要被好好审计。未来审计公司的市场会越来越大,白客赏金的市场也会越来越大。Vyper 团队也计划在事情正式结束梳理后,开启审查漏洞赏金的计划。

当然我们也不用对底层基础设施存在的风险过度恐慌。目前大多数编译器 Bug 仅在特定代码模式下触发,还需要根据项目情况具体评估实际影响。定期升级编译器版本、充分的单元测试都能帮助预防风险。

区块律动BlockBeats

媒体专栏

阅读更多

Foresight News

金色财经 Jason.

白话区块链

金色早8点

LD Capital

-R3PO

MarsBit

深潮TechFlow

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金星链

[0:15ms0-0:968ms