一、前言
在研究繞過(guò)UAC(用戶賬戶控制)的新型技術(shù)時(shí),我發(fā)現(xiàn)了一種新的繞過(guò)方法。雖然微軟并不認(rèn)為UAC屬于安全邊界范疇,但我們依然將這個(gè)問(wèn)題反饋給微軟,也愿意在此處與大家分享。我們已經(jīng)在Windows 10 Build 17134上測(cè)試過(guò)這種方法。在深入分析繞過(guò)方法之前,本文首先將簡(jiǎn)要回顧一下UAC的背景知識(shí),以便幫助大家了解UAC的內(nèi)部工作原理。
二、背景知識(shí)
當(dāng)隸屬于Administrators組的用戶想執(zhí)行需要高權(quán)限的某個(gè)進(jìn)程時(shí),系統(tǒng)就會(huì)彈出UAC提示窗口,確認(rèn)用戶提升進(jìn)程權(quán)限。然而,Windows系統(tǒng)中并非所有的特權(quán)可執(zhí)行程序都會(huì)彈出UAC窗口,某些例外情況下并不會(huì)彈出該窗口,而會(huì)“自動(dòng)提升”目標(biāo)可執(zhí)行文件的權(quán)限,這樣就能繞過(guò)UAC機(jī)制(許多人肯定會(huì)感到非常驚訝)。
系統(tǒng)對(duì)這類(lèi)受信任的可執(zhí)行文件做了其他一些安全檢查,以確保這些文件的確可信,不會(huì)被攻擊者濫用。之前的UAC繞過(guò)技術(shù)中廣泛利用了這種方法,本文的利用思路也不例外。然而,為了成功繞過(guò)UAC,我們需要在攻擊過(guò)程中跳過(guò)一些“坑”。如果我們的可執(zhí)行文件想實(shí)現(xiàn)“自動(dòng)提權(quán)”,就必須遵循某些強(qiáng)制性條件。為了分析整個(gè)過(guò)程,這里我將給大家展示appinfo.dll(處理權(quán)限提升的AIS服務(wù),屬于UAC的核心組件之一)中的一些反匯編代碼片段。
條件1:autoElevate為T(mén)rue
當(dāng)出現(xiàn)程序權(quán)限提升情況時(shí),系統(tǒng)就會(huì)對(duì)AIS(appinfo.dll)執(zhí)行RPC調(diào)用,將目標(biāo)可執(zhí)行文件的路徑作為調(diào)用參數(shù)。隨后,該服務(wù)會(huì)映射目標(biāo)可執(zhí)行文件的內(nèi)容以便后續(xù)讀取,系統(tǒng)會(huì)嘗試讀取可執(zhí)行文件的manifest信息,解析autoElevate字段(如果該字段存在)的值。

圖1. 讀取可執(zhí)行文件的Manifest信息解析可能存在的autoElevate值
如果該字段存在并且值為T(mén)rue,那么系統(tǒng)會(huì)認(rèn)為這是一個(gè)可以自動(dòng)提升權(quán)限的可執(zhí)行文件,隨后執(zhí)行權(quán)限提升,繞過(guò)UAC提示框(前提是該文件已通過(guò)另一個(gè)限制條件,下文會(huì)提到這個(gè)問(wèn)題)。然而,這種autoElevate規(guī)則依然存在一個(gè)例外情況。無(wú)論manifest的具體內(nèi)容是什么,如果文件名匹配某個(gè)白名單中的EXE名稱(chēng),系統(tǒng)也會(huì)將其當(dāng)成具備“自動(dòng)提升權(quán)限的”可執(zhí)行文件。如下圖所示,代碼中在manifest檢查過(guò)程后有一個(gè)bsearch調(diào)用,檢查文件名是否匹配白名單可執(zhí)行文件名列表。如果文件名滿足條件,那么就會(huì)自動(dòng)提升權(quán)限,無(wú)視manifest數(shù)據(jù)。

圖2. bsearch調(diào)用測(cè)試可執(zhí)行文件名是否匹配自動(dòng)提升權(quán)限的exe文件名
硬編碼的白名單文件名部分列表如下:
cttunesvr.exe
inetmgr.exe
migsetup.exe
mmc.exe
oobe.exe
pkgmgr.exe
provisionshare.exe
provisionstorage.exe
spinstall.exe
winsat.exe’
條件2:經(jīng)過(guò)簽名
如果UAC請(qǐng)求所對(duì)應(yīng)的二進(jìn)制文件已配置為“自動(dòng)提升權(quán)限”,那么系統(tǒng)就會(huì)使用wintrust!WTGetSignatureInfo來(lái)檢查文件的簽名。這意味著攻擊者無(wú)法簡(jiǎn)單地構(gòu)造manifest信息或者可執(zhí)行文件名來(lái)實(shí)現(xiàn)自動(dòng)權(quán)限提升,因?yàn)楣粽叩奈募芸赡軟](méi)有經(jīng)過(guò)正確的簽名處理,并且很有可能無(wú)法滿足第3個(gè)條件(即從可信目錄中執(zhí)行)。
條件3:從可信目錄中執(zhí)行
實(shí)現(xiàn)自動(dòng)權(quán)限提升的第3個(gè)條件:目標(biāo)可執(zhí)行文件位于“可信目錄”中,比如C:\Windows\System32。如圖3所示,AIS會(huì)檢查權(quán)限提升請(qǐng)求所對(duì)應(yīng)的文件路徑,在本例中,“可信目錄”為C:\Windows\System32。

圖3. 檢查可信路徑
既然本文的名字為“如何通過(guò)模擬可信目錄繞過(guò)UAC”,大家應(yīng)該能猜到我們下文的內(nèi)容了。
三、繞過(guò)UAC
在背景知識(shí)中我們提到過(guò),如果滿足如下條件,則可以實(shí)現(xiàn)權(quán)限自動(dòng)提升(UAC繞過(guò)):
1、配置為權(quán)限自動(dòng)提升;
2、經(jīng)過(guò)正確簽名;
3、從可信目錄(C:\Windows\System32)中執(zhí)行。
在檢查可信目錄時(shí),Appinfo.dll(AIS)會(huì)使用RtlPrefixUnicodeString這個(gè)API來(lái)檢查目標(biāo)可執(zhí)行文件路徑是否以C:\Windows\System32\作為前綴。這是非常可靠的檢查過(guò)程,因?yàn)橄到y(tǒng)會(huì)檢查目標(biāo)可執(zhí)行文件的標(biāo)準(zhǔn)路徑。為了繞過(guò)這個(gè)檢查步驟,我構(gòu)造了一個(gè)目錄:C:\Windows \(請(qǐng)注意Windows后面跟著一個(gè)空格符)。當(dāng)然這個(gè)路徑并不能繞過(guò)RtlPrefixUnicodeString,并且由于Windows不允許在目錄名末尾附加一個(gè)空格符,因此這并不是一個(gè)有效的目錄名(或者至少不是一個(gè)“友好的”目錄名)。然而,如果我們使用CreateDirectory API,然后在待創(chuàng)建的目錄名前加上\\?\,那么我們就可以繞過(guò)系統(tǒng)的一些命名規(guī)則,將目錄創(chuàng)建請(qǐng)求直接發(fā)送給文件系統(tǒng)。

圖4. 調(diào)用API
這將導(dǎo)致系統(tǒng)中出現(xiàn)一個(gè)尷尬的目錄,能夠與真正的C:\Windows\目錄和諧共存(然而我們不能在Windows資源管理器中對(duì)這個(gè)目錄做任何操作)。

圖5. 目錄刪除請(qǐng)求無(wú)法成功,也無(wú)法通過(guò)重命名來(lái)刪除末尾的空格符
現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)C:\Windows \目錄,我們可以在該目錄中創(chuàng)建一個(gè)system32目錄,然后將C:\Windows\System32目錄中經(jīng)過(guò)簽名的、能夠自動(dòng)提升權(quán)限的可執(zhí)行應(yīng)用拷貝到該目錄中。這里我選擇拷貝winSAT.exe(這是位于自動(dòng)提升權(quán)限白名單中的一個(gè)Windows可執(zhí)行文件)。當(dāng)我們嘗試運(yùn)行C:\Windows \System32\winSAT.exe時(shí),appinfo.dll在檢查可信目錄時(shí)會(huì)先調(diào)用如下API(如圖6所示)。這一點(diǎn)非常關(guān)鍵,這也是我們?yōu)槭裁茨芾@過(guò)UAC的原因所在。
圖6. API調(diào)用過(guò)程
當(dāng)請(qǐng)求權(quán)限提升過(guò)程將這個(gè)尷尬的目錄發(fā)送到AIS時(shí),該路徑會(huì)傳遞給GetLongPathNameW函數(shù),該函數(shù)會(huì)將該路徑轉(zhuǎn)換回C:\Windows\System32\winSAT.exe(刪除了空格符)。非常完美,現(xiàn)在這個(gè)路徑已經(jīng)變成了可信目錄(可以通過(guò)RtlPrefixUnicodeString的檢查)。更加完美的是,當(dāng)完成可信目錄檢查后,后續(xù)檢查(以及最終的權(quán)限提升請(qǐng)求)依然會(huì)使用原始的文件名(帶有空格符)。這樣我們就能通過(guò)其他所有檢查,最終讓appinfo.dll執(zhí)行我們復(fù)制的winSAT.exe,自動(dòng)提升權(quán)限(因?yàn)樵撐募呀?jīng)過(guò)正確簽名,并且處于自動(dòng)提升權(quán)限的白名單中)。
為了通過(guò)這種方法真正執(zhí)行攻擊者的代碼,我將一個(gè)偽造的WINMM.dll(該dll會(huì)被winSAT.exe加載)釋放到了C:\Windows \System32\中,通過(guò)本地dll劫持技術(shù)執(zhí)行我們的代碼。完整的流程如下圖所示。

圖7. 完整利用過(guò)程
完整代碼可以訪問(wèn)Github下載。
|