您的位置:首頁(yè) > 菜鳥(niǎo)學(xué)院 > 深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

來(lái)源:互聯(lián)網(wǎng) | 時(shí)間:2015-01-22 14:18:44 | 閱讀:196 |    | 分享到:


0×0 背景


    微軟(2014-11-18)發(fā)布了一個(gè)緊急補(bǔ)丁,修復(fù)了一個(gè)影響全部版本W(wǎng)indows服務(wù)器的嚴(yán)重漏洞。今天發(fā)布的MS14-068漏洞補(bǔ)丁用于解決Microsoft Windows Kerberos KDC漏洞(CVE-2014-6324),該漏洞允許黑客提升任意普通用戶權(quán)限成為域管理員(Domain Admin)身份。也就是說(shuō),你在一臺(tái)普通域用戶的機(jī)器上利用這個(gè)漏洞,那么這個(gè)域用戶就變成域管理員權(quán)限,然后,該域用戶就可以控制整個(gè)域的所有機(jī)器了。

那么,問(wèn)題來(lái)了,該漏洞的威力真的有這么大嗎?

網(wǎng)上出現(xiàn)了Github上爆出的該漏洞的Python利用程序,Python Kerberos Exploitation Kit,也就是PyKek,當(dāng)然,其它站點(diǎn)也都開(kāi)始了轉(zhuǎn)發(fā)。經(jīng)過(guò)測(cè)試,Win7的普通域用戶運(yùn)行該漏洞程序確實(shí)能夠成為域管理員權(quán)限。但網(wǎng)上大家的測(cè)試都是在域用戶的本地賬戶中才能測(cè)試成功。

為什么Windows關(guān)于MS14-068的公告板中并沒(méi)有提出這一點(diǎn)?按道理來(lái)說(shuō),越是有限制的漏洞利用對(duì)軟件開(kāi)發(fā)人員越是有利的,漏洞利用的機(jī)會(huì)越少,他們受到的譴責(zé)就會(huì)越少。

那么,問(wèn)題又來(lái)了,真的只能用域用戶的本地賬戶漏洞才能利用成功嗎?

自從Freebuf發(fā)布該漏洞預(yù)警后,再也沒(méi)看到另有分析文章出現(xiàn),甚至也沒(méi)有POC,這讓我為心目中偉大的Freebuf捉急哇,心情低落到極點(diǎn),所以,自己決心從頭開(kāi)始研究該漏洞。

這樣的話,問(wèn)題又來(lái)了,作為不懂Kerberos協(xié)議的小白,這個(gè)漏洞到底是怎么產(chǎn)生的?

帶著種種疑問(wèn),我開(kāi)始了分析之旅,時(shí)隔半月,分析完成后,沒(méi)想到卻發(fā)現(xiàn)了一個(gè)天大的秘密,我從下面幾點(diǎn)向大家分析一下關(guān)于這個(gè)漏洞的方方面面,來(lái)揭示這個(gè)筆者認(rèn)為有人精心策劃的漏洞。

0×1 Python版PoC的測(cè)試?yán)?/span>

首先網(wǎng)上的Python版PyKek,搭建域環(huán)境、Python環(huán)境,對(duì)該漏洞進(jìn)行了測(cè)試:

(1)測(cè)試環(huán)境

目的:將普通域用戶權(quán)限提升為域控權(quán)限(漏洞利用后,net
use swg.server.comc$可以直接訪問(wèn)域控的網(wǎng)絡(luò)資源)

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

(2)測(cè)試步驟

A.利用域賬戶domainuser/Dom12345登錄普通域機(jī)器Win7,獲得該域賬戶的域SID:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

B.以本地賬戶test/123456登錄普通域機(jī)器Win7,運(yùn)行PyKek漏洞利用程序:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

此時(shí)在C:Userstest文件件會(huì)產(chǎn)生MIT格式的TGT文件[email protected]

C.利用mimikatz工具將得到的[email protected]寫(xiě)入內(nèi)存,創(chuàng)建緩存證書(shū):

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

利用klist命令能夠看到mimikatz創(chuàng)建緩存證書(shū)前后的區(qū)別。

創(chuàng)建緩存證書(shū)之前:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

創(chuàng)建緩存之后:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

D. 在普通域機(jī)器Win7的本地賬戶中執(zhí)行:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

你會(huì)驚奇地發(fā)現(xiàn),不用提供Win2003域控的賬號(hào)密碼就直接可以連接到其C盤(pán),也就是說(shuō),現(xiàn)在可以訪問(wèn)Win2003域控機(jī)器C盤(pán):

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

正如宣稱的那樣,漏洞成功利用后,域用戶在不知道域控密碼的情況下,可以隨意訪問(wèn)域控上的資源,怪不得大家都說(shuō),有了這個(gè)漏洞,再也不用狂掃密碼了。

這是網(wǎng)上普遍轉(zhuǎn)發(fā)的一種漏洞利用姿勢(shì),需要注意的是,域SID是以域用戶登錄Win7域機(jī)器獲得的,而漏洞利用則是在該域機(jī)器的本地賬戶下才能測(cè)試成功。如果搭建了測(cè)試環(huán)境,你會(huì)發(fā)現(xiàn),“先用域賬戶獲得SID,然后不得不再登錄本地賬戶測(cè)試漏洞”這一過(guò)程是多么繁(dan)瑣(teng)。

當(dāng)然,后面會(huì)討論為什么在域賬戶下無(wú)法利用成功,并提出一種繞過(guò)方法。

漏洞利用就是這樣的,接下來(lái)我們分析一下這個(gè)漏洞到底是怎樣產(chǎn)生的。

0×2 關(guān)于Kerberos協(xié)議

在談MS14-068漏洞之前,有必要先了解一下Kerberos協(xié)議。

