Rubeus酷炫的新功能
ofollow,noindex">Rubeus 是具備 @gentilkiwi 的 Kekeo 工具集部分功能的C#版本,1.1.0版本中已經有了一些新的更新,1.2.0版本中又有了另一個新功能。本文將介紹其主要的新功能以及其他一些更改,並深入探討酷炫的新功能——基於密碼更改的假代理TGT和Kerberos。
我想強調 @gentilkiwi 是這些技術的創始人,而本專案只是他工作的重新實現。我將重新實現Kekeo的部分功能。並且會盡力解釋tgt :: deleg / tgtdeleg和misc :: changepw / changepw函式(Kekeo和Rubeus)的內幕,以便每個人都瞭解Benjamin所實現的內容。
首先來看一些背景知識,這有助於澄清一些事情。
一、從TGTs到.kirbis
正如大多數人傳統上所理解的那樣,在Kerberos交換中,使用雜湊(ntlm / rc4_hmac,aes128_cts_hmac,aes256_cts_hmac .etc)從域控制器(也稱為KDC,金鑰分發中心)獲取票據授予票證。Kerberos交換中涉及對KDC / DC進行身份驗證的AS-REQ(身份驗證服務請求),如果成功,則會生成AS-REP(身份驗證服務響應),其中包含TGT。但是,這並不是它所包含的全部內容。
註釋:TGT本身沒用。TGT是使用Kerberos服務(krbtgt)雜湊加密/簽名的不透明blob,因此作為普通使用者是無法解碼的。那麼TGT實際上是如何使用的呢?
在驗證使用者(AS-REQ)時,TGT並不是AS-REP中返回的唯一資料塊。還有一個“enc-part”,它是一個標記的EncKDCRepPart結構,使用使用者的雜湊加密。所使用的雜湊(rc4_hmac,aes256_cts_hmac_sha1等)在初始交換期間進行協商。解密此blob,其中包含一組元資料,包括啟動時間、結束時間和票據的續訂,但最重要的是還包含一個會話金鑰,此會話金鑰也包含在不透明的TGT blob中(它再次用krbtgt雜湊加密)。
那麼使用者/機器如何“使用”TGT?
與TGT一起提供了使用會話金鑰加密的Authenticator,證明客戶端知道在初始認證交換中返回的會話金鑰(包含在TGT中)。這是TGT續訂,服務票據請求,S4U請求等所必需的。
所有這些資料都包含在KRB-CRED結構中,也就是Mimikatz中的.kirbi檔案,這表明可通過已建立的LSA API提交的完整Kerberos憑證重現編碼結構。因此,當我們談論“TGT”時,實際上意味著可用的TGT .kirbi檔案(包含明文會話金鑰),而不僅僅是TGT blob。這是一個重要的區別,我們將更深入的介紹一下。
此外,我想快速介紹一下從許可權提升(高完整性)和非提升中提取Kerberos票據的差異。Rubeus.exe dump命令將採取適當的方法,具體取決於Rubeus正在執行的完整性級別。
如果許可權高,一般方法為:
1.提升到SYSTEM許可權。
2.使用LsaRegisterLogonProcess註冊虛假登入程序,返回LSA伺服器的特權控制代碼。
3.使用LsaEnumerateLogonSessions列舉當前登入會話。
4.對於每個登入會話,構建一個KERB_QUERY_TKT_CACHE_REQUEST結構,指定登入會話的ID和KerbQueryTicketCacheMessage的訊息型別。這將返回有關指定使用者登入會話的所有快取Kerberos票據的資訊。
5.使用KERB_QUERY_TKT_CACHE_REQUEST呼叫LsaCallAuthenticationPackage並解析生成的票據快取資訊。
6.對於來自快取的每一條票據資訊,構建一個KERB_RETRIEVE_TKT_REQUEST結構,其訊息型別為KerbRetrieveEncodedTicketMessage。這表明想要從快取中為特票據證編碼KRB-CRED(.kirbi)blob。 PS-在C#中弄清楚這有點煩人;
7.使用KERB_RETRIEVE_TKT_REQUEST呼叫LsaCallAuthenticationPackage並解析生成的票據資訊.kirbi。
這將返回當前系統上所有使用者的TGT和服務票據的完整.kirbi blob,而無需開啟LSASS的讀取控制代碼。或者可以使用Mimikatz'sekurlsa :: tickets / export命令直接從LSASS的記憶體中匯出所有Kerberos票據,但請記住,這不是唯一的方法。
如果許可權不夠,則方法略有不同:
1.使用LsaConnectUntrusted開啟與LSA的不可信連線。
2.使用訊息型別KerbQueryTicketCacheMessage構建KERB_QUERY_TKT_CACHE_REQUEST,返回有關當前使用者的登入會話的所有快取Kerberos票據的資訊。
3.使用KERB_QUERY_TKT_CACHE_REQUEST呼叫LsaCallAuthenticationPackage並解析生成的票據快取資訊。
4.對於來自快取的每一條票據資訊,構建一個KERB_RETRIEVE_TKT_REQUEST結構,其訊息型別為KerbRetrieveEncodedTicketMessage。這表明我們想要從快取中為特定票據編碼KRB-CRED(.kirbi)blob。
5.使用KERB_RETRIEVE_TKT_REQUEST呼叫LsaCallAuthenticationPackage並解析生成的票據資訊.kirbi。
如果未提升許可權,則從邏輯上僅可以查詢當前登入會話中的票據。此外,在Win7 +中,Windows在從userland查詢時限制了TGT會話金鑰的檢索,因此在轉儲TGT時會得到類似的東西:
這意味著如果沒有提升許可權,則無法為當前使用者提取可用的TGT .kirbis,因為所需的會話金鑰為空。此外,如上面的Mimikatz輸出中所述,Microsoft引入了一個允許返回TGT會話金鑰的登錄檔項(allowtgtsessionkey)。但是,預設情況下並未啟用,並且需要更高許可權。
後面的tgtdeleg一章解釋了Benjamin繞過這個限制的訣竅。
但是,會為服務票據返回會話金鑰。這在以後很重要。
二、asktgs
第一個“大”的新功能是通用服務票據請求:
Rubeus.exe asktgs </ticket:BASE64 | /ticket:FILE.KIRBI> </service:SPN1,SPN2,...> [/dc:DOMAIN_CONTROLLER] [/ptt]
asktgs與asktgt接受相同的/ dc:X / ptt引數。 / ticket:X接受相同base64編碼的.kirbi檔案或磁碟上.kirbi檔案的路徑。此票據需要是TGT的.kirbi(包括會話金鑰,如前所述),因此可以在TGS-REQ / TGS-REP交換中正確請求服務票據。
/ service:SPN引數是必需的,並指定要為其提供服務票據的服務主體名稱(SPN)。此引數接受一個或多個常見的分隔SPN,因此以下內容將起作用:
C:\Temp\tickets>Rubeus.exe asktgt /user:harmj0y /rc4:2b576acbe6bcfda7294d6bd18041b8fe _______ (_____ \| | _____) )__| |_______ _____ |__/| | | |_ \| ___ | | | |/___) | |\ \| |_| | |_) ) ____| |_| |___ | |_||_|____/|____/|_____)____/(___/ v1.0.0 [*] Action: Ask TGT [*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe [*] Using domain controller: PRIMARY.testlab.local (192.168.52.100) [*] Building AS-REQ (w/ preauth) for: 'testlab.local\harmj0y' [*] Connecting to 192.168.52.100:88 [*] Sent 232 bytes [*] Received 1405 bytes [+] TGT request successful! [*] base64(ticket.kirbi): doIFFjCCBRKgAwIBBa...(snip)... C:\Temp\tickets>Rubeus.exe asktgs /ticket:doIFFjCCBRKgAwIBBa...(snip...)== /service:LDAP/">LDAP/primary.testlab.local,cifs/primary.testlab.local /ptt _______ (_____ \| | _____) )__| |_______ _____ |__/| | | |_ \| ___ | | | |/___) | |\ \| |_| | |_) ) ____| |_| |___ | |_||_|____/|____/|_____)____/(___/ v1.0.0 [*] Action: Ask TGS [*] Using domain controller: PRIMARY.testlab.local (192.168.52.100) [*] Building TGS-REQ request for: 'LDAP/primary.testlab.local' [*] Connecting to 192.168.52.100:88 [*] Sent 1384 bytes [*] Received 1430 bytes [+] TGS request successful! [*] base64(ticket.kirbi): doIFSjCCBUagAwIBBaEDA...(snip)... [*] Action: Import Ticket [+] Ticket successfully imported! [*] Action: Ask TGS [*] Using domain controller: PRIMARY.testlab.local (192.168.52.100) [*] Building TGS-REQ request for: 'cifs/primary.testlab.local' [*] Connecting to 192.168.52.100:88 [*] Sent 1384 bytes [*] Received 1430 bytes [+] TGS request successful! [*] base64(ticket.kirbi): doIFSjCCBUagAwIBBaEDAgE...(snip)... [*] Action: Import Ticket [+] Ticket successfully imported! C:\Temp\tickets>C:\Windows\System32\klist.exe tickets Current LogonId is 0:0x570ba Cached Tickets: (2) #0>Client: harmj0y @ TESTLAB.LOCAL Server: cifs/primary.testlab.local @ TESTLAB.LOCAL KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96 Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_delegate name_canonicalize Start Time: 9/30/2018 18:17:55 (local) End Time:9/30/2018 23:17:01 (local) Renew Time: 10/7/2018 18:17:01 (local) Session Key Type: AES-128-CTS-HMAC-SHA1-96 Cache Flags: 0 Kdc Called: #1>Client: harmj0y @ TESTLAB.LOCAL Server: LDAP/primary.testlab.local @ TESTLAB.LOCAL KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96 Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_delegate name_canonicalize Start Time: 9/30/2018 18:17:55 (local) End Time:9/30/2018 23:17:01 (local) Renew Time: 10/7/2018 18:17:01 (local) Session Key Type: AES-128-CTS-HMAC-SHA1-96 Cache Flags: 0 Kdc Called:
如果沒有提升許可權,也不想通過應用上週描述的新TGT來stomp現有登入會話的TGT,則可以請求給定帳戶的TGT並使用此blob與asktgs請求/應用需要的服務票據。
有關服務票據接管的更多資訊,請參閱Sean Metcalf的“ How Attackers Use Kerberos Silver Tickets to Exploit Systems ”帖子中的“Service to Silver Ticket Reference”。
三、tgtdeleg
tgtdeleg功能是Kekeo的tgt ::deleg功能的重新編碼,允許從當前使用者中提取可用的TGT .kirbi,而無需提升系統許可權。這是Benjamin發現的一個非常酷的技巧,我將嘗試詳細解釋,最後介紹操作用例。
有一個稱為通用安全服務應用程式介面(GSS-API)的東西,它是應用程式用來與安全服務互動的通用API。雖然Microsoft沒有正式支援GSS-API,但它確實實現了與Kerberos GSS-API相容的Kerberos安全服務提供程式介面(SSPI),這意味著它應該支援所有常見的Kerberos GSS-API結構/方法。我們將在本文中使用RFC4121作為參考。
基本上,可以使用Windows API來請求委託TGT,此TGT通過SSPI / GSS-API傳送到遠端主機/ SPN。這些結構中包含一個當前使用者的轉發TGT,它使用了用KRB-CRED(.kirbi)結構,該結構在AP-REQ內被加密併發送到目標伺服器。用於加密Authenticator / KRB-CRED的會話金鑰包含在目標SPN的可訪問的快取服務票據中。將這些結合在一起,就能為當前使用者提取這個可用的TGT而無需任何許可權提升!
首先,使用AcquireCredentialsHandle來獲取當前使用者現有Kerberos票據的控制代碼。指定fCredentialUse引數為SECPKG_CRED_OUTBOUND,該引數將“允許本地客戶端憑證準備一個傳出令牌”。
然後使用InitializeSecurityContext從AcquireCredentialsHandle返回的票據控制代碼中啟動“客戶端,出站安全上下文”。此處的技巧是為fContextReq引數指定ISC_REQ_DELEGATE和ISC_REQ_MUTUAL_AUTH標誌。請求委託TGT,意思是伺服器可以使用上下文作為客戶端向其他伺服器進行身份驗證。我們還為具有無約束委派(預設為HOST / DC.domain.com)的伺服器指定SPN。這是我們假裝準備委派請求的SPN /伺服器。
那麼當觸發這個API呼叫時會發生什麼?
首先,進行TGS-REQ / TGS-REP交換以請求我們假裝委託的SPN的服務票據。這樣就可以在目標伺服器和我們正在通訊的機器之間建立共享會話金鑰。此服務票據儲存在本地Kerberos快取中,這意味著我們以後可以提取共享會話金鑰。
接下來,為當前使用者請求轉發的TGT。有關轉發票據的更多資訊,請參閱此處( section here )的“What are forwarded tickets?”部分。KDC將使用當前TGT的單獨會話金鑰返回新TGT。然後,系統使用該轉發的TGT為目標伺服器構建AP-REQ,其請求中的Authenticator包含轉發TGT的可用KRB-CRED編碼。這將在RFC4121的4.1.1 Authenticator Checksum中解釋:
如果一切都成功,我們將得到傳遞給InitializeSecurityContext的pOutput指標所指向的SSPI SecBufferstructure中編碼的AP-REQ(包括新TGT的.kirbi)。我們可以在輸出流中搜索KerberosV5 OID,並從GSS-API輸出中提取AP-REQ。
然後,從快取中提取服務票據會話金鑰,並使用它來解密從AP-REQ中提取的Authenticator。最後,從Authenticator校驗和中提取編碼的KRB-CRED,並將其輸出為可用的TGT .kirbi:
成功!
從操作的角度來看,這是一個小眾特色。主要情況是,在一個至少有一臺無法提升許可權的機器的環境中你有多個客戶端。在這臺機器上,可以使用Rubeus的tgtdeleg提取當前使用者的TGT,並將傳遞給另一臺機器上執行的Rubeus renew函式。這將允許在沒有提升許可權的情況下提取使用者憑證,並將其保留在另一個系統上以供重複使用,有限期最多7天(預設情況下)。
無論這個TTP是否非常有用,理解和重新編碼都有很多樂趣:)
四、changepw
changepw(Kekeo中的misc :: changepw)實現了 @Aorato POC ,允許攻擊者從TGT .kirbi中更改使用者的明文密碼(不知道之前的值)。將此與asktgt以及使用者的rc4_hmac / aes128_cts_hmac_sha1 / aes256_cts_hmac_sha1雜湊相結合,意味著攻擊者可以輕鬆的強制重置使用者的純文字密碼。或者,如果使用Rubeus dump命令(來自許可權提升的上下文),攻擊者只能通過LSA API強制重置使用者密碼。
解釋此過程的RFC是RFC3244(Microsoft Windows 2000 Kerberos更改密碼和設定密碼協議)。下面是傳送到域控制器上埠464(kpasswd)的圖表:
有兩個主要的部分:AP-REQ以及特殊構造的KRB-PRIVASN.1結構。AP-REQ訊息包含使用者的TGT blob,以及使用來自TGT .kirbi的TGT會話金鑰加密的Authenticator。Authenticator必須具有隨機的子會話金鑰集,用於加密KRB-PRIV結構。KRB-PRIV包含新的明文密碼,序列/隨機數和發件人的主機地址(可以是任何東西。)
如果密碼設定成功,則返回KRB-PRIV結構,結果程式碼為0(KRB5_KPASSWD_SUCCESS)。錯誤反映在KRB-ERROR或其他錯誤程式碼中(在RFC3244的第2節末尾指定)。
注意:我不確定原因,但使用tgtdeleg技巧獲取的票據不能與此changepw方法一起使用,會返回一個KRB5_KPASSWD_MALFORMED錯誤。我用Rubeus和Kekeo測試了這個,均返回相同的結果¯\ _ _(ツ)_ /¯
五、其它改動
其他更改/修復:
· s4u操作現在接受多個備用snames(/altservice:X,Y,…)
只執行一次S4U2self / S4U2proxy程序,並將多個備用服務名稱替換為最終生成的服務票據結構,獲得指定數量的sname。
· 修正了kerberoast的雜湊輸出中的encType,來自 @machosec 的KerberosRequestorSecurityToken.GetRequest方法。
· 修復了asreproast雜湊的salt分界線,添加了最終的Hashcat雜湊輸出格式。
· 修復了dump操作中的一個 bug – 完整的ServiceName / TargetName字串,現在已正確提取。
· 添加了一個基於CHANGELOG.md的Keep a Changelog來跟蹤當前和未來的變化。