票據攻擊
- 2019 年 10 月 4 日
- 筆記
No.1
聲明
由於傳播、利用此文所提供的資訊而造成的任何直接或者間接的後果及損失,均由使用者本人負責,雷神眾測以及文章作者不為此承擔任何責任。 雷神眾測擁有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。未經雷神眾測允許,不得任意修改或者增減此文章內容,不得以任何方式將其用於商業目的。
No.2
前言
名詞鋪墊:
Master Key:將密碼通過hash運算得到的一個Key,和密碼具有相同效力。
session Key:session key是一個一段會話中使用的對稱加密密鑰。
KC_Session_Key:KDC和Client之間的session key。
CS_Session_Key:Client和Server之間的session key。
在域內Client想要連接Server需要通過Kerberos認證,在認證的過程中會有一個叫做KDC的第三方。這個KDC通常由域控扮演,其存儲著域內所有賬戶的一個資料庫。首先Kerberos認證會分為六步。第一和第二步為Client和KDC的AS(Authentication Service Exchange)伺服器通訊,第三和第四步為Client和KDC的TGS(Ticket Granting Service)通訊,第五步和第六步為Client和想要連接的Server之間的通訊。

步驟一:Client –〉DC(KDC(as));客戶端向認證伺服器(AS)發送一個認證請求(KRB_AS_REQ)。
發送內容① :[Pre-authentication data(client is ntlm_hash for Timestamp),Client name & realm(DomainNameUsername),Server Name(KDC TGS NAME)] //其中的pre data為自己身份的一些證明。
步驟二:DC(KDC(as)) –〉Client ;認證伺服器(AS)認證通過後(對比用戶名是否在本地資料庫中),給客戶端發送加密後的KC_Session Key和TGT憑證(KRB_AS_REP)。
發送內容②:[Client_ntlm_hash(KC_Session_Key)]和[Krbtgt_ntlm_hash(KC_Session_Key,Client_name(DomainNameUsername),TGT_EndTime)]。這裡我們注意到KDC的AS發送了兩部分內容給Client,第一部分是第一個方括弧里的內容——通過Client的Master Key(就是Client_ntlm_hash)加密的KC_Session_Key。
第二部分是第二個方括弧里的內容——通過KDC的Master Key加密的KC_Session_Key、DomainNameUsername和TGT_EndTime。
步驟三:Client –〉DC(KDC(tgs));Client將AS發送來的第一部分使用自己的Master Key解密得到了KC_Session_Key的值。客戶端拿著自己用KC_Session_Key加密的Authenticator(內含一些表明自己身份的資訊)和TGT憑證向票據生成伺服器(TGS)發起一個認證請求(KRB_TGS_REQ)。
發送內容③ :[KC_Session_Key(Authenticator([DomainNameUsername,ServerName(DomainNameServer)]))],[TGT]
步驟四:DC(KDC(tgs)) –〉Client ;TGS收到Client發來的資訊後想要校驗Authenticator中的內容,以確定Client的身份。但Authenticator的內容是被KC_Session_Key加密的,而KC_Session_Key放在TGT里,所以我們首先要用KDC的Master Key解密TGT,然後取出TGT中的KC_Session_Key解密Authenticator。將Authenticator裡面的內容進行驗證,驗證通過後,給客戶端發送KC_Session_Key加密後的CS_Session_key(KRB_TGS_REP)和使用Server的Maskter Key加密的ticket票據。
發送內容④ :KC_Session_Key加密的CS_Session_key和[Server_ntlm_hash(Tiket(CS_Session_Key,Client_Name(domainNameUsername),TGT_EndTime))]。
步驟五:Client –〉Server ;Client用KC_Session_Key解密被加密了的CS_Session_Key得到CS_Session_Key的值,並用該CS_Session_Key的值去加密一個Authenticator(證明自己身份所用)並帶著一個被加密的ticket去訪問伺服器。
發送內容⑤:CS_Session_Key加密[Authenticator([DomainNameUsername,ServerName(DomainNameServer)])],[Tiket]
步驟六:Server–〉Client ;伺服器使用Server的Master Key解密ticket,獲得ticket中的CS_Session_Key,並用該Session_Key解密Auth資訊,驗證Client身份是否正確正確的話,放行,驗證通過。而如果是雙向認證的話還給客戶端發送一個加密的Authenticator,用於讓客戶端識別是否訪問正確的服務端。
發送內容⑥:CS_Session_Key加密[Authenticator]
No.3
黃金票據
在client和KDC(keberos)的AS(認證伺服器)認證成功之後會返回給client一個TGT和session_key,黃金票據發生在這一步。TGT為[Krbtgt_ntlm_hash(KC_Session_Key,Client_name(DomainNameUsername),TGT_EndTime)]。可以看到,在我們知道了Krbtgt_ntlm_hash,那麼TGT裡面的內容是可以偽造的。
而第三步的發送的數據內容為:[KC_Session_Key(Authenticator([DomainNameUsername,ServerName(DomainNameServer)]))],[TGT]
我們可以修改TGT中的Client_name和Server_Name,從而可以以任意身份訪問任意伺服器。可以看到,問題的根源就在於得到kerberos的ntlm_hash,只要我們有了ntlm_hash,偽造自己的身份(如將自己指定為域控)就可以和任意伺服器連接!
No.4
黃金票據復現
mimikatz.exe "kerberos::golden /domain:<域名> /sid:<域SID> /rc4:< kerberos NTLM Hash> /user:<任意用戶名> /ptt" exit
獲得sid和kerberos ntlm hash可以通過下面方式:
mimikatz(commandline) # privilege::debug
Privilege '20' OK
mimikatz(commandline) # lsadump::dcsync /user:krbtgt
用戶名可以用Administrator
第一段命令執行之後可以執行下面命令驗證黃金票據是否導入成功
dir \ANHENG520.test.comc$
其中AHENG520是test.com這個域中的域控制器
黃金票據導入成功後會回顯出域控中c盤目錄
No.5
白銀票據
和黃金票據不同,白銀票據發送在驗證的第5步。我們需要得到想要連接的伺服器的ntlm_hash。可以看到第5步驗證和第3步驗證的差別在於,黃金票據我們使用的時候得到的是kerberos的hash。那時候我們可以修改Client_Name和,而在白銀票據階段,我們拿到的是想要連接的伺服器的ntlm_hash,此時的Server Master Key已經固定了,只能修改自己的身份而不能修改想要連接的伺服器。也就是說我們可以以任意身份連接某一個伺服器。這也是白銀票據和黃金票據的區別所在—-白銀票據連接某一個指定伺服器,黃金票據可以連接任意伺服器。
No.6
白銀票據復現
mimikatz.exe "kerberos::golden /user:administrator /domain:test.com /sid:S-1-5-21-3794943108-2167292304-869428770-500 /target:ANHENG.test.com /rc4:3daa81d4a957bbd06f94f5ee1bbcff33 /service:cifs /ptt" exit
白銀這裡復現最好用這條命令,reference的文章里的命令有點小問題(他的user欄位錯了)。這裡用到的欄位挨個解釋一下。user就是用戶,domain為域名,sid為域sid,target為要連接的伺服器(這裡我連得是域控),rc4為ANHENG這台域控的ntlm_hash。service就用cifs就行了。
驗證票據是否導入成功
dir \ANHENG.test.comc$
成功會列出域控c盤目錄
END