作者:
百度安全攻防實驗室
·
2014/10/23 16:48
0x00 漏洞背景
近日CrowdStrike團隊發現Win64bit2008 R2伺服器系統上存在可疑攻擊行為,並捕獲到相關樣本。百度安全攻防實驗室根據外界放出的poc進行了研究,漏洞成因和利用細節如下。 此類提權漏洞曾經出現在2011年的8個CVE中(CVE-2011-1878~CVE-2011-1885),由挪威安全公司Norman的核心漏洞達人TarjeiMandt(@kernelpool)報告的(微軟公告編號MS11-054),其相關的細節未被公開。 2013年,MJ0011曾經因分析藍色畫面崩潰dump檔案,重現了此類漏洞並編寫了poc和分析文章。
此次漏洞poc執行後的截圖如下:
以普通使用者許可權執行poc成功後,一個system許可權的cmd程式被建立出來,說明提權成功,已從普通使用者許可權提升到了系統system最高許可權。
0x01 漏洞分析
漏洞主要發生在win32k!xxxTrackPopupMenuEx函式中,該函式用於彈出一個選單,是同步的,也就是說只有等選單彈出並選擇之後才返回的,漏洞發生的根本原因在於可以讓該函式執行過程中中斷一次並執行ring3程式碼再返回繼續執行;
以下是來自win32k!xxxTrackPopupMenuEx函式中部分程式碼:
1.經過一系列的初始化工作後,呼叫win32k!xxxMNLoop進入選單迴圈等待選擇:
2.跟進win32k!xxxMNLoop ,win32k!xxxMNLoop在進入真正的while迴圈之前會呼叫win32k!xxxHandleMenuMessages :
3.繼續跟進win32k!xxxHandleMenuMessages ,其會事先呼叫win32k!xxxMNFindWindowFromPoint來得到選單視窗物件指標ptagWND,之後再呼叫win32k!xxxSendMessage給選單視窗傳送訊息:
4.繼續跟進win32k!MNFindWindowFromPoint,其會呼叫win32k!xxxSendMessage給控制程式碼視窗傳送訊息來確定選單視窗座標,可以看到訊息值為:0x1EB(MN_FINDWINDOWFROMPOINT)
5.POC在應用層安裝了一個WH_WNDPROC鉤子,將這個訊息(MN_FINDWINDOWFROMPOINT)給攔截下來,並在其視窗處理執行緒上下文中呼叫了EndMenu讓選單視窗銷燬,下面是樣本中的應用層程式碼:
Wh_wnd_proc:
Wnd_proc_long:
之所以在鉤子函式還要多一步透過SetWindowLong設定視窗函式,在視窗函式里再呼叫EndMenu是因為得在視窗處理函式執行緒的上下文空間中呼叫EndMenu才有意義(每個視窗都有與之關聯的pti--tagTHREADINFO).
6.可以看到,由於win32k!xxxSendMessage是非同步的,呼叫完應用層程式碼(即選單視窗已經銷燬)返回到win32k!xxxMNFindWindowFromPoint, 此時由於失敗,win32k!xxxMNFindWindowFromPoint返回0xFFFFFFFB, 回到win32k!xxxHandleMenuMessages
7.回到win32k!xxxHandleMenuMessages之後,問題來了,原因就在於其在檢查win32k!xxxMNFindWindowFromPoint函式的返回值ptagWnd的合法性時的不嚴謹,便直接呼叫win32k!xxxSendMessage(ptagWnd …….);
8.由於呼叫xxxSendMessage(ptagWnd ,….)的引數ptagWnd為0xFFFFFFFB, 在函式內會取tagWND.lpfnWndProc欄位,並呼叫該函式,該欄位的偏移為: 0x60 , 即地址0Xfffffffb+0x60=0x5B,所有在樣本中事先申請了0頁面記憶體,並向0x5B處寫入了shellcode地址,從而實現了exploit.
至此,上面就是整個漏洞的流程分析了。
9.最後給出一份直觀的流程圖:
下面透過除錯來重現整個情景;
0x02 漏洞重現與除錯
1.應用層與核心層同時進行除錯,核心層下條件斷點
win32k!xxxFindWindowFromPoint :
bpwin32k!xxxFindWindowFromPoint ".if poi(poi(poi(fs:0x124)+0x50)+0xb4) = 0x130 {} .else {gc}" ----0x130為程式ID
應用層單步到分配0頁面構造Fake TagWnd時,檢視0頁面:
2.應用層繼續單步到call TrackPopMenu時.
1.應用層F8單步步過call TrackPopMenu時, 核心層win32k!xxxFindWindowFromPoint斷下,可以看到其呼叫棧如下
2.win32k!xxxFindWindowFromPoint單步到呼叫xxxSendMessage(MN_FINDWINDOWFROMPOINT)時,並在應用層的視窗函式Wnd_proc_long下斷點:
3.F10 步過call xxxSendMessage時,應用層Wnd_proc_long斷下:
如果是0x1EB(MN_FINDWINDOWFROMPOINT)訊息,則進入到如下:
4.回到核心層單步從xxxMNFindWindowFromPoint返回到xxxHandleMenuMessages,此時:
5.xxxHandleMessages繼續執行,單步到呼叫xxxSendMessage()時:視窗物件ptagWnd為xxxMNFindWindowFromPoint()返回值:0xFFFFFFFB :
6.此時檢視patgWnd -00xFFFFFFFB:
7.下斷點“ba r4 0x5c“ ,”bp 0x00d21830” , g執行 ,來到斷點處:
至此可看到,ShellCode已執行成功~~~~~;
0x03 參考連結
- crowdstrike 《CrowdStrike Discovers Use of 64-bit Zero-Day Privilege Escalation Exploit (CVE-2014-4113) by Hurricane Panda》
- 微軟 《Microsoft 安全公告 MS14-058 - 嚴重》
- MJ0011 《從Dump到POC系列一:Win32k核心提權漏洞分析》
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!