當前位置:
首頁 > 最新 > EOS節點遠程代碼執行漏洞—EOS智能合約WASM函數表數組越界

EOS節點遠程代碼執行漏洞—EOS智能合約WASM函數表數組越界

漏洞報告者

Yuki Chen of Qihoo 360 Vulcan Team

Zhiniang Peng of Qihoo 360 Core Security

漏洞描述

我們發現了EOS區塊鏈系統在解析智能合約WASM文件時的一個越界寫緩衝區溢出漏洞,並驗證了該漏洞的完整攻擊鏈。

使用該漏洞,攻擊者可以上傳惡意的智能合約至節點伺服器,在節點伺服器解析惡意合約後,攻擊者就能夠在節點伺服器上執行任意代碼並完全控制伺服器。

在控制節點伺服器後,攻擊者可以將惡意合約打包進新的區塊,進而攻擊和控制其他新的節點,最終攻擊和控制整個EOS網路。

漏洞報告時間線

2018-5-11 發現EOS越界寫緩衝區溢出漏洞

2018-5-28 測試開發了完整攻破EOS超級節點的漏洞驗證程序

2018-5-28 將漏洞細節報告給廠商

2018-5-29 廠商在Github託管代碼庫中修復漏洞,並關閉問題跟蹤項

2018-5-29 提醒廠商漏洞未完全修復

一些在Telegram上與Daniel Larimer的溝通細節:

我們嘗試和Daniel溝通並報告漏洞,Daniel回應我們在沒有修復漏洞情況下不會發布新版EOS,同時請求我們在有人公開測試漏洞前,先將漏洞報告提交給他。

Daniel給了我們一個官方的郵件地址,讓我們以郵件形式提交漏洞報告。

最後Daniel承諾在EOS的漏洞修復後,將給予我們公開致謝。

漏洞細節

這是一個緩衝區溢出越界寫漏洞

漏洞存在於在 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() table.initial);

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

table[offset + i] = segment.data[i];

}

}

這裡的table是一個std :: vector包含在函數表中的名稱,在將元素存儲到table中時,|offset| 欄位沒有被正確檢查。注意在設置該值之前是有一個assert 斷言的,它會檢查偏移量,但不幸的是assert 僅適用於Debug版本,不適用於發布版本。

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

|module->table.initial| 這個代碼片段讀取的值是根據函數表聲明,在WASM文件中的讀取的,該欄位的有效值為0?1024。

|offset| 欄位的值是根據數據段從WASM文件中讀取的,它是一個帶符號的32位值。

所以通過這個漏洞,我們可以在table向量之後的內存,越界寫入一定範圍的內容。

重現漏洞過程

1.編譯最新的EOS代碼release版本

./eosio-build.sh

2.啟動EOS節點Start EOS node, 完成如下所有必要的配置

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

3.設置一個漏洞合約

我們提供了一個會造成程序崩潰的WASM漏洞驗證文件(POC)

在這個PoC中, 我們簡單的設置了 |offset| 欄位引用 0xfffffff地址,所以會觸發越界寫造成程序崩潰

開始測試 PoC:

cd poc

cleos set contract eosio ../poc -p eosio

順利的話我們會看到 nodeos 進程出現 segment fault錯誤

崩潰信息:

(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 : 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超級節點解析惡意合約觸發漏洞後,攻擊者將可以完全控制這個節點。

攻擊者可以竊取超級節點的私鑰或控制新區塊的內容,更重要的是攻擊者可以將惡意合約打包成一個新塊並發布進行攻擊,最終整個網路中的所有節點都將受到攻擊並被控制。

我們完成了概念性的漏洞驗證程序,並在基於64位Ubuntu系統的nodeos上進行了測試。這個漏洞的攻擊過程是這樣的:

1.攻擊者將惡意合約上傳到nodeos伺服器。

2.伺服器nodeos進程解析引發漏洞的惡意合約。

3.使用越界寫入的原生代碼,我們可以覆蓋WASM模塊實例的WASM內存緩衝區,在惡意WASM代碼的幫助下,最終可以在nodeos進程中實現了任意內存讀/寫操作,並繞過了64位操作系統上的DEP / ASLR等常見的攻擊緩解技術。

4.漏洞利用一旦成功,會啟動一個反向shell連接攻擊者。

可以參考我們提供的視頻,了解這個概念性的漏洞利用過程,稍後我們可能會提供完整的漏洞利用鏈。

(請移步觀看http://v.youku.com/v_show/id_XMzYzMTg1NjYwMA==.html)

漏洞修復

Bytemaster在EOS的Github託管項目中,為我們報告的漏洞建立了3498編號的issue跟進修復問題。

修復的相關代碼

但是根據此次漏洞發現者Yuki所提交的評論,這個漏洞並沒有完全被修復,在32位進程的處理過程中仍然存在問題。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

2018年第一季度的DDoS攻擊概況
necp_client_action系統調用中的堆溢出漏洞分析

TAG:嘶吼RoarTalk |