国外安全研究员@elad_shamir在2019年一月底发表了一篇名为”Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory”的文章,不同于以往利用无约束委派以及传统约束委派攻击,首次提出并详细介绍利用基于资源的约束委派进行活动目录攻击的方式。文中详细解释了该攻击发现过程,对协议的分析以及攻击原理,并给出不同场景下基于此攻击进行的远程代码执行,本地权限提升等操作。
绿盟科技M01N Red Team对基于该攻击的本地权限提升进行了研究和复现,并在此基础上结合PowerShell Remoting对进一步获得域管理员权限进行了分析探讨。
委派
委派(Delegation)是一种让用户可以委托服务器代表自己与其他服务进行验证的功能,它允许服务账户在活动目录中模拟其他域用户身份,主要用于当服务需要以某个用户的身份来请求访问其他服务资源的场景。委派分为无约束委派,传统的约束委派以及基于资源的约束委派。
无约束委派(Unconstrained Delegation)是一种风险性极大的委派方式,它通过TGT转发使服务器具有模拟用户的能力。服务账户根据用户发给自己的可转发的TGT代表用户请求其他任何服务,由此可知,一旦开启了无约束委派的服务账户被攻陷,用户身份将被滥用。已有较多分析无约束委派攻击利用的文章,在Windows的官方博客中也建议用户删除使用Kerberos无约束委派的账户。 本文在此不再做详细解释。
为了解决无约束委派的问题,微软更新发布了Kerberos协议拓展S4U,该拓展包含两个协议:传统的约束委派(Constrained Delegation,aka S4U2Proxy)和协议转换(Protocol Transition, aka S4U2Self).
S4U2Proxy (约束委派):
为了方便理解,本文在此假设A为IIS Web Server,B为SQL Server,A需要使用数据库B以支撑用户访问。通过设置约束委派,可以让A模拟用户,验证并访问B以获取相应的资源。
用户通过域控制器请求访问服务A,域控验证并返回A的TGS服务票据,用户发送此TGS给A与A认证并建立连接。若该服务A允许委派给服务B,则A能使用S4U2Proxy协议将用户发送给自己的TGS (此TGS必须是可转发的,后文中会提到)再转发给域控制器认证服务器,为用户请求访问服务B的TGS,此后,A便能使用新获得的TGS模拟用户访问服务B。如下图所示:
S4U2Proxy
S4U2Self (协议转换):
上图中用户是通过Kerberos协议与服务A进行认证的,而当用户以其他方式(如NTLM认证,基于表单的认证等方式)与Web服务器进行认证后,用户是无法向Web服务器提供请求该服务的服务票据TGS的,因而服务器也无法进一步使用S4U2Proxy协议请求访问服务B。S4U2Self协议便是解决该问题的方案,被设置为TrustedToAuthForDelegation的服务能够调用S4U2Self向认证服务器为任意用户请求访问自身的可转发的服务票据,此后,便可通过S4U2Proxy使用这张TGS向域控制器请求访问B的票据:
S4U2Self
然而,传统的约束委派中仍然存在一些缺点,如无法进行跨域委派。微软在Windows Server 2012中引入了基于资源的约束委派,相对于传统的约束委派,主要有三处改进:
- 委派的权限授予给了拥有资源的后端(B)而不再是前端(A)
- 不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑”msDS-AllowedToActOnBehalfOfOtherIdentity”属性的能力
- 委派功能现在可以跨域和林
基于资源的约束委派(Resource-Based Constrained Delegation)是一种允许资源自己去设置哪些账户委派给自己的约束委派。
传统的约束委派是“正向的”,通过修改服务A属性”msDS-AllowedToDelegateTo”,添加服务B的SPN(Service Principle Name),设置约束委派对象(服务B),服务A便可以模拟用户向域控制器请求访问服务B以获得服务票据(TGS)来使用服务B的资源。
而基于资源的约束委派则是相反的,通过修改服务B属性”msDS-AllowedToActOnBehalfOfOtherIdentity”,添加服务A的SPN,达到让服务A模拟用户访问B资源的目的。
权限提升
S4U攻击原理
该攻击由国外安全研究员Elad Shami提出,他在文章指出,无论服务账号的UserAccountControl属性是否被设为TrustedToAuthForDelegation, 服务自身都可以调用S4U2Self为任意用户请求访问自己的服务票据。但是当没有设置时, 通过S4U2Self请求到的TGS将是不可转发的,前文中数次提到可转发的TGS服务票据,微软给出了”forwardable”标志位的作用:
forwardable: A flag, as specified in [RFC4120] section 2.6, used in an S4U2self KRB_TGS_REQ message to request that the resulting service ticket be marked as forwardable, allowing it to be used in a subsequent S4U2proxy KRB_TGS_REQ message.
通过S4U2Self获得的服务票据被标志为可转发时,该票据可以在接下来的S4U2Proxy中被使用,而不可转发的TGS是无法通过S4U2Proxy转发到其他服务进行传统的约束委派认证的。令人意外的是,不可转发的TGS竟然可以用于基于资源的约束委派。S4U2Proxy会接收这张不可转发的TGS,请求相关服务并最后得到一张可转发的TGS。
根据官方文档的描述,这并不是一个设计漏洞:
If the service ticket in the additional-tickets field is not set to forwardable<20> and the PA-PAC- OPTIONS [167] ([MS-KILE] section 2.2.10) padata type has the resource-based constrained delegation bit:
- Not set, then the KDC MUST return KRB-ERR-BADOPTION with STATUS_NO_MATCH.
- Set and the USER_NOT_DELEGATED bit is set in the UserAccountControl field in the KERB_VALIDATION_INFO structure ([MS-PAC] section 2.5), then the KDC MUST return KRB- ERR-BADOPTION with STATUS_NOT_FOUND.
引用博客文章中的一张图说明该攻击步骤:
DACL Abuse
如果我们能够在B上配置基于资源的约束委派让服务A访问(拥有修改服务B的msDS-AllowedToActOnBehalfOfOtherIdentity属性权限),并通过服务A使用S4U2Self向域控制器请求任意用户访问自身的服务票据,最后再使用S4U2Proxy转发此票据去请求访问服务B的TGS,那么我们将能模拟任意用户访问B的服务!
配置委派
每个资源都可以通过LDAP为自己配置基于资源的约束委派,如果我们能拿到计算机账号的密码或TGT,或直接拿到本地管理员账户,便能使用Powershell直接为该计算机(服务)账号配置基于资源的约束委派。但当我们只是一个普通的域用户时,并没有权限(如GenericAll、GenericWrite、WriteDacl等)为服务修改msDS-AllowedToActOnBehalfOfOtherIdentity属性。
如果我们能诱使计算机账户通过HTTP进行无签名或加密的NTLM认证,通过NTLM中继攻击,将认证转发到LDAP服务,便能为该账户配置委派。但是,大部分由计算机账户发起的连接都会协商签名,而位于域控制器的LDAP服务会忽略所有没有签名的信息。因此,我们需要一个不会协商签名的客户端进行连接认证,如Windows 10/Windows Server 2016/2019上默认安装的WebDAV客户端。
Elad Shamir研究发现,当用户在Windows 10/2016/2019上修改账户图片时,SYSTEM会打开图片读取文件属性。当我们将本地文件路径修改为UNC (Universal Naming Convention) 路径时,系统将会访问该路径并进行NTLM认证以获得图片信息。通过搭建一个NTLM中继服务器,将NTLM认证中继到域控制器的LDAP服务上以计算机账户权限为自身设置基于资源的约束委派,便能完成上文中设置服务B委派设置的工作。
攻击实现
- 获得一台计算机A的普通用户权限,使用Powermad创建一个新的计算机账户(计算机账户具备SPN属性)
此处的普通用户必须是域用户,不能使用本地账户:
- Web客户端默认只会在内网中与主机进行自动认证,这就意味者我们的中继服务器需要有DNS记录,因为以”点”分的IP地址会阻止计算机域名被成功识别,而Windows默认所有经过身份验证的用户都可以在活动目录集成DNS区域ADIDNS Zone(Active Directory-Integrated DNS Zone) 中进行安全的动态更新:
使用刚刚创建的计算机账户添加DNS记录:
此处密码为刚刚创建的计算机账户密码。
- 使用WebDAV NTLM relay Server脚本在攻击机器上搭建中继服务器(IP地址的域控制器IP):
- 在目标计算机上更改账户图片(此处的低权限用户可以是本地普通用户或域普通用户)。
ServiceB的WebDAV客户端使用PROPFIND请求方法向中继服务器发起无签名的NTLM认证并请求获取图片的属性:
服务器中继NTLM凭证在LDAP会话中使用(连接LDAP服务器进行查询和更新操作,修改ServiceB的msDS-AllowedToActOnBehalfOfOtherIdentity属性以完成基于资源的约束委派的配置):
可以看到,通过NTLM中继,服务器已经在LDAP上完成为服务B配置了基于资源的约束委派的操作。
- 使用Rubeus进行完整的S4U攻击以获得任意用户访问服务B的TGS:
(此处rc4为新创建的计算机账户的NTLM Hash,可以在攻击计算机上创建相同密码账户以获得此Hash)
此时我们已经为域管理员账户请求了访问ServiceB的CIFS(Common Internet File System)服务的服务票据。
- 使用Rubeus进行票据传递(PTT, Pass-The-Ticket)攻击:
可以看到,以当前普通域用户权限是无法访问ServiceB的CIFS服务的:
进行票据传递攻击:
通过pass-the-ticket,Rubeus将票据应用于当前会话,我们还是普通域用户的身份,但是已经可以以域管理员权限访问ServiceB的CIFS 服务了:
此外,经过实验,以上攻击操作也可以通过在一台计算机上配置自建服务(计算机账户)对服务自身的基于资源的约束委派完成本地提权操作。
思考
我们现在已经可以通过S4U攻击获取访问ServiceB任意服务的域管理员身份的服务票据,能否通过这些服务票据进一步获得权限或者以域管理员身份执行命令呢?
根据adsecurity网站中一篇关于银票据(即伪造的TGS服务票据)的利用的文章可知,当ServiceB主机开启了远程管理服务(WinRM)时,我们可以通过请求HTTP和WSMAN的服务票据,利用Powershell Remoting以域管理员身份连接到目标主机:
以上的实验是当我们已经拥有两台域内计算机的普通用户权限,且管理员已经开启了Powershell远程管理服务时,我们可以通过基于资源的约束委派从普通域用户变为域管理员。如果我们把条件简化一下,一个拥有本地管理员权限的域用户能否直接被提权到域管理员呢?
此时我们作为计算机本地管理员,已经拥有修改服务属性为服务配置基于资源的约束委派的权限,便无需通过NTLM中继攻击进行委派的配置,直接为当前计算机账户配置给自己的(反射的)基于资源的约束委派。使用Powershell的Active Directory Module便能完成委派:
使用Mimikatz获得当前计算机账户的Hash值以进行S4U攻击:
开启PSRemoting:
通过S4U攻击获取以域管理员身份访问当前计算机HTTP和WSMAN服务的服务票据:
清空当前域用户的所有票据:
使用Rubeus进行pass-the-ticket攻击,加载域管理员身份票据进当前会话:
使用域管理员身份新建到本地计算机的会话:
但是,我们真的成为域管理员并获得整个域了吗?
可以看到,与域控制器请求数据使被拒绝访问了,难道只有本地管理员权限?抓包分析认证过程(命令:”net user administrator /domain”):
Session Setup Request 1
Session Setup Response 1
Session Setup Request 2
Session Setup Response 2
可以看到,当域管理员向域控制器发起请求,协商后使用的是NTLM认证,并没有使用Kerberos认证。根据名为” The Simple and Protected GSS-API Negotiation Mechanism”的[RFC2478]文档可知,客户端向服务器发送协商请求negTokenInit,告知服务端自己支持的认证协议等信息,服务端返回negTokenTarg(包括选择好的安全机制以及协商结果negResult)完成协商。
negTokenInit Negotiation token sent by the initiator to the target, which contains, for the first token sent, one or more security mechanisms supported by the initiator (as indicated in the field mechTypes) and the service options (reqFlags) that are requested to establish the context. The context flags should be filled in from the req_flags parameter of init_sec_context().
negTokenTarg
Negotiation token returned by the target to the initiator which
contains, for the first token returned, a global negotiation result
and the security mechanism selected (if any).
negResult
The result accept_completed indicates that a context has been
successfully established, while the result accept_incomplete
indicates that additional token exchanges are needed.
(在微软名为” Simple and Protected GSS-API Negotiation Mechanism (SPNEGO) Extension”的官方文档中使用的是新版的[RFC4178]文档,negTokenTarg已经被更改为negTokenResp。)
图中客户端只向域控制器提供了NTLM认证的方式,并在第二次请求(Session Setup Request 2)使用了空的用户名和域名,只提供了主机名(后文中会解释)。
对比一下正常的请求:
Request
Response
建立会话连接的请求中客户端向服务器提供了Kerberos认证方式,服务端接收并采用了MS KRB5的认证方式,使得用户可以直接以域用户身份与域控制器进行验证。
那么为什么域管理员在当前计算机的PSSession中无法使用Kerberos协议进行与域控制器进行认证呢?
国外研究人员将“在多个连接中保持用户Kerberos认证凭证”的方法称为 Kerberos Double Hop。本例中我们便是使用Kerberos身份连接主机进行Powershell远程管理,而又希望以当前在Powershell上的身份与域控进行认证连接以便获得实质上的域管理员权限。为了弄清楚连接后拒绝访问的原因,我们必须先明白Powershell是在会话中是如何工作的。
在PSSession中,Powershell是通过委派用户凭证的方式让用户在远程计算机上执行任务的。用户从计算机A创建会话连接到计算机B,Powershell通过委派,使得计算机B以用户身份执行任务,好像就是用户自己在执行一样。此时,用户试图与其他计算机C建立连接,得到的却是红色的拒绝访问。因为此时并不是以该用户身份请求访问C,而是以计算机B账户请求的,这也解释了前文中客户端与域控制器建立连接时只发送了计算机而不是用户名。
微软在博客中提供了一些在Powershell 远程管理中安全地解决Kerberos Double Hop问题的方案。其中不使用用户明文密码的只有前文中介绍的三种委派。
为了证明该理论,我们在域控制器上为当前计算机设置无约束委派(仅为实验,请不要配置该委派方式):
在配置完约束委派之后,已经能够在Powershell远程会话中以域管理员身份向域控制器请求数据执行命令了:
回到最开始的话题,我们利用基于资源的约束委派进行了本地权限提升的攻击,摇身一变成为域管理员,而又因为Powershell Remoting委派的本质,变为实质上的本地管理员。其实在一开始获得域管理员的身份访问计算机的服务票据时,已经限制了域管理员的作用域。
结论
通过利用基于资源的约束委派,攻击者能够令普通的域用户以域管理员身份访问本地计算机的服务,实现本地权限提升。
Powershell Remoting通过委派用户凭证的方式使用户在远程计算机上执行任务,本质上却是远程计算机模拟用户进行操作,如果该计算机并没有被配置委派,登录到Powershell会话中的用户无则法再次使用自己凭证请求访问其他远程计算机。
修复
将高权限账户设置为敏感账户,不能被委派:
可以看到,Rubeus已经无法通过S4U2Proxy为Administrator用户请求服务。
Elad Shamir在文章最后的缓解因素中指出被标志为委派敏感(Sensitive for Delegation)账户和被保护组(“Protected Users Group”)用户并不受此攻击(除了S4U2Self攻击)影响,但在实际测试过程中发现,尽管域管理员账户加入了被保护用户组,仍然可以为其请求有效的服务票据并访问服务。此处有待考证。
请不要把服务或计算机账户加入”Protected Users”组,微软官方文档认为此行为会影响正常的认证并给出了警告:
启用LDAP签名 能修复上述实验中通过NTLM中继的本地提权。
检测
在活动目录中检查配置了基于资源的约束委派的服务器,并检查其可委派对象。在目录服务对象修改事件(Event 5136)中可检测到基于资源的约束委派配置变化(需要开启审核目录服务更改)。
使用Powershell的Active Directory模块可以直接列出配置了基于资源的约束委派的资源对象:
Get-ADComputer –Filter {msDS-AllowedToActOnBehalfOfOtherIdentity –like “*”} | Out-GridView
列出允许委派到资源的对象:
Get-ADComputer –LDAPFilter “(name=*)” –Properities PrincipalsAllowedToDelegateToAccount | Out-GridView
参考资料
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html#case-study-2-windows-1020162019-lpe
https://adsecurity.org/?p=2011
https://blog.netspi.com/exploiting-adidns/
https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/
https://alsid.com/company/news/kerberos-resource-based-constrained-delegation-new-control-path
https://blog.kloud.com.au/2013/07/11/kerberos-constrained-delegation/
https://tools.ietf.org/html/rfc2478
https://www.ietf.org/rfc/rfc4178.txt
https://blogs.technet.microsoft.com/askds/2008/06/13/understanding-kerberos-double-hop/
https://devblogs.microsoft.com/scripting/enabling-multihop-remoting/
关于M01N Team
绿盟科技M01N红队安全研究团队专注于Red Team、APT等高级攻击技术、战术及威胁研究,涉及WEB安全、终端安全、AD安全、云安全等相关领域。通过研判现网攻击技术发展方向,以攻促防,为风险识别及威胁对抗提供决策支撑,全面提升安全防护能力。