溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

BlueKeep 漏洞利用分析

發(fā)布時間:2020-08-11 02:04:59 來源:ITPUB博客 閱讀:161 作者:酷酷的曉得哥 欄目:網(wǎng)絡安全

作者:SungLin@知道創(chuàng)宇404實驗室
時間:2019年9月18日

原文鏈接: https://paper.seebug.org/1035/

0x00 信道的創(chuàng)建、連接與釋放

通道的數(shù)據(jù)包定義在MCS Connect Inittial PDU with GCC Conference Create Request中,在rdp連接過程如下圖所示:

BlueKeep 漏洞利用分析

信道創(chuàng)建數(shù)據(jù)包格式如下:

BlueKeep 漏洞利用分析

在MCS Connect Inittial中屬于Client Network Data數(shù)據(jù)段, MS_T120將會在連接一開始的時候通過函數(shù) termdd!_IcaRegisterVcBin創(chuàng)建一個虛擬通道id是0x1f大小為0x18的結構體,之后就調(diào)用 termdd!IcaCreateChannel開始創(chuàng)建大小為0x8c的信道結構體之后將會與虛擬通道id是0x1f綁定,也就是這個結構體將會被我們利用

BlueKeep 漏洞利用分析

信道的定義字段主要是名字加上配置,配置主要包括了優(yōu)先級等

BlueKeep 漏洞利用分析

在server對MCS Connect Inittial應答包,將會依次給出對應虛擬通道的id值:

BlueKeep 漏洞利用分析

在rdp內(nèi)核中依次注冊的值對應應該是0、1、2、3, MS_T120信道將會通過我們發(fā)送的用戶虛擬id為3的值再一次綁定,首先通過 termdd!_IcaFindVcBind找到了剛開始注冊的虛擬通道id是0x1f,如下所示:

BlueKeep 漏洞利用分析

但是在 termdd!_IcaBindChannel時,卻將我們自定義的id值為3與信道結構體再一次綁定在一起了,此信道結構體就是MS_T120

BlueKeep 漏洞利用分析

同時我們自己的用戶id將內(nèi)部綁定的0x1f給覆蓋了

BlueKeep 漏洞利用分析

我們往信道MS_T120發(fā)送數(shù)據(jù)主動釋放其分配的結構體,其傳入虛擬通道id值為3通過函數(shù) termdd!IcaFindChannel在channeltable中查找返回對應的信道結構體:

BlueKeep 漏洞利用分析

下圖為返回的MS_T120信道結構體,其中0xf77b4300為此信道可調(diào)用的函數(shù)指針數(shù)組:

BlueKeep 漏洞利用分析

在這個函數(shù)指針數(shù)組中主要存放了三個函數(shù),其中對應了 termdd!IcaCloseChannel、 termdd!IcaReadChannel、 termdd!IcaWriteChannel

BlueKeep 漏洞利用分析

我們傳入釋放MS_T120信道的數(shù)據(jù)如下,字節(jié)大小為0x12,主要數(shù)據(jù)對應了0x02

BlueKeep 漏洞利用分析

之后將會進入 nt! IofCompleteRequest函數(shù),通過apc注入后,將會通過 nt! IopCompleteRequestnt!IopAbortRequest進行數(shù)據(jù)請求的響應,最終在 termdd!IcaDispatch完成我們發(fā)送數(shù)據(jù)的的請求, _BYTE v2就是我們發(fā)送的數(shù)據(jù),所以我們發(fā)送的數(shù)據(jù)0x02將會最終調(diào)用到IcaClose函數(shù)進入IcaCloseChannel函數(shù),最后主動釋放掉了 MS_T120信道結構體

BlueKeep 漏洞利用分析

BlueKeep 漏洞利用分析

0x01 通過RDPDR信道進行數(shù)據(jù)占位

我們先來了解下rdpdr信道,首先rdpdr信道是文件系統(tǒng)虛擬通道擴展,該擴展在名為rdpdr的靜態(tài)虛擬通道上運行。目的是將訪問從服務器重定向到客戶端文件系統(tǒng),其數(shù)據(jù)頭部將會主要是兩種標識和PacketId字段組成:

BlueKeep 漏洞利用分析

在這里我們剛好利用到了rdpde客戶端name響應的數(shù)據(jù)來進行池內(nèi)存的占位

BlueKeep 漏洞利用分析

在完全建立連接后,將會創(chuàng)建rdpdr信道的結構體

BlueKeep 漏洞利用分析

在window7中,在建立完成后接收到server的rdpdr請求后,通過發(fā)送客戶端name響應數(shù)據(jù),將會調(diào)用到 termdd! IcaChannelInputInternal中的ExAllocatePoolWithTag分配非分頁池內(nèi)存,并且其長度是我們可以控制的,基本滿足了UAF利用的需求:

BlueKeep 漏洞利用分析

可是在windowsxp中,直接發(fā)送client name request將會導致內(nèi)存分配失敗,直接進入 termdd! _IcaCopyDataToUserBuffer,并且在Tao Yan and Jin Chen[1]一文中也提到了通過發(fā)送client name request在觸發(fā)一定的條件后將會繞過 termdd!_IcaCopyDataToUserBuffer而進入ExAllocatePoolWithTag分配我們想要的非分頁內(nèi)存,而打破條件如下:

BlueKeep 漏洞利用分析

我們先來看看最開始信道結構體的創(chuàng)建,我們可以發(fā)現(xiàn)從一開始創(chuàng)建信道結構體的時候,將會出現(xiàn)兩個標志,而這兩個標志是按照地址順序排列的,而在上面需要打破的條件中,只要channelstruct +0x108的地址存放的是同一個地址,循環(huán)就會被break

BlueKeep 漏洞利用分析

我們發(fā)送一個正常的rdpdr的name request數(shù)據(jù)包,頭部標識是0x7244和0x4e43

BlueKeep 漏洞利用分析

經(jīng)過 termdd!_IcaCopyDataToUserBuffer之后,將會進入 nt!IofCompleteRequest,在響應請求后進入 rdpdr!DrSession::ReadCompletion,此函數(shù)處理邏輯如下,其將會遍歷一個鏈表,從鏈表中取出對應的vftable函數(shù)數(shù)組

BlueKeep 漏洞利用分析

遍歷第一次取出第一張函數(shù)數(shù)組

BlueKeep 漏洞利用分析 BlueKeep 漏洞利用分析

傳入我們發(fā)送的數(shù)據(jù)后,通過函數(shù)數(shù)組調(diào)用 rdpdr!DrSession::RecognizePacket進行讀取

BlueKeep 漏洞利用分析

判斷頭部標志是否為(RDPDR_CTYP_CORE)0x7244

BlueKeep 漏洞利用分析

接著將會讀取函數(shù)vftable第二個地址,進行轉發(fā)

BlueKeep 漏洞利用分析

如下圖可以看到rdpdr的數(shù)據(jù)包處理邏輯

BlueKeep 漏洞利用分析

rdpdr經(jīng)過一系列數(shù)據(jù)包處理后最終進入了我們關心的地方,將會傳入channelstruct通過調(diào)用 termdd! _IcaQueueReadChannelRequest進行標志位的處理

BlueKeep 漏洞利用分析

最初rdpdr的channelstruct的標志位如下

BlueKeep 漏洞利用分析

經(jīng)過函數(shù) termdd! _IcaQueueReadChannelRequest對此標志的處理后變成如下,所以下一個數(shù)據(jù)依然會進入 termdd!_IcaCopyDataToUserBuffer,導致我們進行池噴射的失敗

BlueKeep 漏洞利用分析

回到rdpdr頭部處理函數(shù) rdpdr!DrSession::RecognizePacket,我們發(fā)現(xiàn)在鏈表遍歷失敗后將會進行跳轉,最后將會進入讀取失敗處理函數(shù) rdpdr!DrSession::ChannelIoFailed,然后直接return了

BlueKeep 漏洞利用分析 BlueKeep 漏洞利用分析

我們構造一個頭部異常的數(shù)據(jù)包發(fā)送,頭部標志我們構造的是0x7240,將會導致 rdpdr!DrSession::RecognizePacket判斷失敗,之后將會繼續(xù)遍歷鏈表依次再取出兩張函數(shù)數(shù)組

BlueKeep 漏洞利用分析

最后兩個函數(shù)數(shù)組依次調(diào)用 rdpdr!DrExchangeManager::RecognizePacketrdpdr!DrDeviceManager::RecognizePacket,都會判斷錯誤的頭部標志0x7240,最后導致鏈表遍歷完后進行錯誤跳轉,直接繞過了 termdd! _IcaQueueReadChannelRequest對標志位的修改,將會打破循環(huán)

BlueKeep 漏洞利用分析 BlueKeep 漏洞利用分析

最后我們連續(xù)構造多個錯誤的數(shù)據(jù)包后將會進入 ExAllocatePoolWithTag,分配到我們需要的非分頁內(nèi)存!

BlueKeep 漏洞利用分析 BlueKeep 漏洞利用分析

0x02 win7 EXP 池噴射簡要分析

首先被釋放的MS_T120池大小包括是0x170,池的標志是TSic

BlueKeep 漏洞利用分析

分析Win7 exp 可以知道數(shù)據(jù)占位是用的rdpsnd信道,作者沒有采用rdpdr信道,應該也和噴射的穩(wěn)定性有關,rdpsnd噴射是再建立完了rdpdr初始化后開始的,在free掉MS_T120結構體前,發(fā)送了1044個數(shù)據(jù)包去申請0x170大小的池內(nèi)存,這樣做可以說應該是為了防止之后被free掉的內(nèi)存被其他程序占用了,提高free后內(nèi)存被我們占用的生存幾率

BlueKeep 漏洞利用分析

占位被free的實際數(shù)據(jù)大小為0x128,利用的中轉地址是0xfffffa80ec000948

BlueKeep 漏洞利用分析

之后開始池噴射,將payload噴射到可以call [rax] == 0xfffffa80ec000948的地方,噴射的payload大小基本是0x400,總共噴射了200mb的數(shù)據(jù)大小,我們先來看下噴射前帶標志TSic總共占用池內(nèi)存大小是58kib左右

BlueKeep 漏洞利用分析

BlueKeep 漏洞利用分析

噴射完后帶TSic標志池內(nèi)存大小大約就是201mb,池內(nèi)存噴射基本是成功的,我的win7是sp1,總共內(nèi)存大小是1GB,再噴射過程中也沒有其他干擾的,所以噴射很順利

BlueKeep 漏洞利用分析

BlueKeep 漏洞利用分析

圖中可以發(fā)現(xiàn)基本已經(jīng)很穩(wěn)定的0x400大小的池噴射payload,地址越高0x400大小的內(nèi)存基本就很穩(wěn)定了

BlueKeep 漏洞利用分析

最后斷開連接時候,被free的內(nèi)存已經(jīng)被我們噴射的0x128大小的數(shù)據(jù)給占用了

BlueKeep 漏洞利用分析

執(zhí)行call指令后穩(wěn)定跳轉到了我們的payload,成功執(zhí)行!

BlueKeep 漏洞利用分析

參考鏈接:
[0]   https://github.com/rapid7/metasploit-framework/pull/12283
[1]   https://unit42.paloaltonetworks.com/exploitation-of-windows-cve-2019-0708-bluekeep-three-ways-to-write-data-into-the-kernel-with-rdp-pdu/
[2] https://wooyun.js.org/drops/%E7%BE%8A%E5%B9%B4%E5%86%85%E6%A0%B8%E5%A0%86%E9%A3%8E%E6%B0%B4%EF%BC%9A%20%E2%80%9CBig%20Kids%E2%80%99%20Pool%E2%80%9D%E4%B8%AD%E7%9A%84%E5%A0%86%E5%96%B7%E6%8A%80%E6%9C%AF.html

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI