Kerberos Attacks - Kerberos协议简析

Kerberos

Kerberos 协议的开发始于麻省理工学院 (MIT) 的 雅典娜项目。该项目于 1983 年启动,旨在为学生和研究人员提供尖端计算资源,包括联网工作站、高速网络和协作软件工具。Kerberos v5于 1993 年发布,并于 2005 年更新以解决以前版本的问题。此版本添加了其他加密类型、跨领域身份验证和通用安全服务应用程序接口,从 Windows Server 2000 开始, Kerberos 取代了 Windows NTLM 成为默认的身份验证协议;不过,Microsoft 仍然支持 NTLM 以实现向后兼容。

相关组成

Realm: A set of network nodes (hosts, workstations, VMs, servers, etc) that share a common Kerberos database. I like to think of it as all of those nodes plus the KDC (and associated database). This brings it in line with definitions I’ve given for similar concepts across the other identity protocols.

Principal: A unique identity to which Kerberos tickets can be assigned. This could be a client, a user, or a server providing a service. The Principal name in Kerberos v5 is of the form primary/instance@REALM. See here for more information.

Hosts/Clients: A process, host, server, VM, or other network node that makes use of a network service (that understands Kerberos and is part of the same Realm or a trusted-Realm) on behalf of a user.

Server (sometimes called a Service Server — SS): A particular Principal that provides a resource to network Clients. The server is, also, sometimes referred to as the Application Server.

Service: A resource provided to network clients. Typically, provided by more than one server.

Key Distribution Center (KDC): A network service that supplies tickets
and temporary session keys; or an instance of that service or the host on which it runs. The KDC services both initial ticket and ticket-granting ticket requests. It is composed of the Authentication Service and Ticket Granting Server (see below).

Authentication Server (AS): The KDC component that handles the initial request and issues a TGT. The AS is responsible for maintaining a database of principals (users and servers) and the associated secret keys.

Ticket-granting service (TGS): A service that issues tickets for admission to other services in its own domain or for admission to the ticket-granting service in another domain.

Ticket-granting ticket (TGT): A special type of ticket that can be used to obtain other tickets. The TGT is obtained after the initial authentication in the Authentication Service (AS) exchange; thereafter, users do not need to present their credentials, but can use the TGT to obtain subsequent tickets.

认证流程图

image-20250115234731778

image-20250115234750957

image-20250115234827541

上图对应使用的加密密钥

AS-REQ:用户 NTLM HASH
AS-REP:用户 NTLM HASH + Krbtgt账户 NTLM HASH
TGS-REQ:会话密钥 + Krbtgt账户 NTLM HASH
TGS-REP:服务账户的 NTLM HASH
AP-REQ:会话密钥 + 服务账户的 NTLM HASH

大概流程为:

  • AS_REQ:Client向KDC发起AS_REQ请求包,使用用户hash加密时间戳

  • AS_REP:KDC使用Client hash进行解密,如果结果正确就返回 用户hash加密的信息和krbtgt hash加密的TGT票据,TGT里面包含PAC,PAC包含Client的sid,Client所在的组

  • TGS_REQ:Client凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求

  • TGS_REP:KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务 hash加密 的ST票据(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回ST票据)

  • AP_REQ:Client拿着ST票据去请求服务

  • AP_REP:服务使用自己的hash解密ST票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。对应 6-7-8

小结为:

  • AS-REQ与AS-REP:认证服务(AS)交换
  • TGS-REQ与TGS-REP:票证授予服务 (TGS) 交换
  • AP-REQ、AP-REP:客户端/服务器 (AP) 交换

预认证

目的:防止重放攻击

Windows 域要求在 KRB_AS_REQ 消息中提供 预身份验证数据,最简单的预身份验证形式称为 PA-ENC-TIMESTAMP,即使用Client的hash对YYYYMMDDHHmmssZ 形式的 时间戳进行加密,这样KDC 就知道该请求不是先前请求的重放。

在 Active Directory 环境中,是否需要进行预身份验证由 是否开启 不需要预身份验证 选项 决定,该标志是每个用户帐户上的设置。默认情况下所有用户都需要进行预身份验证。当启用该选项时,会造成 AS-REP roasting 的攻击

image-20250116010805452

特权属性证书-PAC

Kerberos 协议不提供授权,微软为了访问控制而引进的一个扩展,特权属性证书 (PAC) 的创建是为了为 Kerberos 协议扩展提供授权数据,如果说Kerberos 解决了 who am i 的认证问题,那么PAC就是解决了 What can I do 的问题

PAC结构:

image-20250116215110555

PAC整体的结构上是一个AuthorizationData的结构

AuthorizationData ::= SEQUENCE OF SEQUENCE {
ad-type [0] Int32,
ad-data [1] OCTET STRING
}

最外层:ad-type = AD-IF-RELEVANT,ad-data = 又一个AuthorizationData结构

第二层:ad-type = AD-WIN2K-PAC,ad-data = 一段连续的空间

连续空间:一个头部 PACTYPE 以及 若干个 PAC_INFO_BUFFER

其中PAC_INFO_BUFFER为 key-value 类型

0x00000001 登录信息。PAC结构必须包含一个这种类型的缓冲区。其他登录信息缓冲区必须被忽略。
0x00000002 凭证信息。PAC结构不应包含多个此类缓冲区。第二或后续凭证信息缓冲区在接收时必须被忽略。
0x00000006 服务器校验和。PAC结构必须包含一个这种类型的缓冲区。其他登录服务器校验和缓冲区必须被忽略。
0x00000007 KDC校验和。PAC结构必须包含一个这种类型的缓冲区。附加的KDC校验和缓冲区必须被忽略。
0x0000000A 客户名称和票证信息。PAC结构必须包含一个这种类型的缓冲区。附加的客户和票据信息缓冲区必须被忽略。
0x0000000B 受约束的委派信息。PAC结构必须包含一个S4U2proxy请求的此类缓冲区,否则不包含。附加的受约束的委托信息缓冲区必须被忽略。
0x0000000C 用户主体名称(UPN)和域名系统(DNS)信息。PAC结构不应包含多个这种类型的缓冲区。接收时必须忽略第二个或后续的UPN和DNS信息缓冲区。
0x0000000D 客户索取信息。PAC结构不应包含多个这种类型的缓冲区。附加的客户要求信息缓冲区必须被忽略。
0x0000000E 设备信息。PAC结构不应包含多个这种类型的缓冲区。附加的设备信息缓冲区必须被忽略。
0x0000000F 设备声明信息。PAC结构不应包含多个这种类型的缓冲区。附加的设备声明信息缓冲区必须被忽略。

其中 0x00000001(登录信息)结构定义了 DC 提供的用户登录和授权信息,如下:

