mt logoMyToken
시가총액:
0%
FGI:
0%
암호화폐:--
교환 --
ETH Gas:--
EN
USD
APP
Ap Store QR Code

Scan Download

黑客来袭!手把手带你深挖区块链安全漏洞

수집
공유하다

目前,区块链漏洞安全问题频发。

区块链行业正面临着私钥生成与保护、共识过程中心化、智能合约代码漏洞、签名过程算法漏洞、系统实现代码漏洞等安全问题,对于以上问题,开发者该如何应对及避免漏洞频发呢?

吴家志(PeckShield研发副总裁、原360 C0RE Team创始成员及360超级ROOT产品负责人,专注于区块链智能合约安全以及数据分析)围绕以太坊智能合约及公链安全问题主题,先是对最近流行的Fomo3D游戏存在”薅羊毛“漏洞展开了深入浅出的分析,之后又对allowance和overflow相关漏洞做了解读,最后,又针对此前影响较大的以太坊EPoD致命报文漏洞做了深入剖析和实操演练。

那么,你对智能合约和公链安全问题了解多少?目前以太坊智能合约存在哪些漏洞?公链安全正遭受哪些威胁?如何去深入剖析区块链现已曝出的漏洞?来听一听区块链资深漏洞专家是怎么说的!

作者 | 吴家志 PeckShield研发副总裁

责编 | kou

以下为吴家志在CSDN主办,区块链大本营、柏链道捷、极客帮创投协办的 「第 9 期 CSDN 区块链技术沙龙」 上的发言内容,区块链大本营在不改变原意的情况下作了精心整理。

我先自我介绍一下,我叫吴家志,目前在PeckShield担任研发副总。我们是今年年初转到区块链领域的,其实创业初期我们有做过一些其他的尝试,之前我的工作比较偏向操作系统安全方面,主要在安卓方向,像360 C0RE Team、360超级ROOT都是我在 360期间开发出来的产品。

目前, 区块链发展的趋势是怎样的 ?可以看一下数据,蓝线代表创建智能合约数量的趋势。

可以看出,去年9月份,智能合约数量出现了大幅下滑,年底各种ICO的出现,使智能合约数量有了很大的上升,今年2月份又出现了明显的下降,过去的两到三个月也都在下降,不过7月份开始又往上涨了,这其中的原因,在场的大家都知道,我就不说了。

而且, 至少2017年下半年开始到今年年初,由于区块链各行业DApp不断落地,行业形势看起来一片大好

区块链这么火,投资人会投入大量资金去买币、炒币...

但在我们安全研究人员眼里来看,它其实是黑客非常感兴趣的目标。

2014年的Mt.Gox的事件 开始,一直到今年这个时间,出现了很多区块链安全事件。比如今年4月份有关智能合约漏洞的 美链(BEC) 事件,5月份的 EDU ,到近期的交易所被黑,各类安全事件很多很多。

这种安全问题,它造成的结果是非常严重的, 你的钱是真的不见了 。不像是手机里面的照片、隐私被窃这种,这根本不是一个级别的。

今天我主要讲两个主题, 智能合约安全 公链安全

深入浅出:Fomo 3D漏洞

先讲一下智能合约相关的安全问题,近期F3D十分火爆,它有很多有趣的东西,就在6天前,我们就有一个比较 新的研究 ……

微博:https://weibo.com/ttarticle/p/show?id=2309404265433178991610

这个故事是这样的,大概7月 23日晚上 8点多,我在微博上发现了一条关于F3D的信息, Geth客户端开发团队的 team leader、以太坊核心成员 Peter 发现了一个F3D的 airdrop() 问题,这引起了我的兴趣,然后我们就去分析。

这个事情很有趣,先看右边蓝色框内,它就是F3D的智能合约之一,它其实有很多合约,今天我只讲其中一个。

其中有一个环节做 airdrop() ,你可以理解为它利用了 彩票抽奖 的机制,假设你投注F3D,不管你买了多少Key,买完之后它就有一个小概率事件,会让你中奖,然后你就会有一个额外的激励。我觉得这个设计也挺合理的,它可以活跃用户参与。

0.1个ETH是F3D最低的奖金,有人刻意用最低的投入去薅羊毛 ,他只要操作个钱,就有机会中奖。最后智能合约里面的 withdraw() 函数把钱取出来。

先看一下 function airdrop() 这个函数,有个名为seed的变量,seed是随机数中很重要的一个概念, 计算机世界中不存在一个绝对的随机数 ,你只能通过seed去生成一个相对的随机数。

一旦你可以通过某种方法预测seed值,这个随机其实就会 从小概率事件可能变成一个大概率事件

比如说我刚开始学编程的时候,一开始学C,我用 random() 函数获取随机数,我那时候还不知道seed,我就会传空值或者传零进去,然后我发现每次跑都会是同一个结果。

这个黑客找到了一个方式, 在每次投注的时候,预测说这里一定会开奖,百分之百会开奖 。确定之后他再投这个钱,所以他每次都可以从里面拿钱出来。

说一下这个东西是怎么被预测的?其实它的实现是这样的,可以看到seed运算里面有这么几个关键点,比如说timestamp、difficulty、coinbase、gaslimit和number。

还有一个比较特别的,就是 airDropTracker_ ,事实上这些都是合约里面的一个值,你可以随时把它读出来,所以你可以认为前面提到的全部都是已知的,唯一你不能预测的,就是 msg.sender

当时Peter认为F3D团队假设认为 msg.sender 的随机性是足够的,其实 msg.sender 就是你进到合约时的钱包地址,F3D团队认为你不可能生成大量的钱包去尝试,然后让seed变成可预测的, 但并不是只能从钱包进来,也可以从另外一个合约进来 ,这个其实就是关键。

这就又涉及到一个算法,有一个叫 isHuman() 的函数判断,判断是真人钱包还是其他合约,但问题是这个判断有一个错误,就是 Extcodesize()

你可以用智能合约不停地刷 airdrop() ,这很像一个挖矿的过程,因为智能合约生成的新合约地址是可预测的,所以你就可以一直不停的算,直到算出一个seed结果满足 return(true) 时,就可以保证开奖。

一旦智能合约在 constructor() 里面去调 isHuman() 判断时,它就会误判,然后造成人为开奖的结果。

所以,就会出现这样一个的攻击模式——首先可以生成多个合约,然后就一直算,直到算到某一个可以搭配当下 airDropTracker_ 的合约X时,就可以保证开奖,然后再根据合约X去投注,就可以不断把财经池里面的财经全部都拿走。

但其实对F3D来说,这也不是一个太大的问题。因为 被攻击的财经池只是F3D整个奖金环节中的很小一块

所以,它就好比你玩某一个游戏,有一个外挂,你的攻击力每次都加9,保证你可以把人砍死,大概是这样,有点类似破坏游戏平衡吧,但其实对整个游戏的影响不会太大,比如说把所有人的个人资产都拿走。

其他智能合约相关漏洞

接下来讲一些其他有关智能合约安全的问题。

有一类问题是跟allowance有关的 ,比如ERC20里面有一个标准的API叫 transferFrom() ,它允许某一个人把你的钱转走,但前提是事先已经声明好的,在哪里去声明?就是在 allowed[] 这个数组里。

这里有一个问题, 虽然它可以允许你把钱转走,但是却无法判断你要转走多少钱 ,它其实是仅仅把这个allowance剪掉了,这是代码上的一个bug,EDU问题就属于这种类型。

这是我做的一个实验,我隐去了一些信息

最上面那个0xd开头的值是我的一个钱包地址,然后To指向是受我攻击的合约的地址,攻击完成后,我把0xa地址其中的一个EDU,就是好多0后面有1个的那个,转到了0x6这个地址,其实0x6也是我的钱包地址。

Input Data这一块是一些攻击的细节,其实这个构造起来非常简单,你只要去调 transferFrom() 函数,然后你就传入from、to和value。所以,我偷了一个EDU到我的钱包,这个攻击就是这样的。

接下来,以 batchTransfer() 为例,讲一下overflow相关的漏洞,它的攻击是这样完成的。

在调用 batchTransfer() 函数时,有两个可以传入的参数,一个是receivers,一个是value。

receivers是一个数组,它传入了40这个数,这个数值表示偏移量,是需要传给智能合约的。然后下面还有2或者8开头的。

这个逻辑是这样的,在 batchTransfer() 的实现上面,就是把8开头后面全部都是0的这个值,同时转给两个人

如果按一般的逻辑去理解,账号里必须有足够的钱才能够转过去。但问题是,在它实现检查时,它的实现方法是直接算两个数的乘积。

用0去乘,结果是很明显的,就算用最大的字节去乘,乘完之后它也会变成0

所以,你可以在没有任何钱的情况下把这么多钱转给那两个人,也就是上面红色框部分,你会看到这个地方两个transfer都是这么大量的Token,美链事件就是这样,通过这种方式可以 无中生有造出大量的假币 ,然后再把假币充到OKEx里面,然后就可以进行砸盘等各种操作。

另外一个案例和transfer还蛮像的,但稍微复杂一点,两个address跟value都是数组。

它们溢出的方式一样,就是说把这些值加起来或者乘起来,然后造成的结果也是一样的,就是很大量的假币就充进你钱包地址。

到这里,我大概简单讲了讲智能合约方面的安全问题,其中一个是F3D薅羊毛的最新研究,还有一些过去我们发现的其他问题。

公链安全

今天的第二个主题,我讲一下关于Infrastructure方面的安全问题,就是所谓的公链安全。

PeckShield在以太坊公链上做了很多研究,EOS相关的也有一些

讲到公链问题其实你可以这样理解,比如说你用一个360手机卫士,可以理解为有一个客户端在手机上运行,然后还有各种服务端,你要发送各种请求,然后它会推送一些信息给你。

而在区块链里面,你可以理解为只有客户端没有服务端,至少以太坊上是这样子的,每一个节点基本上长的都是一模一样的。

