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節點遠程執行代碼漏洞,目前問題尚未完全解決


分享到:


相關文章: