首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

对于以太坊客户端缺陷的探讨

各位读者好,我们又见面了!本文的宗旨在于,从技术的角度讨论最近有消息指出的以太坊生态缺陷。通过推测、验证与模拟攻击,和各位读者一起,共同增强安全意识。文中说法如有不当之处,还请谅解。

00

引言

数字账户的安全保护,是每个区块链参与者都会关心的问题。作为除比特币以外最大的区块链生态系统,以太坊平台的安全性也在运行中不断受到考验。

最近,有消息指出一种黑客可能采用的,针对以太坊平台的盗币手法[1]。我们了解到,黑客的可能攻击手法如下:

全球扫描 8545 端口(HTTPJSON RPC API)、8546 端口(WebSocketJSON RPC API)等开放的以太坊节点,发送 eth_getBlockByNumber、eth_accounts、eth_getBalance 遍历区块高度、钱包地址及余额

不断重复调用 eth_sendTransaction 尝试将余额转账到攻击者的钱包

当正好碰上节点用户对自己的钱包执行 unlockAccount 时,在 duration 期间内无需再次输入密码为交易签名,此时攻击者的eth_sendTransaction 调用将被正确执行,余额就进入攻击者的钱包里了

根据这些特点,我们对于最核心的部分进行了模拟。即没有“全球扫描8545、8546等端口”,而是定向攻击自己的某个服务器节点,模拟最核心的、在扫描到匹配IP地址后的操作。为了行文的方便,我们将被攻击的节点称为服务器,将实施攻击的节点称为攻击者

警告:请勿在没有其他安全防护的情况下,对公网以太坊节点做下文所述的模拟!!!

01

攻击过程的模拟

1.1配置服务器节点

将服务器的8545端口打开,并对服务器节点的Geth做一定的配置。即开启远程RPC,且接受任意地址的连接、启用eth、personal、web3库。

当然,直接在启动Geth服务时增加以下启动参数:

--rpc --rpcaddr "0.0.0.0"--rpcport 8545 --rpccorsdomain "*" --rpcapi"db,eth,personal,net,web3"

也能够达到同样效果。

1.2配置攻击者

在Node环境中导入Web3库,依次输入命令。

调用函数,确认攻击者已与服务器的Geth节点连接:

1.3操作攻击者

调用web3.eth.accounts,查看服务器存储了哪些以太坊地址的KeyFile。

遍历每个地址下的以太币余额。

可以看到,第一个账户下的以太币余额不为,共有4.999622个以太币。则尝试构造交易,将该地址下的以太币转账至攻击者提供的地址。

由于此时sender代表的账户还没有解锁,所以交易无法被签名,自然发送失败。

但攻击者会在接下来的一段时间里,尝试不断重复发送该交易。

1.4服务器恰好解锁账户

某一时刻,服务器上账户的主人在转账、签名等的需求下,解锁账户,并设置20秒的授权时间。在这段时间里,可以向Geth提交需要该账户签名的交易,而不需要再次输入密码授权。

1.5攻击者继续发送交易

由于不断地尝试,在这20秒的时间里,攻击者成功发送了交易。

此时服务器的Geth将出现交易已提交的提示,但服务器再做其他的补救措施为时已晚,因为攻击者往往会设置较高的矿工费,以便交易被尽快确认。

在接下来的第9571个块,该交易被打包。从提交交易到一个确认,前后不到一分钟时间。

20秒后,如果攻击者继续尝试提交其他交易,将被拒绝;因为授权时间已过。

1.6攻击结果

攻击结束,分别查看两个地址的余额。

攻击者的地址余额从变为4.9ether,而服务器的地址余额从4.999622 ether变为0.099244ether。

可见,服务器地址的4.9个以太币已被转账到攻击者的地址下。

在实际操作中,攻击者也可以构造其他的智能合约交易。例如将服务器地址的ERC20Token转走,等等。

02

实现如此大规模攻击的可能性

成功模拟攻击,在震惊之余,我们不禁思考,这一缺陷真的能够被黑客大规模利用吗?

2.1疑问一:黑客的扫描成本

2.1.1检测全网IP的8545端口是否开启的成本

目前世界范围内广泛使用的IPV4地址理论上共有约42亿个[2],假设1秒钟检测10个IP地址是否开启了8545端口,也需要4.2亿秒、约合13年才能完成整个扫描。即便考虑到实际上被使用的IP地址只有约36亿个,扫描全网这种操作,从直觉来看似乎也是成本过高而不能实现的。

但实际上,在目前的技术水平下,扫描全网的IP远没有想象中那么困难。2015年的一篇论文《Who Is Scanning the Internet?》中已经提到,通过一些特殊的策略,对全网的IP做一次快照只需要最短44分钟[3]。

