1、最近發(fā)生的關(guān)于虛擬機(jī)軟件的漏洞
VM產(chǎn)品的漏洞有一些特殊性,涉及到幾個(gè)操作環(huán)境,比如有主操作系統(tǒng)、客操作系統(tǒng),還有一個(gè)比較特殊的是它的虛擬機(jī)管理器里面也可能有漏洞,
虛擬機(jī)軟件的漏洞和虛擬機(jī)執(zhí)行環(huán)境的檢測與反檢測
。我列出了大概五種可以產(chǎn)生漏洞的地方。首先是VMM本身可能有漏洞,我列出了三個(gè)。其中有一個(gè)是比較新的,是在x64系統(tǒng)模擬上VMM存在漏洞,這使Guest OS可以提升本地權(quán)限。當(dāng)然在Guest OS里面也可能有漏洞,一個(gè)比較典型的案例就是CVE-2007-5671,這個(gè)就是利用在客操作系統(tǒng)里面安裝的一個(gè)驅(qū)動(dòng)程序HGFS.sys,這個(gè)HGFS使主操作系統(tǒng)和客操作系統(tǒng)可以共享文件和目錄。它里面存在一個(gè)漏洞,這個(gè)漏洞是驅(qū)動(dòng)上是非常常見的,對IO ctl提供的參數(shù)沒有進(jìn)行足夠的驗(yàn)證,導(dǎo)致從用戶態(tài)能夠讀寫任意的內(nèi)存地址。這也是本地提權(quán)非常典型的一個(gè)案例。
現(xiàn)在我個(gè)人覺得,像這種利用驅(qū)動(dòng)IO ctl來提權(quán)的情況發(fā)生的比較多。原因是因?yàn)橛泻芏郔O ctl fuzz工具的產(chǎn)生,可以向一個(gè)驅(qū)動(dòng)設(shè)備任意地發(fā)送IO ctl,并且變換它的參數(shù)。如果發(fā)現(xiàn)機(jī)器藍(lán)屏了,你就會(huì)覺得有可能這是可以利用的漏洞,它比較好找,發(fā)生的原因也比較簡單,一般都是用戶態(tài)傳進(jìn)來的參數(shù),內(nèi)核態(tài)可能直接拿參數(shù)里面的一個(gè)地址進(jìn)行讀寫,而沒有驗(yàn)證參數(shù)的合法性。比較好分析漏洞的成因,所以數(shù)量就比較多。
當(dāng)然在HOST OS里也存在比較多的漏洞,我列出了兩個(gè)是我自己發(fā)現(xiàn)并上報(bào)給VMware的,是在Host OS中進(jìn)行本地提權(quán)的兩個(gè)漏洞。如果一會(huì)兒還有時(shí)間,我會(huì)講一下。
另外一個(gè)比較有趣的,也是比較獨(dú)特的類型,是從客操作系統(tǒng)向主操作系統(tǒng)的逃逸。比如說在Windows里執(zhí)行Linux代碼,可以從Linux VM里面滲透出來,在Windows主操作系統(tǒng)環(huán)境里面執(zhí)行代碼,這就叫做VM逃逸。最近比較常見的就是我列出的三個(gè),一個(gè)HGFS堆溢出,一個(gè)是HGFS共享目錄遍歷漏洞,還有一個(gè)是通過RPC的調(diào)用。從VM里面可以向VMX進(jìn)程發(fā)起RPC調(diào)用,RPC可以攜帶參數(shù),如果參數(shù)是畸形的,可以導(dǎo)致在VMX這個(gè)進(jìn)程里產(chǎn)生溢出,從而執(zhí)行代碼。
最后一種情況,因?yàn)閂Mware會(huì)大量的使用第三方軟件,如果第三方軟件有漏洞,比如像OpenSSL,像JAVA的運(yùn)行庫,圖形庫出現(xiàn)問題,VMware一樣會(huì)受到影響。
虛擬機(jī)逃逸,這個(gè)比較有意思,據(jù)我所知,大概有三種可能的方式從VM里面的操作系統(tǒng)逸出到外面的系統(tǒng)。以VMware為例:
首先是共享文件夾,今年已經(jīng)有兩個(gè)這樣的漏洞了,里面的操作系統(tǒng)可以通過HGFS的問題訪問讀寫外面主操作系統(tǒng)里的任何文件。
還有一種是通過DHCP Server的問題,這是VMware自帶的一個(gè)服務(wù),它存在一些整數(shù)溢出漏洞。如果在Guest OS里面的某個(gè)程序發(fā)送一些精心構(gòu)造的數(shù)據(jù)包,就會(huì)導(dǎo)致在主操作系統(tǒng)里執(zhí)行代碼。
最后一種方式,利用VMware中的用于支持客操作系統(tǒng)向外面的操作系統(tǒng)通訊的渠道,它是由一個(gè)特定的IO端口來實(shí)現(xiàn)的,端口號是5658。當(dāng)虛擬機(jī)監(jiān)控器捕獲到里面的操作系統(tǒng)對這個(gè)端口的訪問,它就會(huì)認(rèn)為是里面的Guest OS想要讓外面的程序提供某一種服務(wù)。比如說共享一下剪切板,拖拽一些文件,很多類似這樣的功能都是用這個(gè)后門端口來實(shí)現(xiàn)的。
這個(gè)后門包括很多命令,可以在下面這個(gè)URL找到這些命令的列表,這些命令會(huì)攜帶一些參數(shù)。如果這些參數(shù)有問題,是畸形的,而且外面的程序?qū)Υ蓑?yàn)證不足,就會(huì)引起在Host OS里執(zhí)行任意代碼。
除了上述虛擬機(jī)漏洞可能出現(xiàn)的地方,在虛擬機(jī)監(jiān)控器中也會(huì)出現(xiàn)問題。這些問題,一般來說是比較難以去調(diào)試和跟蹤的。為什么這么說?因?yàn)樘摂M機(jī)監(jiān)控器運(yùn)行的環(huán)境,用任何現(xiàn)有的一般調(diào)試器跟蹤不到,或者說根本跟不進(jìn)去。當(dāng)你進(jìn)行上下文切換的時(shí)候,切換到客操作系統(tǒng)空間時(shí),調(diào)試器不被映射,所以不能跟進(jìn)去。只有用一個(gè)相當(dāng)于硬件調(diào)試器的BOCHS,在里面再裝VMware才可以抓到主客兩個(gè)操作系統(tǒng)進(jìn)行上下文切換的動(dòng)作,來進(jìn)行調(diào)試。
可能用過VMware的人有時(shí)候會(huì)發(fā)現(xiàn),在客操作系統(tǒng)中執(zhí)行某一個(gè)程序以后,VMware會(huì)彈出一個(gè)對話框,告訴你虛擬機(jī)監(jiān)控器出現(xiàn)了問題,這時(shí)它就會(huì)自動(dòng)產(chǎn)生一個(gè)轉(zhuǎn)儲(chǔ)文件,用IDA可以加載這個(gè)文件進(jìn)行分析。我們怎么來保證每次都能產(chǎn)生這個(gè)文件呢?可以用下面我這個(gè)方法,寫一個(gè)程序,這個(gè)程序?qū)⒃L問一些沒有實(shí)現(xiàn)的虛擬設(shè)備,比如對IOAPIC的未實(shí)現(xiàn)的寄存器的讀寫,訪問將引起VMware的崩潰,VMware自身會(huì)產(chǎn)生一個(gè)轉(zhuǎn)儲(chǔ)文件,里面包含了VMM的狀態(tài)信息,包括VMM代碼全部在里面,可以進(jìn)行調(diào)試,由此來發(fā)現(xiàn)一些在VMM里面的漏洞。
VMM在執(zhí)行過程中,在主客操作系統(tǒng)會(huì)進(jìn)行切換,會(huì)擁有兩個(gè)獨(dú)立的空間,并有五個(gè)不同的上下文環(huán)境,大家有興趣的話調(diào)試一下VMware就可以看到這些東西。
對于VMM我有一些安全性上的考慮,如果我們把一段惡意代碼,用某種方法把它注入到VMM的空間里面,它就會(huì)在特權(quán)級0來執(zhí)行,
電腦資料
《虛擬機(jī)軟件的漏洞和虛擬機(jī)執(zhí)行環(huán)境的檢測與反檢測》(http://www.oriental01.com)。這個(gè)想法和今年一個(gè)國外研究者在BlackHat上講的如何通過DMA或者是利用某些漏洞的方式來改寫Hypervisor類似。大家可以從網(wǎng)絡(luò)上找到演講的PPT,非常精彩的一個(gè)演講,它的基本思想和我說到的這個(gè)有異曲同工的地方。如果你想運(yùn)行在ring0下,可以直接寫一段代碼并注入到VMM中,它將會(huì)自動(dòng)執(zhí)行。問題是怎么樣把代碼寫到VMM中,一個(gè)比較簡單的方法是你打開VMX這個(gè)進(jìn)程,VMM會(huì)被映射到這個(gè)進(jìn)程的內(nèi)存地址空間中,找到它以后把一些沒有用的函數(shù)替換掉,然后直接把代碼注入進(jìn)去,這段代碼就會(huì)在客操作系統(tǒng)環(huán)境中有機(jī)會(huì)執(zhí)行。
這是前面看到的,在主客操作系統(tǒng)切換后會(huì)有一些不同的上下文環(huán)境,只有VMM是真正運(yùn)行在ring0的,而Guest OS在VMM的控制下,他自己認(rèn)為自己是運(yùn)行在ring0,而實(shí)際上不是,這就是一種欺騙。TSS和IDT并不是由Guest OS直接操縱的,并且對于產(chǎn)生的異常VMM有的會(huì)自己處理,有的則會(huì)轉(zhuǎn)發(fā)給Guest OS去處理。GDT中的描述符,有一部分是給Guest OS使用的,有一部分是給VMM自己使用的。
2、虛擬機(jī)執(zhí)行環(huán)境的檢測與反檢測
為什么要進(jìn)行虛擬機(jī)執(zhí)行環(huán)境的探測?因?yàn)橛幸恍┎《?惡意程序不想在蜜罐里進(jìn)行發(fā)作,它們要是發(fā)現(xiàn)自己執(zhí)行在這樣的環(huán)境中,就不會(huì)把某些(惡意)動(dòng)作表現(xiàn)出來,所以實(shí)際上看不到它們在做什么。
我們?yōu)槭裁匆M(jìn)行反檢測?作為一個(gè)反病毒工程師,當(dāng)他發(fā)現(xiàn)什么病毒跡象都看不到的時(shí)候,是非常痛苦的,所以我們下面就教你如何使這些病毒樣本在VMware中進(jìn)行發(fā)作。
現(xiàn)在已知的虛擬機(jī)檢測方法有下面幾種:
檢測虛擬機(jī)軟件的一些進(jìn)程、注冊表項(xiàng),虛擬的硬件設(shè)備名稱,利用不可虛擬指令,或者通過計(jì)時(shí)的方法。
通過檢測VM軟件留下的印記或虛擬的硬件設(shè)備,這種方法原理比較簡單:VM軟件會(huì)在里面的客操作系統(tǒng)中安裝一些特定的程序,它有自己特定的一些進(jìn)程和注冊表項(xiàng)名稱。同時(shí),有些虛擬硬件設(shè)備名稱中的某些字樣是固定的。病毒和惡意程序通過直接檢測這些名稱,就可以知道自己身處在虛擬機(jī)環(huán)境中。
針對這種檢測方法,我們的反檢測可以使用一個(gè)API監(jiān)控器來看一下它到底是在檢測哪些東西。當(dāng)然,最好使用一個(gè)盡量底層實(shí)現(xiàn)一些的。
對于使用不可虛擬的指令的檢測,比如說像SIDT、SGDT這種指令在虛擬機(jī)里面執(zhí)行出來的效果和在真實(shí)的機(jī)器上執(zhí)行的結(jié)果是不一樣的。比如說SIDT它取到的IDT的地址和實(shí)際的Guest OS IDT的地址是不太一樣的(ring3下執(zhí)行)。如果你發(fā)現(xiàn)取得的地址非常高,你就能確定你處在一個(gè)虛擬環(huán)境中執(zhí)行。這個(gè)原因是由于VMware對于Guest OS ring3的執(zhí)行沒有采用二進(jìn)制翻譯,而是讓它直接執(zhí)行,所以它對這些指令沒辦法去進(jìn)行干預(yù)。
可以解決的辦法就是在VMware的配置文件里禁止加速(或打開模擬模式),這樣的話,VMware對ring3也會(huì)進(jìn)行二進(jìn)制翻譯,運(yùn)行會(huì)相對慢一些,雖然慢,但這種反檢測方法對于利用不可虛擬指令的檢測方法是非常有效的。
剛才我們講到VMware Backdoor Port,這同樣也是一個(gè)可以用來檢測VMware環(huán)境的一個(gè)方法。當(dāng)然我們也有相應(yīng)的對策,可以在同樣的配制文件里,通過使用一些配置項(xiàng),把某些Backdoors的調(diào)用禁止掉。當(dāng)然,有一些Backdoors調(diào)用不可以把它取消,否則機(jī)器就不能正常啟動(dòng),這點(diǎn)我們只能手動(dòng)地來進(jìn)行,在這個(gè)機(jī)器啟動(dòng)起來以后,再手工地把它們禁止掉。這是VMware VMX進(jìn)程中的GetMemSize函數(shù),在用紅色標(biāo)記的一行處可以把ESI寄存器的內(nèi)容清零,這樣利用這個(gè)Backdoor的檢測就會(huì)失效。
還有一種檢測方法,就是通過利用一些VMware模擬實(shí)現(xiàn)上的Bugs,就是VMM模擬出來的效果和真實(shí)執(zhí)行的效果可能有一些不同。報(bào)出來的漏洞其中有一個(gè)是VMware對于超過CS段界限的近程控制轉(zhuǎn)移,沒有進(jìn)行正確的模擬。應(yīng)該是先產(chǎn)生一個(gè)#GP(通用保護(hù)錯(cuò)誤),而EIP保持不變。而VMware模擬出來的卻是先改變了EIP,再產(chǎn)生#GP,這和真實(shí)環(huán)境有一些差異,所以可以用來檢測VMware的模擬模式。對于這種檢測方法,我們目前暫時(shí)還無能為力,只能等待VMware來修補(bǔ)這個(gè)模擬上的缺陷。
最后一種檢測方法是通過計(jì)時(shí)。有些指令必須通過VMM的模擬才可以執(zhí)行,所以說它這條指令的執(zhí)行所需要的CPU周期和真實(shí)的指令執(zhí)行是不一樣的。我們可以在這條指令執(zhí)行之前,讀一下TSC,執(zhí)行之后再讀一下,如果發(fā)現(xiàn)它的差值過大的話,這條指令就有可能被進(jìn)行了模擬。針對這種檢測方法,經(jīng)過我的實(shí)驗(yàn),有一個(gè)尚可接受的解決方案,就是可以通過配置文件的一個(gè)配置項(xiàng),讓它把VIRTUAL_RDTSC這個(gè)選項(xiàng)設(shè)置成False,這樣可以在一定程度上解決這個(gè)問題(需要使用直接執(zhí)行模式)。還有一個(gè)方法,就是把控制寄存器CR4的TSD位置位,這樣RDTSC這個(gè)指令在ring3下執(zhí)行就會(huì)產(chǎn)生異常,連接一個(gè)內(nèi)核調(diào)試器上去就能夠捕獲到這個(gè)異常,并繼續(xù)跟蹤下去。本文主要內(nèi)容整理自McAfee研究員孫冰先生在2008中國軟件安全峰會(huì)上的演講。