0x01 Kerberos簡介
在Kerberos認證中,最主要的問題是如何證明“你是你”的問題,如當一個Client去訪問Server服務器上的某服務時,Server如何判斷Client是否有權限來訪問自己主機上的服務,同時保證在這個過程中的通訊內容即使被攔截或篡改也不影響通訊的安全性,這正是Kerberos解決的問題。在域滲透過程中Kerberos協議的攻防也是很重要的存在。
1.1 Kerberos協議框架
在Kerberos協議中主要是有三個角色的存在:
1.訪問服務的Client
2.提供服務的Server
3.KDC(Key Distribution Center)密鑰分發中心
其中 KDC 服務默認會安裝在一個域的域控中,而 Client 和 Server 為域內的用戶或者是服務,如 HTTP 服務, SQL 服務。在 Kerberos 中 Client 是否有權限訪問 Server 端的服務由 KDC 發放的票據來決定。
kerberos的簡化認證認證過程如下圖
如果把Kerberos中的票據類比為一張火車票,那么Client端就是乘客,Server端就是火車,而KDC就是就是車站的認證系統。如果Client端的票據是合法的(由你本人身份證購買並由你本人持有)同時有訪問Server端服務的權限(車票對應車次正確)那么你才能上車。當然和火車票不一樣的是Kerberos中有存在兩張票,而火車票從頭到尾只有一張。
由上圖中可以看到 KDC 又分為兩個部分:
Authentication Server: AS 的作用就是驗證Client端的身份(確定你是身份證上的本人),驗證通過就會給一張 TGT(Ticket Granting Ticket)票給 Client 。
Ticket Granting Server: TGS 的作用是通過AS發送給Client的票(TGT)換取訪問Server端的票(上車的票ST)。ST(ServiceTicket)也有資料稱為TGS Ticket,為了和 TGS 區分,在這里就用ST來說明。
KDC服務框架中包含一個KRBTGT賬戶,它是在創建域時系統自動創建的一個賬號,可以暫時理解為他就是一個無法登陸的賬號。
1.2 Kerberos認證流程
當 Client 想要訪問 Server 上的某個服務時,需要先向 AS 證明自己的身份,然后通過 AS 發放的 TGT 向 Server 發起認證請求,這個過程分為三塊:
The Authentication Service Exchange Client與AS的交互
The Ticket-Granting Service (TGS) Exchange Client與TGS的交互
The Client/Server Authentication Exchange Client與Server的交互
1.ASREQ: Client向KDC發起ASREQ,請求憑據是Client hash加密的時間戳
2.AS_REP: KDC使用Client hash進行解密,如果結果正確就返回用krbtgt hash加密的TGT票據,TGT里面包含PAC,PAC包含Client的sid,Client所在的組。
3.TGSREQ: Client憑借TGT票據向KDC發起針對特定服務的TGSREQ請求
4.TGS_REP: KDC使用krbtgt hash進行解密,如果結果正確,就返回用服務hash 加密的TGS票據(這一步不管用戶有沒有訪問服務的權限,只要TGT正確,就返回TGS票據)
5.AP_REQ: Client拿着TGS票據去請求服務
6.AP_REP: 服務使用自己的hash解密TGS票據。如果解密正確,就拿着PAC去KDC那邊問Client有沒有訪問權限,域控解密PAC。獲取Client的sid,以及所在的組,再根據該服務的ACL,判斷Client是否有訪問服務的權限。
1.3 PAC
在Kerberos最初設計的幾個流程里說明了如何證明 Client 是 Client 而不是由其他人來冒充的,但並沒有聲明 Client 有沒有訪問 Server 服務的權限,因為在域中不同權限的用戶能夠訪問的資源是有區別的。
所以微軟為了解決這個問題在實現 Kerberos 時加入了 PAC 的概念, PAC 的全稱是 Privilege Attribute Certificate(特權屬性證書)。可以理解為火車有一等座,也有二等座,而PAC就是為了區別不同權限的一種方式。
(1)PAC的實現
當用戶與 KDC 之間完成了認證過程之后, Client 需要訪問 Server 所提供的某項服務時, Server 為了判斷用戶是否具有合法的權限需要將 Client 的 User SID 等信息傳遞給 KDC, KDC 通過 SID 判斷用戶的用戶組信息,用戶權限等, 進而將結果返回給 Server, Server 再將此信息與用戶所索取的資源的 ACL 訪問控制列表(Access Control Lists,ACL)進行比較,最后決定是否給用戶提供相應的服務。
PAC會在 AS_REP 中 AS 放在 TGT 里加密發送給Client,然后由 Client 轉發給 TGS 來驗證 Client 所請求的服務。
在PAC中包含有兩個數字簽名 PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM ,這兩個數字簽名分別由 Server 端密碼 HASH 和 KDC 的密碼 HASH 加密。
同時 TGS 解密之后驗證簽名是否正確,然后再重新構造新的 PAC 放在 ST 里返回給客戶端,客戶端將 ST 發送給服務端進行驗證。
特別說明的是,PAC對於用戶和服務全程都是不可見的。只有KDC能制作和查看PAC。
(2)Server與KDC
PAC可以理解為一串校驗信息,為了防止被偽造和篡改,原則上是存放在 TGT 里,並且 TGT 由 KDC hash 加密。同時尾部會有兩個數字簽名,分別由KDC密碼和server密碼加密,防止數字簽名內容被篡改。
同時PAC指定了固定的 User SID 和 Groups ID,還有其他一些時間等信息,Server 的程序收到 ST 之后解密得到 PAC 會將 PAC 的數字簽名發送給 KDC,KDC 再進行校驗然后將結果已 RPC 返回碼的形式返回給 Server。
0x02 Kerberos與SPN
2.1 SPN簡介
服務主體名稱(SPN:ServicePrincipal Names)是服務實例(可以理解為一個服務,比如HTTP、MSSQL)的唯一標識符。Kerberos 身份驗證使用 SPN 將服務實例與服務登錄帳戶相關聯。如果在整個林或域中的計算機上安裝多個服務實例,則每個實例都必須具有自己的 SPN 。如果客戶端可能使用多個名稱進行身份驗證,則給定服務實例可以具有多個 SPN 。SPN 始終包含運行服務實例的主機的名稱,因此服務實例可以為其主機的每個名稱或別名注冊SPN。
如果用一句話來說明的話就是如果想使用 Kerberos 協議來認證服務,那么必須正確配置SPN。
2.2 SPN格式與配置:
在SPN的語法中存在四種元素,兩個必須元素和兩個額外元素:
<serviceclass>/<host>:<port>/<service name>
<service class>:標識服務類的字符串
<host>:服務所在主機名稱
<port>:服務端口
<service name>:服務名稱
其中<service class>
和<host>
為必須元素
例:
如果我想把域中一台主機 S2 中的 MSSQL 服務注冊到 SPN 中則可以使用命令:
Setspn-A MSSQLSvc/s2.yunying.lab:1433 tsvc
注冊成功之后可以通過以下命令來查看已經注冊的SPN:
setspn -Tyunying.lab –q */*
或
setspn –q */*
SPN在其注冊的林中必須是唯一的。如果它不唯一,則身份驗證將失敗。
在注冊SPN時,可以使用 NetBIOS 名稱,如s2。也可以使用 FQDN(FullyQualified Domain Name全限定域名) ,如 s2.yunying.lab 。有可能存在某一種名稱注冊的 SPN 不能成功訪問的情況,如果沒有配置正確可以換一種名稱試一試。
一般情況下基於主機的服務會省略后面兩個組件,格式為
MSSQLSvc/s2.yunying.lab
如果服務使用非默認端口或者此主機存在多個服務實例的情況下,需要包括端口號或服務名:
MSSQLSvc/ s2.yunying.lab:1433
2.3 SPN掃描
在了解了 Kerberos 和 SPN 之后我們可以通過 SPN 來獲取我們想要的信息,比如想知道域內哪些主機安裝了什么服務,我們就不需要再進行批量的網絡端口掃描。
在一個大型域中通常會有不止一個的服務注冊 SPN ,所以可以通過 “SPN掃描” 的方式來查看域內的服務。相對於通常的網絡端口掃描的優點是不用直接和服務主機建立連接,且隱蔽性更高。
(1)掃描工具
掃描工具有多種,下面挑選幾種較為常見的工具來說明一下:
Discover-PSMSSQLServers: 是 Powershell-AD-Recon 工具集中的一個工具,用來查詢已經注冊了的 MSSQL 類型的 SPN。
GetUserSPNs.ps1: 是 Kerberoast 工具集中的一個 powershell 腳本,用來查詢域內注冊的 SPN
PowerView.ps1: 在 Powersploit 和 Empire 工具里都有集成,PowerView 相對於上面幾種是根據不同用戶的 objectsid 來返回,返回的信息更加詳細。
(2)原理說明
在 SPN 掃描時我們可以直接通過腳本,或者命令去獲悉內網已經注冊的 SPN 內容。那如果想了解這個過程是如何實現的,就需要提到 LDAP 協議。
LDAP協議全稱是LightweightDirectory Access Protocol,一般翻譯成輕量目錄訪問協議。是一種用來查詢與更新 Active Directory 的目錄服務通信協議。AD 域服務利用 LDAP 命名路徑(LDAP naming path)來表示對象在 AD 內的位置,以便用它來訪問 AD 內的對象。
那些 Powershell 腳本其實主要就是通過查詢 LDAP 的內容並對返回結果做一個過濾,然后展示出來。
0x03 Kerberoasting
在前面介紹 Kerberos 的認證流程時說到,在 TGS_REP 中,TGS 會返回給 Client 一張票據 ST,而 ST 是由 Client 請求的 Server 端密碼進行加密的。當 Kerberos 協議設置票據為 RC4 方式加密時,我們就可以通過爆破在 Client 端獲取的票據 ST,從而獲得 Server 端的密碼。
下圖為設置 Kerberos 的加密方式,在域中可以在域控的“組策略管理”中進行設置:設置完成之后運行里輸入“gpupdate”刷新組策略,策略生效。
3.1 早期的Kerberoasting
攻擊流程:
1.在域內主機s1中通過Kerberoast中的GetUserSPNs.ps1或者GetUserSPNs.vbs進行SPN掃描。
2.根據掃描出的結果使用微軟提供的類 Kerberos Requestor Security Token 發起 kerberos 請求,申請 ST 票據。
PS C:\> Add-Type -AssemblyNameSystem.IdentityModel
PS C:\> New-ObjectSystem.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList"MSSQLSvc/s2:1433"
可以看到這個過程通過AS-REQ、AS-REP、TGS-REQ、TGS-REP這四個認證流程,獲取到 RC4 方式加密的票據。
3.Kerberos 協議中請求的票據會保存在內存中,可以通過 klist 命令查看當前會話存儲的 kerberos 票據:
這里可以借助 mimikatz 導出:
使用 kerberoast 工具集中的 tgsrepcrack.py 工具進行離線爆破,成功得到 tsvc 賬號的密碼 admin1234! :
3.2 Kerberoasting的“新姿勢”
攻擊流程:
1.在之前的 Kerberoasting 中需要通過 mimikatz 從內存中導出票據,這里使用的是Empire中的Invoke-Kerberoast.ps1;Invoke-Kerberoast 通過提取票據傳輸時的原始字節,轉換成John the Ripper或者 HashCat 能夠直接爆破的字符串。
Invoke-kerberoast –outputformat hashcat |fl
2.這里–outputformat參數可以指定輸出的格式,可選John the Ripper和Hashcat兩種格式,這里以Hashcat做演示:
這個腳本申請訪問的是 MSSQLSvc/s2.yunying.lab:1433
這個 SPN ,查看數據包可以看到 Invoke-Kerberoast 輸出的 Hash 值就是 TGS-REP 中返回的票據內容,然后拼接成了 Hashcat 可以直接爆破的格式(以 $krb5tgs$23*
開頭的)
3.可以把內容保存至文檔,也可以直接重定向到TXT文件:
PS C:> Invoke-Kerberoast-Outputformat Hashcat | fl > test1.txt
4.使用HASHCAT工具進行破解:
PSC:> hashcat64.exe –m 13100 test1.txt password.list --force
在這里 –m
表示選擇不同的加密類型,其中 13100 對應的是 Kerberos 5 TGS-REP 類型的密文。
可以看到這里已經離線破解成功,輸出了s2的密碼admin1234!。
Kerberoasting 的本質是通過破解在 Kerberos 認證流程中的 TGS_REP 這個過程中 TGS 返回給 Client 的票據內容來進行密碼的獲取,在一個大型的域中還是有一定的利用價值,並且這種方式是離線爆破,過程較為隱蔽。
0x04 MS14-068
當我們拿到了一個普通域成員的賬號后,想繼續對該域進行滲透,拿到域控服務器權限。如果域控服務器存在 MS14_068 漏洞,並且未打補丁,那么我們就可以利用 MS14_068 快速獲得域控服務器權限。
MS14-068編號CVE-2014-6324,補丁為3011780,如果自檢可在域控制器上使用命令檢測。
systeminfo |find "3011780"
如下,為空說明該服務器存在MS14-068漏洞。
這個之前有寫過:[內網滲透]MS14-068復現(CVE-2014-6324)
這個漏洞產生的原因主要是以下幾個問題:
A、在域中默認允許設置 Include-pac 的值為 False(不能算漏洞,應該是微軟對於某些特定場景的特殊考慮設計出的機制)
B、PAC 中的數字簽名可以由 Client 端指定,並且Key的值可以為空
C、PAC 的加密方式也可以由 Client 指定,並且Key的值為 generate_subkey 函數生成的16位隨機數
D、構造的 PAC 中包含高權限組的 SID 內容
通過以上幾點, Client 完全偽造了一個 PAC 發送給 KDC ,並且 KDC 通過 Client 端在請求中指定的加密算法來解密偽造的 PAC 以及校驗數字簽名,並驗證通過。KDC 在根據對偽造的 PAC 驗證成功之后,返回給 Client 端一個新的TGT,也就是說這時 Client 已經獲得了一張包含有高權限 PAC 內容的正常的TGT票據(564eab開頭)。
在這個漏洞中主要的問題是存在於KDC會根據客戶端指定PAC中數字簽名的加密算法,以及PAC的加密算法,來校驗PAC的合法性。這使得攻擊者可通過偽造PAC,修改PAC中的SID,導致KDC判斷攻擊者為高權限用戶,從而導致權限提升漏洞的產生。
0x05 Golden Ticket
5.1 簡介
Golden Ticket(下面稱為金票)是通過偽造的 TGT(Ticket Granting Ticket),因為只要有了高權限的 TGT ,那么就可以發送給 TGS 換取任意服務的 ST 。可以說有了金票就有了域內的最高權限。
制作金票的條件:
域名稱
域的SID值
域的KRBTGT賬戶密碼HASH
偽造用戶名,可以是任意的
5.2 實驗流程
1.金票的生成需要用到 krbtgt 的密碼 HASH 值,可以借助 mimikatz 來獲取 krbtgt 的值:
lsadump::dcsync/domain:yunying.lab /user:krbtgt
如果已經通過其他方式獲取到了 KRBTGT HASH 也可以直接進行下一步。
2.得到 KRBTGT HASH 之后使用 mimikatz 中的 kerberos::golden 功能生成金票 golden.kiribi,即為偽造成功的TGT。
kerberos::golden /admin:administrator /domain:yunying.lab /sid:*** /krbtgt:*** /ticket:golden.kiribi
參數說明:
/admin: 偽造的用戶名
/domain: 域名稱
/sid: SID值,注意是去掉最后一個-后面的值
/krbtgt: krbtgt的HASH值
/ticket: 生成的票據名稱
3.金票的使用:
通過 mimikatz 中的 kerberos::ptt 功能(Pass The Ticket)將 golden.kiribi 導入內存中:
4.已經可以通過dir成功訪問域控的共享文件夾。
這樣的方式導入的票據20分鍾之內生效,如果過期再次導入就可以,並且可以偽造任意用戶。
0x06 Silver Tickets
6.1 簡介
Silver Tickets(下面稱銀票)就是偽造的 ST(Service Ticket),因為在 TGT 已經在 PAC 里限定了給 Client 授權的服務(通過 SID 的值),所以銀票只能訪問指定服務。
制作銀票的條件:
域名稱
域的SID值
域的服務賬戶的密碼HASH(不是krbtgt,是域控)
偽造的用戶名,可以是任意用戶名,這里是silver
6.2 實驗流程
1.首先我們需要知道服務賬戶的密碼 HASH ,這里同樣拿域控來舉例,通過 mimikatz 查看當前域賬號 administrator 的 HASH 值。注意,這里使用的不是 Administrator 賬號的HASH,而是DC$ 的 HASH。
2.通過mimikatz生成銀票:
kerberos::golden /domain:yunying.lab /sid:*** /target:dc.yunying.lab /service:cifs /rc4:*** /user:silver /ptt
參數說明:
/domain: 當前域名稱
/sid: SID值,和金票一樣取前面一部分
/target: 目標主機,這里是 dc.yunying.lab
/service: 服務名稱,這里需要訪問共享文件,所以是 cifs
/rc4: 目標主機的 HASH 值
/user: 偽造的用戶名,這里是silver
/ptt: 表示的是 Pass The Ticket攻擊,是把生成的票據導入內存,也可以使用/ticket導出之后再使用kerberos::ptt來導入
3.這時通過 klist 查看本機的 kerberos 票據可以看到生成的票據:
4.可以成功訪問DC的共享文件夾。
dir \\dc.yunying.lab\c$
銀票生成時沒有KRBTGT的密碼,所以不能偽造TGT票據,只能偽造由Server端密碼加密的ST票據,只能訪問指定的服務。
0x07 Enhanced Golden Tickets(增強型金票)
7.1 簡介
在Golden Ticket部分說明可利用 krbtgt 的密碼 HASH 值生成金票,從而能夠獲取域控權限同時能夠訪問域內其他主機的任何服務。但是普通的金票不能夠跨域使用,也就是說金票的權限被限制在當前域內。
7.2 普通金票的局限性
為什么普通金票會被限制只能在當前域內使用?
在上一篇文章中說到了域樹和域林的概念,同時說到YUNYING.LAB為其他兩個域(NEWS.YUNYING.LAB和DEV.YUNYING.LAB)的根域,根域和其他域的最大的區別就是根域對整個域林都有控制權。而域正是根據Enterprise Admins組(下文會說明)來實現這樣的權限划分。在一個域林中,域控權限不是終點,根域的域控權限才是域滲透的終點。
7.3 突破限制
普通的黃金票據被限制在當前域內,在2015年Black Hat USA中國外的研究者提出了突破域限制的增強版的黃金票據。通過域內主機在遷移時SIDHistory屬性中保存的上一個域的SID值制作可以跨域的金票。這里沒有遷移,直接拿根域的SID號做演示。
如果知道根域的 SID 那么就可以通過子域的 KRBTGT 的 HASH 值,使用 mimikatz 創建具有 Enterprise Admins組權限(域林中的最高權限)的票據。環境與上文普通金票的生成相同。
1.通過 whoami /all 可以看到 YUNYING.LAB 中 Enterprise Admins 組的SID號是:
S-1-5-21-4249968736-1423802980-663233003-519
2.通過 klist purge 刪除當前保存的 Kerberos 票據,也可以在 mimikatz 里通過 kerberos::purge 來刪除。
3.然后通過 mimikatz 重新生成包含根域 SID 的新的金票:
注意這里是不知道根域 YUNYING.LAB 的 krbtgt 的密碼 HASH 的,使用的是子域 NEWS.YUNYING.LAB 中的 KRBTGT 的密碼 HASH。
4.然后再通過 dir 訪問 DC.YUNYING.LAB 的共享文件夾,發現已經可以成功訪問。
此時的這個票據票是擁有整個域林的控制權的。我們知道制作增強金票的條件是通過 SIDHistory ,那么防御方法就是在域內主機遷移時進行 SIDHistory 過濾,它會擦除 SIDHistory 屬性中的內容。
0x08 委派
8.1 簡介
委派在域環境中其實是一個很常見的功能,對於委派的利用相較於先前說的幾種攻擊方式較為“被動”,但是一旦利用也會有很大的危害。
先說一下委派是什么意思吧:在域中如果出現 A 使用 Kerberos 身份驗證訪問域中的服務 B,而 B 再利用 A 的身份去請求域中的服務 C ,這個過程就可以理解為委派。
User訪問主機 s2 上的 HTTP 服務,而 HTTP 服務需要請求其他主機的 SQLServer 數據庫,但是 S2 並不知道 User 是否有權限訪問 SQLServer ,這時 HTTP 服務會利用 User 的身份去訪問 SQLServer,只要 User 有權限訪問 SQLServer 服務就能訪問成功。
而委派主要分為非約束委派(Unconstraineddelegation)和約束委派(Constrained delegation)兩個方式,下面分別介紹兩種方式如何實現。
8.2 非約束委派
非約束委派在 Kerberos 中實現時,User 會將從 KDC 處得到的 TGT 發送給訪問的 service1(可以是任意服務),service1 拿到 TGT 之后可以通過 TGT 訪問域內任意其他服務,所以被稱為非約束委派。
非約束委派的設置:
Windows域中可以直接在賬戶屬性中設置:
流程圖如下:
可以看到在前5個步驟中 User 向 KDC 申請了兩個 TGT (步驟2和4),一個用於訪問 Service1 一個用於訪問 Service2 ,並且會將這兩個都發給 Service1 。並且 Service1 會將 TGT2 保存在內存中。
8.3 約束委派
由於非約束委派的不安全性,微軟在 windows2003 中發布了約束委派的功能。約束委派在 Kerberos 中 User 不會直接發送 TGT 給服務,而是對發送給 service1 的認證信息做了限制,不允許 service1 代表 User 使用這個 TGT 去訪問其他服務。這里包括一組名為S4U2Self(Service for User to Self)和S4U2Proxy(Service forUser to Proxy)的 Kerberos 協議擴展。
從下圖可以看到整個過程其實可以分為兩個部分,第一個是S4U2Self的過程(流程1-4),第二個是S4U2Proxy的過程(流程5-10)。
在這個過程中,S4U2Self 擴展的作用是讓 Service1 代表用戶向 KDC 驗證用戶的合法性,並且得到一個可轉發的 ST1。S4U2Proxy 的作用可以說是讓 Service1 代表用戶身份通過 ST1 重新獲取 ST2,並且不允許 Service1 以用戶的身份去訪問其他服務。同時注意 forwardable 字段,有 forwardable 標記為可轉發的是能夠通過 S4U2Proxy 擴展協議進行轉發的,如果沒有標記則不能進行轉發。
約束委派的配置: