安全動(dòng)態(tài)

aswSnx.sys中的內(nèi)核分頁池緩沖區(qū)溢出漏洞分析(CVE-2015-8620)

來源:聚銘網(wǎng)絡(luò)    發(fā)布時(shí)間:2016-03-02    瀏覽次數(shù):
 

信息來源:FreeBuf   

近日,Nettitude安全人員在Avast Virtualization內(nèi)核模式驅(qū)動(dòng)(aswSnx.sys)中發(fā)現(xiàn)一個(gè)安全漏洞,使用普通賬戶登錄的本地攻擊者可利用該漏洞提升權(quán)限,以系統(tǒng)權(quán)限執(zhí)行任意代碼,進(jìn)而完全控制受影響主機(jī)。

AvastVirtualization(aswSnx.sys)驅(qū)動(dòng)用于處理所有Avast Windows產(chǎn)品的“Sandbox”和“DeepScreen”功能。

受影響產(chǎn)品及版本

Avast InternetSecurity v11.1.2245

Avast ProAntivirus v11.1.2245

Avast Premierv11.1.2245

Avast FreeAntivirus v11.1.2245

上述產(chǎn)品中的早期版本也可能受到影響。

技術(shù)細(xì)節(jié)

AvastVirtualization內(nèi)核模式驅(qū)動(dòng)(aswSnx.sys)沒有驗(yàn)證用戶空間的IOCTL請(qǐng)求中的Unicode文件絕對(duì)路徑的長度,而該路徑長度會(huì)被復(fù)制到固定大小的分頁池內(nèi)存中,攻擊者可以借助特制的代碼導(dǎo)致內(nèi)核分頁池分配的數(shù)據(jù)塊溢出,并損壞其相鄰的攻擊者控制的內(nèi)核對(duì)象,如圖一。

Figure-1.-Attacker-Controlled-Directory-Object-1030x240.png

圖一 攻擊者控制的內(nèi)核對(duì)象

圖二顯示了aswSnx.sys驅(qū)動(dòng)對(duì)nt!memmove函數(shù)的調(diào)用,但是這一過程沒有驗(yàn)證數(shù)據(jù)是否按可用大小被復(fù)制到分頁池的數(shù)據(jù)塊中。這些信息取自10.x版本,同樣適用于11.x版本。

Figure-2.-The-Bug-1030x411.png

圖二 漏洞原因

堆緩沖區(qū)溢出的利用

在處理基于緩沖區(qū)的動(dòng)態(tài)內(nèi)存分配,也就是基于堆的緩沖區(qū)溢出時(shí),首先需要預(yù)測(cè)緩沖區(qū)溢出發(fā)生的位置,以便于控制該漏洞的執(zhí)行。這在處理內(nèi)核地址空間的代碼運(yùn)行時(shí)是十分重要的,因?yàn)槿绻檬?,系統(tǒng)可能會(huì)出現(xiàn)故障。損壞一個(gè)不可控制的隨機(jī)內(nèi)核對(duì)象實(shí)在不是一個(gè)明智的選擇。

為了達(dá)到這個(gè)目的,面臨的另一個(gè)挑戰(zhàn)就是,根據(jù)數(shù)據(jù)塊的大小創(chuàng)建一個(gè)合理的動(dòng)態(tài)內(nèi)存分配布局,用于溢出的產(chǎn)生。如果已知數(shù)據(jù)塊的大小,那么我們就可以沒有更多限制的實(shí)現(xiàn)這個(gè)目的。然而,當(dāng)我們處理固定掉的數(shù)據(jù)塊(在該實(shí)例中為0×418字節(jié)),很難找到一個(gè)合適大小的對(duì)象導(dǎo)致堆溢出。想要克服該問題的人可以參考此處。

溢出內(nèi)核分頁池

私有命名空間是創(chuàng)建可控大小的分頁池對(duì)象的有效方法。通過創(chuàng)建多個(gè)帶有邊界描述符名稱的、特制長度的私有命名空間,我們可以獲得以下內(nèi)存布局:

Figure-3.-Heap-Spraying-1030x284.png

圖三 堆溢出#1

因此,在這種情況下,我們并不能控制分頁池?cái)?shù)據(jù)塊的大小,但是,我們可以控制分頁池對(duì)象的大小,如圖三所示,指定一個(gè)內(nèi)存頁(4KB)來顯示分頁池的開始。

也就是說,我們可以創(chuàng)建一個(gè)控制內(nèi)存頁開始的對(duì)象,然后就可以擁有一個(gè)0x3b8字節(jié)大小的可用空間,和兩個(gè)一直到內(nèi)存頁結(jié)束都可以控制的相鄰對(duì)象。由于邊界描述符名稱的長度可變,甚至可以使用可控對(duì)象占據(jù)整個(gè)內(nèi)存頁。

Figure-4.-Heap-Spraying-2-1030x283.png

圖四 堆溢出#2

但是,由于可溢出的緩沖區(qū)是固定大?。?×418字節(jié))的,并且可以以內(nèi)存頁中最后分配的對(duì)象為目標(biāo),因此我們完全不用考慮page_allocation_base + 0×418中的空間內(nèi)容。也就是說,我們?nèi)匀豢梢栽试S內(nèi)核使用該空間。

通過使用ProcessExplorer,我們可以更清楚地看到堆溢出后的分頁池內(nèi)存分配情況,如圖五。

Figure-5.-Pagedpool-memory-allocations-layout.png

圖五 分頁池的內(nèi)存分配布局

圖六為堆溢出后的內(nèi)存頁的布局情況。我們利用該漏洞導(dǎo)致了SnxN緩沖區(qū)的溢出,并損壞了相鄰對(duì)象。

Figure-6.-Heap-Spraying-3-1030x241.png

圖六 堆溢出#3

私有命名空間不僅可以使攻擊者控制分頁池大小,而且可以通過重寫NAMESPACE_DESCRIPTOR結(jié)構(gòu)體的LIST_ENTRY字段中的指針來控制執(zhí)行情況。該字段將NAMESPACE_DESCRIPTOR結(jié)構(gòu)體鏈接到系統(tǒng)中所有可用私有命名空間的列表。

假定我們已經(jīng)成功損壞了特定私有命名空間的NAMESPACE_DESCRIPTOR結(jié)構(gòu)體的LIST_ENTRY字段。

Figure 7. Not-So-Safe Unlinking (Win 7 SP1)

圖七 不太安全的Unlinking功能(Win 7 SP1)

但是在Windows 8及更高版本中,由于安全的LIST_ENTRY結(jié)構(gòu)體的使用,該方法并不能奏效。

Figure 8. Safe Unlinking (Win 8.1)

圖八 安全的Unlinking功能(Win 8.1)

圖九為私有命名空間的目錄對(duì)象的損壞前后對(duì)比??梢钥吹?,NAMESPACE_DESCRIPTOR結(jié)構(gòu)體的LIST_ENTRY字段已經(jīng)使用用戶空間地址(0×41414141)成功重寫。

Figure-9.-Directory-Object-of-PrivateNamespace-–-Before-and-after-corruption..png

圖九 目錄對(duì)象的損壞前后對(duì)比

控制EIP

成功損壞目錄對(duì)象后,接下來就是控制漏洞的執(zhí)行了。使用write-what-where條件重寫HalDispatchTable的函數(shù)指針,尤其是存儲(chǔ)在HalDispatchTable+sizeof(ULONG_PTR)這的hal!HaliQuerySystemInformation函數(shù),然后通過調(diào)用ntdll!NtQueryIntervalProfile將漏洞執(zhí)行重定向到我們自己的負(fù)載。

函數(shù)調(diào)用序列為ntdll!NtQueryIntervalProfileà nt!NtQueryIntervalProfile à nt!KeQueryIntervalProfileà call   [nt!HalDispatchTable+sizeof(ULONG_PTR)](0×41414141)。

目前我們可以做到的是重寫內(nèi)核地址空間中的任意指針,并通過劫持攻擊控制EIP。但是這是遠(yuǎn)遠(yuǎn)不夠的。

write-what-where條件在斷開私有命名空間和系統(tǒng)中可用私有命名空間的連接時(shí)發(fā)生,也就是我們?cè)陉P(guān)閉處理器或者使用特定私有命名空間中的目錄對(duì)象時(shí)。可以通過調(diào)用ClosePrivateNamespace或CloseHandle來實(shí)現(xiàn)該過程。

需要注意的是,為了堆溢出的發(fā)生,分頁池的數(shù)據(jù)塊頭已經(jīng)損壞,一旦釋放數(shù)據(jù)塊頭中的任意對(duì)象,都會(huì)觸發(fā)SoD,因?yàn)閮?nèi)核會(huì)對(duì)比之前對(duì)象的實(shí)際大小和釋放的數(shù)據(jù)大小。

我們可以通過隔離這兩個(gè)階段來避開這個(gè)問題。我們是通過調(diào)用ZwDeletePrivateNameSpace而觸發(fā)的what-where條件,這會(huì)導(dǎo)致連接斷開,但是并不是釋放對(duì)象內(nèi)存。我們可以在post-exploitation清理階段重新保存LIST_ENTRY字段。

最后,我們可以安全地修復(fù)損壞的目錄對(duì)象,和NAMESPACE_DESCRIPTOR結(jié)構(gòu)體,以保證系統(tǒng)不會(huì)報(bào)錯(cuò)。

廠商修復(fù)

Figure-10.-Vulnerable-Function.png

圖十 存在漏洞的函數(shù)

Figure-11.-Fixed-Function.png

圖十一 修復(fù)的函數(shù)

由圖可以發(fā)現(xiàn),修復(fù)的函數(shù)中添加了一個(gè)調(diào)用子程序的call sub_C161C指令,它的目的是驗(yàn)證復(fù)制到固定大小的內(nèi)存中的數(shù)據(jù)大小,如果大小不合適,程序會(huì)調(diào)用ExAllocatePoolWithTag函數(shù)重新分配一個(gè)合適的空間,可以安全地保存數(shù)據(jù)。

*原文地址:nettitude,F(xiàn)B小編vul_wish編譯,轉(zhuǎn)載請(qǐng)注明來自FreeBuf黑客與極客(FreeBuf.COM)

 
 

上一篇:國家信息安全漏洞共享平臺(tái)(CNVD)周報(bào)-2016年第8期

下一篇:網(wǎng)絡(luò)安全信息與動(dòng)態(tài)周報(bào)-2016年第7期(點(diǎn)擊下載)