Kerberos協(xié)議是一種基于第三方可信主機(jī)的計(jì)算機(jī)網(wǎng)絡(luò)協(xié)議,它允許兩個(gè)實(shí)體之間在非安全網(wǎng)絡(luò)環(huán)境(可能被竊聽(tīng)、被重放攻擊)下以一種安全的方式證明自己的身份。

下面我們從Kerberos是如何設(shè)計(jì)出來(lái)的來(lái)學(xué)習(xí)該協(xié)議的原理。

這個(gè)協(xié)議解決的根本問(wèn)題,假設(shè)A和B共有一個(gè)秘密,在一個(gè)非安全網(wǎng)絡(luò)環(huán)境中,A怎樣才能向B證明自己就是A。

最簡(jiǎn)單的方式就是,A直接將秘密發(fā)送給B,由B來(lái)判斷這個(gè)秘密的真?zhèn)。但在非安全網(wǎng)絡(luò)環(huán)境中,秘密可能會(huì)被竊聽(tīng)或中間人攻擊,所以這種方式不可取。

接下來(lái)考慮的是,A用秘密作為密鑰加密一段文字生成一段密文,然后將文字本身和密文一起發(fā)給B,B接收后用秘密解密密文得到文字,然后和接收的文字對(duì)比,如果兩者一致,那么也能證明秘密的正確性,從而也能驗(yàn)證A的身份。

但如果該認(rèn)證請(qǐng)求被竊聽(tīng),攻擊者能得到加密后密文和加密前的明文,只要時(shí)間允許,總能推導(dǎo)出密鑰的數(shù)值,也就是秘密肯定會(huì)被竊取。所以密碼界有個(gè)規(guī)定,長(zhǎng)期存在的密鑰不適合在網(wǎng)絡(luò)中傳輸,否則總會(huì)有被竊取的風(fēng)險(xiǎn)。

不使用長(zhǎng)期存在的密鑰,那使用短期存在的密鑰進(jìn)行驗(yàn)證應(yīng)該是沒(méi)問(wèn)題的,關(guān)鍵是,誰(shuí)來(lái)提供這個(gè)短期存在密鑰給A和B?于是就出現(xiàn)了第三方可信機(jī)構(gòu)KeyDistribution Center,KDC。

在請(qǐng)求認(rèn)證之前,Client-A先去向KDC申請(qǐng)本次向Server-B認(rèn)證需要的SessionKey,由KDC將SessionKey分發(fā)給Client-A和Server-B,最后Client-A就可以利用這個(gè)SessionKey向Server-B進(jìn)行認(rèn)證了。為了SessionKey不被竊取,該SessioKey用A和B自身的密碼分別加密:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

這里會(huì)有兩個(gè)問(wèn)題:

(1)A向KDC申請(qǐng)SessionKey,它可能很快就收到SessionKey,但B可能因?yàn)榫W(wǎng)絡(luò)環(huán)境原因,很晚或者根本收不到SessionKey,這樣就導(dǎo)致認(rèn)證無(wú)法進(jìn)行,解決辦法就是,KDC將兩份加密的SessionKey都發(fā)給A,由A在向B發(fā)出認(rèn)證請(qǐng)求時(shí)將原本屬于Server-B的SessionKey一同發(fā)送給Server-B

(2)A提出SessionKey的申請(qǐng)時(shí),KDC憑什么就生成了SessionKey給了A,也就是說(shuō),KDC缺乏對(duì)A的認(rèn)證,所以在分發(fā)SessionKey之前,KDC需要增加對(duì)A的認(rèn)證,解決辦法就是,將KDC機(jī)構(gòu)分成兩部分:

ASAuthentication Service,用于KDC對(duì)A的認(rèn)證 TGSTicket Granting Ticket,用于KDCAB分發(fā)Session Key

另外,還有一點(diǎn)需要注意的是,為了對(duì)短期有效的SessionKey進(jìn)行驗(yàn)證,Kerberos協(xié)議要求系統(tǒng)內(nèi)的所有主機(jī)基于時(shí)間同步,所以Client-A向Server-B進(jìn)行認(rèn)證就不用SessionKey加密一段密文后還得發(fā)送一段明文過(guò)去,直接用SessionKey加密當(dāng)前時(shí)間即可。

到此為止,整個(gè)Kerberos協(xié)議大體框架已經(jīng)出來(lái)了:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

需要注意的是,這里涉及到兩個(gè)SessionKey的申請(qǐng),一個(gè)是SessionKeya-kdc,另一個(gè)是SessionKeya-b,這是因?yàn)榛趧偛诺娜秸J(rèn)證以及盡量使用短期有效密鑰的思想,本協(xié)議變成了兩次三方認(rèn)證:

(1)AS作為Client-A與TGS之間的第三方,需要完成對(duì)A進(jìn)行認(rèn)證,同時(shí)為Client-A向TGS提出SessionKeya-b請(qǐng)求提供一個(gè)SessionKeya-kdc,根據(jù)剛才的分析,為了防止TGS無(wú)法收到SessionKey,如圖第②步,原本需要發(fā)往TGS的SessionKeya-kdc(被KDC密碼加密為T(mén)GT)會(huì)一同發(fā)往Client-A,由Client-A在第③步中轉(zhuǎn)交給TGS

(2)TGS作為Client-A與Server-B之間的第三方,需要為A和B分別提供SessionKeya-b,為了防止Server-B無(wú)法收到SessionKey,如圖第④步,原本需要發(fā)往Server-B的SessionKeya-b(被Server-B密碼加密為service Ticket)會(huì)一同發(fā)往Client-A,由Client-A在第⑤步中轉(zhuǎn)交給Server-B

上述過(guò)程也就是Kerberos協(xié)議的基本框架,基于微軟對(duì)Kerberos的介紹,上面其實(shí)對(duì)應(yīng)的是下面微軟提供的Kerberos協(xié)議流程:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

或者你也可以認(rèn)為,是網(wǎng)上解釋MS14-068漏洞時(shí)用的這張示意圖:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

