作者:無明@天玄安全實驗室
原文鏈接:https://mp.weixin.qq.com/s/LONOffiPKM2kSh74EmI8xA

一 漏洞簡介

前段時間,微軟公布Windows PrintNightmare兩個安全漏洞,分別為CVE-2021-1675CVE-2021-34527。公布幾天后,minikatz率先工具化集成了CVE-2021-1675和CVE-2021-34527的EXP。通過查看minikatz源碼,在CVE-2021-1675的EXP中,調用的RPC函數為RpcAddPrinterDriverEx;在CVE-2021-34527的EXP中,調用的RPC函數為RpcAsyncAddPrinterDriver。系統處理這兩個RPC函數后,都調用了YAddPrinterDriverEx函數,但是沒有對參數dwFileCopyFlags進行條件判斷。由此可設置APD_INSTALL_WARNED_DRIVER標志,使添加打印機驅動時,以高權限加載DLL。

image-20210714104510164

image-20210714104611566

(補丁前后對比:Windows PrintNightmare漏洞和補丁分析)

本文復現和分析的環境為 Windos Server 2016 Standard。通過afwu發布的EXP進行修改修改,復現CVE-2021-1675。復現文章也挺多,這里推薦一篇,不復現了。值得一提的是,在復現時,除了修改UNIDRV.DLL文件路徑以外,還需要修改pConfigFile賦值的路徑。如果采用1方式的路徑,由于在打開文件句柄之后執行驅動文件的更新,Old目錄還未生成,所以打開句柄時,找不到文件。采用2方式的路徑,文件句柄打開后,并未釋放處于占用狀態,導致后面加載DLL的時候,加載失敗。

image-20210714104805328

二 漏洞分析

1 動態查看CVE調用

1)CVE-2021-1675

通過Process Moniter抓取到EXP加載DLL時,執行過程中的堆棧調用。

image-20210714104840494

該漏洞點在于,調用YAddPrinterDriverEx函數時,沒有對參數dwFileCopyFlags做校驗,能夠使用APD_INSTALL_WARNED_DRIVER標志,導致后面對驅動合法性校驗失效,可以任意的加載DLL,并且為system權限。

image-20210714104951017

2)CVE-2021-34527

同樣通過process moniter抓取mimikatz中CVE-2021-34527的EXP執行數據,加載DLL的堆棧調用。

image-20210714105024830

通過地址可以找到,spoolsv.exe的調用的處理函數為NThreadingLibrary::TWorkCrew::tpSimpleCallback。

image-20210714105059900

繼續調用TFunction4::Run(__int64 a1)函數,最后調用YAddPrinterDriverEx。由此可知CVE-2021-34527和CVE-2021-1675,最終都是調用YAddPrinterDriverEx函數,只是RPC調用不同,所以可以說這個漏洞是CVE-2021-1675的補丁繞過。引發思考,如果再有不同RPC調用了YAddPrinterDriverEx函數,也是能繞過CVE-2021-1675補丁的。

image-20210714105135916

2 功能分析

EXP會通過RpcBindingSetAuthInfoExW函數,綁定句柄的認證,授權和安全質量的服務信息。當函數執行成功時,identity.User設置用戶名,代表了權限。如果是低權限用戶,執行ValidateObjectAccess函數后結果為0,administrator用戶的權限執行ValidateObjectAccess函數后結果為1。

image-20210714105206263

1)繞過ValidateObjectAccess檢測

CVE-2021-1675是邏輯漏洞,通過RPC添加打印機驅動程序的時候,參數dwFileCopyFlags(v7)的標志位APD_INSTALL_WARNED_DRIVER(0x8000)為1時,_bittest函數的結果為1,則v12被賦值為0,從而不執行ValidateObjectAccess的檢查。

image-20210714105259590

但在Server 12的中,a7的值是固定為1,一定會執行ValidateObjectAccess檢測。

image-20210714105324374

image-20210714105348314

2)檢查驅動基本信息

image-20210714105413311

MyName:檢查驅動名稱是否合法,ValidateDriverInfo的執行流程。

  • 檢查是否為本地文件
  • 核對初始化key
  • 校驗驅動文件的合法性

image-20210714105440049

image-20210714105459596

但是當dwFileCopyFlags含有 APD_INSTALL_WARNED_DRIVER(0x8000)標志位時,dwFileCopyFlags & 0x8000的結果為0x8000,0x8000取非后值為0,將會跳過驅動進一步的校驗。

image-20210714105521194

3)獲取文件句柄

v13的值是由dwFileCopyFlags的低8位取反后,右移4位,再跟1做與運算得出。v13的值決定CreateInternalDriverFileArray函數的第5個參數(a5)。經過計算,當dwFileCopyFlags低8位的值為0x1X時(X可為0-F中任意值),可以使a5為0。當a5的值為0,可以規避對驅動文件的合法性檢查。

通過CreateFile打開文件,得到3個文件句柄,并保存到DllAllocSplMem申請的空間中,用于后面文件更新使用。

image-20210714105600993

4)拷貝文件到驅動空間

dwFileCopyFlags的成員pConfigFile、pDataFile、pDriverPath分別保存了配置文件、數據文件、驅動文件的文件路徑。將上述成員中的文件路徑下的文件,移動到C:\Windows\System32\spool\drivers\x64\3下時,需要經過以下操作:

  • 文件句柄的文件信息進行核對
  • 將文件拷貝到C:\Windows\System32\spool\drivers\x64\3\new
  • 通過WaitRequiredForDriverUnload函數下的MoveNewDriverRelatedFiles函數,將spool\drivers\x64\3下的同名文件移動到spool\drivers\x64\3\old\x (x∈[1,3] ) 目錄下,再把spool\drivers\x64\3\new目錄文件,移動到spool\drivers\x64\3下,從而實現更新文件。

image-20210714105633247

5)更新驅動文件

通過更新Config文件,將spool\drivers\x64\3下新的配置文件加載起來。

image-20210714105655115

三 總結

CVE-2021-1675繞過用戶權限檢查,可以低用戶的權限添加打印機驅動,由于是RPC執行打印機添加驅動,所以也能稱為RCE漏洞。不過實現RCE條件是比較苛刻的,至少需要有域控的普通用戶,且還需要有共享目錄。個人認為該漏洞可用于持久化的操作,得到域控的administrator的賬號和密碼時,在有共享目錄、能訪問到域控的情況下,打上6月份的補丁,也能遠程的加載共享目錄下的DLL。

四 參考鏈接

[1]https://www.freebuf.com/vuls/279876.html

[2]https://422926799.github.io/posts/c257aa46.html

[3]https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/b96cc497-59e5-4510-ab04-5484993b259b

[4]https://github.com/afwu/PrintNightmare


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1635/