主頁 > 企業開發 > CVE-2021-1732 LPE漏洞分析

CVE-2021-1732 LPE漏洞分析

2021-12-06 21:57:59 企業開發

概述

  CVE-2021-1732是一個發生在windows內核win32kfull模塊的LPE漏洞,并且由于創建視窗時呼叫win32kfull!xxxCreateWindowEx程序中會進行用戶模式回呼(KeUserModeCallback),從而給了用戶態行程利用的機會,

  該漏洞由安恒資訊在2020年12月在野外攻擊樣本中發現,在2021年2月份公開披露,相關樣本在2020年APT組織蔓靈花針對國內的一次攻擊中作為提權組件被發現,

分析

  Windows中創建視窗時,會呼叫API CreateWindowEx,最終在內核會呼叫至win32kfull!xxxCreateWindowEx,在win10 1909上除錯時呼叫堆疊回溯如下:

  ... ...     win32kfull!xxxCreateWindowEx+0x1259

  ... ...     win32kfull!NtUserCreateWindowEx+0x6a0

  ... ...     nt!KiSystemServiceCopyEnd+0x25

  ... ...     win32u!NtUserCreateWindowEx+0x14

  ... ...     USER32!VerNtUserCreateWindowEx+0x211

  ... ...     USER32!CreateWindowInternal+0x1b4

  ... ...     USER32!CreateWindowExW+0x82

  win32kfull模塊的xxxCreateWindowEx函式為最終負責視窗物件創建的程序,CVE-2021-1732主要是在win32kfull!xxxCreateWindowEx呼叫win32kfull! xxxClientAllocWindowClassExtraBytes進行視窗擴展記憶體時觸發,xxxClientAllocWindowClassExtraBytes函式中會呼叫KeUserModeCallback進行用戶模式回呼,以在用戶模式執行回呼,該函式中指定的回呼ApiNumber為0x7B,即為user32! _xxxClientAllocWindowClassExtraBytes,相關回呼函式表可在PEB->KernelCallBackTable中查看,

  查看user32! _xxxClientAllocWindowClassExtraBytes,只是在用戶模式當前行程堆中分配了指定大小的空間,并將分配的堆地址通過NtCallbackReturn傳回內核,

  由于用戶模式回呼函式的執行是在用戶態進行,因此用戶可以直接從行程中對該函式進行Hook,改變執行流程,

  分析時使用POC為https://github.com/KaLendsi/CVE-2021-1732-Exploit,經過和原始樣本的比對,可以發現該POC是對原始樣本的完全還原,僅是在部分變數名含義上不正確,

  漏洞首先對user32! _xxxClientAllocWindowClassExtraBytes進行Hook,在之后行程每次呼叫CreateWindowExW創建視窗時將會走到Hook函式處,替換后的KernelCallBackTable如下所示:

  接著創建多個普通視窗,后續都會經過Hook函式,對于普通視窗,Hook函式仍舊按照舊流程,為其呼叫user32! _xxxClientAllocWindowClassExtraBytes,判斷依據是傳入的引數值,即tagWnd. cbwndExtra,相關細節在創建利用視窗時再說,

  不過雖然普通視窗的創建仍是走的正常流程,但是會記錄每個創建視窗的物件地址,視窗物件地址利用HMValidateHandle進行泄露,該函式未匯出,不過可以通過呼叫了該函式的其他API進行搜尋,比如IsMenu,

  呼叫方式為HMValidateHandle(HANDLE h, int type),傳入視窗句柄和type值,如果句柄型別和引數type一致,回傳句柄對應的物件在用戶態記憶體的地址,值得注意的是,該呼叫成功回傳值實際為poi(tagWnd+0x28),視窗傳入type為1,

  1:TYPE_WINDOW

  如此連續創建多個視窗,查詢(VirtualQuery)每個視窗物件所在記憶體塊的基址,記錄其中最小的基址,接著除了視窗0和1,呼叫DestroyWindow銷毀其余視窗,保留下的視窗0和1將結合后續將創建的magicWnd進行漏洞利用,而記錄的最小基址將用于搜尋magicWnd,

  對比視窗0和1分別相對于桌面堆的偏移,較小者和較大者分別記為WndMin、WndMax,偏移值位于視窗物件tagWnd物件偏移0x08處,

  tagWnd物件結構部分偏移如下:

  +0x00         Handle

  +0x08         cLockObj

  +0x10         unk

    ++0x00    ETHREAD

      ... ...

      +++0x220    EPROCESS

        ... ...

        ++++0x2e8    UniqueProcessId

        ++++0x2f0    ActiveProcessLinks

        ++++0x360    Token

        ++++0x3e8    InheritedFromUniqueProcessId

        ... ...

      ... ...

  +0x18

    ++0x80    桌面堆基址

  ... ...

  +0x20         pSelf

  +0x28

    ++0x00    Handle

    ++0x08    *(tagWnd+0x28)相對于桌面堆基址的偏移

    ++0x18    exStyle

    ++0x1c    dwStyle

    ++0x98    spMenu

      ... ...

      +++0x50    tagWnd

      ... ...

    ++0xc8    cbwndExtra,指定Extrabytes位元組數

    ++0xe8    不明flag,flag|=0x800可指定pExtrabytes屬性為偏移

    ++0x128   pExtrabytes,指向分配的Extrabytes記憶體

  ... ...

  +0xa8    spMenu

    ... ...

    ++0x50    tagWnd

    ... ...

  視窗銷毀后呼叫NtUserConsoleControl,指定引數ConsoleControl為6,ConsoleCtrlInfoLength為0x10,將視窗WndMin物件pExtrabytes(0x128)欄位屬性設定為偏移,設定成功后pExtrabytes欄位值為相對于桌面堆的偏移值,而0xe8處的flag將|=0x800,重新申請后的Extrabytes記憶體大小由poi(poi(tagWnd+0x28)+0xc8)指定,

