趙利軍 董莎莎 張沙石
(陸軍工程大學軍事理論創(chuàng)新與作戰(zhàn)實驗中心 江蘇 徐州 221000)
隨著嵌入式設(shè)備的廣泛使用,如何攻克嵌入式設(shè)備成為當前網(wǎng)絡(luò)空間作戰(zhàn)中的關(guān)鍵環(huán)節(jié),為了能繼續(xù)持有攻擊主機的訪問特權(quán),惡意程序必須較好地隱藏自己不被檢測工具發(fā)現(xiàn)。作為一種高級的隱藏技術(shù),近幾年P(guān)C機上的陷門攻擊技術(shù)——Bootkit技術(shù),得到了廣泛使用和發(fā)展。Bootkit技術(shù)是一種更高級的Rootkit技術(shù),兩者的不同之處在于Bootkit將存儲位置從文件系統(tǒng)變?yōu)橛布鎯Γ⑶以诓僮飨到y(tǒng)加載之前啟動。Rootkit修改操作系統(tǒng)內(nèi)核,重裝系統(tǒng)可將其清除。Bootkit在加載操作系統(tǒng)之前啟動,因此獨立于任何操作系統(tǒng)。與傳統(tǒng)的Rootkit技術(shù)主要是在系統(tǒng)啟動時提升權(quán)限不同,Bootkit通過篡改內(nèi)核及操作系統(tǒng)引導過程隱藏自身。
2007年研究人員IceLord(網(wǎng)名)發(fā)布的公開資料是可以找到的第一個Windows環(huán)境下的BIOS Rootkit[1]。由此,針對BIOS的陷門設(shè)計從一個技術(shù)構(gòu)想變成了程序?qū)嶓w。同一年,Nitin Kumar和Vipin Kumar在Black Hat大會上呈現(xiàn)了一種名為Vbootkit的Bootkit攻擊技術(shù),并成功突破Windows Vista系統(tǒng)。Vbootkit能夠篡改引導向量獲取執(zhí)行權(quán)限,繞過啟動管理器的簽名機制。通過Hook Windows Vista系統(tǒng)啟動文件入侵操作系統(tǒng)內(nèi)核[2]。在2008年,Wenbin Zhen等[3]發(fā)布了Tophet.a,一款基于篡改OSLoader的Bootkit技術(shù)。該技術(shù)可使攻擊者獲取系統(tǒng)控制權(quán)并通過篡改boot.ini文件中的語法格式將控制權(quán)轉(zhuǎn)換到攻擊者的驅(qū)動。同年的Black Hat大會上,C.Miller通過嗅探MacBook電池中內(nèi)建的電量控制器經(jīng)I2C收到的數(shù)據(jù),對電池的嵌入式微控制器固件進行修改,可以使電池過度發(fā)熱甚至起火,并能夠在獲得微控制器的控制權(quán)后對系統(tǒng)進行配置[4]。Lee等[5]提出了劫持ARM Linux嵌入式設(shè)備的方法,該方法借鑒通用計算機下的Linux系統(tǒng)常用劫持方案,將系統(tǒng)調(diào)用表或者系統(tǒng)調(diào)用函數(shù)進行修改,并指向自己的惡意代碼,從而實現(xiàn)控制流的轉(zhuǎn)移,達到劫持目的。在文獻[6]中闡述了破解Netgear NTV300電視機頂盒的方法。文中作者dump下Netgear NTV300中的固件映像,通過Binwalk解析固件組成、使用的壓縮算法等,并使用IDA的靜態(tài)分析功能,最終實現(xiàn)了對該設(shè)備的漏洞注入和遠程控制。2013年,Ang Cui等[7]介紹了惠普HP-RFU(遠程固件升級)激光打印機固件修改漏洞,通過打印含有特殊命令的文檔來隱蔽地修改打印機的固件,進而獲得該打印機的控制權(quán),并采用靜態(tài)分析方法對其中使用的第三方庫分析發(fā)現(xiàn)超過80.4%的固件程序存在zlib漏洞。文獻[8]對惠普RFU漏洞進行了驗證,攻擊者通過MS Office Word、Adobe PostScript等標準的打印文檔向任意打印機中注入惡意代碼和命令,使用這種攻擊途徑可以向打印機發(fā)送修改后的固件。2015年,李成林[9]針對目前主流殺毒軟件對KiFastCallEntry掛鉤提出了躲避方案,提出了改進型SSDT掛鉤,該方法不再直接修改SSDT分發(fā)表里的函數(shù)入口地址,而是在函數(shù)體的內(nèi)部進行修改。2016年,馮培鈞等[10]在“一種新型 Linux 內(nèi)核級 Rootkit 設(shè)計與實現(xiàn)”一文中設(shè)計并實現(xiàn)了一種新型Linux內(nèi)核級Rootkit,該Rootkit能夠?qū)崿F(xiàn)后門提權(quán)、進程隱藏及文件隱藏等功能,并能繞過當前主流的Rootkit檢測工具的檢測。2017年,李揚等[11]提出一種基于硬件虛擬化的內(nèi)核Rootkit技術(shù),該技術(shù)利用Intel VT-x硬件虛擬化技術(shù)將客戶系統(tǒng)(Guest OS)遷移到VMM之上運行實現(xiàn)Rootkit。
但是,對于一個新的嵌入式設(shè)備,多數(shù)的陷門設(shè)計技術(shù)都難以在有限的時間內(nèi)設(shè)計出來,設(shè)計的陷門通用性也較差,無法部署到不同目標設(shè)備上。為此,本文通過研究嵌入式設(shè)備的啟動過程,建立涵蓋不同啟動流程異同點的、陷門模板化設(shè)計框架,為設(shè)計具有一定程度通用性的陷門提供依據(jù)。
嵌入式設(shè)備的軟硬件結(jié)構(gòu)特點及啟動過程的差異性嚴重影響陷門的設(shè)計效率,人們可以針對不同設(shè)備,進行分析和設(shè)計符合需求的陷門。但本文嘗試引入陷門設(shè)計的模板化框架,旨在為提煉出一種具有一定程度通用性的、適用于主流嵌入式設(shè)備的陷門設(shè)計提供方便。
首先,我們對各種不同的嵌入式設(shè)備啟動流程進行分析,歸納它們的相同點與差異性,建立統(tǒng)一的啟動流程。
存儲芯片不同會造成Bootloader引導的差異;Bootloader不同會造成內(nèi)核啟動流程的差異;不同內(nèi)核加載過程也存在較大差異;不同文件系統(tǒng)掛載的機制也有區(qū)別。啟動流程分析主要是對這些差異性進行總結(jié)和歸納。
Bootloader的啟動過程可以是單個階段的,也可劃分為多個階段,嵌入式設(shè)備下一般為二階段的啟動過程,分Stage1和Stage2兩部分啟動。二階段的Bootloader啟動流程如圖1所示。
圖1 Bootloader啟動流程
導致Bootloader啟動方式差異的因素還有內(nèi)核掛載文件系統(tǒng)機制的差異。以Linux內(nèi)核為例,Linux內(nèi)核中包含兩種掛載早期根文件系統(tǒng)的機制,即initrd機制和initramfs機制。
initrd是一個功能完備的小型根文件系統(tǒng),是一種啟動早期用戶空間處理流程的老式方法,它通常包含一些指令,用于在系統(tǒng)引導完成之前加載一些特定的設(shè)備驅(qū)動程序。為了使用initrd的功能,大多數(shù)架構(gòu)的引導加載程序會將initrd鏡像傳遞給內(nèi)核。常見的場景是,引導加載程序先將壓縮過的內(nèi)核鏡像加載到內(nèi)存中,接著將initrd鏡像加載到另一段可用內(nèi)存中。如圖2所示。
圖2 initrd機制啟動流程
在這個過程中,引導加載程序負責在將控制權(quán)轉(zhuǎn)交給內(nèi)核之前,將initrd鏡像的地址傳遞給內(nèi)核。具體的機制取決于架構(gòu)、引導加載程序和平臺的實現(xiàn)。然而,內(nèi)核必須知道initrd鏡像的位置才能夠加載它。當內(nèi)核引導時,它首先會檢測內(nèi)核命令行中是否包含root=參數(shù)并指定一個ramdisk(比如root=/dev/ram0)。然后,將這個壓縮的二進制文件從內(nèi)存中的指定位置復制到一個合適的內(nèi)核ramdisk中,并掛載它作為根文件系統(tǒng)。與PC機上Linux內(nèi)核會卸載initrd,嘗試掛載另一個文件系統(tǒng)作為其根文件系統(tǒng)不同,這類系統(tǒng)中唯一的根文件系統(tǒng)就是ramdisk,在整個系統(tǒng)初始化完成后,initrd就會成為最終的根文件系統(tǒng)。
與initrd是一種基于RAM的塊設(shè)備不同,initramfs是一種基于RAM的內(nèi)存文件系統(tǒng)。initramfs在編譯內(nèi)核的同時被編譯,并與內(nèi)核連接成一個文件。在引導階段它與內(nèi)核同時被Bootloader加載到RAM中。而initrd是另外單獨編譯生成的,是一個獨立的文件,它由Bootloader單獨加載到RAM中內(nèi)核空間外的地址。其啟動過程如圖3所示。
圖3 initramfs機制啟動流程
不同機制下根文件系統(tǒng)的掛載方式不同,如圖4所示。
圖4 根文件系統(tǒng)掛載方式示意圖
根據(jù)上述分析的Bootloader啟動流程和內(nèi)核掛載文件系統(tǒng)機制的差異,對啟動流程的共性和特性進行歸納,得到Linux內(nèi)核嵌入式設(shè)備啟動流程的一般化描述,如圖5所示。
圖5 嵌入式Linux啟動流程
圖中①與①2代表啟動過程中不同的執(zhí)行路徑,其中①表示不同設(shè)備之間啟動過程中的共性階段,①2表示不同設(shè)備之間啟動過程的差異性階段。同理,②與②2、③與③2、④與④2分別代表不同設(shè)備系統(tǒng)啟動過程中不同的執(zhí)行路徑。
Linux系統(tǒng)啟動流程中,將涉及陷門模塊設(shè)計的執(zhí)行階段劃分出來,隔離成黑盒,得到粗粒度的Linux啟動流程,如圖6所示。
圖6 隔離涉及陷門模塊設(shè)計執(zhí)行階段后的啟動流程圖
圖6中,黑盒1和黑盒2屬于引導代碼級陷門組件模塊。黑盒3屬于內(nèi)核級陷門組件模塊,黑盒4為文件系統(tǒng)級陷門組件模塊。其中,除黑盒1外,其他黑盒內(nèi)部均存在路徑分支,陷門的設(shè)計需要依據(jù)設(shè)備的實際執(zhí)行路徑進行考慮。建立的嵌入式Linux啟動模型如圖7所示。
圖7 嵌入式Linux啟動模型
由于Bootloader Stage2、加載initrd、內(nèi)核自解壓與搬移、解壓與搬移initrd操作在某些設(shè)備啟動過程中不存在,因而用虛線框表示。陷門設(shè)計時,這些階段對應的陷門組件需要依據(jù)實際設(shè)備的啟動過程和陷門需求進行組合。
高級語言中模板是根據(jù)參數(shù)類型生成函數(shù)和類的機制(有時稱為“參數(shù)決定類型”)。通過使用模板,可以只設(shè)計一個類來處理多種類型的數(shù)據(jù),而不必為每一種類型分別創(chuàng)建類。借鑒高級語言中模板函數(shù)、模板類等思想,提出陷門模板化技術(shù)。
陷門模板可以比作一個生成陷門攻擊代碼的“模子”,是對適用于某一類型設(shè)備(功能相同、結(jié)構(gòu)相似)的攻擊方式的抽象化概括,一個陷門模板允許根據(jù)具體的設(shè)備分析結(jié)果填寫某些參數(shù),將模板實例化成針對某個特定設(shè)備的陷門。陷門模板化設(shè)計方法能夠?qū)崿F(xiàn)部分環(huán)節(jié)的自動化、減少人工工作量,從一定程度上降低了陷門開發(fā)的難度,提高了陷門設(shè)計的效率。結(jié)合啟動模型,模板化陷門設(shè)計框架如圖8所示。
圖8 模板化陷門設(shè)計框架
整個陷門模板分為BootLoader級組件、內(nèi)核級組件和文件系統(tǒng)級組件,分別對應引導階段、內(nèi)核啟動階段、文件系統(tǒng)掛載階段的操作。其中文件系統(tǒng)級組件可單獨實現(xiàn)陷門攻擊,也可與其他兩個組件配合使用。陷門模板留有拼接各組件的配置接口,可根據(jù)實際對目標設(shè)備的分析結(jié)果進行擴展。每個組件也以可配置的形式存在,可根據(jù)陷門設(shè)計需求實例化為某個特定功能的組件。
陷門功能組件中又分別存在不同部件,不同部件功能也相對獨立,部件間一般需要互相配合完成特定功能。部件內(nèi)部也留有“個性化”的配置接口,可根據(jù)對實際設(shè)備的分析填寫相應的參數(shù)。特別說明路徑選擇部件主要負責根據(jù)設(shè)備啟動階段的判別信息,選擇陷門設(shè)計所需的部件。
本文提出的模板化陷門設(shè)計框架適用于跨平臺的陷門設(shè)計。根據(jù)陷門框架設(shè)計的陷門模板如下所示:
# Trapdoor Paramaters Start #
Para0, 0x12345678
Para1, 0x12345678
……
Paran, 0x12345678
# Trapdoor Paramaters End#
# Bootloader Stage Trapdoor Start #
……
# Kernel Stage Trapdoor Start #
……
# Trapdoor Start #
……
# Trapdoor End #
# Kernel Stage Trapdoor End #
# Bootloader Stage Trapdoor End #
陷門模板代碼的開頭為各模塊可配置的參數(shù)區(qū)。陷門代碼的實體部分是一個嵌套的實現(xiàn)過程,與陷門代碼逐級感染設(shè)備的流程想匹配。陷門最外層為最先執(zhí)行的陷門代碼模塊,即引導級陷門代碼模塊。第二層為內(nèi)核級陷門代碼模塊。最里層為陷門實際需要完成的功能模塊,如網(wǎng)絡(luò)劫持、文件下載、破壞設(shè)備等,可根據(jù)實際設(shè)備選擇。每一層的執(zhí)行任務完成后都會由下一層負責清理上一層陷門代碼執(zhí)行留下的痕跡,達到陷門隱蔽的效果。
從陷門設(shè)計框架可知,陷門結(jié)構(gòu)也可能只由文件系統(tǒng)級陷門模塊和陷門實際功能模塊組成。由前面提出的可重構(gòu)陷門設(shè)計方法可知陷門結(jié)構(gòu)中各模塊的組合以及各模塊內(nèi)部不同部件的組成,都可根據(jù)實際需求進行調(diào)整。
陷門功能需要匯編語言實現(xiàn),因此陷門模板的實現(xiàn)只適用于某個特定架構(gòu)。以ARM架構(gòu)為例,闡述陷門模板具體實現(xiàn)。由于完整代碼太長,將陷門模板的實現(xiàn)過程進行分塊說明。
陷門模板中的可配置參數(shù)保留區(qū)分為全局參數(shù)區(qū)和局部參數(shù)區(qū)。全局參數(shù)區(qū)主要是一些執(zhí)行各模塊時必須配置的參數(shù),如Bootloader級模塊和內(nèi)核級模塊必須配置內(nèi)核鏡像加載的起始地址及結(jié)束地址。局部參數(shù)區(qū)主要用作陷門各模塊內(nèi)部件執(zhí)行時的參數(shù)配置,如Bootloader級模塊陷門寄生加載部件需要配置陷門加載的地址和大小、碎片重組部件需要配置碎片數(shù)目和各碎片加載的地址及大小??膳渲脜?shù)區(qū)的實現(xiàn)如下:
# 全局參數(shù)區(qū) #
.equ Para0, 0x30008000
//內(nèi)核加載到內(nèi)存的起始地址
.equ Para1, 0x30008128
//內(nèi)核壓縮數(shù)據(jù)起始地址
.equ Para2, 0x12345678
……
.equ Paran, 0x12345678
# Bootloader Stage Trapdoor Start #
# 局部參數(shù)區(qū) #
MSAK_Parameter:
.word 0xefefefea
//陷門起始地址
.word 0xefefefeb
//陷門結(jié)束地址
……
RecoverPara_MSAK:
//陷門控制流劫持可能覆蓋引某條關(guān)鍵指令
.word 0xefefeff1
//將需要恢復的指令保存于此
.word 0x00080000
……
“程序棧”是保存和恢復陷門劫持控制流后破壞的設(shè)備運行時上下文信息的區(qū)域,一般位于每個陷門模塊和模塊部件的開頭和結(jié)尾處。具體實現(xiàn)如下:
# 程序棧 #
b SelfDefinationStack
.word 0x11111111
.word 0x00001110
……
.word 0x0000111f
.word 0x00001120
SelfDefinationStack:
str r0, [pc, #-76]
//pc-76為程序棧的第一個數(shù)據(jù)地址
str r1, [pc, #-76]
……
str r14, [pc, #-76]
mrs r0, cpsr
str r0, [pc, #-80]
mrs r0, spsr
str r0, [pc, #-84]
……
RelocationStack:
ldr r0, RelocationStack
//獲取程序棧的位置
sub r0, pc, r0
sub r0, r0, #0xc
ldr r14, SelfDefinationStack
add r14, r14, r0
ldr r0, [r14, #-4]
//恢復保存的寄存器數(shù)據(jù)
msr spsr, r0
ldr r0, [r14, #-8]
msr cpsr, r0
ldr r14, [r14, #-12
……
ldr r0, [r14, #-68]
ldr r1, [r14, #-64]
數(shù)據(jù)池不僅可以用來存儲下一個模塊的代碼和數(shù)據(jù),也可作為當前模塊需要傳遞給下一個模塊的數(shù)據(jù)保存區(qū)。數(shù)據(jù)池的實現(xiàn)較為簡單,但是陷門模板設(shè)計中不可或缺的重要部分,具體形式如下:
B Lable:
Data_Buffer:
.word 0x11111111
.word 0x11111111
.word 0x11111111
……
.ascii
"xffx5fx2dxe9x00x60x0fxe1x40x00x2dxe9x00x60x4fxe1x40......"
Lable: ……
其中第一部分為模塊間傳遞的數(shù)據(jù)區(qū),.ascii 為某個shellcode形式的陷門模塊。
由于嵌入式設(shè)備“客制化”的生產(chǎn)模式,大多數(shù)情況下難以在給定的時間內(nèi)設(shè)計出針對一個新的嵌入式設(shè)備的陷門,設(shè)計的陷門通用性也較差,無法部署到不同目標設(shè)備上。本文通過研究嵌入式設(shè)備的啟動過程,建立涵蓋不同啟動流程異同點的,搭建了陷門模板化設(shè)計框架,最后通過勢力說明了陷門模板的設(shè)計方法。本文提出了框架為設(shè)計具有一定程度通用性的陷門提供了依據(jù)。