360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

奇虎360漏洞团队Yuki Chen和奇虎360核心安全团队Zhiniang Peng发现EOS节点在远程执行代码时存在漏洞,他们在360官方博客上发布了这一问题,以下为博客编译内容:

漏洞描述

在解析WASM文件时,我们发现、并成功利用了EOS缓冲区越界写入漏洞。

通过这个漏洞,攻击者可以把一个恶意智能合约上传到节点服务器,之后节点服务器就会解析这个恶意合约,然后恶意合约就会在服务器上被执行,之后控制该节点服务器。

在控制了节点服务器之后,攻击者可以将恶意合约打包到新的区块中,继而进一步控制EOS网络内的所有节点。

漏洞报告时间表

2018-5-11 发现EOS越界写入漏洞

2018-5-28 EOS超级节点完全利用演示完成

2018-5-28 漏洞详细信息报告给供应商

2018-5-29 供应商修复了GitHub上的漏洞,并解决了问题

2018-5-29 注意到供应商修复尚未完成

下面是一些和Daniel Larimer在Telegram上的聊天截图:

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

我们尝试将漏洞报告告诉他。

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

他表示,他们不会在没有修复漏洞的情况下发布EOS,并且要求我们私下发送报告,因为有些人正在使用公共测试网。

Daniel Larimer提供了他的电子邮件,我们将漏洞报告发送给了他。

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

EOS修复了这个漏洞,Daniel Larimer将会给予确认。

技术细节漏洞

这是一个缓冲区越界写入漏洞。在“ libraries/chain/webassembly/binaryen.cpp(代码第78行),Function binaryen_runtime::instantiate_module:”

for (auto& segment : module->table.segments) {

Address offset = ConstantExpressionRunner(globals).visit(segment.offset).value.geti32();

assert(offset + segment.data.size() <= module->table.initial);

for (size_t i = 0; i != segment.data.size(); ++i) {

table[offset + i] = segment.data[i]; <= OOB write here !

}

}

这里的表示一个std::矢量包含了功能表的“Names”。当存储元素导入到表内,|offset|函数域将无法正确实施检查工作。请注意,在设置该值之前,有一个asset函数,它会检查|offset|函数,但不幸的是,assert函数只适用于Debug版本,而不适用于正式的发布版。

table.resize(module->table.initial);

|offset|函数域还会从WASM文件被读取,在数据部分,它是一个符号型32位值。

所以基本上,利用这个漏洞,我们可以在表矢量的内存之后写入相当广泛的range。

如何重现该漏洞

1、构建最新EOS代码发布版本

./eosio-build.sh

2、启动EOS节点,按照下面链接里的描述,完成所有必要的设置

https://github.com/EOSIO/eos/wiki/Tutorial-Getting-Started-With-Contracts

3、设置一个“脆弱”的节点

我们提供了一个WASM概念证明来证明这个漏洞。

在我们的概念证明中,我们只需设置|offset|函数域为0xffffffff,这样在越界写入发生时,就会立刻崩溃。

测试概念证明:

cd poc

cleos set contract eosio ../poc -p eosio

如果一切都就绪,你会看到nodeos进程发生段错误。

崩溃信息:

(gdb) c

Continuing.

Program received signal SIGSEGV, Segmentation fault.

0x0000000000a32f7c in eosio::chain::webassembly::binaryen::binaryen_runtime::instantiate_module(char const*, unsigned long, std::vector >) ()

(gdb) x/i $pc

=> 0xa32f7c <_zn5eosio5chain11webassembly8binaryen16binaryen_runtime18instantiate_moduleepkcmst6vectorihsaihee>: mov %rcx,(%rdx,%rax,1)

(gdb) p $rdx

$1 = 59699184

(gdb) p $rax

$2 = 34359738360

Here |rdx| points to the start of the |table| vector,

And |rax| is 0x7FFFFFFF8, which holds the value of |offset| * 8.

利用此漏洞实现远程代码执行

攻击者可以利用此漏洞在nodeos进程中实现远程代码执行,方法是将恶意合约上传到节点,并让节点解析恶意合约。在实际攻击中,攻击者可能会向EOS主网发布恶意合约。

EOS超级节点会首先解析恶意合约,然后触发漏洞,之后攻击者回控制解析了恶意合约的EOS超级节点。

接下来,攻击者可以窃取超级节点的私钥,或是控制新区块的内容。更重要的是,攻击者可以将恶意合约打包成一个新区块并发布。这样做的结果,就是让这个网络中的所有完整节点都被攻击者控制。

我们完成了概念验证漏洞测试,并且在64位的Ubunt操作系统的nodeos进程中进行了测试,这个漏洞是这样工作的:

攻击者将恶意合约上传到nodeos服务器上;

服务器nodeos进程被解析能够触发漏洞的恶意合约;

在越界写入漏洞下,我们可以重写WASM模块实例的WASM内存缓冲区。此外,在恶意WASM代码的帮助下,我们最终在nodeos进程中实现了内容内存读/写操作,并且绕过了64位操作系统上的DEP / ASLR等常见的防恶意攻击技术;

一旦成功利用该漏洞,就会启动一个反向shell程序,并连接回攻击者;

您可以参阅我们提供的视频,以了解该漏洞的具体情况,稍后我们还会提供完整的漏洞利用链。

漏洞修复

BM在EOS的GitHub第3498个开放问题上披露了正在处理我们报告的漏洞问题:

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

修复的相关代码

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决

但是,正如Yuki对所提交修复内容做出的评论,在处理32位进程的时候仍然存在问题,因此问题还没有被得到完美解决。

360发现EOS节点远程执行代码漏洞,目前问题尚未完全解决


分享到:


相關文章: