目录

Kerberos基础

PAC特权属性证书

1. PAC结构

2. PAC凭证信息

3. PAC签名

4. KDC验证PAC

5. PAC在kerberos中的优缺点

Kerberos实验

AS-REQ & AS-REP

1. AS-REQ请求包分析

2. AS-REP回复包分析

(1) TGT认购权证

(2) Logon Session Key

TGS-REQ & TGS-REP

1. TGS-REQ请求包分析

2. TGS-REP回复包分析

(1) ST服务票据

(2) Service Session Key

如何双向认证?(AP-REQ&AP-REP)

1. AP-REQ请求包分析

2. AP-REP回复包分析

S4u2Self&S4u2Proxy

1. S4u2Self

2. S4u2Proxy

Kerberos协议的安全问题

Kerberos协议是由麻省理工学院提出的一种网络身份验证协议,提供了一种在开放的非安全网络中认证识别用户身份信息的方法。它旨在通过使用密钥加密技术为客户端/服务端应用程序提供强身份验证。Kerberos是西方神话中守卫地狱之门的三头犬的名字。之所以使用这个名字是因为Kerberos需要三方的共同参与才能完成一次认证流程。目前主流使用的Kerberos版本为2005年RFC4120(https://www.rfc-editor.org/rfc/rfc4120.html)标准定义的KerberosV5版本,Windows、Linux和Mac OS均支持Kerberos协议。

一.

Kerberos基础

在Kerberos协议中,主要有以下三个角色:

  • 访问服务的客户端:Kerberos客户端是代表需要访问资源的用户进行操作的应用程序,例如打开文件、查询数据库或打印文档。每个Kerberos客户端在访问资源之前都会请求身份验证。

  • 提供服务的服务端:域内提供服务的服务端,服务端都有一个独一的SPN。

  • ‍提供认证服务的KDC(Key Distribution Center,密钥分发中心):KDC密钥发行中心是一种网络服务,它向活动目录域内的用户和计算机提供会话票据和临时会话密钥,其服务帐户为krbtgt。KDC作为活动目录域服务ADDS的一部分运行在每个域控制器上。

    这里说一下krbtgt帐户,该用户是在创建活动目录时系统自动创建的一个账号,其作用是KDC密钥发行中心的服务账号,其密码是系统随机生成的,无法正常登陆主机。在后面的域学习中,会经常和krbtgt帐户打交道,关于该帐户的其他信息会在后面的文章中详细讲解。

如图所示,可以看到krbtgt帐户的信息。

Kerberos是一种基于票据Ticket的认证方式。客户端想要访问服务端的某个服务,首先需要购买服务端认可的 ST服务票据(Service Ticket)。也就是说,客户端在访问服务之前需要先买好票,等待服务验票之后才能访问。但是这张票并不能直接购买,需要一张 TGT认购权证(Ticket Granting Ticket)。也就是说,客户端在买票之前必须先获得一张TGT认购权证。TGT认购权证ST服务票据 均是由KDC(密钥分发中心)发放;因为KDC是运行在域控制器上,所以说TGT认购权证和ST服务票据均是由域控发放。

Kerberos使用TCP/UDP 88端口进行认证,使用TCP/UDP 464端口进行密码重设。如图所示,可以看到域控制器AD01上开放的88和464端口。

Kerberos中一些名词的简称及含义如表所示:

简称

全拼

DC

Domain Controller,域控

krbtgt

KDC密钥发行中心服务账户

KDC

Key Distribution Center:密钥分发中心,由域控担任

AD

Active Directory:活动目录,里面包含域内用户数据库

AS

Authentication Service:认证服务

TGT

Ticket Granting Ticket:TGT认购权证,由KDC的AS认证服务发放

TGS

Ticket Granting Service:票据授予服务

ST

Service Ticket:ST服务票据,由KDC的TGS票据授予服务发放

Kerberos协议有两个基础认证模块:AS_REQ & AS_REPTGS_REQ & TGS_REP ,以及微软扩展的两个认证模块 S4U 和 PAC 。S4U是微软为了实现委派而扩展的模块,分为 S4U2Self 和 S4U2Proxy 。在Kerberos最初设计的流程里只说明了如何证明客户端的真实身份,但是并没有说明客户端是否有权限访问该服务,因为在域中不同权限的用户能够访问的资源是不同的。因此微软为了解决权限这个问题,引入了 PAC (Privilege Attribute Certificate,特权属性证书) 的概念。

在分析AS_REQ & AS_REP 和 TGS_REQ & TGS_REP之前,我们先来看看什么是PAC。

PAC特权属性证书

PAC (Privilege Attribute Certificate,特权属性证书),其中所包含的是各种授权信息、附加凭据信息、配置文件和策略信息等。例如用户所属的用户组, 用户所具有的权限等。在最初的RFC1510中规定的标准Kerberos认证过程中并没有PAC,微软在自己的产品中所实现的Kerberos流程加入了PAC的概念,因为在域中不同权限的用户能够访问的资源是不同的,因此微软设计PAC用来辨别用户身份和权限。

在一个正常的Kerberos认证流程中,KDC返回的TGT认购权证和ST服务票据中都是带有PAC的。这样做的好处就是在以后对资源的访问中, 服务端再接收到客户请求的时候不再需要借助KDC的帮助提供完整的授权信息来完成对用户权限的判断, 而只需要根据请求中所包含的PAC信息直接与本地资源的ACL相比较做出裁决。

1

PAC结构

PAC的顶部结构如下:

typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef unsigned long64 ULONG64;
typedef unsigned char UCHAR;typedef struct _PACTYPE {ULONG cBuffers;ULONG Version;                         PAC_INFO_BUFFER Buffers[1];
} PACTYPE;

这些顶部字段的定义如下:

 · cBuffers:包含数组缓冲区中的条目数。

 · Version:版本

 · Buffers:包含一个PAC_INFO_BUFFER结构的数组。

如图所示,是WireShark抓包的PAC结构部分,可以看到cBuffers、Version和Buffers部分:

而PAC_INFO_BUFFER结构包含了关于PAC的每个部分的信息,这部分是最重要的,结构如下:

typedef struct _PAC_INFO_BUFFER {    ULONG ulType;    ULONG cbBufferSize;    ULONG64 Offset;} PAC_INFO_BUFFER;

类型字段的定义如下:

 · ulType:包含此缓冲区中包含的数据的类型。它可能是以下之一:

· Logon Info (1)

· Client Info Type(10)

· UPN DNS Info (12)

· Sserver Cechksum (6)

· Privsvr Cechksum (7)

 · cbBufferSize:缓冲大小

 · Offset:缓冲偏移量

如图所示,是WireShark抓包的PAC_INFO_BUFFER结构部分。

2

PAC凭证信息

LOGON INFO类型的PAC_LOGON_INFO包含Kerberos票据客户端的凭据信息。数据本身包含在一个KERB_VALIDATION_INFO结构中,该结构是由NDR编码的。NDR编码的输出被放置在LOGON INFO类型的PAC_INFO_BUFFER结构中。如下:

typedef struct _KERB_VALIDATION_INFO {FILETIME Reserved0;FILETIME Reserved1;FILETIME KickOffTime;FILETIME Reserved2;FILETIME Reserved3;FILETIME Reserved4;UNICODE_STRING Reserved5;UNICODE_STRING Reserved6;UNICODE_STRING Reserved7;UNICODE_STRING Reserved8;UNICODE_STRING Reserved9;UNICODE_STRING Reserved10;USHORT Reserved11;USHORT Reserved12;ULONG UserId;ULONG PrimaryGroupId;ULONG GroupCount;[size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;ULONG UserFlags;ULONG Reserved13[4];UNICODE_STRING Reserved14;UNICODE_STRING Reserved15;PSID LogonDomainId;ULONG Reserved16[2];ULONG Reserved17;ULONG Reserved18[7];ULONG SidCount;[size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;PSID ResourceGroupDomainSid;ULONG ResourceGroupCount;[size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
} KERB_VALIDATION_INFO;

主要还是关注以下几个字段:

 · Acct Name:该字段对应的值是用户sAMAccountName属性的值

 · Full Name:该字段对应的值是用户displayName属性的值

 · User RID:该字段对应的值是用户的RID,也就是用户SID的最后部分

 · Group RID:对于该字段,域用户的Group RID恒为513(也就是Domain Users的RID),机器用户的Group RID恒为515(也就是Domain Computers的RID),域控的Group RID恒为516(也就是Domain Controllers的RID)

 · Num RIDS:用户所属组的个数

 · GroupIDS:用户所属的所有组的RID

如图所示,是是WireShark抓包的PAC_LOGON_INFO部分。

3

PAC签名

      PAC中包含两个数字签名:PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM。PAC_SERVER_CHECKSUM是使用服务密钥进行签名,而PAC_PRIVSVR_CHECKSUM是使用KDC密钥进行签名。签名有两个原因。首先,存在带有服务密钥的签名,以验证此PAC由服务进行了签名。其次,带有KDC密钥的签名是为了防止不受信任的服务用无效的PAC为自己伪造票据。

这两个签名分别以PAC_SERVER_CHECKSUM和PAC_PRIVSVR_CHECKSUM类型的PAC_INFO_BUFFER发送。在PAC数据用于访问控制之前,必须检查PAC_SERVER_CHECKSUM签名。这将验证客户端是否知道服务的密钥。而PAC_PRIVSVR_CHECKSUM签名的验证是可选的,默认不开启。它用于验证PAC是否由KDC签发,而不是由KDC以外的具有访问服务密钥的人放入票据中。

签名包含在以下结构中:

typedef struct _PAC_SIGNATURE_DATA {ULONG SignatureType;UCHAR Signature[1];
} PAC_SIGNATURE_DATA, *PPAC_SIGNATURE_DATA;

这些字段定义如下:

 · SignatureType:此字段包含用于创建签名的校验和的类型,校验和必须是一个键控的校验和。

 · Signature:此字段由一个包含校验和数据的字节数组组成。字节的长度可以由包装PAC_INFO_BUFFER结构来决定。

如图所示,是PAC中的签名部分,可以看到PAC_SERVER_CHECKSUM和PAC_PRIVSVR_CHECKSUM。

4

KDC验证PAC

我们注意到,PAC中是有两个签名的:PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM。一个是使用服务密钥(PAC_SERVER_CHECKSUM)进行签名,另一个使用KDC密钥(PAC_PRIVSVR_CHECKSUM)进行签名。当服务端收到客户端发来的AP-REQ消息时,只能校验PAC_SERVER_CHECKSUM签名,而并不能校验PAC_PRIVSVR_CHECKSUM签名。因此,正常来说如果需要校验PAC_PRIVSVR_CHECKSUM签名的话,服务端还需要将客户端发来的ST服务票据中的PAC签名发给KDC进行校验。

但是,由于大部分服务默认并没有KDC验证PAC这一步(需要将目标服务主机配置为验证KDC PAC签名,默认未开启),因此服务端就无需将ST服务票据中的PAC签名发给KDC校验了。这也是白银票据攻击能成功的前提,因为如果配置了需要验证PAC_PRIVSVR_CHECKSUM签名的话,服务端会将这个PAC的数字签名以KRB_VERIFY_PAC的消息通过RPC协议发送给KDC,KDC再将验证这个PAC的数字签名的结果以RPC返回码的形式发送给服务端,服务端就可以根据这个返回结果判断PAC的真实性和有效性了。 因此如果目标服务主机配置了要校验PAC_PRIVSVR_CHECKSUM签名的话,就算攻击者拥有服务密钥,可以制作ST服务票据,也不能伪造KDC的PAC_PRIVSVR_CHECKSUM签名,自然就无法通过KDC的签名校验了。

那么如何配置服务主机开启KDC签名校验呢,根据微软官方文档的描述,若要开启KDC校验PAC,需要有以下条件:

 · 应用程序具有SeTcbPrivilege权限。SeTcbPrivilege权限允许为用户帐户分配“作为操作系统的一部分”。本地系统、网络服务和本地服务帐户都是由windows定义的服务用户帐户。每个帐户都有一组特定的特权。

 · 应用程序是一个服务,验证KDC PAC签名的注册表项被设置为1,默认为0。修改方法如下:

1.启动注册表编辑器regedit.exe

2.找到以下子键:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters

3.添加一个ValidateKdcPacSignature的键值(DWORD类型)。该值为0时,不会进行KDC PAC校验。该值为1时,会进行KDC PAC校验。因此可以将该值设置为1启用KDC PAC校验。

对于验证KDC PAC签名这个注册表键值,有以下几点注意事项:

 · 如果服务端并非一个服务程序,而是一个普通应用程序,它将不受以上注册表的影响,而总是进行KDC PAC校验。

 · 如果服务端并非一个程序,而是一个驱动,其认证过程在系统内核内完成,它将不受以上注册表的影响,而永不进行PAC校验。

 · 使用以上注册表项,需要在Windows Server 2003 SP2或更新的操作系统。

 · 在运行Windows Server 2008或更新操作系统的服务器上,该注册表项的值缺省为0(默认没有该ValidateKdcPacSignature键值),也就是不进行KDC PAC校验。

注:需要说明的是,注册在本地系统帐户下的服务无论如何配置,都不会触发KDC验证PAC签名。也就是说譬如SMB、CIFS、HOST等服务无论如何都不会触发KDC验证PAC签名。

那么为什么默认情况下,KDC都不会验证PAC的签名呢?

执行KDC验证PAC的话,意味着在响应时间和带宽使用方面的成本。它需要带宽使用来在应用服务器和KDC之间传输请求和响应。这可能会导致大容量应用程序服务器中出现一些性能问题。在这样的环境中,用户身份验证可能会导致额外的网络延迟和大量的流量。因此,默认情况下,KDC不验证PAC签名。

5

PAC在kerberos中的优缺点

那么PAC的存在究竟给我们的验证过程带来了哪些优点,亦或是缺点呢?

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

如图所示, 在没有PAC的情况下,Server与KDC之间必须进行用户授权信息的查询与返回 :

当引入PAC之后则变成了如图所示:

但是,PAC的引入并不是百利而无一害的,PAC在用户的认证阶段引入会导致认证耗时过长。Windows Kerberos客户端会通过RPC调用KDC上的函数来验证PAC信息,这时候用户会观察到在服务器端与KDC之间的RPC包流量的增加。而另一方面, 由于PAC是微软特有的一个特性,所以启用了PAC的域中将不支持装有其他操作系统的服务器, 制约了域配置的灵活性。并且在2014年,由于PAC的安全性导致产生了一个域内极其严重的提权漏洞MS14-068(在后面的文章中我们会介绍这个漏洞)。

Kerberos实验

为了更直观的分析Kerberos协议,接下来我们用普通域帐户xie/hack使用impacket工具请求win10机器的cifs服务票据 ,然后远程SMB连接,在该过程中使用WireShark进行抓包。

实验环境如下:

用户(xie/hack):10.211.55.2

域内主机(Win10): 10.211.55.16

域控(AD01):10.211.55.4

impacket使用命令如下:

#使用hack账号密码请求win10的cifs服务的ST服务票据
python3 getST.py -dc-ip 10.211.55.4 -spn cifs/win10.xie.com xie.com/hack:P@ss1234#导入该ST服务票据
export KRB5CCNAME=hack.ccache#使用smb远程连接win10
python3 smbexec.py -no-pass -k win10.xie.com

如图所示,可以看到在请求了服务票据后,成功远程SMB连接win10机器。

在这个过程中,我们使用WireShark抓包,来进一步的分析Kerberos协议。如图所示,是该过程的抓包图:

整个Kerberos认证流程如图所示:

下面我们来具体分析Kerberos认证流程的每个步骤:

AS-REQ & AS-REP

我们先来看看AS-REQ&AS-REP请求部分,也就是WireShark抓的第一、二个包,如图所示:

如图所示,是一个简易的AS-REQ&AS-REP请求过程图,便于我们直观的了解AS-REQ&AS-REP请求过程。

下面让我们具体的分析下AS-REQ&AS-REP过程中的数据包细节:

首先,我们来看看客户端是如何获得TGT认购权证的。TGT认购权证是由KDC的 AS(Authentication Service) 认证服务发放的。

1

AS-REQ请求包分析

      AS-REQ:当域内某个用户想要访问域内某个服务时,于是输入用户名和密码,本机就会向KDC的AS认证服务发送一个AS-REQ认证请求。该请求包中包含如下信息:

 · 请求的用户名(cname)。

 · 域名(realm)。

 · Authenticator:一个抽象的概念,代表一个验证。这里是用户密钥加密的时间戳。

 · 请求的服务名(sname):AS-REQ这个阶段请求的服务都是krbtgt。

 · 加密类型(etype)。

 · 以及一些其他信息:如版本号,消息类型,票据有效时间,是否包含PAC,协商选项等。

如图所示,是AS-REQ请求包的详细:

下面我们来看看AS-REQ请求包中每个字段的含义,如下所示:

pvno: kerberos版本号,这里为5
msg-type: 消息类型, AS_REQ 对应的是 krb-as-req(10)
padata:主要是一些认证信息,每个认证消息有type和value。PA-DATA PA-ENC-TIMESTAMP:这个是预认证,就是用用户Hash加密时间戳,作为value发送给KDC的AS服务。然后KDC从活动目录中查询出用户的hash,使用用户Hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。由于是使用用户密码Hash加密的时间戳,所以也就造成了哈希传递攻击padata-type: padata类型,这里是 pA-ENC-TIMESTAMP(2)padata-vaule: 加密后的值etype:  加密类型,这里是 eTYPE-AES256-CTS-HMAC-SHA1-96(18)cipher: 密钥PA-DATA PA-PAC-REQUEST:这个是启用PAC支持的扩展。这里的value对应的值为True或False,KDC根据include的值来确定返回的票据中是否需要携带PAC。padata-type: padata类型,这里是pA-PAC-REQUEST(128)padata-vaule: padata的值include-pac: 是否包含PAC,这里为True,说明要PAC
req-body:请求bodypadding:填充,这里为0kdc-options:用于与KDC协商一些选项设置reservedforwardableforwardedproxiableproxyallow-postdatepostdatedunused7renewableunused9unused10opt-hardware-authunused12unused13constrained-delegationcanonicalize request-anonymousunused17unused18unused19unused20unused21unused22unused23unused24unused25disable-transited-checkrenewable-okenc-tkt-in-skeyunused29renewvalidatecname:请求的用户名,这个用户名存在和不存在,返回的包有差异,因此可以用于枚举域内用户名。并且当用户名存在,密码正确和错误时,返回包也不一样,因此也可以进行密码喷洒。name-type:名字类型,这里是KRB5-NT-PRINCIPAL(1)cnmae-string:名字,也就是请求的用户名CNameString: 请求的用户名,这里为 hackrealm:域名,这里为XIE.COMsname:请求的服务,包含type和Value。在AS-REQ里面sname始终为krbtgtname-type:名字类型,这里是KRB5-NT-PRINCIPAL(1)sname-string: krbtgt用户的信息,这里有2个itemsSNameString: 这里是krbtgt用户名SNameString: 这里是域名XIE.COMtill:到期时间rtime:也是到期时间nonce:随机生成的一个数etype:加密类型ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1-96(18)

我们着重讲一下PA-DATA PA-ENC-TIMESTAMP字段,该字段是用于预认证。

在AS-REQ请求包中,只有PA-DATA PA-ENC-TIMESTAMP部分是加密的,这一部分属于预认证,我们称这部分为Authenticator。

如图所示,在impacket/krb5/kerberosv5.py中可以看到使用用户的密码Hash或用户的密码AES Key来加密时间戳。

对WireShark抓取的流量进行解密,如图所示,可以看到这里是使用hack用户的密钥来解密该值,如下的patimestamp和pauses是解密后的值。

2

AS-REP回复包分析

       AS-REP:当KDC的AS认证服务接收到客户端发来的AS-REQ请求后,从活动目录数据库中取出该用户的密钥,然后用该密钥对请求包中的Authenticator预认证部分进行解密,如果解密成功,并且时间戳在有效的范围内,则证明请求者提供的用户密钥正确。

KDC的AS认证服务在成功认证客户端的身份之后,发送AS-REP响应包给客户端。AS-REP响应包中主要包括如下信息:

 · 请求的用户名(cname)。

 · 域名(crealm)。

 · TGT认购权证:包含明文的版本号,域名,请求的服务名,以及加密部分enc-part。加密部分用krbtgt密钥加密。加密部分包含Logon Session Key、用户名、域名、认证时间、认证到期时间和authorization-data。authorization-data中包含最重要的PAC特权属性证书(包含用户的RID,用户所在组的RID) 等。

 · enc_Logon Session Key:使用用户密钥加密Logon Session Key后的值,其作用是用于确保客户端和KDC下阶段之间通信安全。也就是AS-REP中最外层的enc-part。

 · 以及一些其他信息:如版本号,消息类型等。

如图所示,是AS-REP回复包的详细:

下面我们来看看AS-REP回复包中每个字段的含义,如下所示:

pvno:kerberos版本号,这里为5
msg-type:消息类型,AS_REP对应的是 krb-as-rep(11)
padata:主要是一些认证信息。一个列表,包含若干个认证消息用于认证PA-DATA PA-ENCTYPE-INFO2padata-type: padata的类型,这里是 pA-ETYPE-INFO2(19)padata-value: 加密后的值ETYPE-INFO2-ENTRYetype: eTYPE-AES256-CTS-HMAC-SHA1-96(18)salt: 盐值,这里是 XIE.COMhack
crealm: 域名,这里是XIE.COM
cname:请求的用户名name-type: 用户名类型,这里是 kRB5-NT-PRINCIPAL(1)cname-string: 1itemCNameString: hack
ticket:TGT认购权证tkt-vno: TGT版本号,这里为5realm: 域名,这里是 XIE.COMsname: 服务用户名,这里是krbtgt 密码分发中心服务账号name-type: KRB5-NT-SRV-INST(2)sname-string: 2itemsSNameString: krbtgtSNameString: XIE.COMenc-part: TGT票据中的加密部分,这部门是用krbtgt的密码Hash加密的。因此如果我们拥有krbtgt的hash就可以自己制作一个ticket,这就造成了黄金票据攻击etype: 加密类型,这里是 eTYPE-AES256-CTS-HMAC-SHA1-96(18)kvno: 版本号,这里为2cipher:加密后的值
enc-part:Login session key,这部分是用请求的用户密码Hash加密的,作为下阶段的认证密钥。etype: eTYPE-AES256-CTS-HMAC-SHA1-96(18)kvno: 版本号,这里为3cipher:加密后的值

AS-REP返回包中最重要的就是TGT认购权证和加密的Logon Session Key了。TGT认购权证中加密部分是使用krbtgt密钥加密的,而Logon Session Key是使用请求的用户密钥加密的。

下面我们通过解密WireShark来看看TGT认购权证和Logon Session Key中到底包含哪些内容。

1

TGT认购权证

AS-REP响应包中的ticket便是TGT认购权证了。TGT认购权证中包含一些明文显示的信息,如版本号tkt-vno、域名realm、请求的服务名sname。但是TGT认购权证中最重要的还是加密部分,加密部分是使用krbtgt帐户密钥加密的。加密部分主要包含的内容有Logon Session Key、请求的用户名cname、域名crealm、认证时间authtime、认证到期时间endtime、authorization-data等信息。

最重要的还是authorization-data部分,这部分中包含客户端的身份权限等信息,这些信息包含在PAC中。

如图所示,是TGT认购权证:

我们来看看TGT认购权证中authorization-data字段下代表用户身份权限的PAC是啥样的。我们对PAC进行解密,只查看PAC的凭证信息部分PAC_LOGON_INFO。

    如图所示,最主要的还是通过User RID和Group RID来辨别用户权限的。

    KDC生成PAC的过程如下:KDC在收到客户端发来的AS-REQ请求后,从请求中取出cname字段,然后查询活动目录数据库,找到sAMAccountName属性为cname字段的值的用户,用该用户的身份生成一个对应的PAC。

2

Logon Session Key

AS-REP响应包最外层的那部分便是加密的Login session Key了,其作用是用于确保客户端和KDC下阶段之间通信安全,它使用请求的用户密钥加密。

我们对最外层的enc-part部分进行解密,如图所示,可以看到是使用hack用户的密钥对其进行解密的。

解密结果如下:主要包含的内容是认证时间authtime、认证到期时间endtime、域名srealm、请求的服务名sname、协商标志flags等一些信息。需要说明的是,在TGT认购权证中也包含Logon Session Key。

TGS-REQ&TGS-REP

我们再来看看TGS-REQ&TGS-REP请求部分,也就是WireShark抓的第三、四个包,如图所示:

如图所示,是一个简易的TGS-REQ&TGS-REP请求过程图,便于我们直观的了解TGS-REQ&TGS-REP请求过程。

    下面让我们具体的分析下TGS-REQ&TGS-REP过程中的数据包细节:

客户端再收到KDC的AS-REP回复后,使用用户密钥解密enc_Logon Session Key(也就是最外层的enc-part),得到Logon Session Key,并且也拿到了TGT认购权证。之后它会在本地缓存此 TGT认购权证 和 Logon Session Key。现在客户端需要凭借这张TGT认购凭证向KDC购买相应的ST服务票据(Service Ticket)。ST服务票据是KDC的另一个服务 TGS(Ticket Granting Service)票据授予服务发放的。在这个阶段,微软引入了两个扩展子协议 S4u2self 和 S4u2Proxy(当委派的时候,才用的到,我们会在后面的4.5章中详细介绍)。

1

TGS-REQ请求包分析

     TGS-REQ:客户端拿着上一步获得的TGT认购权证发起TGS-REQ请求,向KDC购买针对指定服务的ST服务票据,该请求主要包含如下信息:

 · 域名(realm)。

 · 请求的服务名(sname)。

 · TGT认购权证。

 · Authenticator:一个抽象的概念,代表一个验证。这里使用Logon Session Key加密的时间戳。

· 加密类型(etype)。

 · 以及一些其他信息:如版本号,消息类型,协商选项,票据到期时间等。

如图所示,是TGS-REQ请求包的详细:

下面我们来看看TGS-REQ请求包中每个字段的含义,如下所示:

pvno:kerberos版本号,这里为5
msg-type:消息类型,TGS_REQ对应的是 krb-tgs-req(12)
padata:padata中包含ap_req,这个是TGS_REQ必须携带的部分,这部分会携带AS_REP里面获取到的TGT认购权证和使用原始的Logon Session Key加密的时间戳。还有可能会有PA_FOR_USER,类型是S4U2SELF,是一个唯一的标识符,该标识符指示用户的身份,该标识符由用户名和域名组成。S4U2Proxy必须扩展PA_FOR_USER结构,指定服务代表某个用户去请求针对服务自身的kerberos服务票据。还有可能会有PA_PAC_OPTIONS,类型是PA_PAC_OPTIONS。S4U2Proxy必须扩展PA-PAC-OPTIONS结构。如果是基于资源的约束委派,就需要指定Resource-based Constrained Delegation位。padata-type: padata类型,这里是 pA-TGS-REQ(1)padata-value: padata的值ap-req:这个是TGS_REQ必须携带的部分pvn0:5msg-type:krb-ap-req(14)padding:0ap-options:00000000reserved: Falseuse-session-key: Falsemutual-required: Falseticket AS-REP响应包中返回的TGT认购权证tkt-vno:5realm: XIE.COMsnamename-type: kRB5-NT-SRV-PRINCIPAL(1)sname-string:2 itemsSNameString: krbtgtSNameString: XIE.COMenc-partetype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)kvno: 2cipher: 加密后的值authenticator: 原始Logon Session Key加密的时间戳,用于保证会话安全etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)cipher: 加密后的值
req-body:请求bodypadding:这里为0kdc-options:用于与KDC约定一些选项设置reservedforwardableforwardedproxiableproxyallow-postdatepostdatedunused7renewableunused9unused10opt-hardware-authunused12unused13constrained-delegationcanonicalize request-anonymousunused17unused18unused19unused20unused21unused22unused23unused24unused25disable-transited-checkrenewable-okenc-tkt-in-skeyunused29renewvalidaterealm:域名,这里为XIE.COMsname:要请求的服务名name-type: KRB5-NT-SRV-INST(2)sname-string: 2 itemsSNameString: cifsSNameString: win10.xie.comtill:到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具。nonce:随机生成的一个数。etype:加密类型ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5(23)ENCTYPE: eTYPE-DES3-CBC-SHA1(16)ENCTYPE: eTYPE-DES-CBC-MD5 (3)ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1-96(18)

我们着重讲一下ap-req中的authenticator字段,该字段主要用于后阶段的会话安全认证。

为了确保后阶段的会话安全,TGS-REQ中ap-req中的authenticator字段的值是用上一步AS-REP中返回的Logon Session Key加密的时间戳,如图所示:

如图所示,在impacket/krb5/kerberosv5.py可以看到使用如下加密方式使用Logon Session Key加密的时间戳。

2

TGS-REP回复包分析

      TGS-REP:KDC的TGS服务接收到TGS-REQ请求之后。首先使用krbtgt密钥解密TGT认购权证中加密部分得到Logon Session key和PAC等信息,如果能解密成功则说明该TGT认购权证是KDC颁发的。然后验证PAC的签名,如果签名正确,则证明PAC未经过篡改。然后使用Logon Session Key解密Authenticator得到时间戳等信息,如果能够解密成功,并且票据时间在范围内,则验证了会话的安全性。在完成上述的检测后,KDC的TGS服务完成了对客户端的认证,TGS服务发送响应包给客户端。响应包中主要包括如下信息:

 · 请求的用户名(cname)

 · 域名(crealm)

 · ST服务票据:包含明文的版本号,域名,请求的服务名,以及加密部分enc-part,加密部分用服务密钥加密。加密部分包含用户名、域名、认证时间、认证到期时间、Service Session key和authorization-data。authorization-data中包含最重要的PAC特权属性证书(包含用户的RID,用户所在的组的RDI) 等。

 · enc_Service Session key:使用Logon Session key加密的Service Session key,其作用是用于确保客户端和KDC下阶段之间通信安全。

 · 以及一些其他信息:如版本号、消息类型等。

     注:这里需要说明的是,TGS-REP这步中KDC并不会验证客户端是否有权限访问服务端。因此,这一步不管用户有没有访问服务的权限,只要TGT正确,均会返回ST服务票据,这也是kerberoasting能利用的原因,任何一个域内用户,都可以请求域内任何一个服务的ST服务票据。

如图所示,是TGS-REP回复包的详细:

下面我们来看看TGS-REP回复包中每个字段的含义,如下所示:

pvno:kerberos版本号,这里为5
msg-type:消息类型,TGS_REP对应的是 krb-tgs-rep(13)
crealm: 域名,这里是XIE.COM
cname:请求的用户名name-type: 名称类型,这里为 KRB5-NT-PRINCIPAL(1)cname-string: 1 itemCNameString: hack
ticket:即ST服务票据tkt-vno: 服务票据版本号,这里为5realm: 域名,这里是XIE.COMsname:name-type: KRB5-NT-SRV-HST(3)sname-string: 2 itemsSNameString: cifsSNameString: win10.xie.comenc-part: 这部分是用服务的密钥加密的etype: 加密类型,eTYPE-AES256-CTS-HMAC-SHA1-96(18)kvno: 版本号,这里为3cipher:加密后的值
enc-part:这部分是用原始的Logon Session Key加密的。里面最重要的字段是Service session key,作为下阶段的认证密钥。etype: 加密类型eTYPE-AES256-CTS-HMAC-SHA1-96(18)cipher: 加密后的值

TGS-REP返回包中最重要的就是ST服务票据和Service Session key了。ST服务票据中加密部分是使用服务密钥加密的,而Service Session key是使用Logon Session Key加密的。

下    面我们通过解密WireShark来看看ST服务票据和Service Session key中到底包含哪些内容。

1

ST服务票据

TGS-REP响应包中的ticket便是ST服务票据了。ST服务票据中包含明文显示的信息,如版本号tkt-vno、域名realm、请求的服务名sname。但是ST服务票据中最重要的还是加密部分,加密部分是使用服务密钥加密的。加密部分主要包含的内容有Server Session Key、请求的用户名cname、域名crealm、认证时间authtime、认证到期时间endtime、authorization-data等信息。最重要的还是authorization-data部分,这部分中包含客户端的身份权限等信息,这些信息包含在PAC中。

    如图所示,是ST服务票据:

我们来看看ST服务票据中authorization-data字段下代表用户身份权限的PAC是啥样的。我们对PAC进行解密,只查看PAC的凭证信息部分PAC_LOGON_INFO。

如图所示,最主要的还是通过User RID和Group RID来辨别用户权限的。可以看到,ST服务票据中的PAC和TGT认购权证中的PAC是一致的。在正常的非S4u2Self请求的TGS过程中,KDC在ST服务票据中的PAC是直接拷贝TGT票据中的PAC。

2

Service Session Key

TGS-REP响应包最外层的那部分便是Service Session Key了,其作用是用于确保客户端和KDC下阶段之间通信安全,它使用Logon Session Key加密。

如图所示,对其进行解密,它主要包含的内容是认证时间authtime、认证到期时间endtime、域名srealm、请求的服务名sname、协商标志flags等一些信息。需要说明的是,在ST服务票据中也包含Service Session Key。

如何双向认证?

(AP-REQ&AP-REP)

客户端在收到KDC返回的TGS-REP消息,从中取出ST服务票据后,就准备要开始申请访问服务了。

由于我们是通过SMB协议远程连接的,因此AP-REQ&AP-REP消息是放在SMB协议中。如图所示:

     注:通过impacket远程连接服务默认是不需要验证提供服务的服务端的,因此这里没有AP-REP回复。

如图所示,是一个简易的AP-REQ&AP-REP请求过程图,便于我们直观的了解AP-REQ&AP-REP请求过程。

1

AP-REQ请求包分析

    AP-REQ:客户端接收到KDC的TGS回复后,通过缓存的Logon Session Key解密enc_Service Session key得到Service Session Key,同时它也拿到了ST(Service Ticket)服务票据。Serivce Session Key 和 ST服务票据会被客户端缓存。

客户端访问指定服务时,将发起AP-REQ请求,该请求主要包含如下的内容:

 · ST服务票据(ticket)

 · Authenticator:一个抽象的概念,代表一个验证。这里指Serivce Session Key加密的时间戳

 · 以及一些其他信息:如版本号、消息类型,协商选项等

如图所示,是AP-REQ请求包的详细:

下面我们来看看AP-REQ请求包中每个字段的含义,如下所示:

pvno:kerberos版本号,这里为5
msg-type:消息类型, AP_REQ 对应的是 krb-ap-req(14)
Padding:填充,这里为0
ap-options: 一些协商选项reserveduse-session-keymutual-required  该选项代表客户端是否希望验证提供服务的服务端
ticket: ST服务票据tkt-vno: 版本号,这里为5realm: XIE.COMsname:服务名name-type: KRB5-NT-SRV-INST(2)sname-string: 2 item2SNameString: cifsSNameString: win10.xie.comenc-part: ST服务票据中加密部分etype:加密类型,eTYPE-AES256-CTS-HMAC-SHA1-96(18)kvno: 版本号,这里是2cipher:加密后的值
authenticator: Serivce Session Key加密的时间戳etype:加密类型cipher:加密后的值

2

AP-REP回复包分析

     AP-REP:这一步是可选的,当客户端希望验证提供服务的服务端时(也就是AP-REQ请求中mutual-required协商选项为True),服务端返回AP-REP消息。服务端收到客户端发来的AP-REQ消息后,通过服务密钥解密ST服务票据得到Service Session Key和PAC等信息,然后用Service Session Key 解密 Authenticator得到时间戳。如果能解密成功且时间戳在有效范围内,则验证了客户端的身份。验证了客户端身份后,服务端从ST服务票据中取出PAC中代表用户身份权限信息的数据,然后与请求的服务ACL做对比,生成相应的访问令牌。同时,服务端会检查AP-REQ请求中mutual-required协商选项是否为True,如果为True的话,说明客户端想验证服务端的身份。此时,服务端会用Service Session Key加密时间戳作为Authenticator,在AP-REP响应包中发送给客户端进行验证。

如果mutual-required选项为False的话,服务端会根据访问令牌的权限决定是否返回相应的服务给客户端。

    注:由于impacket默认是不需要验证服务端身份的,因此如图所示是其他请求方式的AP-REP回复包截图。

AP-REP响应包中主要包括如下信息:

 · 版本号

 · 消息类型

 · enc-part:使用Serivce Session Key加密的时间戳。

如下是AP-REP回复包的详细:

pvno:5
msg-type:消息类型, AP_REP 对应的是 krb-ap-rep(15)
enc-part:Serivce Session Key加密的时间戳etype:加密类型cipher:加密后的值

S4u2Self&S4u2Proxy

为了在Kerberos协议层面对约束性委派的支持,微软对Kerberos协议扩展了两个自协议 S4u2self(Service for User to Self) 和 S4u2Proxy (Service for User to Proxy )。S4u2self 可以代表任意用户请求针对自身的服务票据;S4u2Proxy可以用上一步获得的ST服务票据以用户的名义请求针对其它指定服务的ST服务票据。

执行如下命令,machine$机器用户模拟administrator身份访问自身服务。

python3 getST.py -dc-ip AD01.xie.com xie.com/machine\$:root -spn cifs/ad01.xie.com -impersonate administrator

如图所示,machine$机器账号以S4u2Self协议模拟administrator身份访问自身服务

1

S4u2Self

和正常的TGS-REQ请求包相比,S4u2Self协议的TGS-REQ请求包会多一个PA-DATA pA-TGS-USER,name为要模拟的用户。

并且sname也是请求的服务自身。如图所示:

2

S4u2Proxy

和正常的TGS-REQ请求包相比,S4u2Proxy协议的TGS-REQ请求包会增加一个additional-tickets字段,该字段的内容就是上一步利用S4u2Self请求的ST服务票据。如图所示:

Kerberos协议的安全问题

如图所示,是Kerberos协议各阶段容易产生的安全问题:

    在AS-REQ请求阶段,是用用户密码Hash或AES Key加密的时间戳。因此当只获得了用户密码Hash时,也可以发起AS-REQ请求,所以也就造成了PTH哈希传递攻击;当只获得用户密码的AES Key时,也可以发起AS-REQ请求,所以也就造成了PTK密钥传递攻击

而 AS-REQ 请求包中 cname 字段的值代表用户名,这个值存在和不存在,返回的包有差异,所以可以用于枚举域内用户名,这种攻击方式被称为 域内用户枚举攻击 (当未获取到有效域用户权限时,可以使用这个方法枚举域内用户)。并且当用户名存在,密码正确和密码错误时,返回的包也不一样,所以可以进行用户名密码爆破。但是在实战中,渗透测试人员通常都会使用一种被称为 密码喷洒(Password Spraying)的攻击方式来进行测试和攻击。对密码进行喷洒式的攻击,这个叫法很形象,因为它属于自动化密码猜测的一种。这种针对所有用户的自动密码喷洒通常是为了避免帐户被锁定,因为针对同一个用户的连续密码猜测会导致帐户被锁定。所以只有对所有用户同时执行特定的密码登录尝试,才能增加破解的概率,消除帐户被锁定的概率。普通的爆破就是用户名固定,爆破密码,但是密码喷洒是用固定的密码去跑所有的用户名。

    在 AS-REP 阶段,由于返回的 TGT 认购权证是由 krbtgt 用户的密码Hash加密的,因此如果我们拥有 krbtgt 的密码 hash 就可以自己制作一个TGT认购权证,这种攻击方式被称为黄金票据攻击。同样,在TGS-REP阶段,TGS_REP里面的ST服务票据是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以签发任意用户的ST服务票据,这个票据也被称为白银票据,这种攻击方式被称为白银票据攻击。相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash。

    在AS-REP阶段,Login session key是用用户密码 Hash 加密的。对于域用户,如果设置了“Do not require Kerberos preauthentication”不需要预认证选项,此时攻击者向域控制器的 88 端口发送 AS_REQ 请求,此时域控不会做任何验证就将 TGT认购权证 和 该用户Hash加密的Login Session Key返回。因此,攻击者就可以对获取到的 用户Hash加密的Login Session Key进行离线破解,如果破解成功,就能得到该用户的密码明文,这种攻击方式被称为 AS-REP Roasting攻击

    在TGS-REP阶段,由于ST服务票据是用服务Hash加密的。因此,如果我们能获取到ST服务票据,就可以对该ST服务票据进行利息破解,得到服务的Hash,这种攻击方式被称为Kerberoasting攻击。这个问题存在的另外一个因素是因为用户向KDC发起TGS_REQ请求,不管用户对服务有没有访问权限,只要TGT认购权证正确,那么KDC都会返回ST服务票据。其实AS_REQ里面的服务就是krbtgt,也就是说这个攻击方式同样可以用于爆破AS_REP里面的TGT认购权证,但是之所以没见到这种攻击方式是因为krbtgt的密码是随机生成的,爆破不出来。


非常感谢您读到现在,由于作者的水平有限,编写时间仓促,文章中难免会出现一些错误或者描述不准确的地方,恳请各位师傅们批评指正。

参考:

https://www.rfc-editor.org/rfc/rfc4120.html

https://www.cnblogs.com/artech/archive/2011/01/24/kerberos.html

https://docs.microsoft.com/en-us/previous-versions/aa302203(v=msdn.10)?redirectedfrom=MSDN#signatures-pac_server_checksum-and-pac_privsvr_checksum

https://docs.microsoft.com/zh-cn/archive/blogs/apgceps/packerberos-2

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962

https://docs.microsoft.com/en-us/previous-versions/aa302203(v=msdn.10)#top-level-pac-structure

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc772815(v=ws.10)?redirectedfrom=MSDN

https://docs.microsoft.com/zh-cn/archive/blogs/openspecification/understanding-microsoft-kerberos-pac-validation

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94

相关文章:

https://www.anquanke.com/post/id/171552#h3-5

https://zhuanlan.zhihu.com/p/473625225

https://www.zhihu.com/question/22177404

- END -

全网最详细 | Kerberos协议详解相关推荐

  1. windows认证原理kerberos协议详解

    这里写目录标题 什么是kerberos协议 kerberos协议简略流程以及详细流程 kerberos协议局限性 什么是kerberos协议 kerberos是一种网络认证协议,通过密钥系统为客户端以 ...

  2. Kerberos协议详解

    协议的安全主要依赖于参加者对时间的松散同步和短周期的叫做Kerberos票据的认证声明. 下面是对这个协议的一个简化描述,将使用以下缩写: AS(Authentication Server)= 认证服 ...

  3. 最详细的流媒体传输协议-rtsp协议详解

    流媒体传输协议-rtsp协议详解 参阅:RTSP协议详解和分析从零开始写一个RTSP服务器(一)RTSP协议讲解关于RTSP_RTP_RTCP协议的深刻初步介绍 rtsp RTSP出现以前,最热的大概 ...

  4. 【HTTP协议】超详细的HTTP协议详解

    基本介绍 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/ ...

  5. HTTP协议详解 转自小坦克

    HTTP协议详解 转自小坦克 -- 有些文章是引用别人的,为了方便我以后或不再备注;引用目的是因为直接网摘里面的地址经常被重置,找不到原来的文章 当今web程序的开发技术真是百家争鸣,ASP.NET, ...

  6. nbns协议_网络协议详解1 - NBNS

    NetBIOS 简介 NetBIOS,Network Basic Input/Output System的缩写,一般指用于局域网通信的一套API,相关RFC文档包括 RFC 1001, RFC 100 ...

  7. IP协议详解---Linux学习笔记

    网络层概述: IP服务的特点: IP协议为上层协议提供无状态.无连接.不可靠的服务. 无状态:IP通讯双方不同步传输状态的信息,因此所有IP数据报发送.传输.接收都是相互独立的,没有上下文关系.这样同 ...

  8. zz:NETCONF协议详解

    随着SDN的大热,一个诞生了十年之久的协议焕发了第二春,它就是NETCONF协议.如果你在两年前去搜索NETCONF协议,基本得到的信息都是"这个协议是一个网管协议,主要目的是弥补SNMP协 ...

  9. IoT:MQTT协议详解

    IoT -- (七)MQTT协议详解 转自:https://blog.csdn.net/anxianfeng55555/article/details/80908795 MQTT是什么? MQTT(M ...

最新文章

  1. 混淆梯度(Obfuscated Gradients Give a False Sense of Security Circumventing Defense)
  2. paper每日谈——动机
  3. SQL注入 ——sql数据库操作基础(一)
  4. python平均分由高到低顺序排列输出选手编号和最后得分_python 字典的使用案例二:求平均分,并按平均分由高到低输出选手编号和最后得分...
  5. 元素内容必须由格式正确的字符数据或标记组成_Blockly Fields积木表单元素
  6. Linux基础知识点
  7. Halcon模板匹配(基于相关性)
  8. java----内省
  9. 产品配件类目税目分类_2018商品和服务税收分类编码表
  10. 关于“H5小游戏源代码如何转换微信小游戏发布”
  11. 最全CacheCloud最完整安装使用文档【实操系列】
  12. 什么是DNS?为什么选择UDP?详细的DNS解析过程?
  13. Linux系统_通过命令新建MySQL数据库并导入sql文件
  14. 深度学习:GAN 对抗网络原理详细解析(零基础必看)
  15. 使用nvm安装node报错,Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get “https://nodej
  16. 这才是实习生写的代码,你学废了吗
  17. python模拟登录网易163邮箱并发送SOS邮件
  18. 4、Lctech Pi(F1C200S)linux5.7.1移植在RAM运行修改默认调试串口为uart1(CherryPi,Mangopi,F1C100S)
  19. 500GB 的数据库怎么发送给客户?大文件传输软件来帮忙
  20. 单点登录,谷歌浏览器系统跳转到指定ie浏览器

热门文章

  1. Windows笔记本电脑电池损耗率查询
  2. WordPress虚拟资源商城主题日主题RiPro6.7 开源版 星空资源网首发
  3. vue-shop电商管理后台
  4. NVIDIA VPI架构解析
  5. 大型商场借力泛微,实现内外协同招商,合同、铺位、费用统一管理
  6. 【Python高级语法】——生成器(generator)
  7. C++入门(三)之内存管理
  8. What is Unified Extensible Firmware Interface (UEFI)?
  9. 以小刀会“的成败论当今创业成败
  10. java rails orm_rails知名应用和工具