为了进行一定程度上的亲自验证,我们使用论文中提到的ZMAP工具,在1M带宽下,随机地对互联网上一定数量的IP地址做扫描,查看它们是否开启了8545端口,得到以下数据:

可见,利用ZMAP工具,确实能够在较短时间内完成对IP地址的扫描。黑客有可能在较短时间内筛选出开放了8545端口的IP,大幅减少下一步待检测的IP地址数量。

2.1.2尝试在8545端口连接以太坊节点的成本

为了从统计的角度计算出黑客遍历连接以太坊节点所需的时间成本,我们编写了最为粗糙简略的脚本,对2.1.1中得到的、开启了8545端口的IP地址做连接测试,Python脚本如下:

需要注意的是,我们得到的这些IP中,很可能没有任何一个IP是正在运行以太坊节点的。但是,一旦某一个IP运行ETH节点、且允许任意IP连接,那么第18行中w3.isConnected()将返回True,使得我们记录这个IP地址。

为了在扫描中再次验证脚本的有效性,我们在得到的IP中手动加入了,我们自己运行的、故意开放了连接权限的以太坊节点IP地址,以验证脚本是否能正常检测。

结果表明,脚本工作正常。

对于其他的IP地址,运行得到的数据如下:

可见,由于不同IP地址的响应速度不同,花费时间与测试IP数量之间并不呈完全的线性关系。但我们仍然可以做最乐观的估计(对于受害者来说算是最悲观的估计),认为单一进程每分钟能够测试10个IP地址。这一速度并不算快,因为网络总是动态的,6秒/地址的测试时间成本将严重拖累黑客攻击成功的可能。

所以,从这个角度来看,黑客的攻击成本过高,我们不禁怀疑这种攻击的有效性。

2.1.3如果对以上过程做优化呢

经过一段时间的讨论,我们认为,也不能排除黑客采用其他手段来优化整个测试过程的可能。

例如,黑客有可能自己运行一个允许最大连接数较大的以太坊客户端,这样,他将获得与他连接的所有节点的IP地址与NodeID。这样做的好处在于,得到的这些IP地址所运行的节点在当前时间是活跃的,而且节点具有公网IP的可能性也较大,此时黑客可以对这些地址做下记录,以便以后进一步缩小检测范围。

并且,黑客也很有可能不是总对全网进行扫描,而是对某些他整理出的IP地址做有针对性的检测与攻击,这就增大了攻击成功的可能性。

除此之外,黑客还可以直接利用现成的结果,例如对EtherNodes网站整理的最近在线节点进行检测,这也会进一步缩小扫描的范围。

2.2疑问二:以太坊节点允许来自任意地址RPC连接的可能性

默认状态下,以太坊节点的RPC通信只允许来自本地(localhost)的连接。如果需要远程RPC,需要用户先手动关闭当前的RPC,再手动开启新的远程RPC。并且,也不是开启了远程RPC就会遭到攻击,而是需要同时将rpccorsdomain的参数设置为星号,即允许任意地址的连接。

对于普通用户来说,这是一种几乎永远不会进行的操作,而且普通用户往往很少使用全节点钱包,也没有机会涉及到这项操作。

对于相关的企业(交易所、服务提供商等)来说,存在开启远程RPC功能的需求。但是,由于rpccorsdomain这项设置的存在,技术人员能够指定允许访问的IP地址。当黑客的连接不在白名单中时,无法连接,更无法实施攻击。此外,从安全的角度出发,企业的技术人员也不一定会直接使用以太坊节点提供的RPC工具做远程控制,而是采用其他途径。这就使得黑客的攻击手段无处实施。

所以,最有可能受到攻击的对象很可能是:①使用全节点钱包、但不熟悉技术的普通用户,失误之下在启动参数里开启了允许任意连接的RPC;②企业,技术人员因失误而开启不安全的RPC;③矿工,为连接方便,开启了允许任意连接的RPC。

从这个角度来看,此缺陷能够威胁到的用户范围,并不是很大。

2.3疑问三:已经暴露在危险中的节点有多少

根据我们在EtherNodes上获取的数据[4],截至3月24日点23分,全网共有以太坊主网节点16900个。

于是我们获取了EtherNodes上最近活跃的100个IP地址,对他们进行Web3的8545端口连接测试。

与之前一样,分别在第1与第5的位置增加了我们自己运行的开放连接的节点,以确认脚本能够正常工作。最终的结果如下:

将结果汇总成表:

可估算认为全网有约3%的以太坊节点在8545端口允许来自任意IP的连接,即在16900个公网节点中,约有507个节点暴露在被直接连接的风险中(由于样本数量较少,暂不能保证这一百分比的准确性,仅供参考)。

对于得到的三个IP地址,我们逐一进行观察。

查看发现,第一个节点开启了eth、net、personal、db的API,没有开启admin。

该节点的最新块高度是1986252,并没有与主网同步。在该区块高度下查看节点地址的以太币余额,结果如下:

但是,当我们在EtherScan上[5]查看前两个地址时,却发现这两个地址既没有余额,也没有任何交易记录。是一个比较奇怪的现象。

我们猜测,是有人使用与以太坊主网相同的genesis.json文件,从头开始自己挖矿。当他挖到某一区块高度时,停止挖矿。随后,他令Geth与其他主网的节点连接,并且不允许同步,这样就能够保持自己的数据不变。所以,我们看到的余额,实际上是某种意义上、私链的余额。当然了,这仅仅是我们的一种猜测,希望得到更多的解答。

另外2个节点,也没有与主网同步,区块高度分别停留在60980与31154。换句话说,虽然我们扫描到了3个暴露在危险中的节点,但这3个节点都是没有攻击价值的。

2.4小结

整理以上三个疑问与测试的结果,我们做出以下小结。

在一些网站中,已经实时统计了(几乎)所有公网以太坊节点的IP地址。黑客可以直接利用这些数据。

按照2.1.2节中,我们得出的6秒/地址的Web3连接测试时间,黑客只需要花费不到29小时就能用单一进程扫描完毕我们在2.3节中看到的1万6千多个IP。辅以并发等手段,黑客将有可能在相当短的时间内获得所有开启了允许任意连接的以太坊节点IP。

随后,黑客可以继续筛选出这些地址中已与主网同步的节点,并在此后有针对性地攻击这些真正有价值的目标。尽管这些目标的数量可能是极其稀少的,但是也足够吸引一些黑客进行攻击。

但要注意的是,正如我们在2.2节中所讨论的,只要稍加注意、不要手动开启允许来自任意地址的连接,就能够避免这种黑客攻击。

03

防范措施

结合前面的讨论,我们为各位读者整理出运行以太坊节点时针对此次攻击常见的防范措施如下:

启动节点时,一般不要开启远程RPC。如果一定要开启,请在rpcport参数中将不常用的端口设为RPC端口。同时,若无特殊需要,应在rpccorsdomain参数中指定允许远程连接的IP,不要因为省事而将参数设置为"*"。

若一定需要允许来自任意IP的远程RPC访问,则不要在rpcapi参数中加入"admin, personal"。或者不要将KeyFile文件存储在节点上。

避免将大额资金地址对应的KeyFile存放在联网的节点上。应当将大额资金存放在普通的离线钱包(方便使用)或完全的冷钱包(更加安全)中。

注:这里“普通的离线钱包”是指把imToken或Electrum等软件作为客户端、利用二维码做离线签名的钱包。而“完全的冷钱包”则是指通过专业的软件或抛硬币的方式生成足够安全的私钥,并且在物理断网的电脑上导出钱包地址,将该地址作为很长一段时间内只进不出的存储地址。关于imToken离线钱包的使用,可以参考我们之前的文章《imToken冷钱包指南》。

04

结语

本次探讨的黑客攻击行为,并没有我们想象中那么严重。

好比某天你在回家取东西时没有关门,小偷在屋门打开的这段时间里,从你的家中盗窃财物。一定要明确的是,在这个过程中,小偷(黑客)既没有偷走你的家门钥匙(Keyfile和Password),更没能偷走你的房产证(Private Key)。而且,小偷能进入你家的前提是,你必须先告诉安保人员(设置RPC参数),允许任意一个人进入你家楼下的单元门(允许来自任意IP的RPC连接)。当你把屋门关闭后(lockAccount),由于小偷没有家门钥匙(Keyfile和Password),更没有房产证(Private Key),所以他也无法继续从你家里偷东西(操作你的ETH账户)。

可见,整个攻击过程想要成功实施的可能性,还是比较小的。而且根据我们在2.2、2.3节中的讨论,真正暴露在这种危险下的节点,很可能相当稀少。相信在最近的消息之后,原本暴露在风险中的节点也已经及时调整了安全策略。

不过,这次的事件也为我们提了醒,一定要了解分布式系统/Blockchain 安全性等基础知识/基本问题,随时注意自己的区块链资产安全!

参考资料:

[1]慢雾区《以太坊生态缺陷导致的一起亿级代币盗窃大案》http://url.cn/5rkbgtf

[3] Roman Trapickin《Who Is Scanning the Internet?》

[4] EtherNodes https://www.ethernodes.org/network/1

[5] EtherScan https://etherscan.io/

感谢你阅读到最后,如果你看罢文章、产生自己的想法,欢迎在评论区留言、拍砖。

下期预告:我们强烈建议各位读者将以太坊客户端升级至1.8.1及以上版本,以避免"Eclipse Attack(日蚀攻击)"。简单来说,就是避免您的节点被两个其他恶意节点包围,而获得错误的以太坊网络信息。下一期我们将为读者送上,关于这种攻击的探讨。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180325G104O400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券