林曄篁 , 劉蕾蕾 , 杜偉 , 彭緯偉 , 金先濤, 胡璇
(1.中國南方電網(wǎng)調(diào)峰調(diào)頻發(fā)電有限公司檢修試驗(yàn)分公司, 廣東 廣州 510610;2.中國南方電網(wǎng)調(diào)峰調(diào)頻發(fā)電公司, 廣東 廣州 510635 3.工業(yè)和信息化部電子第五研究所, 廣東 廣州 510610)
自2010 年以來, ICS 安全問題頻頻出現(xiàn), 對工控系統(tǒng)造成了極其嚴(yán)重的影響,其攻擊普遍借助偽造通信手段為出發(fā)點(diǎn),例如: 震網(wǎng)病毒[2]通過偽造簽名并突破工業(yè)局域網(wǎng)的限制, 通過更改變頻器參數(shù)使得離心機(jī)無法正常工作; Duqu 病毒[3]借助通信機(jī)制傳播惡意代碼, 并控制其大面積隱蔽感染其他計算機(jī); Havex 病毒[4]利用OPC DA 協(xié)議來收集網(wǎng)絡(luò)和聯(lián)網(wǎng)設(shè)備的信息并將其反饋到C&C 服務(wù)器的手段, 通過植入木馬等方式感染監(jiān)測控制和數(shù)據(jù)采集 (SCADA: Supervisory Control and Data Acquisition) 系統(tǒng)及使用的工業(yè)控制軟件等。
在備受矚目的Stuxnet 病毒爆發(fā)前, 有關(guān)ICS安全的大多數(shù)研究工作主要集中在人機(jī)界面(HMI) 和其他SCADA 軟件上, 而對這些嵌入式系統(tǒng)方面所做的分析相對較少。 盡管有許多成熟的工具和技術(shù)可用于分析商用個人計算機(jī)(PC) 上的軟件, 但我們對嵌入式設(shè)備中的漏洞只有一個較淺的了解, 并且很少有用于分析它們的工具。 最近在嵌入式設(shè)備上進(jìn)行的許多安全工作已經(jīng)發(fā)現(xiàn)了嚴(yán)重的安全漏洞, 例如: 從固件映像中提取的硬編碼密碼, 未經(jīng)身份驗(yàn)證的固件上載, 啟用了多個未經(jīng)身份驗(yàn)證的接口和弱密碼散列。 我們相信, 這些發(fā)現(xiàn)將在更多的設(shè)備上得到重復(fù), 并且未來的安全研究將在深入研究固件和硬件上實(shí)現(xiàn)。
固件逆向工程理論按其工作流程可以分為代碼提取、 指令歸一化、 代碼還原、 逆向分析和驗(yàn)證測試等5 個部分。 在本文中, 我們描述了工控設(shè)備固件提取的特點(diǎn), 分析了固件提取的重難點(diǎn),最后對工程上的工控設(shè)備固件提取方法進(jìn)行了歸納。
固件逆向工程是以固件程序或其他具有固件程序結(jié)構(gòu)特征的二進(jìn)制程序?yàn)檠芯繉ο蟮亩M(jìn)制逆向工程, 其主要任務(wù)是獲取固件程序、 生成對應(yīng)的源代碼、 系統(tǒng)結(jié)構(gòu)和相關(guān)設(shè)計原理及算法的文檔, 是軟件逆向工程的一個重要分支。 固件逆向工程按其研究的內(nèi)容可以分為固件逆向工程理論和輔助固件逆向工程兩個部分, 如圖1 所示。
圖1 軟件逆向工程的分支
固件逆向工程理論按其工作流程可以分為代碼提取、 指令歸一化、 代碼還原、 逆向分析和驗(yàn)證測試等5 個部分。 本文主要關(guān)注代碼提取方面。
個性化心理護(hù)理在輸尿管軟鏡腎結(jié)石鈥激光碎石患者中的應(yīng)用 …………………………………………王亞紅(80)
固件逆向工程作為軟件逆向工程的一個重要分支并與其他分支相互區(qū)別, 是因?yàn)槠涮厥獾难芯繉ο蠹垂碳a與其他軟件實(shí)體相比具有不同的特點(diǎn)。 固件是指存儲于非易失存儲器(如ROM/PROM/FLASH 等, 這些存儲芯片在系統(tǒng)掉電后數(shù)據(jù)不會丟失) 中的二進(jìn)制程序。 這是根據(jù)存在形式方面的特殊性對固件進(jìn)行的傳統(tǒng)定義, 隨著超大規(guī)模集成電路的發(fā)展, 固件中的二進(jìn)制程序不僅能夠以非易失存儲器件為載體, 還能夠存儲于微控制器、 SOC 等具有非易失存儲能力的器件中。這些器件中的二進(jìn)制程序也是固件逆向工程研究的對象。 因此, 固件逆向工程研究的固件是指存儲于具有非易失存儲功能的器件中的二進(jìn)制程序,這些器件包括傳統(tǒng)的固件存儲器以及具有內(nèi)部存儲器的微控制器、 SOC/SOPC 和FPGA/CPLD 等。
固件中存儲的代碼程序是一類可以直接運(yùn)行的二進(jìn)制程序, 通常用于嵌入式系統(tǒng)。 固件代碼與通用PC 機(jī)中的可執(zhí)行代碼相比, 在設(shè)計思想、存在形式、 應(yīng)用領(lǐng)域和代碼組織等方面存在許多重要的差異, 主要表現(xiàn)為以下幾個方面。
固件程序的設(shè)計一般以結(jié)構(gòu)化設(shè)計思想為主。結(jié)構(gòu)化程序設(shè)計理論形成于20 世紀(jì)60 年代早期,并由Dijktra 最終提出[5]。 雖然面向?qū)ο蠛兔嫦蚍矫娴某绦蛟O(shè)計正逐步地取代結(jié)構(gòu)化程序設(shè)計思想并主導(dǎo)著桌面及網(wǎng)絡(luò)應(yīng)用程序的開發(fā), 但是在嵌入式系統(tǒng)領(lǐng)域, 結(jié)構(gòu)化程序設(shè)計思想依然指導(dǎo)著嵌入式程序員開發(fā)出各式各樣的固件程序, 而這些根據(jù)結(jié)構(gòu)化程序設(shè)計理念開發(fā)出來的、 存在于嵌入式系統(tǒng)中的代碼正是固件逆向工程的主要研究對象。 固件的這一特點(diǎn)決定了結(jié)構(gòu)化設(shè)計、 分析和驗(yàn)證的方法與理論是固件代碼逆向工程的重要理論工具, 同時也使得固件逆向工程的研究內(nèi)容有別于結(jié)構(gòu)化二進(jìn)制逆向工程。
固件代碼存在于嵌入式系統(tǒng)的存儲設(shè)備中,這給固件逆向工程帶來兩個方面的影響: 1) 固件代碼的獲取相對困難, 這些存儲設(shè)備大多使用了讀寫保護(hù)、 自毀和口令驗(yàn)證, 數(shù)據(jù)加密等安全機(jī)制, 這使得固件代碼的獲取變得相對困難, 需要專門的提取技術(shù)和硬件設(shè)備, 固件代碼獲取技術(shù)的研究和相關(guān)設(shè)備的開發(fā)是固件逆向工程中的一個重要組成部分; 2) 固件代碼的測試需要硬件支持, 驗(yàn)證固件逆向分析的結(jié)果必須將固件置于一個真實(shí)的硬件環(huán)境中, 與固件代碼的獲取一樣,需要專門的硬件設(shè)備, 如下載線、 編程器、 仿真器和運(yùn)行固件代碼的嵌入式系統(tǒng)。
由于嵌入式處理器千差萬別, 品種數(shù)量已經(jīng)超過1 000 多種, 體系結(jié)構(gòu)已經(jīng)超過30 多個[4],應(yīng)用更是遍及家用、 航天、 制造、 醫(yī)療和通信等諸多領(lǐng)域。 與嵌入式處理器相連的外部設(shè)備往往隨著應(yīng)用的不同而變化, 處理器內(nèi)部也難以有穩(wěn)定的硬件配置。 與通用小型計算機(jī)系統(tǒng)相比, 嵌入式處理器的外部設(shè)備更富于變化, 這種不穩(wěn)定的硬件配置為固件逆向工程帶來了以下3 個方面的困難。
a) 增加了虛擬硬件平臺和其他輔助逆向工具開發(fā)的困難
軟件逆向研究人員很難設(shè)計出一個面向所有固件的通用逆向分析工具。 虛擬硬件平臺的設(shè)計是固件代碼輔助逆向工程的一項重要研究內(nèi)容,能夠使固件程序在一個可控的虛擬環(huán)境中運(yùn)行,實(shí)時地觀測其運(yùn)行時的動態(tài)效果, 將大大地提高固件代碼逆向分析的效率。 與具有穩(wěn)定硬件配置的通用計算機(jī)不同, 嵌入式設(shè)備的硬件配置隨著應(yīng)用領(lǐng)域的變化而不斷地改變, 嵌入式系統(tǒng)這種硬件配置上的多樣化和動態(tài)性, 使得開發(fā)出一個類似于PC 虛擬軟件VMware 這樣的虛擬硬件平臺變得相對困難。
b) 加大了逆向分析工作的難度
對固件代碼的正確分析必須了解與之相關(guān)的各類硬件設(shè)備。 對一個嵌入式設(shè)備中的固件程序進(jìn)行逆向分析, 必須首先了解嵌入式設(shè)備的硬件連接、 外部設(shè)備、 處理器結(jié)構(gòu)和匯編指令集等。不同的嵌入式設(shè)備往往具有不相同的硬件連接關(guān)系、 功能各異的外部設(shè)備、 不同體系結(jié)構(gòu)的微控制器和風(fēng)格迥異的匯編指令集。 這些繁重的準(zhǔn)備工作明顯地增加了逆向分析人員的工作負(fù)擔(dān), 加大了逆向分析工作的難度。
c) 限制了某些逆向分析策略的應(yīng)用
因?yàn)閼?yīng)用領(lǐng)域廣泛的特點(diǎn)而引起的硬件配置上的多樣化和動態(tài)性同時也限制了某些逆向分析策略的應(yīng)用。 例如: 由于嵌入式系統(tǒng)硬件配置的不穩(wěn)定, 并且資源相對有限, 我們往往難以在其中嵌入一個通用動態(tài)分析軟件(類似于PC 上的Soft ICE) 來實(shí)時地觀測設(shè)備的動態(tài)運(yùn)行情況, 雖然各類仿真器、 JTAG 調(diào)試器可以完成類似的功能, 但需要硬件設(shè)備的輔助, 缺乏靈活性, 而且也只能觀測處理器和部分芯片的狀態(tài), 不能獲取整個系統(tǒng)的運(yùn)行情況; 另外, 因?yàn)槟壳吧袥]有一個通用虛擬硬件平臺來模擬固件的執(zhí)行, 所以代碼的動態(tài)分析技術(shù)難以用于固件的逆向分析[4]。
固件代碼在代碼組織方面表現(xiàn)為如下特點(diǎn)。
a) 不包含結(jié)構(gòu)信息
在馮·諾伊曼機(jī)器中, 內(nèi)存里的數(shù)據(jù)和指令均以同樣的二進(jìn)制形式存儲。 這意味著, 只有當(dāng)一個給定字節(jié)從內(nèi)存被讀出放入一個寄存器作為數(shù)據(jù)或指令使用的時候, 我們才知道它是數(shù)據(jù)還是指令。 即使是在分段的體系結(jié)構(gòu)上, 其中數(shù)據(jù)段里只有數(shù)據(jù)信息、 代碼段只有指令, 數(shù)據(jù)仍然能夠以表的形式被儲存在一個代碼段中, 指令同樣也能夠以數(shù)據(jù)的形式被儲存然后通過解釋這些指令而運(yùn)行[6]。 在結(jié)構(gòu)化二進(jìn)制程序中, 指令和數(shù)據(jù)的區(qū)分部分依賴于規(guī)范的文件格式, 而固件程序中只包含數(shù)據(jù)和指令, 沒有任何關(guān)于程序的入口地址、 函數(shù)的開始地址、 代碼和數(shù)據(jù)空間的位置大小和分布情況的任何信息, 與有著規(guī)范文件格式的結(jié)構(gòu)化二進(jìn)制程序相比, 固件代碼能夠提供給逆向分析人員的信息十分有限, 其逆向分析的難度相對較大。
b) 混合編碼模式
混合編碼模式是固件程序的另一個重要特點(diǎn),編碼模式是關(guān)于機(jī)器指令的一系列編碼規(guī)范的總稱, 編碼模式指出了指令中操作數(shù)的默認(rèn)大小,提供了指令如何解析的信息, 通常的編碼模式包括8 、 16 、 32 位和現(xiàn)在的64 位編碼, 編碼的位數(shù)指定了指令中操作數(shù)的默認(rèn)大小, 例如: DOS是16 位操作系統(tǒng), 所以CPU 在16 位環(huán)境下執(zhí)行它的代碼。 同時編碼模式還指定了指令的長度,例如: ARM 處理器32 位模式(ARM 模式), 指令長度為4B, 而16 位模式(Thumb 模式) 下指令長度為2B。 混合編碼在固件代碼中極為常見,I386 機(jī)器BIOS 程序中經(jīng)常出現(xiàn)實(shí)模式和虛擬模式相互切換的情況, 而ARM 的BOOTLOADER 程序里也有ARM 模式和Thumb 模式的混合編碼的情況, 混合編碼模式將影響控制流恢復(fù)的正確性,增加控制流恢復(fù)算法的復(fù)雜性。
c) 硬件相關(guān)性
固件代碼與硬件緊密關(guān)聯(lián), 是直接與硬件交互的程序, 固件中的大部分指令都在訪問硬件設(shè)備, 上層應(yīng)用程序的資源可以表現(xiàn)為文件的形式,而固件程序的資源則表現(xiàn)為IO 端口。 對固件代碼的逆向分析需要與硬件相關(guān)的信息, 對固件的安全檢測也是通過硬件資源的訪問控制來實(shí)現(xiàn)的[7]。固件代碼具有很強(qiáng)的硬件相關(guān)性。
由于固件代碼在設(shè)計思想、 存在形式、 代碼組織和應(yīng)用領(lǐng)域等方面的特殊性, 使得固件逆向工程與其他軟件逆向工程相區(qū)別并獲得了獨(dú)立的發(fā)展。
工控設(shè)備固件的提取存在特殊性, 很難直接使用傳統(tǒng)方法來獲取固件, 部分原因在于較為封閉的工控環(huán)境中處理器架構(gòu)未知、 存儲設(shè)備未知和內(nèi)存通信方式多樣等一系列的因素, 對于工控固件的提取來說, 這是不可避免的阻礙條件。 但就工控設(shè)備的固件提取而言, 重點(diǎn)和難點(diǎn)主要在于專用工具稀缺、 工控設(shè)備種類繁多、 固件解密困難和固件結(jié)構(gòu)未知4 個方面。
首先, 就專用工具而言, 盡管有許多成熟的工具和技術(shù)可用于分析商用個人計算機(jī)(PC) 上的軟件, 但對于工控設(shè)備的固件提取與修復(fù)而言,很少有相應(yīng)的專用工具。 不僅每次固件提取時,都需要開發(fā)想用工具, 而且不同工控設(shè)備使用的工具不能通用, 增加了固件提取的成本和難度,大大地降低了固件提取的效率。
其次, 工控設(shè)備的種類繁多, 也是工控設(shè)備固件提取的難點(diǎn)之一。 從可編程芯片方面分類,工控設(shè)備固件包含以下幾類: FPGA 固件、 SOC 內(nèi)部固件和外掛FLASH 固件。 每類固件的提取方法完全不同, 而且每種架構(gòu)芯片包含多個廠家, 每個廠家之間的提取方法也不通用。 例如: PowerPC處理器、 AVR 處理器、 PIC 處理器、 ARM 處理器和MIPS 處理器等SOC, 它們對應(yīng)的應(yīng)用場景不同, 固件提取的方法也不同。 從工控設(shè)備用途來分 類, 工 控 設(shè) 備 包 含: PLC、 RTU、 HMI 和SCADA 等4 類設(shè)備, 每類設(shè)備的固件規(guī)模、 固件格式和提取場景均不相同。 PLC 和RTU 設(shè)備是典型的嵌入式設(shè)備, 而HMI、 SCADA 設(shè)備可能包含通用操作系統(tǒng)映像。
另一方面, 固件解密非常困難。 對某些處理器, 采用內(nèi)置ROM 存儲固件, 自帶加密和解密算法, 對原始固件進(jìn)行加密和解密, 即使提取到固件, 也無法對固件解密; 甚至某些工控設(shè)備依據(jù)芯片特性, 在出廠后從硬件上配置了禁止固件上載, 導(dǎo)致無法獲取固件。 同時, 部分工控設(shè)備通過軟件實(shí)現(xiàn)的方法對固件進(jìn)行加密和解密, 除非得到密鑰, 否則即使得到固件, 也無法修復(fù)。
最后, 工控設(shè)備固件結(jié)構(gòu)未知, 影響固件的修復(fù)。 在二進(jìn)制逆向工程中, 根據(jù)程序的結(jié)構(gòu)特點(diǎn), 可以將二進(jìn)制程序分為兩類: 1) 結(jié)構(gòu)化二進(jìn)制程序, 這類程序具有規(guī)范的文件格式, 包含了程序動態(tài)執(zhí)行與靜態(tài)分析相關(guān)的程序信息, PE、ELF 等格式的目標(biāo)代碼就是典型的結(jié)構(gòu)化二進(jìn)制程序; 2) 非結(jié)構(gòu)化二進(jìn)制程序, 非結(jié)構(gòu)化二進(jìn)制程序中僅包含數(shù)據(jù)和指令的序列, 如bin、 hex 格式的芯片內(nèi)置程序、 51 處理器內(nèi)部ROM 程序、 ARM處理器的BootLoader 和I386 機(jī)器固件芯片中的BIOS 程序等。 非結(jié)構(gòu)化二進(jìn)制程序多為固件程序,通常也被稱作為固件或固件代碼。 固件代碼因?yàn)榻Y(jié)構(gòu)未知, 當(dāng)從flash 中拷貝整個數(shù)據(jù)時, 無法從flash 映像中分離出有效數(shù)據(jù)和無效數(shù)據(jù)。
工程上主要包含9 種工控設(shè)備固件提取方法。固件提取分為兩個方向: 1) 基于硬件直接提??;2) 基于固件(軟件) 本身提取。 具體內(nèi)容如表1所示。
表1 兩類不同固件的提取方法
每種獲取固件的方法都會遇到不同的困難。
使用調(diào)試(JTAG) 端口連接到設(shè)備對某些設(shè)備有效, 但是很多時候接口被禁用或使用非標(biāo)準(zhǔn)協(xié)議。 從閃存讀取固件始終能夠獲得固件, 但是異常的內(nèi)存布局可能使重新組裝整個固件變得困難。 如果固件來自多個閃存芯片, 則必須重新組裝。 由于固件的結(jié)構(gòu)尚不清楚, 因此此過程可能會很復(fù)雜。
當(dāng)通過接口干擾、 定向爆破等技術(shù)使其保護(hù)機(jī)制失效, 然后直接讀取芯片數(shù)據(jù)時, 難點(diǎn)在于如何使存儲器的保護(hù)機(jī)制失效, 只要使芯片失去保護(hù), 即可隨意地讀取任意位置的數(shù)據(jù), 獲取完整的固件代碼, 如果芯片數(shù)據(jù)加密, 那么還需要進(jìn)行數(shù)據(jù)解密或者解析系統(tǒng)中的加密/解密邏輯電路。 加密邏輯通常存在于靠近處理器或存儲器的CPLD/FPGA 芯片中。
當(dāng)監(jiān)聽總線, 使用數(shù)據(jù)采集設(shè)備(如邏輯分析儀等) 獲取系統(tǒng)運(yùn)行時總線上的數(shù)據(jù)和地址信息, 恢復(fù)出被運(yùn)行程序的片段時, 需要專門的數(shù)據(jù)采集設(shè)備和數(shù)據(jù)恢復(fù)軟件, 對數(shù)據(jù)采集部件的工作頻率要求較高(一般為存儲器工作頻率的2倍或更高), 恢復(fù)出來的數(shù)據(jù)也難以驗(yàn)證其完整性。 無論是摧毀固件芯片的保護(hù)機(jī)制還是使用總線監(jiān)聽技術(shù), 其獲取的難度將遠(yuǎn)大于通用PC 機(jī)上的可執(zhí)行文件。
深入地了解工控設(shè)備的底層實(shí)現(xiàn)機(jī)制是很重要的, 因?yàn)殡S著工控系統(tǒng)的互聯(lián)互通, 他們的功能變得越來越復(fù)雜, 對ICS 的攻擊往往會降到較低的抽象級別。 雖然電子產(chǎn)品的逆向工程已有很長的歷史, 工控設(shè)備固件提取和逆向工程并不是一個新的領(lǐng)域, 但是安全社區(qū)沒有像x86 軟件和硬件那樣有足夠的經(jīng)驗(yàn)或工具來處理嵌入式設(shè)備上的固件提取與安全分析。 工控設(shè)備固件提取方面,還需要開發(fā)專用的工具和技術(shù), 需要使用工具來識別固件、 嵌入式操作系統(tǒng)和處理器, 并且應(yīng)開發(fā)工具包以進(jìn)行動態(tài)分析或調(diào)試。