所以,那时候我们开始进入区块链行业、研究主链安全时, 我们其实就是去看所有客户端的代码,看它实现的逻辑有没有什么错误

这边是一个统计,Ethereum Nodes这个网站可以统计以太坊上都运行了哪些客户端,比如说有Geth、C++和Parity,还有Python。所以, 用的比较多的是Geth和Parity ,今天的研究主要在Geth,因为它是官方的且用户量大,对Parity也有一些研究。

首先讲Geth这一块,其实谈到任何的安全问题,我们都需要先理解这样一个事情,就比如说Geth是一个盒子,我们用什么方式可以攻破它?就是所谓的 Attack Surface(攻击面) 的问题。

比如说可以通过一个 智能合约 去攻击它,那它可能就是EVM方面的问题。

还可以通过一个 RPC接口 ,它就可以类比成以前那种Web安全相关的这种问题。

还有一种,通过 协议栈 攻击,这两个其实是有点不一样的。因为区块链里面的每一个客户端之间,它们会互相去同步,或者互相分享信息,所以协议栈的问题是最底层、也比较关键的问题,一旦出问题的话,整个系统可能就不运行了。所以,接下来我主要在协议栈这一方面进行一些探讨。

这是以太坊的协议栈,大概是这样,很多部分可能你们以前没有听到,像ETH、LES和Whisper是你们比较熟知的,就是以太坊的协议。然后跟它并列的还有一些其他的,它的底层其实是包含RLPx、ÐΞVp2p的。

假设说你运行过Parity或者Geth,你要同步一个full node其,实很花时间,我那时候刚开始弄花了可能有小一个月,就看你的带宽怎么样了;还有就是硬盘,我发现机械式硬盘基本没戏,一定要SSD才有可能进行同步。

与ETH并列的协议LES,它是 一个比较轻的协议 ,你在同步时,你不需要将所有的信息都同步,你可能只会同步一些metadata。

所以, 在运行Geth时,你可以去指定运行LES mode这种模式

接下来,详细介绍一下我们之前发现的关于LES的安全问题。

简单的说,就是一个 越界读 的问题,问题出在上面这一行代码,就在query.Skip这里。

我们可以自己去写一个类似于Geth的客户端,我只要知道你Geth的IP就ok。比如说有一个矿池,矿池总要有一个节点去同步到链上,我一旦知道这个IP是什么,我就可以伪造这个东西,然后让你崩溃。

那么,如何让它崩溃的?我 把Skip值设成-1 (在协议栈上你可以自由设置),-1+1就是0,就等于说我可以尝试让你去分配一个长度为0的数组,然后我又可以去读这个数组的Skip值为-1的位置,那一定不再是你的位置了,它已经超过了你可以控制的内存范围,所以它就必然会崩溃。

接下来,演示一下这个 EPoD Demo ,问题出现在1810版本之前,也包括1810这个版本。

在拍摄视频时,我用的是 官网上面的1810版本 ,对比过MD5,它是没有经过任何修改的;还需要处于 离线环境 ,避免遭受外界攻击,保证所受攻击都来自本机;运行Geth的 LES mode

然后监听从本机发出来的30303端口,在运行攻击代码后, EXP后面的地址(即本机地址)是127.0.0.1,端口是30303,此时的Geth差不多就已经崩了。

index out of range ,崩的理由就是这样,一个越界读。它在处理某一个这种LESMessages的时候,造成了一个越界读。TCpdump就是我攻击的钱包,我们把这个漏洞叫EPoD,我只要知道你的IP,发一个包,Geth就会崩溃,大概就是这样。

还有一些攻击,我应该会在9月份举办的ISC上讲到。

比如说你新成立一个X交易所,然后有一个成立很久的Y交易所,你觉得它的交易量很大,想让它变小,你就可以去攻击Y交易所。

一旦你知道了Y交易所的IP以及它同步的node,就可以把信息扩散出去,就会忙死一片了。

像刚刚讲的矿池, 矿池最基本的一个事情就是算力,每个矿池之间都在竞争算力,那我一旦可以让某些矿池瘫痪,这个矿池后面的算力也就没了 ,这也是非常严重的。

但是通常我知道,矿池在使用Geth的同时,也会使用Parity,两个客户端会实时进行同步。一旦我们发现Geth和Parity同时存在问题的时候,就十分有趣了。

还有就是所谓的Boot Node,这个玩过的人可能会知道,一开始同步的时候你需要知道从哪边开始同步,从哪边开始就是所谓的Boot Node。

所以, 当你瘫痪掉以太坊所有的Boot Node时,新的Geth就没有办法去同步 ,因为它根本没有办法启动。

一旦找到这种涉及公链安全而且又是协议栈的问题,就可能会遭受这些攻击的影响。

所以, 如果Geth低于1810版本就赶紧升级吧

면책 조항: 이 기사의 저작권은 원저자에게 있으며 MyToken을 대표하지 않습니다.(www.mytokencap.com)의견 및 입장 콘텐츠에 대한 질문이 있는 경우 저희에게 연락하십시오