具體來(lái)說(shuō),Kerberos協(xié)議分為以下步驟(第六步可選):

第①步:KRB_AS_REQ:Client-A發(fā)送Authenticator向KDC的AS服務(wù)認(rèn)證自己的身份(通過(guò)提供自身密碼加密的一個(gè)時(shí)間戳TimeStamp)

第②步:KRB_AS_REP:AS通過(guò)KDC數(shù)據(jù)庫(kù)中存儲(chǔ)的Client-A密碼的副本,解密收到的Authenticator,如果解密出的TimeStamp符合要求,則AS服務(wù)認(rèn)為Client-A就是所謂的Client-A。認(rèn)證成功后,AS服務(wù)生成一個(gè)短期有效的SessionKeya-kdc,將該Key使用A的密碼副本加密成密文1,另外將Key連同時(shí)間戳標(biāo)志(控制該SessionKey的有效時(shí)間)通過(guò)TGS服務(wù)的密碼也就是KDC的密碼加密為密文2(稱為T(mén)GT),將這兩個(gè)密文組合成KRB_AS_REP返回給Client-A

第③步:KRB_TGS_REQ:Client-A在接收到KRB_AS_REP后,首先使用自身密碼解密密文1得到SessionKeya-kdc,此時(shí)需要注意的是,密文2(TGT)是被KDC的密碼加密的,所以Client-A無(wú)法解密,這也是Kerberos協(xié)議設(shè)計(jì)的精妙之處,既解決了Server端(TGS相對(duì)于Client-A也稱之為Server端)無(wú)法及時(shí)接收SessionKey的問(wèn)題,又不怕Client-A對(duì)該TGT的偽造,因?yàn)镃lient-A不知道Server端的密碼

得到SessionKeya-kdc后,Client-A利用其加密時(shí)間戳生成Authenticator用于向TGS申請(qǐng)Client-A與Client-B進(jìn)行認(rèn)證所需的SessionKeya-b,連同剛才KRB_AS_REP接收的TGT一同組合成KRB_TGS_REQ發(fā)送給TGS

第④步:KRB_TGS_REP:TGS在接收到KRB_TGS_REP之后,利用KDC密碼解密TGT獲得本來(lái)就該發(fā)送給自己的SessionKeya-kdc,然后用其解密KRB_TGS_REQ中的Authenticator得到Client-A發(fā)送過(guò)來(lái)的時(shí)間戳,如果時(shí)間戳符合要求,則生成一個(gè)短期有效的SessionKeya-b,注意此時(shí)利用SessionKeya-kdc將SessionKeya-b加密為密文1,然后利用Server-B的密碼將SessionKeya-b加密為密文2(稱為ServiceTicket),兩個(gè)密文一同構(gòu)成KRB_TGS_REP返回給Client-A

第⑤步:KRB_AP_REQ:Client-A在接收到KRB_TGS_REP之后,首先使用緩存的SessionKeya-kdc將密文1中的SessionKeya-b解密出來(lái),然后利用其加密時(shí)間戳生成Authenticator用于向B進(jìn)行對(duì)自身的驗(yàn)證,另外,和剛才TGT一樣,密文2也就是ServiceTicket是用Server-B的密碼加密的,所以Client-A無(wú)法解密,也就無(wú)法偽造,這也同樣解決了在三方認(rèn)證中作為Server端的B無(wú)法及時(shí)接收SessionKey的問(wèn)題,又不怕Client-A對(duì)ServiceTicket的偽造

第⑥步:KRB_AP_REP:Server-B受到KRB_AP_REQ之后,利用自身密碼解密ServiceTicket,得到SessionKeya-b,然后用SessionKeya-b解密Authenticator得到時(shí)間戳,驗(yàn)證A的身份

這就是整個(gè)Kerberos協(xié)議的基本流程。

0×3 PAC與Kerberos的關(guān)系

上面是標(biāo)準(zhǔn)Kerberos協(xié)議的基本流程,MIT也實(shí)現(xiàn)了一套標(biāo)準(zhǔn)的Kerberos協(xié)議,而微軟在Windows平臺(tái)上的Kerberos并沒(méi)有采用MIT的實(shí)現(xiàn),而是對(duì)Kerberos協(xié)議進(jìn)行了一些擴(kuò)充,其中最重要的擴(kuò)充就是增加了認(rèn)證過(guò)程中的權(quán)限認(rèn)證,也就是在協(xié)議中增加了PAC(Privilege
Attribute Certificate),特權(quán)屬性證書(shū)。

為什么會(huì)增加這些呢?可以這樣理解,當(dāng)用戶Client-A與Server-B完成認(rèn)證,只是向Server-B證明了Client-A就是所謂的Client-A,但此時(shí)Client-A如果需要訪問(wèn)Server-B上的網(wǎng)絡(luò)資源,但Server-B現(xiàn)在其實(shí)并不知道Client-A是否有訪問(wèn)自身網(wǎng)絡(luò)資源的權(quán)限(Kerberos協(xié)議中并沒(méi)有規(guī)定權(quán)限問(wèn)題)

難不成此時(shí)Server-B必須再向KDC驗(yàn)證Client-A是否有訪問(wèn)網(wǎng)絡(luò)資源的權(quán)限?當(dāng)然不是,微軟實(shí)現(xiàn)Kerberos認(rèn)證協(xié)議的同時(shí)巧妙地引入了PAC解決了這個(gè)問(wèn)題。(至少M(fèi)S14-068漏洞之前大家是這樣認(rèn)為的)

在一個(gè)域中,如何才能知道某個(gè)域用戶所擁有的權(quán)限呢?自然是需要提供User的SID和所在組Group的SID。必須了解的一個(gè)前提是,KDC、A和B三者中,B只信任KDC所提供的關(guān)于A到底是什么權(quán)限,所以在一個(gè)域初始時(shí),KDC上擁有A和B的權(quán)限,F(xiàn)在需要解決的是,KDC必須告訴B關(guān)于A的權(quán)限,這樣B驗(yàn)證A的權(quán)限后才能決定讓不讓A訪問(wèn)自身的網(wǎng)絡(luò)資源。