(由于中間反復除錯過幾次,截圖之間的資料可能有些對不上)

  然后創建一個magic視窗WndMagic,同之前一樣,會執行到xxxClientAllocWindowClassExtraBytes的Hook函式處,此時將進入另一分支,觸發Hook函式真正作用流程,判斷方式是傳入的引數值,之前創建的普通視窗和現在的magic視窗指定的cbWndExtra值是不同的,普通視窗固定為32位元組,magic視窗為一個隨機值,

  而wndClass.cbWndExtra值將被賦值到視窗物件poi(tagWnd+0x28)+0xc8處,并作為ExtraBytes記憶體分配時的大小指定值,然后進行用戶模式回呼,用戶態回呼函式執行結束后回傳記憶體地址到內核,賦值到poi(tagWnd+0x28)+0x128處,而Hook函式的目的就是為了回傳一個虛假偏移,指向其他地址,實作可任意地址寫的功能,

  視窗創建程序中,執行到Hook函式中,通過比對傳入的引數值和隨機值,可確定此次創建是WndMagic,不過此時win32kfull! xxxCreateWindowEx尚未執行完畢,所以HWND句柄值還未回傳,尚不可知,然而在進行額外記憶體進行創建時,視窗物件部分屬性已經完成初始化,比如句柄值、視窗屬性、擴展屬性等,

  所以通過匹配cbWndExtra值,再比對視窗擴展屬性值exStyle(此次利用中所有視窗屬性值都設定為了WS_EX_NOACTIVATE [0x8000000]),一致的情況下可以大概率確認WndMagic位置,自然可通過偏移獲取到相應屬性值,

  獲取WndMagic視窗句柄后,呼叫NtUserConsoleControl設定magic視窗pExtrabytes屬性為相對于桌面堆的偏移,接著再借助NtCallbackReturn將普通視窗WndMin物件poi(tagWnd+0x28)+0x08處的值傳回內核,從而結束回呼,而poi(tagWnd+0x28)+0x08的值為poi(tagWnd+0x28)基于桌面堆基址的記憶體偏移,因此這里將導致WndMagic物件pExtrabytes值實際是指向WndMin視窗物件的偏移,

  之后呼叫SetWindowLongW,指定引數為(WndMagic句柄、Index=0x128、WndMin物件在記憶體中的偏移),回傳資料應為原偏移處的舊資料,所以此處回傳值為Hook函式中回傳的WndMin虛假偏移,

    LONG SetWindowLongW(

        [in] HWND hWnd,

        [in] int  nIndex,

        [in] LONG dwNewLong

    );

  呼叫API SetWindowLongW最終執行到win32kfull! xxxSetWindowLong,Index大于等于0的情況下會執行到下圖所示的位置,而此次利用中wndClass.cbClsExtra指定為0 ,poi(tagWnd+0x28)+0xfc也持續為0,可以忽略,因為poi(tagWnd+0x28)+0xe8已被設定0x800屬性,所以poi(poi(tagWnd+0x28)+0x128)+DesktopHeapBaseAddr+Index=tagWnd_WndMin+0x128,也就是說雖是對WndMagic進行的操作,實際上實對WndMin物件pExtrabytes欄位的寫入,值為自身WndMin在桌面堆中的偏移,

  然后執行SetWindowLongW(hWndMagic, offset_0xc8, 0xFFFFFFF),設定WndMin物件poi(tagWnd+0x28)+0xc8處cbwndExtra值設為0xFFFFFFF,擴大可以寫入的范圍,在xxxSetWindowLong和xxxSetWindowLongPtr中都存在對該值和Index的大小比較判定,

  現在WndMagic可控制WndMin,而WndMax物件偏移已知,因此也可控制,可以實作任意位置寫,接著就是對任意位置資料讀,這里采用的的是API GetMenuBarInfo,對Menu Bat資訊的獲取,這種利用一次可以讀取8位元組內容,

  BOOL GetMenuBarInfo(

      [in]      HWND         hwnd,

      [in]      LONG         idObject,

      [in]      LONG         idItem,

      [in, out] PMENUBARINFO pmbi

  );

  利用中構造了一個fakeMenu,將復制給WndMax,SetWindowLongPtr指定Index為-12,且視窗dwStyle為WS_CHILDWINDOW(0x40000000L),那么視窗spMenu欄位可以被設定為指定的值,spMenu欄位有兩處位置,poi(tagWnd+0x28)+0x98tagWnd+0xa8,而SetWindowLongPtr成功呼叫后回傳的值為視窗的原spMenu,記錄該值,

  但是此時視窗并不是子視窗型別,所以在這之前需要對該欄位手動進行設定,呼叫SetWindowLongPtrA,引數為(hWndMin, offset_0x18+WndMax_offset-WndMin_offset, poi(poi(tagWnd+0x28)+0x18)^0x4000000000000000),可以將WndMax視窗型別添加上WS_CHILDWINDOW屬性,從而通過檢測,

  為WndMax設定WS_CHILDWINDOW屬性,并添加spMenu后,再次呼叫SetWindowLongPtrA恢復其dwStyle,去除WS_CHILDWINDOW屬性,原因是后續在使用GetMenuBarInfo讀取指定地址資料時,視窗不能為子視窗型別,

  WndMax的fake spMenu設定完成,且已獲取了舊spMenu,記為old_spMenu,而在spMenu結構的0x50偏移處是spMenu所屬視窗物件地址,即poi(spMenu+0x50)==tagWnd,

  了解以上資訊后,需要對指定地址進行讀,該漏洞利用對GetMenuBarInfo進行了封裝,傳入地址,封裝函式回傳該地址下的內容,

  對GetMenuBarInfo的利用核心主要是指定idObject為-3,idItem為1,pmbi接收資料,API最侄訓走到win32kfull! xxxGetMenuBarInfo函式,傳參資料同GetMenuBarInfo,對該函式分析,可以看到需要對一些特殊的位置進行偽造,從而進入目的代碼處,其中poi(tagWnd+0x28)+0x58和poi(tagWnd+0x28)+0x5C處的值常為0,忽略,

  最終讀取時,可以看到pmbi->left讀取值為poi(poi(poi(poi(menu)+0x58))+0x40),pmbi->top為poi(poi(poi(poi(menu)+0x58))+0x44),其中poi(poi(poi(menu)+0x58))值可由用戶進行控制,令其為X,也就意味著我們通過控制X值,可以讀取X+0x40處的8位元組內容,即pmbi.rcBar.left+(pmbi.rcBar.top<<32),那么只需要控制X為欲要讀取的目的地址減去0x40,即可獲取相應資料,

  回到漏洞利用時封裝的讀取函式中,函式中首先向X指向的記憶體中每4個位元組填寫一個相對于X基址的偏移值,這樣GetMenuBarInfo讀取回的pmbi.rcBar.left即為目標讀取地址應減去的差值,這么做的目的可能是為了防止系統版本的不同導致的差值不同,比如此次除錯時win10 1909就為0x40,

  然后第二次呼叫GetMenuBarInfo,傳入(目的讀取地址- pmbi.rcBar.left),即可獲取目的地址8位元組內容,

  這么一步步通過讀取,可以獲取到EPROCESS,然后通過ActiveProcessLinks,遍歷找到當前行程和system行程EPROCESS位置,

  再次兩次呼叫SetWindowLongPtrA,替換當前行程Token為system行程,獲取system權限,第一次將當前行程Token地址寫入WndMax物件pExtrabytes處,第二次將system行程Token寫入當前行程Token中,完成提權,

 

參考

https://ti.dbappsecurity.com.cn/blog/articles/2021/02/10/windows-kernel-zero-day-exploit-is-used-by-bitter-apt-in-targeted-attack-cn/

https://www.freebuf.com/vuls/271177.html

https://github.com/KaLendsi/CVE-2021-1732-Exploit

https://xiaodaozhi.com/exploit/29.html

https://theevilbit.github.io/posts/a_simple_protection_against_hmvalidatehandle_technique/

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/373863.html

標籤:其他

上一篇:Fuzz前置技能-unicorn模擬執行

下一篇:打破開發專案管理困境!聯電的數字化轉型實踐分享

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more