关键知识

为了能够更轻松地理解后文中的认证原理,需要先了解以下几个关键知识

Active Directory(活动目录)

概念

Windows提供了为企业管理资产、服务、网络对象进行组织化的管理,这非常符合企业架构的管理模式。而承载这些管理机制的就是活动目录服务。如果要搭建一个域,就需要安装活动目录服务。

活动目录服务以域名来划分域的边界,域外就不属于管理范围了,也就是说,一个域对应一个域名,域之间也可以相互信任。

  • Active Directory存储了有关网络对象的信息,并且让管理员和用 户能够轻松地查找和使用这些信息。Active Directory使用了一种 结构化的数据存储方式,并以此作为基础对目录信息进行合乎逻 辑的分层组织。
  • 网络对象分为:用户、用户组、计算机、域、组织单位以及安全 策略等。

功能

  • 服务器及客户端计算机管理:管理服务器及客户端计算机账户, 所有服务器及客户端计算机加入域管理并实施组策略。
  • 用户服务:管理用户域账户、用户信息、企业通讯录(与电子邮 件系统集成)、用户组管理、用户身份认证、用户授权管理等, 按省实施组管理策略。
  • 资源管理:管理打印机、文件共享服务等网络资源。
  • 桌面配置:系统管理员可以集中的配置各种桌面配置策略,如: 用户使用域中资源权限限制、界面功能的限制、应用程序执行特 征限制、网络连接限制、安全配置限制等。
  • 应用系统支撑:支持财务、人事、电子邮件、企业信息门户、办 公自动化、补丁管理、防病毒系统等各种应用系统。

在域中,网络对象可以相互访问,但是在真实情况中,需要对某些部门的计算机进行限制,例如:销售部门不能访问技术部门的服务器。

这个中间就需要Kerberos认证协议来验证网络对象间的权限。

Domain Controller(域控)

域控制器,简称DC,一台计算机,实现用户、计算机的统一管理。

Key Distribution Center(KDC)

秘钥分发中心,简称KDC,默认安装在域控里,包括AS和TGS。

Authentication Service(AS)

身份验证服务,简称AS,用于KDC对Client认证。

Ticket Grantng Service(TGS)

票据授予服务,简称TGS,用于KDC向Client和Server分发Session Key(临时秘钥)。

Active Directory(AD)

活动目录,简称AD,用于存储用户、用户组、域相关的信息。

Client

客户端,指用户。

Server

服务端,可能是某台计算机,也可能是某个服务。

域认证体系 - Kerbroes

打个比方:当 Bob要和 Tom进行通信的时候,Bob就需要向 Tom 证明自己是Bob,直接的方式就是Bob用二人之间的秘密做秘钥加密明文文字生成密文,把密文和明文文字一块发送给 Tom,Tom再用秘密解密得到明文,把明文和明文文字进行对比,若一致,则证明对方是Bob。

但是网络中,密文和文字很有可能被窃取,并且只要时间足够,总能破解得到秘钥。所以不能使用这种长期有效的秘钥,要改为短期的临时秘钥。那么这个临时秘钥就需要一个第三方可信任的机构来提供,即 KDC(Key Distribution Center)秘钥分发中心。

Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被 任意地读取、修改和插入数据。在以上情况下, Kerberos 作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。

Kerberos 认证粗略流程

首先我们根据以下这张图来大致描述以下整个认证过程:

  1. 首先 Client 向域控制器 DC 请求访问 Server,DC 通过去 AD 活动目录中的白名单中查找依次区分 Client 来判断 Client 是否可信。
  2. 认证通过后返回 TGT 给 Client,Client 得到 TGT(Ticket Granting Ticket)。
  3. Client 继续拿着 TGT 请求 DC 访问 Server,TGS 通过 Client 消息中的 TGT,判断 Client 是否有访问权限。
  4. 如果有,则给 Client 有访问 Server 的权限 Ticket,也叫 ST(Service Ticket)。
  5. Client 得到 Ticket 后,再去访问 Server,且该 Ticket 只针对这一个 Server 有效。
  6. 最终 Server 和 Client 建立通信。

Kerberos 认证详细流程

大概分为三个阶段

第一步(AS_REQ & AS_REP)

首Client要通过AS验证,获得TGT

首先,当域内某个客户端用户 Client 想要访问域内的某个服务,于是输入用户名和密码,此时客户端本机会向 KDC 的 AS 认证服务发送一个AS_REQ认证请求。这个AS_REQ里包含了使用Client的NTLM-Hash加密的时间戳以及客户端信息(Client-info)、服务端信息(Server-info)等数据,以及一些其他信息。