為了最終使得Server-B能知道Client-A所具有的權(quán)限,微軟在KRB_AS_REP中的TGT中增加了Client-A的PAC(特權(quán)屬性證書(shū)),也就是Client-A的權(quán)限,包括Client-A的User的SID、Group的SID:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

可以看到被KDC加密的TGT中,不僅包括了被加密的Session
Keya-kdc,還包括KRB_AS_REQ中申請(qǐng)者(Client-A)的權(quán)限屬性證書(shū),為了防止該特權(quán)證書(shū)被篡改(即使被KDC加密,Client-A無(wú)法輕易解密,但誰(shuí)也無(wú)法保證絕對(duì)的安全),在PAC的尾部增加了兩個(gè)校驗(yàn)Server Signature和KDC Signature:

這兩個(gè)校驗(yàn)一個(gè)是Server Signature,另一個(gè)是KDC Signature,對(duì)于Client-A與AS服務(wù)來(lái)說(shuō),Server代表的是TGS服務(wù),KDC代表的是AS服務(wù)(AS作為Client-A與TGS的第三方信任機(jī)構(gòu)),而AS服務(wù)與TGS服務(wù)具有相同的krgtgt賬號(hào),所以這兩個(gè)校驗(yàn)都是krgtgt賬號(hào)的密碼生成的,當(dāng)然,整個(gè)TGT也是用KDC的密碼也就是krgtgt賬號(hào)密碼加密的,它們?nèi)卟煌氖,用的算法和加密?nèi)容有所不同。

微軟是這樣打算的,無(wú)論如何也要把PAC從KDC傳送到Server-B,為了在Kerberos認(rèn)證過(guò)程中實(shí)現(xiàn),微軟選擇了如下做法:

將PAC放在TGT中加密后從AS服務(wù)經(jīng)Client-A中轉(zhuǎn)給TGS服務(wù),再放在由TGS服務(wù)返回的Service
Ticket中加密后經(jīng)Client-A中轉(zhuǎn)給Server-B

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

需要注意的是,在KRB_TGS_REQ階段,攜帶PAC的TGT被TGS服務(wù)接收后,認(rèn)證A的合法性后(解密Authenticator符合要求)會(huì)將PAC解密出來(lái),驗(yàn)證尾部?jī)蓚(gè)簽名的合法性,如果合法則認(rèn)為PAC沒(méi)有被篡改,于是重新在PAC的尾部更換了另外兩個(gè)簽名,一個(gè)是Server Signature,這次是以Server-B的密碼副本生成的簽名(因?yàn)閷?duì)于Client-A和Server-B,這次的第三方機(jī)構(gòu)是TGS服務(wù)),另外一個(gè)是KDC Signature,這次不再使用KDC的長(zhǎng)期有效的Key,而是使用在AS階段生成的短期有效的SessionKeya-b,(網(wǎng)上說(shuō)的是第二個(gè)簽名仍舊是KDC Key,但如果用KDC中krgtgt賬號(hào)密碼生成簽名,最后轉(zhuǎn)發(fā)給Server-B后,由于沒(méi)有krbtgt的密碼而無(wú)法驗(yàn)證第二個(gè)簽名的正確性,所以這里用SessionKeya-b生成簽名才是合理的,或許這里理解錯(cuò)了,敬請(qǐng)指出)最終成為New Signed PAC被拷貝在ServericeTicket中被加密起來(lái)。

最終繞過(guò)來(lái)繞過(guò)去,KDC上所擁有的關(guān)于Client-A的權(quán)限證書(shū)PAC終于發(fā)給了Server-B,Server-B在對(duì)Client-A進(jìn)行認(rèn)證的同時(shí),同時(shí)也能判斷Client-A有沒(méi)有訪問(wèn)網(wǎng)絡(luò)資源的權(quán)限。

到這里PAC與Kerberos協(xié)議的關(guān)系也就明朗了。

0×4 從Pykek源碼分析MS14-068漏洞

現(xiàn)在切入正題,開(kāi)始研究MS14-068漏洞的產(chǎn)生。

首先看一下微軟關(guān)于MS14-068公告板:

This security update resolves a privately reported vulnerability in Microsoft Windows Kerberos KDC th

at could allow an attacker to elevate unprivileged domain user account privileges to those of the dom

ain administrator account.An attacker could use these elevated privileges to compromise any comput

er in the domain, including domain controllers.An attacker must have valid domain credentials to expl

oit this vulnerability.

The affected component is available remotely to users who have standard user accounts withdomain c

redentials;this is not the case for users with local account credentialsonly.

仔細(xì)看看,其實(shí)這個(gè)公告板就是說(shuō)了這個(gè)洞的危害,可以把沒(méi)有域控權(quán)限的普通域用戶提權(quán)為域控權(quán)限。另外,網(wǎng)上也有兩種對(duì)該漏洞產(chǎn)生原因的說(shuō)法:

從客戶端解釋:

當(dāng)用戶進(jìn)行登錄身份驗(yàn)證服務(wù),服務(wù)會(huì)驗(yàn)證PAC中的簽名,并使用PAC中的數(shù)據(jù)為用戶創(chuàng)建一個(gè)登錄令牌。譬如說(shuō),如果PAC能夠攜帶有效的簽名表明“Secpulse”是“域管理”安全組的成員,那么創(chuàng)建的登錄令牌就將Secpulse當(dāng)作“域管理”組中成員。這樣的Kerberos認(rèn)證存在問(wèn)題,攻擊者可以偽造身份,從域用戶提升到域管理權(quán)限。

從服務(wù)端解釋:

微博@jacktang310 程序員在實(shí)現(xiàn)KDC服務(wù)器的PAC signature時(shí)沒(méi)有嚴(yán)格控制使用checksum的算法,在原來(lái)的設(shè)計(jì)中要用到HMAC系列的checksum算法,也就是必須要有key的參與,但實(shí)現(xiàn)的時(shí)候允許所有的checksum算法都可以,包括MD5,這樣客戶端就可以偽造PAC的包了。

從上面的說(shuō)法來(lái)看,該漏洞利用是通過(guò)客戶端來(lái)偽造高權(quán)限的PAC產(chǎn)生的,但根據(jù)前面對(duì)PAC與Kerberos關(guān)系的分析,貌似沒(méi)有破綻來(lái)說(shuō)明客戶端有機(jī)會(huì)偽造PAC,那到底是怎么回事呢?帶著這個(gè)疑惑,我開(kāi)始分析了Github上很火的PyKek攻擊包源碼。

首先,在0×1小節(jié)POC代碼測(cè)試步驟C中,使用Pykek攻擊包期間利用Wireshark抓包如下:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

mimikatz在內(nèi)存新建緩存證書(shū)后,net
use過(guò)程中的抓包如下:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

看到抓包結(jié)果,我立即產(chǎn)生了兩個(gè)疑惑:

(1)傳說(shuō)中Kerberos協(xié)議中的KRB_AP_REQ和KRB_AP_REP過(guò)程哪里去了? (2)為什么會(huì)產(chǎn)生兩次TGS_REQ和TGS_REP過(guò)程??

第一個(gè)問(wèn)題的原因很好解決,查閱資料得知,由于Kerberos協(xié)議是一種認(rèn)證網(wǎng)絡(luò)協(xié)議,它通常是其它網(wǎng)絡(luò)有關(guān)協(xié)議的前提,比如說(shuō)SMB、FTP等,在SMB等協(xié)議的實(shí)現(xiàn)中SMB第一個(gè)請(qǐng)求包實(shí)際上會(huì)包含KRB_AP_REQ,這也就是協(xié)議整合吧,我們通過(guò)打開(kāi)第一個(gè)SMB請(qǐng)求的數(shù)據(jù)包就可發(fā)現(xiàn):

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

而第二個(gè)問(wèn)題,到底為什么會(huì)產(chǎn)生兩次TGS_REQ和TGS_REP過(guò)程,這個(gè)疑惑基本是我在全部分析完整個(gè)漏洞才搞懂的,但它卻影響了我整個(gè)分析過(guò)程,下面一點(diǎn)點(diǎn)向大家解釋。

既然網(wǎng)上都說(shuō),本次漏洞利用是通過(guò)客戶端偽造高權(quán)限PAC產(chǎn)生的,那PyKek工具產(chǎn)生的AS_REQ、AS_REP和TGS_REQ、TGS_REP過(guò)程中肯定有端倪,下面我們從PyKek源碼仔細(xì)分析一下

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

可以看到,真?zhèn)漏洞利用過(guò)程經(jīng)歷了以下幾步:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

不知道你是否注意,接收AS_REP后,能解密得到TGT,但接收TGS_REP后,卻同樣接收的是TGT,這是怎么回事?原理上不是說(shuō)TGS_REP之后,Client端接收的是ServiceTicket嗎?其實(shí)這就是該漏洞的根源,下面根據(jù)源碼逐步分析一下具體過(guò)程。

0×4.1 構(gòu)造AS_REQ

首先看一下AS_REQ的構(gòu)造過(guò)程,這里是代碼主體:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

上面對(duì)于AS_REQ的構(gòu)造,主要用current_time和Key構(gòu)造了用于提交給AS服務(wù)驗(yàn)證的Authenticator,另外,卻增加了一個(gè)include-PAC標(biāo)志,通過(guò)查看源代碼,發(fā)現(xiàn)該include-PAC標(biāo)志被設(shè)置為了false:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

查閱資料得知,微軟在實(shí)現(xiàn)PAC的過(guò)程中,特意增加了一個(gè)include-PAC標(biāo)志,通常情況下,AS_REQ請(qǐng)求中如果該標(biāo)志被設(shè)置為true,只要AS服務(wù)對(duì)Client-A通過(guò)認(rèn)證,那么會(huì)在返回的AS_REP數(shù)據(jù)包中的TGT中加入PAC信息;而如果在AS_REQ請(qǐng)求時(shí),include-PAC標(biāo)志被設(shè)置為false,那么AS_REP返回的TGT中就不會(huì)包含PAC信息。

這一點(diǎn),我們?cè)趧偛臰ireshark抓包中顯示AS_REQ數(shù)據(jù)包和AS_REP數(shù)據(jù)包的大小就可以看出來(lái)(通常攜帶PAC信息的AS_REP數(shù)據(jù)包可以達(dá)到上千字節(jié))。

0×4.2 接收AS_REP

將AS_REQ發(fā)送給KDC后,KDC按照協(xié)議規(guī)定將會(huì)返回兩個(gè)東西:利用user_key加密的Session
Keya-kdc和被KDC密碼加密的TGT(不包含PAC信息)。下面我們看一下PyKek是如何接收AS_REP并解密的:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

具體對(duì)session_key的解密也和之前的原理類似:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

根據(jù)上面的接收過(guò)程,并參考Wireshark對(duì)AS_REP的截圖更形象地理解整個(gè)解密過(guò)程:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

0×4.3 構(gòu)造PAC及TGS_REQ

之后,PyKek就開(kāi)始了最重要的一步:構(gòu)造PAC并放入TGS_REQ中。下面是整個(gè)過(guò)程:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

分別看一下兩個(gè)過(guò)程。

0×4.3.1 構(gòu)造PAC

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

由于前面我們學(xué)習(xí)了PAC的整個(gè)結(jié)構(gòu),所以不難看出來(lái)該地方構(gòu)造的PAC由三部分組成:

1. User SID & Group SID 2. Chksum of Server_key 3. Chksum of Kdc_key

通過(guò)深入跟蹤源碼,可以看出,User
SID & Group SID的構(gòu)造中,其實(shí)是將該域用戶的SID截?cái),留取前面的部分?

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

然后構(gòu)造高權(quán)限的User
SID & Group SID:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

對(duì)于后面兩個(gè)chksum的構(gòu)造:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

由前面的定義可知:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

可以很容易看出,這里直接用不需要Key的MD5構(gòu)造的簽名。也就是說(shuō)什么什么意思呢,只要用戶構(gòu)造了前面的data(User
SID & Group SID),只需對(duì)data進(jìn)行MD5運(yùn)算,生成一個(gè)32位的MD5值即可。

服務(wù)端對(duì)于MD5簽名又是如何驗(yàn)證的呢?它只需要將前面的data取出來(lái),進(jìn)行MD5運(yùn)算,如果得到的MD5值,與后面的簽名一致,則認(rèn)為該簽名合法。

但是,到這里,可能會(huì)有疑問(wèn),關(guān)于PAC尾部的簽名,不是說(shuō)需要server_key和kdc_key的參與嗎?這就是微軟犯的第一個(gè)錯(cuò)誤:

在KDC機(jī)構(gòu)對(duì)PAC進(jìn)行驗(yàn)證時(shí),對(duì)于PAC尾部的簽名算法,雖然原理上規(guī)定必須是帶有Key的簽名算法才可以,但微軟在實(shí)現(xiàn)上,卻允許任意簽名算法,只要客戶端指定任意簽名算法,KDC服務(wù)器就會(huì)使用指定的算法進(jìn)行簽名驗(yàn)證。

所以PyKek在客戶端的攻擊代碼中很巧妙地利用了這個(gè)漏洞,規(guī)定使用不需要Key的MD5進(jìn)行簽名,只要簽名構(gòu)造的User
SID & Group SID權(quán)限信息在傳輸過(guò)程中不改變,那么服務(wù)端肯定能驗(yàn)證通過(guò)。

那肯定有人還有疑問(wèn),PAC不是被放在TGT中嗎?但根據(jù)include-PAC標(biāo)志設(shè)置為false后,AS_REP解密得到的TGT是不攜帶PAC信息的,難不成要把構(gòu)造的PAC放在TGT中?但TGT是被KDC密碼加密的,客戶端根本無(wú)法解密。

這就是微軟犯的第二個(gè)錯(cuò)誤:

PAC沒(méi)有被放在TGT中,而是放在了TGS_REQ數(shù)據(jù)包的其它地方。但可笑的是,KDC在實(shí)現(xiàn)上竟然允許這樣的構(gòu)造,也就是說(shuō),KDC能夠正確解析出沒(méi)有放在其它地方的PAC信息。

下面我們通過(guò)TGS_REQ的構(gòu)造過(guò)程來(lái)看一下這個(gè)錯(cuò)誤。

0×4.3.2 構(gòu)造TGS_REQ

調(diào)用:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

定義:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

通過(guò)上面的構(gòu)造過(guò)程,結(jié)合Wireshark對(duì)TGS_REQ的截圖:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

可以得知,PAC被放在了TGS_REQ數(shù)據(jù)包中的REQ_BODY中,被subkey加密了,而TGT被放在REQ_BODY前面的PADATA中,這也就是說(shuō),TGT中沒(méi)有攜帶PAC信息,并且可以注意到,TGS_REQ中也設(shè)置了include-PAC標(biāo)志信息為false。

另外得知,PAC信息被subkey加密,我們看一下subkey的來(lái)源:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

subkey竟然是Client端生成的一個(gè)隨機(jī)數(shù)!

PyKek為了使得KDC能夠解密獲取被加密在REQ_BODY中的PAC信息,也一并把這個(gè)生成的subkey隨機(jī)數(shù)放在TGS_REQ數(shù)據(jù)包中的Authenticator發(fā)給了KDC服務(wù)器。

在KDC接收TGS_REQ后,可笑的是,它可以把PAC信息給解密出來(lái)了,并且由于微軟犯的第一個(gè)錯(cuò)誤:允許任意加密算法的簽名,很明顯,該P(yáng)AC信息會(huì)被驗(yàn)證為合法的PAC信息。

也就是說(shuō),微軟所犯第二個(gè)錯(cuò)誤觸發(fā)的兩個(gè)關(guān)鍵:

(1)在TGS_REQ的REQ_BODY中放上被加密的PAC信息,并把加密用到的Subkey放到Authenticator中

(2)TGS_REQ數(shù)據(jù)包中的include-PAC標(biāo)志被設(shè)置為false

只要按照上面的要求構(gòu)造TGS_REQ數(shù)據(jù)包,KDC就會(huì)“錯(cuò)誤地”將PAC信息解密并驗(yàn)證簽名正確性,但你以為這樣就完了嗎?接下來(lái),還有更令人吃驚的事情會(huì)發(fā)生。

0×4.4 接收TGS_REP

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

下面是具體解密的實(shí)現(xiàn)過(guò)程:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

根據(jù)Kerberos協(xié)議原理可知,在返回的TGS_REP中,TGS服務(wù)會(huì)返回給Clinet-A兩個(gè)東西:被SessionKeya-kdc加密的SessionKeya-b,另外一個(gè)是Service
Ticket,但從上面解密的過(guò)程中,Client-A解密獲取SessionKeya-b竟然用的是Subkey,而我們知道,subkey是一個(gè)客戶端隨意生成的隨機(jī)數(shù),這到底是怎么回事?

起初,我也很是疑惑,甚至都想放棄,因?yàn)閷?shí)在分析不下去了,自己分析的過(guò)程和協(xié)議原理竟然有著這么多不同,我也懷疑過(guò)PyKek作者是不是寫(xiě)錯(cuò)了,但通過(guò)無(wú)數(shù)次的查找資料,終于在國(guó)外一個(gè)安全博客上找到了說(shuō)法,這也是微軟犯的第三個(gè)令人吃驚的錯(cuò)誤:

