劉文祺,范明鈺,田 偉,王光衛(wèi)
(1. 電子科技大學(xué)計算機(jī)科學(xué)與工程學(xué)院 成都 611731;2. 中國人民解放軍95333部隊(duì) 長沙 410114)
UEFI是操作系統(tǒng)與固件平臺間新的接口規(guī)范。UEFI使用高級語言開發(fā),采用模塊化構(gòu)建方式,功能豐富,擴(kuò)展性良好[1]。隨著UEFI固件普及,出現(xiàn)了針對UEFI固件的BOOTKIT攻擊。文獻(xiàn)[2]通過固件SMM漏洞向UEFI固件植入惡意代碼,攻擊TXT(trusted execution technology)安全機(jī)制[3]。2015年,文獻(xiàn)[4]對UEFI固件進(jìn)行漏洞攻擊,使數(shù)以百萬的計算機(jī)無法正常使用。
UEFI固件BOOTKIT隱藏在固件中,于操作系統(tǒng)啟動前執(zhí)行,通過篡改UEFI固件文件以及操作系統(tǒng)(OS)核心文件,實(shí)現(xiàn)攻擊目的[4]?;赨EFI的BOOTKIT的防范方法,其最終目的是確保UEFI固件和OS核心文件的完整性?,F(xiàn)有完整性檢測方法主要分為兩類:一是固件完整性檢測;二是OS文件檢測。文獻(xiàn)[5]采用代碼特征對比的策略,提出了一種基于UEFI固件的惡意代碼檢測機(jī)制,但大量的病毒特征碼給UEFI固件內(nèi)存造成了沉重負(fù)擔(dān)。文獻(xiàn)[6]以TPM芯片為可信根,建立了一條系統(tǒng)啟動的可信鏈來確保固件完整;該算法實(shí)現(xiàn)復(fù)雜、代碼量大,且容易被BOOTKIT繞過,存在實(shí)用性低的問題。Copilot[7]利用PCI卡周期性地對OS內(nèi)核進(jìn)行訪問以檢測內(nèi)核代碼的完整性;改進(jìn)的Copilot[7]則能檢測OS內(nèi)核中數(shù)據(jù)的完整性。Servicsor[8]可以在OS的整個運(yùn)行周期中保障可執(zhí)行程序的合法性。這些檢測方法能有效檢測OS內(nèi)核的完整性,但是不能獨(dú)立于OS運(yùn)行,也不能對固件文件進(jìn)行完整性檢測。文獻(xiàn)[9]提出了在執(zhí)行UEFI固件可執(zhí)行文件前驗(yàn)證其數(shù)字簽名的方法,該方法原理簡單,能有效檢測文件的完整性,但是不能對異常文件進(jìn)行恢復(fù)。
針對上述不足,本文提出一種新的UEFI固件BOOTKIT檢測方法UDS(UEFI detection system),其主要特點(diǎn)有:1) 以UEFI虛擬設(shè)備驅(qū)動程序的形式實(shí)現(xiàn)[1],能獨(dú)立于OS運(yùn)行;2) 采用將完整性檢測與文件恢復(fù)相結(jié)合的策略,分別在DXE階段和OS BOOT階段對固件、OS文件進(jìn)行完整性檢測,并對異常文件進(jìn)行恢復(fù);3) 能自我保護(hù),防止BOOTKIT對自身進(jìn)行攻擊;4) 小巧簡便,利用UEFI固件接口和UEFI隱藏分區(qū)開發(fā),減少UDS占用的ROM空間。
最后實(shí)驗(yàn)表明,UDS能在操作系統(tǒng)啟動之前,成功防范固件攻擊并恢復(fù)異常文件,具有啟動早、開銷少,能自我防護(hù)的優(yōu)點(diǎn)。
根據(jù)SPEC[1],UFEI的啟動階段按先后次序被分為:PEI、DXE、BSD、TSL、RT。UEFI內(nèi)核和UEFI基礎(chǔ)服務(wù),如:文件系統(tǒng)、網(wǎng)絡(luò)I/O以及認(rèn)證等,主要在DXE階段完成初始化。因此,UDS要在DXE期間,以UEFI虛擬設(shè)備驅(qū)動的形式,運(yùn)行在UEFI環(huán)境中,借助UEFI基礎(chǔ)服務(wù)完成固件、OS文件檢測和異常文件恢復(fù)等功能。
UDS包括4個功能部件:UDSchecker、UDSprocessor、UDSpatcher以及UDSstore。UDS的結(jié)構(gòu)如圖1所示。
圖1 UDS結(jié)構(gòu)
UDSchecker負(fù)責(zé)檢查UEFI模塊或操作系統(tǒng)核心文件的完整性:若文件完整,則繼續(xù)執(zhí)行;否則,向UDSprcessor發(fā)送警報消息alert=(id,url,len),繼續(xù)檢測。其中id是異常文件名,url是文件的下載地址或文件路徑,len是文件的長度。
UDSprocessor收到警報后,首先分配內(nèi)存addr,并根據(jù)alert.url下載文件至addr;然后發(fā)送補(bǔ)丁消息patch=(id,addr)到UDSpatcher;最后阻塞執(zhí)行,等待UDSpatcher回應(yīng)。UDSpatcher收到補(bǔ)丁消息后,恢復(fù)異常文件,解除UDSprocessor阻塞釋放內(nèi)存。
UDSstore負(fù)責(zé)管理文件加載信息、文件備份信息以及UDS秘鑰。文件加載信息在固件或OS文件加載進(jìn)內(nèi)存時動態(tài)生成;備份信息分成固件、系統(tǒng)文件備份兩類,分別保存在硬盤UEFI隱藏分區(qū)下的/bak/firmware和/bak/OS目錄;這樣不僅有效節(jié)約了ROM空間,在安裝多OS或OS更新時,還能直接對UEFI分區(qū)的備份文件進(jìn)行更新;UDS秘鑰用于加密備份文件信息,在開發(fā)時硬編碼到程序。
當(dāng)UDS啟動時,UDSstore會創(chuàng)建表LFILE和BFILE;表LFILE中保存加載到內(nèi)存中的固件驅(qū)動或OS文件信息,其表項(xiàng)形式化表示為:(id,start_addr,len),id是文件名,作為唯一標(biāo)志,start_addr是文件加載地址,len是內(nèi)存中文件的長度;BFILE表項(xiàng)形式化表示為:(id,url,fhash),id是文件標(biāo)志與LFILE.id相同,url是文件路徑或下載路徑,fhash是備份文件的數(shù)字摘要,用于文件的完整性檢測。
在DXE初期,由于操作系統(tǒng)沒有啟動,BFILE只能保存文件/bak/firmware中的固件文件備份信息。在DXE后期,EFIchecker將對UEFI固件文件進(jìn)行檢測,UDSprocessor以及UDSpatcher則會根據(jù)檢測結(jié)果,實(shí)現(xiàn)對異常文件的恢復(fù)。
BSD階段,UDS根據(jù)用戶選擇的OS啟動項(xiàng),對UEFI全局變量OSid賦相應(yīng)的值;然后讀取備份文件/bak/OS/$(OSid)的內(nèi)容,并將文件信息保存到表BFILE。隨后,UDS就可以對OS的核心文件進(jìn)行完整性檢測和恢復(fù)。
根據(jù)SPEC[1],UDS還可以注冊UEFI系統(tǒng)服務(wù),供其他UEFI程序或OS引導(dǎo)程序調(diào)用[5]。注冊UEFI系統(tǒng)服務(wù),要封裝調(diào)用的服務(wù)接口,并調(diào)用UEFI的Update Capsule機(jī)制[1]來實(shí)現(xiàn)和OS的信息交互。UDS的啟動過程如圖2所示。
圖2 UDS啟動流程
在UDS正常運(yùn)行的情況下,一旦核心文件完整性被破壞,UDS就能完成檢測。如果基于固件的BOOTKIT能夠早于UDS獲得執(zhí)行權(quán),就有可能繞過UDS的檢測,對計算機(jī)系統(tǒng)造成威脅。
通過實(shí)驗(yàn)發(fā)現(xiàn),目前大部分固件BOOTKIT的攻擊目標(biāo)主要是OS,通常不會特別地對某個UFEI驅(qū)動進(jìn)行繞過。存在部分固件BOOTKIT,利用固件代碼特征或者驅(qū)動名稱,來定位攻擊目標(biāo)并完成篡改代碼、隱藏驅(qū)動的目的;在UDS系統(tǒng)的開發(fā)和編譯過程中,可以對核心代碼進(jìn)行混淆或者修改模塊文件名來避免被BOOTKIT定位,從而防范此類攻擊。
恢復(fù)異常文件之前,UDS會根據(jù)alert.url到指定的位置下載備份文件。如果攻擊者能篡改alert.url地址下的文件內(nèi)容,或者直接修改alert.url,并將其指向預(yù)定的惡意文件,那么當(dāng)惡意文件被下載到本地加載運(yùn)行后,就可能造成隱患。因此保證備份文件的安全性十分必要。
為了防止攻擊者直接獲取備份文件中的重要內(nèi)容,第三方在開發(fā)過程中,可以自定義加密算法,對存在備份文件中的內(nèi)容進(jìn)行加密。為了保證下載所得文件的合法性,可以將下載路徑設(shè)置為操作系統(tǒng)官方網(wǎng)址或系統(tǒng)盤根目錄,這樣攻擊者需要獲取官方數(shù)據(jù)庫權(quán)限或本地管理員權(quán)限,才可能篡改下載路徑下的備份文件內(nèi)容。
UDS主要對固件文件、操作系統(tǒng)文件進(jìn)行完整性檢測;并根據(jù)檢測結(jié)果,對異常文件進(jìn)行恢復(fù)。在開發(fā)過程中,UDS借助了UEFI的文件系統(tǒng)、網(wǎng)絡(luò)訪問和數(shù)字簽名等基礎(chǔ)服務(wù)來實(shí)現(xiàn)相應(yīng)功能。
UDS啟動時,要對表LFile與表BFile進(jìn)行初試化,將加載到內(nèi)存中的固件驅(qū)動、OS文件信息以及UFEI分區(qū)上備份文件的信息保存到相應(yīng)的表中。為了避免攻擊者直接獲取備份文件中的重要內(nèi)容,備份文件將被加密保存;因此在初始化時,要使用硬編碼在程序中的秘鑰key對備份文件進(jìn)行解密。
算法1:備份文件加、解密
//加密過程
fuction encode(fe, key):
klen = length(key)
for (i = 0; i < fe.length; i++)
//將文件的每位于key相應(yīng)位異或
result[i]= fe[i]^ key[i % klen]
return result
//解密過程
function decode( fd, key ):
for(i = 0;i < fe.length; i++)
result’[i]= fe[i]^ key[i % klen]
return result’
UDSchecke首先利用LFile表項(xiàng)中的文件加載信息計算文件摘要hash;再根據(jù)LFile.id獲取在BFile中對應(yīng)的備份文件信息,并將hash與BFile.fhash進(jìn)行對比:若兩個摘要相等,表明文件完整,則繼續(xù)對下個文件進(jìn)行完整性檢測;否則,表明文件完整性被破壞,則向UDSprocessor發(fā)送警告消息alert。
算法2:完整性檢測
//當(dāng)表非空時,獲取對應(yīng)表項(xiàng)中的信息
if LFile[i]is not NULL:
addr = LFILE[i].start_addr
len = LFILE[i].len
index = LFILE[i].id
//根據(jù)表項(xiàng)信息,計算對應(yīng)文件的哈希
hash=HASH(mem(addr, len))
//通過標(biāo)志id關(guān)聯(lián)備份文件,并對比哈希
if hash != BFILE[idx].fhash:
//若不相等,發(fā)送alert給UDSprocessor
send alert = (index, BFILE[j].url, len)
//繼續(xù)訪問下一個表項(xiàng)
當(dāng)UDSprocessor收到alert消息后:首先分配一片大小為alert.len的內(nèi)存空間addr,并從alert.url將文件下載到內(nèi)存addr處;隨后UDSprocessor將創(chuàng)建消息patch,通知UDSpatcher對異常文件進(jìn)行恢復(fù);最后阻塞,等待UDSpatcher回復(fù)消息,并釋放內(nèi)存。
算法3:UDSprocessor處理過程
while receive alert:
//分配內(nèi)存空間
addr = allocate(len)
//從alert.url下載備份文件到addr
copy(download(alert.url), addr)
//發(fā)送patch消息給UDSpatcher
send phtch = (alert.id, addr)
//阻塞等待UDSpatcher消息
wait( )
//釋放內(nèi)存
free(addr)
//繼續(xù)處理下一個alert
當(dāng)UDSpatcher收到patch后,開始對異常文件進(jìn)行恢復(fù):首先,通過patch.id訪問LFile中對應(yīng)的表項(xiàng),得到異常文件地址LFile.start_addr;然后用addr保存的合法備份對內(nèi)存中異常文件進(jìn)行恢復(fù);恢復(fù)完成后,向UDSprocessor返回確認(rèn)消息,解除阻塞并繼續(xù)進(jìn)行處理。
算法4:UDSpatcher處理過程while receive patch
//通過patch.id訪問對應(yīng)的LFile表項(xiàng)
assert(patch.id == LFile[idx].id)
//恢復(fù)異常文件
repair(LFile[idx], patch)
//給UDSprocessor返回確認(rèn)消息
send ACK
//繼續(xù)處理下一個patch
實(shí)驗(yàn)?zāi)康氖菣z測UDS的防范能力、空間開銷和啟動效率。首先,在UEFI開源代碼的基礎(chǔ)上,編譯帶有UDS的UDS-UEFI ROM文件;編譯好的ROM文件大小為57 KB,能夠充分滿足固件內(nèi)存的限制;最后利用周立功SmartPRO 9800 plus編程器,將該ROM文件刷寫到UEFI芯片中。測試基于EDKII開發(fā)平臺,操作系統(tǒng)為Window 7旗艦版SP1,CPU型號為Inter Core Q8200,主板為華碩H81-D,4 G內(nèi)存條。
防范能力測試用于測試UDS的完整性檢查、文件修復(fù)及自我保護(hù)能力,實(shí)驗(yàn)結(jié)果如表1所示。BMW、STONED是基于固件的BOOTKIT,實(shí)現(xiàn)篡改固件數(shù)據(jù)和隱藏驅(qū)動的功能;TDL4能在固件初期就開始運(yùn)行,通過HOOK操作篡改固件代碼、繞過驅(qū)動,劫持執(zhí)行流程;Superkit[10]、ADORE-NG[11]、hideme和鬼影等是基于操作系統(tǒng)內(nèi)核的BOOTKIT,主要實(shí)現(xiàn)篡改系統(tǒng)調(diào)用表、關(guān)鍵函數(shù)指針[13]以及修改控制[12]流程等功能。
實(shí)驗(yàn)結(jié)果表明,UDS完成了對固件、OS文件的完整性檢查和異常文件恢復(fù),能有效防范來自基于固件或OS的BOOTKIT的惡意攻擊;通過自我防護(hù),UDS能避免BOOTKIT的影響,保持正常運(yùn)行。
表1 防范能力測試結(jié)果
表2是UDS與其他同類檢測工具的對比結(jié)果。實(shí)驗(yàn)結(jié)果表明,Nickle[14]和SecVisor[8]能夠?qū)S核心文件的完整性進(jìn)行保護(hù),但是不能對固件文件進(jìn)行完整性檢查;UDS和UEFI惡意代碼防范系統(tǒng)(MCDU)[5]都能完成固件文件完整性檢查、OS文件完整性檢查和文件恢復(fù)的功能,但是UDS更加精簡,所占空間更少。與UDS相比,由于MCDU采用基于惡意代碼特征的掃描方法,除了要完成完整性檢查及文件恢復(fù)的功能以外,惡意代碼查詢、定位、匹配等功能還需額外的代碼實(shí)現(xiàn);另外,MCDU模塊中還保存了大量的惡意代碼特征和特征定位信息。而UDS的原理簡單,不用實(shí)現(xiàn)諸如上述的函數(shù),還能將備份文件等信息保存在硬盤分區(qū)上,因而UDS的實(shí)現(xiàn)簡單,配置方便,占有的ROM空間更少。
表2 與其他同類檢測工具對比結(jié)果
圖3 啟動時間對比結(jié)果
圖3是對比UDS-UEFI啟動時間的結(jié)果。實(shí)驗(yàn)表明,UDS-UEFI的啟動時間比UEFI惡意代碼防范系統(tǒng)(MCDU)要少,不會對計算機(jī)啟動造成大的影響。由于UDS的檢測算法簡單,不用實(shí)現(xiàn)MCDU中大量的特征識別函數(shù),還能直接利用UEFI平臺現(xiàn)成的接口,執(zhí)行文件讀寫、數(shù)字簽名、HASH等操作。因此UDS運(yùn)行所需的開銷較少,UDS-UEFI的啟動速度比MCDU的啟動更快。
本文提出的UEFI固件BOOTKIT檢測方法UDS,在操作系統(tǒng)啟動之前(DXE階段)以及OS BOOT階段,分別對UEFI固件文件和操作系統(tǒng)的核心文件進(jìn)行完整性檢測,并能根據(jù)檢測結(jié)果,對異常文件進(jìn)行恢復(fù)。實(shí)驗(yàn)表明,該方法具有啟動早、開銷少及自我防護(hù)性好的優(yōu)點(diǎn)。