typedef struct _KERB_VALIDATION_INFO {
FILETIME LogonTime;
FILETIME LogoffTime;
FILETIME KickOffTime;
FILETIME PasswordLastSet;
FILETIME PasswordCanChange;
FILETIME PasswordMustChange;
RPC_UNICODE_STRING EffectiveName;
RPC_UNICODE_STRING FullName;
RPC_UNICODE_STRING LogonScript;
RPC_UNICODE_STRING ProfilePath;
RPC_UNICODE_STRING HomeDirectory;
RPC_UNICODE_STRING HomeDirectoryDrive;
USHORT LogonCount;
USHORT BadPasswordCount;
ULONG UserId; //用户的sid
ULONG PrimaryGroupId;
ULONG GroupCount;
[size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;//用户所在的组,如果我们可以篡改的这个的话,添加一个500(域管组),那用户就是域管了。在ms14068 PAC签名被绕过,用户可以自己制作PAC的情况底下,pykek就是靠向这个地方写进域管组,成为使得改用户变成域管
ULONG UserFlags;
USER_SESSION_KEY UserSessionKey;
RPC_UNICODE_STRING LogonServer;
RPC_UNICODE_STRING LogonDomainName;
PISID LogonDomainId;
ULONG Reserved1[2];
ULONG UserAccountControl;
ULONG SubAuthStatus;
FILETIME LastSuccessfulILogon;
FILETIME LastFailedILogon;
ULONG FailedILogonCount;
ULONG Reserved3;
ULONG SidCount;
[size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
PISID ResourceGroupDomainSid;
ULONG ResourceGroupCount;
[size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
} KERB_VALIDATION_INFO;

PACTYPE结构是一系列 PAC_INFO_BUFFER 结构的数组,每个结构定义 PAC 缓冲区的类型和字节偏移量。PAC_INFO_BUFFER 数组没有定义的顺序。因此,PAC_INFO_BUFFER 缓冲区的顺序没有意义。但是,一旦生成密钥分发中心 (KDC) 和服务器签名,缓冲区的顺序就不能改变,否则 PAC 内容的签名验证将失败。

协议粗节

简单记录每个请求中的某些字段

AS_REQ

该包发送用户hash加密的时间戳,用于预身份验证

image-20250116002314429

image-20250116004509306

pvno:kerberos协议版本

msg-type:消息类型,此请求包对应为 krb-as-req

padata:pre-authentication data 预认证

  • ENC_TIMESTAMP:就是hash加密时间戳

  • PA_PAC_REQUEST:标志是否包含PAC

req-body:请求主体

  • cname:用户名,此处可根据返回包不同枚举用户名

  • realm:域名

  • sname:在AS_REQ里面sname是krbtgt,类型是KRB_NT_SRV_INST

  • till:到期时间,rubeus 和 kekeo都是 20370913024805Z,此处为工具特征

  • rtime:绝对到期时间

  • nonce:随机数,kekeo/mimikatz 是12381973,rubeus 是1818848256,此处为工具特征

  • etype:加密类型

  • addresses:客户端相关信息

AS_REP

该包在通过身份验证后将TGT返回给Client,主要包含两部分

ticket(TGT):采用krbtgt账户hash加密

用户名
会话密钥
TGT 的到期时间
具有用户权限的 PAC
...

enc-part(一些加密数据):采用用户hash加密

会话密钥-session key
TGT 的到期日期
...

image-20250116223255483

cname:用户名

crealm:域名

enc-part:用户hash加密一些数据

  • session key:作为下阶段的认证密钥

ticket:KDC使用krbtgt hash加密生成的TGT,其中可能包括PAC

TGS_REQ

此时Client将获取的KRB_TGT存储到内存中作为凭证用于请求TGS,发送内容主要为

session key加密的认证
TGT

image-20250116234638578

image-20250116234655450

padata:

  • AP_REQ:必须携带的部分,这部分会携带AS_REP里面获取到的TGT票据
    • authenticator:经Logon Session Key加密的Authenticator
    • ticket:AS_REP中的TGT结构

req-body:

  • sname:要请求的服务SPN

TGS_REP

KDC使用 Krbtgt hash解密TGS_REQ消息以验证 TGT,然后返回 ST,发送内容主要为

使用logon session key加密的 Service Session Key(服务会话密钥)

使用服务账户HASH加密的TGS(ST):
- 服务会话密钥
- 用户名
- TGS(ST) 的有效期
- 具有用户权限的 PAC ,由 KDC 签名

image-20250117000509862

ticket:一张ST(Service Ticket),或者叫做TGS。

  • enc-part:使用所请求服务账户的hash加密的TGS

enc-part:经过Logon Session Key加密的Service Session Key,用于请求服务时的会话密钥,作为作为下阶段的认证密钥

AP_REQ

将ST发送给提供服务的服务器

image-20250117002355773

AP_REP(可选)

KRB_verify_PAC_REQ:应用程序尝试使用 服务账户HASH来解密消息,并验证来自 KDC 的 PAC来识别用户权限

PAC_Verified_REP:KDC验证PAC

Allow Service Access

允许用户在特定的时间内访问该服务

参考

Kerberos I - Overview

kerberos-102-overview

Kerberos and Windows Security: Kerberos v5 Protocol

Kerberos Wireshark Captures: A Windows Login Example

Windows内网协议学习Kerberos篇

Kerberos协议之AS_REQ&AS_REP

再谈Kerberos

详解Kerberos认证流程及常见攻击方式