只要TGS_REQ按照剛才那兩個(gè)要求設(shè)置,KDC服務(wù)器會(huì)做出令人吃驚的事情:它不僅會(huì)從Authenticator中取出來(lái)subkey把PAC信息解密并利用客戶端設(shè)定的簽名算法驗(yàn)證簽名,同時(shí)將另外的TGT進(jìn)行解密得到SessionKeya-kdc;

在驗(yàn)證成功后,把解密的PAC信息的尾部,重新采用自身Server_key和KDC_key生成一個(gè)帶Key的簽名,把SessionKeya-kdc用subkey加密,從而組合成了一個(gè)新的TGT返回給Client-A

沒(méi)錯(cuò),是重新生成一個(gè)TGT,而不是ServiceTicket。

如果你對(duì)前面對(duì)協(xié)議的介紹,很容易知道,TGT原本是通過(guò)AS_REP過(guò)程返回給Client-A的,而現(xiàn)在“毀人三觀”的事情發(fā)生了,在TGS_REP過(guò)程中,KDC竟然返回個(gè)Client-A一個(gè)TGT。

到這里就明白了,PyKek攻擊包中TGS_REP過(guò)程接收的其實(shí)是TGT,SessionKey為SessionKeya-kdc。

最終,這個(gè)TGT和SessionKeya-kdc制作成了[email protected]文件。

而接下來(lái)觀察mimikatz工具創(chuàng)建的內(nèi)存證書(shū),也可以驗(yàn)證上述微軟所犯的第三個(gè)錯(cuò)誤:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

利用TGS_REP接收的Ticket和Session
Key創(chuàng)建的內(nèi)存證書(shū),其Server為krbtgt/SERVER.COM,再根據(jù)我們隊(duì)兩次三方認(rèn)證的理解,很容易就知道這是AS_REQ和AS_REP過(guò)程中才會(huì)將Server端認(rèn)定為krbtgt,也就是說(shuō),接收的Ticket實(shí)質(zhì)為T(mén)GT。

這樣就能理解為啥net use時(shí),會(huì)再多一次TGS_REQ和TGS_REP過(guò)程了,因?yàn)槁┒蠢眠^(guò)程中的TGS_REQ和TGS_REP所完成的并不是申請(qǐng)ServiceTicket,而是通過(guò)“畸形”TGS_REQ請(qǐng)求申請(qǐng)的另外一個(gè)偽造后又增加了PAC信息的TGT,所以在net use之前必須再進(jìn)行一次TGS_REQ與TGS_REP過(guò)程,利用緩存的TGT證書(shū),申請(qǐng)用于net use(其Server為cifs)的ServiceTicket,這里從net use成功后,klist命令增加的內(nèi)存證書(shū)中可以驗(yàn)證這一現(xiàn)象:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

對(duì)于緩存證書(shū),這里根據(jù)微軟的說(shuō)明,可以補(bǔ)充一點(diǎn)背景知識(shí):

Credentials Cache The credentials cache is managed by the Kerberos SSP, which runs in the LSA's security context. When

ever tickets and keys need to be obtained or renewed, the LSA calls the Kerberos SSP to accomplish th

e task.From the client's point of view, a TGT is just another ticket. Before the client attempts to connect

 to any service, the client first checks the user credentials cache for a service ticket to that service. If it 

does not have one, it checks the cache again for a TGT. If it finds a TGT, the LSA fetches the correspond

ing logon session key from the cache, uses this key to prepare an authenticator, and sends both the aut

henticator and the TGT to the KDC, along with a request for a service ticket for the service. In other words, gaining admission to the KDC is no different from gaining admission to any other servi

ce in the domain—it requires a session key, an authenticator, and a ticket (in this case, a TGT).

也就是說(shuō),net use之前,系統(tǒng)會(huì)從Credentials
Cache中查看是否有ServiceTicket,如果沒(méi)有則尋找TGT,找到后就發(fā)送給KDC申請(qǐng)ServiceTicket。

到這里,整個(gè)漏洞的原因就清晰了。

0×5 鐵證如山:這是誰(shuí)的精心策劃

下面我們總結(jié)一下通過(guò)上面的分析找到的微軟所犯的三個(gè)錯(cuò)誤:

第一個(gè)錯(cuò)誤:

在KDC機(jī)構(gòu)對(duì)PAC進(jìn)行驗(yàn)證時(shí),對(duì)于PAC尾部的簽名算法,雖然原理上規(guī)定必須是帶有Key的簽名算法才可以,但微軟在實(shí)現(xiàn)上,卻允許任意簽名算法,只要客戶端指定任意簽名算法,KDC服務(wù)器就會(huì)使用指定的算法進(jìn)行簽名驗(yàn)證。

第二個(gè)錯(cuò)誤:

PAC沒(méi)有被放在TGT中,而是放在了TGS_REQ數(shù)據(jù)包的其它地方。但可笑的是,KDC在實(shí)現(xiàn)上竟然允許這樣的構(gòu)造,也就是說(shuō),KDC能夠正確解析出沒(méi)有放在其它地方的PAC信息。

第三個(gè)錯(cuò)誤:

只要TGS_REQ按照剛才漏洞要求設(shè)置,KDC服務(wù)器會(huì)做出令人吃驚的事情:它不僅會(huì)從Authenticator中取出來(lái)subkey把PAC信息解密并利用客戶端設(shè)定的簽名算法驗(yàn)證簽名,同時(shí)將另外的TGT進(jìn)行解密得到SessionKeya-kdc;

在驗(yàn)證成功后,把解密的PAC信息的尾部,重新采用自身Server_key和KDC_key生成一個(gè)帶Key的簽名,把SessionKeya-kdc用subkey加密,從而組合成了一個(gè)新的TGT返回給Client-A

