MakerDAO治理合约升级背后的安全风波

栏目: 编程工具 · 发布时间: 5年前

内容简介:北京时间 2019年05月07日,区块链安全公司 Zeppelin 对以太坊上的 DeFi 明星项目 MakerDAO 发出安全预警,宣称其治理合约存在安全漏洞,希望已锁仓参与投票的用户尽快解锁 MKR 提并出。MakerDAO 的开发者 Maker 公司亦确认了漏洞存在,并上线了新的治理合约,并宣称漏洞已修复。该安全威胁曝出后,PeckShield 全程追踪了 MKR 代币的转移情况,并多次向社区发出预警,呼吁 MKR 代币持有者立即转移旧合约的 MKR 代币。截止目前,绝大多数的 MKR 代币已经完成了

北京时间 2019年05月07日,区块链安全公司 Zeppelin 对以太坊上的 DeFi 明星项目 MakerDAO 发出安全预警,宣称其治理合约存在安全漏洞,希望已锁仓参与投票的用户尽快解锁 MKR 提并出。MakerDAO 的开发者 Maker 公司亦确认了漏洞存在,并上线了新的治理合约,并宣称漏洞已修复。

该安全威胁曝出后,PeckShield 全程追踪了 MKR 代币的转移情况,并多次向社区发出预警,呼吁 MKR 代币持有者立即转移旧合约的 MKR 代币。截止目前,绝大多数的 MKR 代币已经完成了转移,旧治理合约中尚有 2,463 个 MKR 代币(价值约 128万美元)待转移。

05月07日当天,经 PeckShield 独立研究发现,确认了该漏洞的存在(我们命名为 itchy DAO),具体而言:由于该治理合约实现的投票机制(vote(bytes32))存在某种缺陷,允许投票给尚不存在的 slate(但包含有正在投票的提案)。 等用户投票后,攻击者可以恶意调用 free()退出,达到减掉有效提案的合法票数,并同时锁死投票人的 MKR 代币。

次日05月08日,PeckShield 紧急和 Maker 公司同步了漏洞细节,05月10日凌晨,MakerDAO 公开了新版合约。Zeppelin 和 PeckShield 也各自独立完成了对其新合约的审计,确定新版本修复了该漏洞。

MakerDAO治理合约升级背后的安全风波

在此我们公布漏洞细节与攻击手法,也希望有引用此第三方库合约的其它 DApp 能尽快修复。

细节

在 MakerDAO 的设计里,用户是可以通过投票来参与其治理机制,详情可参照 DAO 的 FAQ。

以下是关于 itchy DAO 的细节,用户可以通过 lock / free 来将手上的 MKR 锁定并投票或是取消投票:

MakerDAO治理合约升级背后的安全风波

在 lock 锁定 MKR 之后,可以对一个或多个提案 (address 数组) 进行投票:

MakerDAO治理合约升级背后的安全风波

注意到这里有两个 vote 函数,两者的传参不一样 (address 数组与 byte32),

而 vote(address[] yays) 最终亦会调用 vote(bytes32 slate),其大致逻辑如下图所示:

MakerDAO治理合约升级背后的安全风波

简单来说,两个 vote 殊途同归,最后调用 addWeight 将锁住的票投入对应提案:

MakerDAO治理合约升级背后的安全风波

可惜的是,由于合约设计上失误,让攻击者有机会透过一系列动作,来恶意操控投票结果,甚致让锁定的 MKR 无法取出。

这里我们假设有一个从未投过票的黑客打算开始攻击:

  • 调用 lock() 锁仓 MKR,此时 deposits[msg.sender] 会存入锁住的额度。
  • 此时黑客可以线下预先算好要攻击的提案并预先计算好哈希值,拿来做为步骤 3 的传参,因为 slate 其实只是 address 数组的 sha3。 这里要注意挑选的攻击目标组合必须还不存在于 slates[] 中 (否则攻击便会失败),黑客亦可以自己提出一个新提案来加入组合计算, 如此便可以确定这个组合必定不存在。 MakerDAO治理合约升级背后的安全风波
  • 调用 vote(bytes32 slate),因为 slate 其实只是 address 数组的 sha3,黑客可以线下预先算好要攻击的提案后传入。这时因为 votes[msg.sender] 还未赋值,所以 subWeight() 会直接返回。接下来黑客传入的 sha3(slate) 会存入 votes[msg.sender], 之后调用 addWeight()。从上方的代码我们可以看到,addWeight() 是透过 slates[slate] 取得提案数组,此时 slates[slate] 获取到的 一样是未赋值的初始数组,所以 for 循环不会执行(由于 yays.length = 0)

    MakerDAO治理合约升级背后的安全风波

  • 调用 etch() 将目标提案数组传入。注意 etch() 与两个 vote() 函数都是 public,所以外部可以随意调用。这时 slates[hash] 就会存入对应的提案数组。
  • 调用 free() 解除锁仓。这时会分成以下两步:
  • deposits[msg.sender] = sub(deposits[msg.sender], wad)解锁黑客在 1. 的锁仓
  • subWeight(wad, votes[msg.sender])从对应提案中扣掉黑客的票数,然而从头到尾其实攻击者都没有真正为它们投过票

从上面的分析我们了解,黑客能透过这种攻击造成以下可能影响:

一、恶意操控投票结果

二、因为黑客预先扣掉部份票数,导致真正的投票者有可能无法解除锁仓

时间轴

MakerDAO治理合约升级背后的安全风波

PeckShield(派盾科技)是面向全球顶尖的区块链数据与安全服务提供商。商业与媒体合作(包括智能合约审计需求), 请通过 Telegram、Twitter 或邮件 (contact@peckshield.com)与我们联系。


以上所述就是小编给大家介绍的《MakerDAO治理合约升级背后的安全风波》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你不知道的JavaScript(上卷)

你不知道的JavaScript(上卷)

[美] Kyle Simpson / 赵望野、梁杰 / 人民邮电出版社 / 2015-4 / 49.00元

JavaScript语言有很多复杂的概念,但却用简单的方式体现出来(比如回调函数),因此,JavaScript开发者无需理解语言内部的原理,就能编写出功能全面的程序;就像收音机一样,你无需理解里面的管子和线圈都是做什么用的,只要会操作收音机上的按键,就可以收听你喜欢的节目。然而,JavaScript的这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发者,如果没有认真学习也无......一起来看看 《你不知道的JavaScript(上卷)》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具