因為你安全了,所以你危險了——空指標引用

Gcow安全團隊發表於2020-03-26

因為你安全了,所以你危險了——空指標引用

1.本文章屬於系列文章《因為你安全了,所以你危險了》中的第一篇
2.本篇文章的作者是Gcow安全團隊複眼小組的晏子霜,未經允許禁止轉載
3.本篇文章需要你對GDI子系統有一定了解,最好閱讀過部分關於Windows顯示驅動,印表機驅動,以及調色盤這一塊的原始碼.並對DDI函式有一定了解,以及編寫Windows Kernel Exploit的能力
(故對一些不涉及這領域或者剛剛入門這一領域的看官會有點吃力)
4.本篇文章一共1300字,圖11張 預計閱讀時間9分鐘
5.該文章僅逆向ulAnimatePalette函式,但同樣的思路在老版本Windows中可挖掘到多個空指標引用漏洞,均為Nday(不過修復也是一次性修復完畢)

0x00 前言

Windows Vista的時候,微軟將印表機驅動從核心態移動到了使用者態,這樣可以解決相當一部分印表機驅動導致的漏洞,因為第三方開發的驅動的安全性有待提高.

 

這樣做好處的顯而易見的,減少了許多第三方開發的印表機驅動的漏洞,但是也帶來了弊端,透過Hook圖形裝置驅動介面Or印表機驅動介面,為安全研究員們擴充套件了一個新的攻擊面,這就有些得不償失了.

 

因此本系列文章將從簡入深的講解多個由安全性提高轉化成安全性”降低”的多個漏洞,其中包含但不限於(空指標引用,記憶體越界讀寫)

0x01 圖形驅動

建立圖形驅動程式必須要建立的函式如下

 

圖片1

 

這些函式是必須要建立的,如果為空,則在核心中建立物件不可能成功.

 

透過CreateDC 指定名稱可以建立一個關於印表機裝置的上下文環境,我們閱讀原始碼後發現他會回撥印表機DDI函式中的DrvEnablePDEV,並傳遞了多個重要資料結構,我們可以Hook DrvEnablePDEV函式來修改函式執行過後的結果,當其返回核心時,我們即可控制函式的執行流程了.

 

圖片2

 

不過在早期的Windows 中,安全性並沒有現在這麼高,很多安全保護都是不存在的,就比如說禁止使用者態從0頁分配記憶體,我們就可以利用他來達到本地許可權提升的目的.

GreAnimatePalette函式分析

AnimatePalette函式置換指定邏輯調色盤中的顏色項,在Win32k中該函式呼叫了實現函式XEPALOBJ::ulAnimatePalette來實現功能.

 

但是在早期的Windows7中,該函式存在空指標引用漏洞,利用該漏洞我們可以達到本地許可權提升的目的.

 

我們可以使用使用者態包裝好的AnimatePalette函式來呼叫到GreAnimatePalette函式或者從ShaDownSSDT中搜素編號呼叫NtGdiDoPalette函式都可以執行到XEPALOBJ::ulAnimatePalette.

 

由於該函式是XEPALOBJ類中的函式,所以存在一個This指標,通常為ecx,此處也是一樣,ecx儲存著指向PALETTE結構的指標.

 

該函式首先判斷了傳入的iStart是否大於顏色項的總個數,如果大於則結束函式

 

圖片3

 

接著判斷iStart+ cEntry 是否大於cEntries,如果大於則將cEntry設定為cEntries-iStart.

 

圖片4

 

判斷是否為某個DC中的調色盤,判斷Palette.cRefhpal是否存在,不存在則跳出迴圈.

 

圖片5

 

判斷Palete->GdiInfo.flRaster & RC_PALETTE是否為真,如果為假,則跳出迴圈.

 

圖片6

 

最後判斷 Palete->ptransCurrent是否存在,如果不存在則跳出迴圈,存在則初始化兩個區域性變數,一個指向Palete->ptransCurrent,另外一個指向Palete->ptransCurrent->ajVector[iStart].

 

圖片7

 

下面是個迴圈,大致意思就是從函式的第三個引數(ppalSrc)複製內容到Palette.pFirstColor[iStart]中,並且判斷Palete->ptransCurrent是否為真,如果為真則讀取Palete->ptransCurrent->ajVector[iStart]處的內容當作偏移,來寫入到palSurf.pFirstColor[Palete->ptransCurrent->ajVector[iStart]]中.(寫入內容為*ppalSrc)

 

圖片8

 

結束迴圈後,函式會再次判斷Palete->ptransCurrent 是否存在,Palete->GdiInfo.flRaster & RC_PALETTE是否為真以及判斷Palete->fs& PDEV_DISABLED是否為假,如果為False,則會從PEDV->apfn[]表中尋找需要的函式函式並跳轉執行.

 

圖9

 

是不是很熟悉PPFNDRV,這個上文是不是回撥過DrvEnablePDEV,這裡是要回撥DrvSetPalette嗎?

 

理論上來說是的,但是實際上來說,上文儲存了一個必須建立圖形驅動程式必須要建立的函式表,其中並沒有DrvSetPalette,因為這個函式是可選的.

 

圖10

  • 問題來了,如果不存在這個函式,但是函式呼叫了他,會出現什麼問題呢?

  • 答對了,空指標引用,在老版本Windows中並沒有對函式指標是否正確進行驗證,所以如果函式指標指向0,依然會Call過去,這樣就造成了一個空指標引用的漏洞,我們只要在0處申請記憶體,填充程式碼,在同一程式上下文中即可觸發該引用,讓作業系統執行我們的程式碼.

圖11

相關文章