当 Client 发送身份信息给 AS 后,AS 会先向活动目录 AD 请求,询问AD中是否有此 Client 用户,如果有的话,就会在AD中取出它的 NTLM-Hash,并对AS_REQ请求中加密的时间戳进行解密,如果解密成功,则证明客户端提供的密码正确,如果时间戳在五分钟之内,则预认证成功。

KDC的AS 认证服务此时会生成一个随机字符串,叫Session-Key AS,使用客户端 Client 的 NTLM-Hash加密Session-Key AS,作为响应包的一部分内容,另一部分内容是使用KDC中krbtgt用户的NTLM Hash加密过的Session-Key AS、时间戳和客户端的信息生成的TGT。然后将这两部分以及 PAC 等信息结合回复给 Client,即AS_REP

创建域控时就会自动生成的 Krbtgt 用户

PAC 中包含的是用户的 SID、用户所在的组等一些信息。

AS-REP 中最核心的东西就是 Session-key 和 TGT。我们平时用 Mimikatz、kekeo、rubeus 等工具生成的凭据是 .kirbi 后缀,Impacket 生成的凭据的后缀是 .ccache。这两种票据主要包含的都是 Session-key 和 TGT,因此可以相互转化。

至此,Kerberos 认证的第一步完成。

第二步(TGS_REQ & TGS_REP)

Client要和TGS认证,获得ST服务票据

客户端 Client 收到 AS 的回复AS_REP后分别获得了 TGT 和加密的 Session-Key AS,因为本来Session-Key AS就是用Client的NTLM-hash加密的,所以它会先用自己的 Client NTLM-hash 解密得到原始的 Session-Key AS,然后它会在本地缓存此 TGT 和原始的 Session-Key AS,如果有需要访问某个服务时就可以构成TGS_REQ提交给TGS,来得到对应的ST。

此时 Client 会使用 Session-Key AS加密时间戳、Client-info、Server-info 等数据作为一部分,由于 TGT 是用 Krbtgt 账户的 NTLM-Hash 加密的,Client 无法解密,所以 Client 会将 TGT 作为另一部分继续发送给 TGS。两部分组成的请求被称为TGS_REQ

TGS 收到该请求,因为收到的第二部分TGT本来就是用 Krbtgt 用户的 NTLM-hash加密的,所以就会先用 Krbtgt 用户的 NTLM-hash 先解密 TGT 得到 Session-key AS、时间戳、Client-info 以及 Server-info。而第一部分是用Session-key AS加密的,所以再用 Session-key AS解密第一部分内容,得到 Client-info、时间戳。

然后将两部分获取到时间戳进行比较,如果时间戳跟当前时间相差太久,就需要重新认证。TGS 还会将这个 Client 的信息与 TGT 中的 Client 信息进行比较,如果两个相等的话,还会继续判断 Client 有没有权限访问 Server,如果都没有问题,认证成功。

认证成功后,KGS 会生成一个 Session-key TGS,并用 Session-key AS 加密 Session key TGS 作为响应的一部分。此 Session-key TGS 用于确保客户端和服务器之间的通信安全。

另一部分是使用服务器 Server 的 NTLM-Hash 加密 Session-key TGS、时间戳以及 Client-info 等数据生成的ST,然后 TGS 将ST和前面Session-key AS 加密的Session key TGS回复给 Client,即TGS_REP

至此,第二步Client 和 KDC 的通信就结束了

第三步(AP-REQ & AP-REP)

Client和Server通信,通过认证的客户端将与服务器建立连接。

客户端 Client 收到TGS_REP后,分别获得了 ST 和加密的 Session-Key TGS。它会先使用先前在本地缓存了的 Session-key AS 解密出了原始的 Session-key TGS。然后它会在本地缓存此 ST 和原始的 Session-Key TGS,当客户端需要访问某台服务器上的服务时会向服务器发送请求。

它会使用 Session-key TGS 加密 Client-info、时间戳等信息作为一部分内容。ST 因为使用的是 Server NTLM-hash 进行的加密,无法解密,所以会原封不动发送给 Server。两部分一块发送给 Server,这个请求即是AP_REQ

Server 收到AP_REQ请求后,用自身的 Server NTLM-Hash 解密了 ST,得到 Session-Key TGS和时间戳以及 Client-info 等数据,再用解出的Session-Key TGS解密出刚刚在客户端加密的Client-info、时间戳等数据。然后与 ST 的Client-info、时间戳等进行一一对比。时间戳有效时间一般时间为8小时。

通过客户端身份验证后,服务器 Server 会拿着 PAC 去询问 DC 该用户是否有访问权限,DC 拿到 PAC 后进行解密,然后通过 PAC 中的 SID 判断用户的用户组信息、用户权限等信息,然后将结果返回给服务端,服务端再将此信息域用户请求的服务资源的 ACL 进行对比,最后决定是否给用户提供相关的服务。通过认证后 Server 将返回最终的AP-REP并与 Client 建立通信。

PAC

前面关于 Kerberos 认证流程的介绍中提到了 PAC(Privilege Attribute Certificate)这个东西,这是微软为了访问控制而引进的一个扩展,即特权访问证书。其中所包含的是各种授权信息, 例如用户所属的用户组, 用户所具有的权限等。

默认情况下,AS_REP信息中将包含一组PAC信息, 也就是说, 用户所得到的TGT(TicketGranting Ticket)会包含用户的授权信息。用户再用包含有授权信息的TGT去申请相应的Service Ticket,KDC在收到这个KBR_AP_REQ请求的时候, 将TGT里的PAC信息解析出来, 加入到Service Ticket里返回。接下来, 当用户向服务器程序提交AP_REQ消息时, 服务器程序则将其中所包含的PAC信息传送给操作系统得到一个访问令牌, 并且同时将这个PAC的数字签名以VERIFY_PAC的消息传输给KDC, KDC再将验证这个PAC的数字签名的结果以RPC返回码的形式告诉服务器, 服务器就可以根据这个结果判断PAC数据的真实性和完整性,并做出最后对AP_REQ的判断。

这样做的好处就是在以后对资源的访问中, 服务端再接收到客户的请求的时候不再需要借助KDC的帮助提供完整的授权信息来完成对用户权限的判断, 而只需要根据请求中所包含的PAC信息直接与本地资源的ACL相比较做出裁决。

PAC的引入其实带来了很多的优点。客户端在访问网络资源的时候服务端不再需要向KDC查询授权信息, 而是直接在本地进行PAC信息与ACL的比较。从而节约了网络资源。

但是,PAC的引入并不是百利而无一害的,PAC在用户的认证阶段引入会导致认证耗时过长。这个问题是因为相较其他的实现,Windows
Kerberos客户端会通过RPC调用KDC上的函数来验证PAC信息,这时候用户会观察到在服务器端与KDC之间的RPC包流量的增加。而另一方面, 由于PAC是微软特有的一个特性,所以启用了PAC的域中将不支持装有其他操作系统的服务器, 制约了域配置的灵活性。

看到了以上缺点,那我们有没有办法不要让服务器程序进行PAC验证以加快验证过程呢?答案是可以的,以下就提供在服务器端关闭PAC验证服务的方法:

  1. 启动注册表编辑器regedit.exe
  2. 找到以下子键:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
  3. 添加一个ValidateKdcPacSignature的键值(DWORD类型), 如果将这个设置为0, 则服务程序就不会进行PAC认证, 而如果将这个键值设置为1, 则相反。
  4. 但是对于这个注册表键值,有以下几点注意事项:
  • 注意:如果服务端并非一个服务程序,而是一个普通应用程序,它将不受以上注册表的影响,而总是进行PAC认证。
  • 注意:如果服务端并非一个程序,而是一个驱动,其认证过程在系统内核内完成,它将不受以上注册表的影响,而永不进行PAC认证。
  • 注意:使用以上注册表项,需要Windows Server 2003 SP2或更新的操作系统。
  • 注意:在运行Windows Server 2008或更新操作系统的服务器上,该注册表项的值缺省为0。

对于单个用户如何指定是否需要进行PAC验证呢?我们可以通过以下方法来控制:

  1. 打开用户属性

  1. 在Account选项卡中把Do not require Kerberos Preauthentication选中,则此用户就不需要进行PAC验证了。

所以,对于PAC的使用还是由用户的应用特性来决定,如果需要减少服务器和KDC之间的认证信息流量从而使得用户能够更快的访问到所需要的资源,我们可以启用PAC;而另一方面,如果用户所属的组非常多,PAC信息本身所占用的容量会变得非常大,使得在做PAC认证的时候,服务器和KDC之间的数据通信变的异常频繁,用户可能因此在认证阶段耗时过长,那么我们就可以考虑禁用PAC来加快验证速度。

在有些服务中并没有验证 PAC 这一步,这也是白银票据能成功的前提,因为就算拥有用户的 Hash,可以伪造 TGS,但是也不能制作 PAC,PAC 当然也验证不成功,但是有些服务不去验证 PAC,这是白银票据成功的前提。

参考:

彻底理解Windows认证 - 议题解读 « 倾旋的博客 (payloads.online)

内网渗透测试:Kerberos 协议& Kerberos 认证原理 - FreeBuf网络安全行业门户

PAC在Kerberos认证协议中的作用(一) | Microsoft Learn

最后修改:2022 年 10 月 22 日
如果觉得我的文章对你有用,请随意赞赏