在我分析出來(lái)這些之后,我感到深深地震驚,這個(gè)漏洞的產(chǎn)生真實(shí)太不可思議了,明明PAC需要放在TGT中,而微軟添加了一個(gè)include-PAC標(biāo)志設(shè)置為false兩次后,就能導(dǎo)致PAC可以放在其它地方;明明是需要key的簽名,微軟卻允許任意簽名算法,包括不帶key的;明明是TGS_REP返回的是ServiceTicket,微軟卻根Kerberos協(xié)議開(kāi)了天大的玩笑,返回了一個(gè)TGT。

我只想說(shuō),這(TMD)得需要多么大的疏忽,才能讓微軟的員工犯下如此“巧妙的”錯(cuò)誤,而且這個(gè)漏洞的觸發(fā)真的是(TMD)太需要技巧了。

到這里,我只能以一個(gè)疑問(wèn)結(jié)束我的震驚:這是誰(shuí)的精心策劃?答案留給讀者思考吧。

0×6 干貨:如何突破“本地賬戶才能漏洞利用”的限制

按照網(wǎng)上的測(cè)試,該漏洞一般用域用戶的本地賬戶會(huì)利用成功。

但如果做過(guò)這個(gè)漏洞測(cè)試的童鞋肯定明白,首先必須登錄域用戶得到其在域中的SID(如果大家知道如何在本地賬戶下得到域用戶的SID,請(qǐng)告知我!@#¥%……&*)

然后再登錄本地賬戶測(cè)試漏洞,這是一件多么蛋疼的事情,于是,基于這個(gè)問(wèn)題,我開(kāi)始分析為什么在域用戶下該漏洞無(wú)法利用成功。

當(dāng)然,我在域用戶下也測(cè)試過(guò)這個(gè)漏洞,當(dāng)然,起初是不成功的。但利用PyKek是可以生成[email protected],并且mimikatz也可以將該文件寫(xiě)進(jìn)緩存證書(shū),也就是說(shuō)TGT在域用戶下可以被寫(xiě)入內(nèi)存作為緩存證書(shū)。那問(wèn)題出在哪里呢?net
use命令肯定沒(méi)問(wèn)題,最終我把問(wèn)題定位在了緩存證書(shū)上。

為什么這樣說(shuō)呢?是因?yàn)榕既坏囊淮螠y(cè)試中,我發(fā)現(xiàn)了一個(gè)奇怪的現(xiàn)象:

在本地賬戶中沒(méi)有使用mimikatz向內(nèi)存注入緩存證書(shū)之前,其內(nèi)存中的緩存證書(shū)個(gè)數(shù)為0,而用mimikatz注入之后,變成1個(gè),net
use之后,變?yōu)?個(gè)。

也就是說(shuō),net
use后會(huì)產(chǎn)生一個(gè)ServiceTicket被放進(jìn)內(nèi)存中。這點(diǎn)沒(méi)有什么變化。

而當(dāng)我在域用戶下做類似測(cè)試時(shí),卻驚奇地發(fā)現(xiàn):

在域用戶中沒(méi)有使用mimikatz向內(nèi)存注入緩存證書(shū)之前,其內(nèi)存中的緩存證書(shū)個(gè)數(shù)是4個(gè),如下面:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

而當(dāng)我使用mimikatz注入緩存證書(shū)以后,變?yōu)椋?

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

可以發(fā)現(xiàn),之后TGT改變了,后面的三個(gè)緩存證書(shū)沒(méi)有改變(第二個(gè)就是net
use所使用的Service
Ticket)

這里我突然又想到了緩存證書(shū)的作用:

net
use之前,系統(tǒng)會(huì)從Credentials
Cache中查看是否有ServiceTicket,如果沒(méi)有則尋找TGT,找到后就發(fā)送給KDC申請(qǐng)ServiceTicket。

也就是說(shuō),mimikatz工具注入后,改變的是TGT,但net
use使用的ServiceTicket沒(méi)有被修改,還是域用戶登錄時(shí)生成的普通域用戶權(quán)限的ServiceTicket,而根據(jù)對(duì)本地賬戶中測(cè)試的了解,起初內(nèi)存中是沒(méi)有net
use的ServiceTicket對(duì)應(yīng)的緩存證書(shū)的,而是注入后,net
use重新生成的緩存證書(shū)。

那關(guān)鍵就來(lái)了,有沒(méi)有辦法在域用戶環(huán)境中清除net
use需要用到的普通域用戶權(quán)限的ServiceTicket對(duì)應(yīng)的緩存證書(shū),然后注入漏洞利用生成的高權(quán)限TGT,最后由net
use重新生成一個(gè)高權(quán)限的ServiceTicket對(duì)應(yīng)的緩存證書(shū)(本地賬戶漏洞利用過(guò)程就是這樣的)?

于是,我懷著好奇的心理,閱讀了列舉緩存證書(shū)的命令klist,果然發(fā)現(xiàn):

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

果然發(fā)現(xiàn)purge這個(gè)單詞,經(jīng)Google翻譯,為“清除”之意,心中竊喜,于是在域用戶下使用該命令:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

果然,緩存證書(shū)被清空了,那接下來(lái)就好辦了,再次利用mimikatz注入高權(quán)限TGT的緩存證書(shū),然后執(zhí)行:

深入解讀MS14-068漏洞:微軟精心策劃的后門(mén)?

你會(huì)發(fā)現(xiàn),在域用戶下,該漏洞也是可以利用的!


好特網(wǎng)發(fā)布此文僅為傳遞信息,不代表好特網(wǎng)認(rèn)同期限觀點(diǎn)或證實(shí)其描述。

相關(guān)視頻攻略

更多

掃二維碼進(jìn)入好特網(wǎng)手機(jī)版本!

掃二維碼進(jìn)入好特網(wǎng)微信公眾號(hào)!

本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]

湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2025 haote.com 好特網(wǎng)