*本文原创作者: kmsrussian,本文属于FreeBuf原创奖励计划,未经许可禁止转载
一、前言——NEO RPC漏洞之争
12月1日下午16:34日,腾讯湛卢实验室宣布发现NEO的RPC漏洞。 官微发文如下。
北约官方微博在4小时后迅速回应腾讯,回答如下。
谁错了? 奥斯链RPC模块的安全状况如何?
二. RPC和RPC漏洞介绍
首先介绍一下RPC。 远程过程调用(Remote Procedure Call )是计算机通信协议。 使用该协议,在一台计算机上运行的程序可以调用另一台计算机的子程序。 程序员不需要对这种交互进行编程。 如果相关软件采用面向对象的编程,则远程过程调用也称为远程调用或远程方法调用。
一些旧的Microsoft RPC漏洞由于畸形的RPC请求,导致C/C字符串复制连接等问题,内存被覆盖,导致安全漏洞。 因为漏洞的表现方法与编程语言密切相关。 微软的许多问题组件基本都是用C/C语言开发的,因此存在内存覆盖的安全问题。 而且,随着SDL的普及,很难再现当时MS08-067那样的“盛况”。
2.1用于奥斯链和令牌的编程语言多种多样
在区块链上,由于令牌和公共链的开发语言多样,比特币、EOS、XRP、XLM、DASH、XMR等主要客户端使用C/C进行开发,实现了以太网eum、bytom等许多杂志构建了基于分片、并行、分布式区块链网络的公共链,从一开始就选择了函数式编程语言。 Rchain用Scala语言开发,而Aeternity用Erlang语言开发。 使用以函数式语言开发的公共链来消除逻辑系统中的漏洞,从而消除了在语言级别上流程式语言中存在的一些安全隐患。
2.2同一公共链中存在不同语言的客户端实现
一个公锁有各种语言实现的不同版本。 比特币网络的主要客户端是使用C/C (如satoshi客户端)开发的,但也有对开发人员友好的客户端。 例如用javascript语言开发的bcoin,用go语言开发的btcd。 在以太网中,主流以太网客户端Geth用Go语言实现,约占所有节点的80%。 基于Rust语言实现的Parity-ethereum占所有节点的20%,其余CPP-ethereum、Python-ethereum、Java-ethereum一般只有研究价值,即使存在漏洞也实际上此次腾讯被认为“有问题”的Neo主流客户端是. Net的实现,一般在windows系统上运行。
以上几点加大了区块链中RPC脆弱性表现方式的差异。
三.区块链上的RPC和鸡肋区块链RPC漏洞
首先,介绍区块链中RPC接口使用的流程和场景。 以比特币为例,交易所如何判断用户比特币确实充值成功? 在内部网中与网段进行环境隔离,并使用docker部署相应的全节点客户端。 例如,比特币可以部署bcoin的全节点客户端。 然后,设置RPC接口调用权限。 一般来说,公共链使用username和password来验证调用方是否具有调用RPC接口的权限。 此时,程序认证成功后,通过调用bcoin客户端提供的rpc api接口Getblock by height,轮询用户对新块是否有充值的交易,等待对应的确认数后
在这个RPC调用过程中重要的是认证,只有认证成功后才有权调用对应的RPC接口。 常用公钥向用户提供CLI工具,以配置RPC是否开放以及开放后的认证方式。 默认RPC接口在本地调用时不需要认证。 调用远程IP时,即使相应的RPC接口存在漏洞,攻击者也无法触发RPC漏洞,因为认证不通过,或者该RPC接口没有配置任何开放。
在BTC/DASH/XMR等Coin中通常存在两个模块: RPC模块和P2P模块。 由于公共链需要执行合同,而且通常具有完整的图灵,因此与Coin相比,公共链有更多的两个模块、虚拟机和编译器。 存在于Coin和公共链中的RPC漏洞非常棘手。 这是因为RPC需要经过认证后才能调用,在实际环境中很难影响安全性。
介绍区块链中曾经或“0day”的RPC的脆弱性
3.1基于RPC认证设计的安全漏洞
目前,这种脆弱性危害最大,但几乎没有。 还没有出现路由器后门万能密码这样的漏洞。 当前存在一个漏洞,只能在初始版本的bitcoind and Bitcoin-Qt中猜测密码。 CVE-2013-4165 (请注意,此漏洞仅影响这两个版本的比特币实现,而不影响go版本的btcd和javascript版本的bcoin。
bitcoind 0.8.1的bitcoinrpc.cpp中的HTTPAuthorized函数在检测到密码的第一个非法字节时提供有关认证失败的信息,使远程攻击者更容易推测爆破攻击并确定密码。
3.2在开机自检期间触发特定语言版本的公共链的RPC漏洞
的代表性表现是cppethereum的CVE-2017-12119。 如上所述,cppethereum是以太坊的研究
性版本,实际中几无影响,并且rpc类漏洞,攻击者必须鉴权后才能调用,更加大大削弱了该漏洞的实际影响。该漏洞由思科的talos团队上报发现。https://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0471
在调用cppethereum的rpc接口的时候,攻击者可以Post传递一个畸形类型的参数,使得类型检查不通过,可以直接导致cpp ethereum崩溃。
注意此类漏洞完全不影响以太坊主流客户端geth和Parity-ethereum。
3.3 RPC设计引发的逻辑类盗币漏洞
目前来看以太坊和EOS都有类似问题。以以太坊举例。
以太坊对于账户的RPC调用支持unlockaccount api。
可以看到,需要提供地址,密码和解锁时间。问题就出在解锁时间上面,一旦解锁,该钱包若还暴露在公网上,在duration期间的钱包,任何人在duration这段期间都有权限将钱包中的eth转走。
整个攻击流程如下:攻击者预先扫描 8545 端口(HTTP JSON RPC API)、8546 端口(WebSocket JSON RPC API)等开放的以太坊节点,遍历区块高度、钱包地址及余额,一旦有余额的地址处于unlock duration,重复调用 eth_sendTransaction 将余额转空。
3.4配置安全引发的问题
前面已经说过RPC调用是要鉴权的。如比特币的bcoin客户端,要远程调用rpc接口必须提供用户名和密码。很多公链,如bytom,默认配置文件即是127.0.0.1,也即本地发起的rpc调用是不需要认证的,通过远程IP发起的rpc调用必须提供用户名和密码,否则无法进行rpc调用。但是如果用户错误配置rpc,如弱密码或者取消鉴权此时就会带来安全隐患。
3.5接口实现逻辑不严谨引发的漏洞
这里我们以Go语言实现的bytom举例,其他公链若有类似逻辑请自行查证。
一般来说公链中都会支持钱包配置文件的备份和恢复,备份一般不会产生问题,但是此时的恢复,恢复本质上是接收外界的post参数,然后公链的进程要往所在的操作系统或者docker中的系统写入一个文件,如果在post传递参数上传递的是跨目录覆盖掉系统关键文件的参数,结果如何呢?Bytom的早期的版本就存在这样的一个漏洞,调用restore-wallet,传递畸形的post参数,在恢复钱包文件的时候可以引发系统关键文件被覆盖,造成远程代码执行。但是注意,攻击者想利用该漏洞也得通过RPC的鉴权,才有权限调用该接口。
修复起来就相对简单。敏感性接口,逻辑实现上一定要禁止跨目录的操作。
四、总结
RPC模块作为支付类币种和公链都共有的模块,会存在一些安全问题。但是由于RPC调用需要鉴权,使得RPC模块即使存在漏洞,也是较难触发利用的。此次的neo的rpc接口安全问题,影响相对有限,北京链安在此也提醒相关用户,注意RPC的安全配置,避免产生RPC配置漏洞。
*本文原创作者:kmsrussian,本文属于FreeBuf原创奖励计划,未经许可禁止转载