0x00 简介

Kerberos是一种计算机网络授权协议,由MIT(麻省理工学院)开放的一套计算机软件。软件设计上采用客户端/服务器结构,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证。可以用于防止窃听、防止重放攻击、保护数据完整性等场合,是一种应用对称密钥体制进行密钥管理的系统。

之前在文章Windows认证与域渗透当中挖了一个坑,说要把里面的认证过程和认证中的缺陷(漏洞)重新复习一遍。温故而知新,通过这几天不断的复习,学到了很多的新知识,也在学习的过程中解决了不少存在的问题。kerberos认证过程确实是挺繁杂的,但是安全性得到了保证。网上也特别多写kerberos认证的文章,我作为一个菜鸟在此就写一篇文章来总结归纳一下学到的知识,若有错误地方请各位前辈斧正,因为Kerberos协议基于对称密码学,我也不是专业密码学的,所以当中涉及加密的部分会略浅介绍。

0x01 环境

建议大家都把环境搭建过一遍,可以参考 VMware中用虚拟机模拟搭建域

主机环境

Windows Server 2019:172.16.0.106 (DC)

Windows 10:172.16.0.111 (SQL Server)

Windows 7:172.16.0.105 (PC)

Kali Linux:172.16.0.107 (Attack)

工具

Wireshark:Download

Setspn:Windows自带

Kerberos Configuration Manager:download

域环境

域:hack.lab

域管理员:testuser

普通用户:lucky、testsql

0x02 认证过程

我们学习kerberos的目的是要了解认证过程中出现的漏洞,但是我们有没有想过一个问题:

我们使用域用户登录某台内网主机的时候,认证过程是怎么样发生的呢?

我们在win7登录域用户会在Wireshark中抓到如下图的流量:

4

KRB5我们可以理解为kerberos v5协议,但这些AS_REQ、TGS_REQ等代表着什么呢,下面我们带着问题来了解一下这个认证过程。

基础认证

我们先了解几个基础的概念:

主题 说明
Winlogon Winlogon 为 GINA DLL 提供一组支持功能。
GINA GINA DLL 提供可自定义的用户标识和身份验证过程。
终端服务 GINA 函数 启用终端服务时,GINA 必须调用 Winlogon 支持功能才能完成多个任务。
Winlogon 与 GINA 之间的交互 Winlogon 的状态决定了调用哪个 GINA 函数来处理 (SAS) 事件的任何给定的 安全注意顺序
Winlogon 通知包 你可以实现通知包来监视和响应 Winlogon 事件。
LSA 本地安全机构
SSPI 安全支持提供者接口,该接口负责与Kerberos和NTLM服务沟通

具体的内容可以阅读 Winlogon 与GINA 之间的交互

可以想象一下,现在我们正使用域用户lucky登录Windows 7(已加入域)其过程如下:

  1. 用户首先按Ctrl+Alt+Del组合键。

  2. Winlogon检测到用户按下SAS键,就调用GINA,由GINA显示登录对话框,以便用户输入账号和密码。

  3. 用户选择所要登录的域和填写账号与密码,GINA将用户输入的信息发送给LSA进行验证,如果是本地用户登录的话将会使用本地数据库进行认证,如果是域渗透的话将会丢给Kerberos SSP去认证。

  4. 在域用户登录到本机的情况下,LSA将请求发送给Kerberos验证程序包。通过散列算法,根据用户信息生成一个密钥,并将密钥存储在证书缓存区中。

过程如图下:

1

这里就开始到了kerberos的步骤了,要注意的就是Windows不会明文保存密钥,都是通过NTLM来进行存储的。当然整个认证过程不会很简单,我们先要了解一些基础的概念:

  • KDC(Key Distribution Center)= 密钥分发中心

  • AS(Authentication Service)= 认证用户的身份,并为其发放TGT的服务

  • TGT(Ticket Granting Ticket)= TGT认证票据,由AS服务发放

  • TGS(Ticket Granting Service)= 票据发放服务

  • ST(Service Tickets)= ST服务票据,由TGS服务发送

  • AP(Application Server)= 提供用户所需的服务

看着概念挺模糊的对吧,而且上面到了kerberos步骤了,怎么还不继续下去,别急,我们明白AS认证服务和TGS认证服务这两个到底是啥,跟KDC有什么关联,那KDC又是什么呢?

KDC(Key Distribution Center):是默认安装在DC(域控制器)上Kerberos的主要服务,负责发行票据。

我们来看下面的一张图:

2

我们可以看到AS认证服务和TGS服务是被包含在KDC中的,那AS认证服务和TGS服务又是什么呢,我们来看下面一张图:

3

从图中我们很清楚可以看出AS服务是用来验证用户身份的,TGS服务是用来验证用户是否可以访问Win7的,具体流程如下:

  1. 域用户Lucky向kerberos服务请求,希望获取登录Win7的权限。 kerberos得到了这个消息,首先得判断Lucky是否是可信赖的, 也就是白名单黑名单的说法。这就是AS服务完成的工作,通过 在AD中存储黑名单和白名单来区分Lucky。成功后,返回AS返回TGT票据给Lucky。
  2. Lucky得到了TGT票据后,继续向kerberos请求,希望获取登录Win7的权限。kerberos又得到了这个消息,这时候通过Lucky消息中的TGT票据,判断出了Lucky拥有了这个权限,给了Lucky登录Win7的权限Service ticket。
  3. Lucky得到Service ticket后,终于可以成功登录Win7。

当然,这个Service ticket只是仅仅登录Win7(Host服务)的,如果还需要访问其他的服务要再次向TGS申请,接下来我们会详细讲一下AS和TGS的认证过程。

AS认证

我们从上面可知,AS这一个步骤是用来识别用户信息的真实性,也是用户从KDC拿到TGT票据的过程,建议大家通过Wireshark来一起实践学习。这里我会分为两部分来讲,一个是AS_REQ(客户端请求包),一个是AS_REP(KDC响应包)。

大家对照每一项进行学习的时候可以看下rfc4120,这是协议的详细标准,下面就举例一部分来讲。

AS_REQ

先来看下Wireshark抓到的kerberos的包:

5

  • pvno:kerberos协议的版本号

  • msg-type:消息类型,AS_REQ固定为krb-as-req,具体的类型和值如下表

  Message Type   Value  Meaning
  
  KRB_AS_REQ     10      初始认证请求
  KRB_AS_REP     11      响应 KRB_AS_REQ 请求
  KRB_TGS_REQ    12      基于 TGT 的认证请求
  KRB_TGS_REP    13      响应 KRB_TGS_REQ 请求
  KRB_AP_REQ     14      对服务器的应用程序请求
  KRB_AP_REP     15      对 KRB_AP_REQ_MUTUAL 的响应
  KRB_RESERVED16 16      为用户到用户保留 krb_tgt_request
  KRB_RESERVED17 17      为用户对用户保留 krb_tgt_reply
  KRB_SAFE       20      安全(校验和)应用程序消息
  KRB_PRIV       21      私有(加密)应用程序消息
  KRB_CRED       22      要转发的私有(加密)消息证书
  KRB_ERROR      30      错误响应
  • padata:PA_DATA主要是一些认证信息,一个列表,包含若干个认证消息用于认证,每个认证消息有padata_type和value。

    7.5.2.  PreAuthentication Data Types
    
       Padata and Data Type    Padata-type   Comment
                                Value
    
       PA-TGS-REQ                  1
       PA-ENC-TIMESTAMP            2
       PA-PW-SALT                  3
       [reserved]                  4
       PA-ENC-UNIX-TIME            5        (deprecated)
       PA-SANDIA-SECUREID          6
       PA-SESAME                   7
       PA-OSF-DCE                  8
       PA-CYBERSAFE-SECUREID       9
       PA-AFS3-SALT                10
       PA-ETYPE-INFO               11
       PA-SAM-CHALLENGE            12       (sam/otp)
       PA-SAM-RESPONSE             13       (sam/otp)
       PA-PK-AS-REQ_OLD            14       (pkinit)
       PA-PK-AS-REP_OLD            15       (pkinit)
       PA-PK-AS-REQ                16       (pkinit)
       PA-PK-AS-REP                17       (pkinit)
       PA-ETYPE-INFO2              19       (replaces pa-etype-info)
       PA-USE-SPECIFIED-KVNO       20
       PA-SAM-REDIRECT             21       (sam/otp)
       PA-GET-FROM-TYPED-DATA      22       (embedded in typed data)
       TD-PADATA                   22       (embeds padata)
       PA-SAM-ETYPE-INFO           23       (sam/otp)
       PA-ALT-PRINC                24       ([email protected])
       PA-SAM-CHALLENGE2           30       ([email protected])
       PA-SAM-RESPONSE2            31       ([email protected])
       PA-EXTRA-TGT                41       Reserved extra TGT
       TD-PKINIT-CMS-CERTIFICATES  101      CertificateSet from CMS
       TD-KRB-PRINCIPAL            102      PrincipalName
       TD-KRB-REALM                103      Realm
       TD-TRUSTED-CERTIFIERS       104      from PKINIT
       TD-CERTIFICATE-INDEX        105      from PKINIT
       TD-APP-DEFINED-ERROR        106      application specific
       TD-REQ-NONCE                107      INTEGER
       TD-REQ-SEQ                  108      INTEGER
       PA-PAC-REQUEST              128      ([email protected])
    

    这里表示pre-authentication data 预认证数据,有两项分别是

    • pA-ENC-TIMESTAMP:按照etype的加密类型,用用户hash加密时间戳,作为value 发送给AS服务器。然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过返回 TGT票据和enc_part(里面包含有session-key)。

    • PA-DATA pA-PAC-REQUEST:这个是启用PAC支持的扩展。PAC(Privilege Attribute Certificate)并不在原生的kerberos里面,是微软引进的扩展。所以我们要清楚kerberos不是Windows上才有的,Linux也可以用这个协议做认证。PAC包含在ASREQ的响应body(ASREP)。这里的value对应的是include=true或者include=false(KDC根据include的值来判断返回的票据中是否携带PAC)。

    6

  • kdc-options:设置一些标志信息可以修改KDC的行为,在官方解释是

    This field appears in the KRB_AS_REQ and KRB_TGS_REQ requests to the KDC and indicates the flags that the client wants set on the tickets as well as other information that is to modify the behavior of the KDC. Where appropriate, the name of an option may be the same as the flag that is set by that option. Although in most cases, the bit in the options field will be the same as that in the flags field, this is not guaranteed

  • cname:这是用户名,采用的是PrincipalName 类型和string类型的组合。sname也是采用这种格式,主要的类型如下:

  7.5.8.  Name Types
  
     Name Type           Value  Meaning
  
     KRB_NT_UNKNOWN        0    未知名称类型
     KRB_NT_PRINCIPAL      1    用户主体名称类型
     KRB_NT_SRV_INST       2    服务和其他唯一实例(krbtgt)的名称类型
     KRB_NT_SRV_HST        3    服务主机名称为实例名的名称类型
     KRB_NT_SRV_XHST       4    服务与主机作为剩余组件名称类型
     KRB_NT_UID            5    唯一ID名称类型
     KRB_NT_X500_PRINCIPAL 6    X.509编码的可分辨名称类型
     KRB_NT_SMTP_NAME      7    邮件名称类型
     KRB_NT_ENTERPRISE    10    企业名称类型

这里存在一个用户名枚举的方法,可以看另外一篇文章域渗透-用户名枚举对照学习。

  • realm:服务端域名

  • sname:关联的服务SPN,在ASREQ里面是krbtgt和域名,类型是KRBNTSRVINST

  • till:此字段包含客户端请求票证的到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具。

  • rtime:如果是一个可更新票据的要求,这个字段是一个绝对到期的时间

  • nonce:随机数,用来防止数据包重放。随机生成的一个数kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具。

  • etype:加密类型,在请求报文之中每个有加密的数据都有一个etype字段对应,KDC就是从这段数据中加密方式,来从AD之中选择对应的hash来进行身份验证。

    des_cbc_crc = 1,
    des_cbc_md4 = 2,
    des_cbc_md5 = 3,
    des3_cbc_md5 = 5,
    des3_cbc_sha1 = 7,
    dsaWithSHA1_CmsOID = 9,
    md5WithRSAEncryption_CmsOID = 10,
    sha1WithRSAEncryption_CmsOID = 11,
    rc2CBC_EnvOID = 12,
    rsaEncryption_EnvOID = 13,
    rsaES_OAEP_ENV_OID = 14,
    des_ede3_cbc_Env_OID = 15,
    des3_cbc_sha1_kd = 16,
    aes128_cts_hmac_sha1 = 17,
    aes256_cts_hmac_sha1 = 18,
    rc4_hmac = 23,
    rc4_hmac_exp = 24,
    subkey_keymaterial = 65
    
  • addresses:客户端IP地址或者是计算机名称。我这里是WIN7,使用的类型是NetBios

    7.5.3.  Address Types
    
       Address Type                   Value
    
       IPv4                             2
       Directional                      3
       ChaosNet                         5
       XNS                              6
       ISO                              7
       DECNET Phase IV                 12
       AppleTalk DDP                   16
       NetBios                         20
       IPv6                            24
    

借鉴一下Kerberos (I): How does Kerberos work? – Theory的图(懒~):

KRB_AS_REQ

AS_REP

接收到请求后,KDC通过解密时间戳验证用户身份,如果信息是正确的话,那么它会响应一个AS_REP,先来看下Wireshark抓包的返回包:

as_rep

这里的pvno、msg-type、crealm、cname这几项跟req的一样,这里就不展开可以返回上面看一下具体作用。as_rep的包主要是ticket和enc-part这两部分。

先来说这个ticket的内容,本质这个就是KDC返回来的一张TGT票据。

  • tkt-vno:这里是票据格式的版本号

  • realm:派发票据的域

  • sname:跟req的作用是一样的

  • enc-part:这个用于TGS_REQ的认证。用户不可读取里面的内容。是使用krbtgt的hash进行加密的,因此如果我们拥有krbtgt的hash就可以自己制作一个ticket,既黄金票据。

    在rfc4120中也称为EncTicketPart,这一部分包含以下参数的内容:

    EncTicketPart   ::= [APPLICATION 3] SEQUENCE {
        flags                   [0] TicketFlags,
        key                     [1] EncryptionKey,
        crealm                  [2] Realm,
        cname                   [3] PrincipalName,
        transited               [4] TransitedEncoding,
        authtime                [5] KerberosTime,
        starttime               [6] KerberosTime 可选,
        endtime                 [7] KerberosTime,
        renew-till              [8] KerberosTime 可选,
        caddr                   [9] HostAddresses 可选,
        authorization-data      [10] AuthorizationData 可选
    }		
    

    总的来说这块就是包含了用户名、 Login Session Key(key)、域信息、主体名称、票据的有效期、还有一项是PAC(authorization-data)

下面还有一项是enc-part部分,这一部分的是用用户的hash加密的,解密后可以得到 Login Session Key,主要是防止被窃取重放数据包。

我们可以使用pykek项目来模拟发包和解密:

from time import time, localtime, strftime
from random import getrandbits
from kek.crypto import generate_subkey, ntlm_hash, RC4_HMAC, HMAC_MD5
user_key = (RC4_HMAC,  ntlm_hash("p@ssw0rd").digest())
as_req=build_as_req("hack.lab", "lucky", user_key, time(), getrandbits(31), pac_request=False)
print as_req
sock = send_req(as_req, "172.16.0.106")
print sock
data = recv_rep(sock)
as_rep, as_rep_enc = decrypt_as_rep(data, user_key)
print as_rep_enc

如下图,解密出来的session-key:

7

这部分的 Login Session Key和TGT票据会在下一个阶段用到。

TGS认证

TGS_REQ

  1. 经过上面的步骤,客户端获得了 TGT票据 和 Login Session Key。
  2. 用自己的密码NTLM Hash解密Login Session Key得到原始的Logon Session Key。
  3. 它会在本地缓存此 TGT票据和 原始的Login Session Key。如果现在它需要访问某台服务器的某个服务,它就需要凭借这张TGT票据向KDC申请相应的ST服务票据(Service Ticket)。
  4. ST服务票据是通过KDC的另一个服务 TGS颁发的。
  5. 在这个阶段,微软引入了两个扩展自协议 S4u2self 和 S4u2Proxy(当委派的时候,才用的到)

下面是TGS_REQ的数据包:

tgs_req

大项的主要有pvno、msg-type、req-body、padata,相信前面三项通过上面的了解已经知道了,这块我们主要是对padata里面的内容进行分析。

padata里面也包含了各种版本和类型,我们主要是看padata-value和ap-req这两项:

  • padata-value:这一串东西包含了使用用户名、域、当前时间、TGT票据(也就是AS_REP当中的ticket->enc-part)、authenticator,这些下面都会说到的,只要理解这一项的值就行,总的来说就是ap-req的总和,可以进行解码得到ap-req的内容。

  • ap-req:这一部分包含协议版本号,主要是看ticket和authenticator的内容。

    ticket:这里面的cipher就是AS_REP响应过来的TGT票据,大家可以仔细观察下,两个cipher的值是一样的

    authenticator:这里是由AS_REP解码出来的sessions-key、msg-type、用户名、域、chksum(这个是由req_body编码而来)、时间戳

req-body:这一项是由需要访问的服务信息组成,包括目标的服务标识、服务名称、域名,这一项通过RSA_MD5加密组成上面authenticator中的chksum。

我们也可以用pykek工具包来模拟这一过程的发包,在krb5.py最下面加入下面的代码运行:

from time import time, localtime, strftime
from random import getrandbits
from kek.crypto import generate_subkey, ntlm_hash, RC4_HMAC, HMAC_MD5
from kek.pac import build_pac, pretty_print_pac
user_key = (RC4_HMAC,  ntlm_hash("p@ssw0rd").digest())
user_realm = "hack.lab"
user_name = "lucky"
target_realm = "dc.hack.lab"
current_time = time()
nonce = getrandbits(31)
as_req = build_as_req(user_realm, user_name, user_key, current_time, nonce, pac_request=False)
sock = send_req(as_req, "172.16.0.106")
data = recv_rep(sock)
as_rep, as_rep_enc = decrypt_as_rep(data, user_key)
tgt_a = as_rep['ticket']
subkey = generate_subkey()
nonce = getrandbits(31)
current_time = time()
pac = None
session_key = (int(as_rep_enc['key']['keytype']), str(as_rep_enc['key']['keyvalue']))
tgs_req = build_tgs_req(user_realm, 'MSSQLSvc', "SQL.hack.lab", user_realm, user_name,
                            tgt_a, session_key, subkey, nonce, current_time, pac, pac_request=False)
sock1 = send_req(tgs_req, "172.16.0.106")
data1 = recv_rep(sock1)
tgs_rep, tgs_rep_enc = decrypt_tgs_rep(data1, subkey)
print tgs_rep

建议大家也去跟一下这部分的代码,可以认识到整过数据包详细的组合流程步骤。

如果MSSQLSvc和SQL.hack.lab不存在可以换成你登录的那台主机名称比如本次环境中主机名称win7.hack.lab,服务类型就换成host。

TGS_REP

  1. TGS接收到请求之后,首先会检查自身是否存在客户端所请求的服务(就是查询SPN)。

  2. 如果服务存在,则通过 krbtgt 用户的NTLM Hash 解密TGT并得到Login Session Key,然后通过Login Session Key解密Authenticator。

  3. 如果解密成功,则验证了对方的真实身份,同时还会验证时间戳是否在范围内。并且还会检查TGT中的时间戳是否过期,且原始地址是否和TGT中保存的地址相同。

  4. 在完成上述的检测后,如果验证通过,则TGS完成了对客户端的认证,会生成一个用Logon Session Key加密后的用于确保客户端-服务器之间通信安全的Service Session Key会话秘钥(也就是最外层enc-part部分),并且会为该客户端生成ST服务票据。

    ST服务票据主要包含两方面的内容:客户端用户信息和原始Service Session Key,整个ST服务票据用该服务的NTLM Hash进行加密。

  5. 最终Service Session Key 和 ST服务票据 发送给客户端。(这一步不管用户有没有访问服务的权限,只要TGT正确,就都会返回ST服务票据,这也是kerberoasting能利用的原因,任何一个用户,只要hash正确,就可以请求域内任何一个服务的ST票据)

下面是TGS_REP的数据包:

tgs_rep

这里主要需要了解的就是ticketenc-part

ticket

这里返回的ticket就是一张ST(Service Ticket)服务票据,也称作TGS票据。

这张票据的ticket->enc-part部分是使用请求的服务对应的密钥(Service Session Key)进行加密的。因此如果我们拥有服务的密码Hash,那么我们就可以自己制作一个ST服务票据,这就造成了白银票据攻击。

enc-part:

经过Logon Session Key加密的Service Session Key(包含请求服务的身份信息等),用于请求服务时的会话密钥。enc-part这里也是可以解密的,解密得到Service Session Key,用来作为作为下阶段的认证密钥。

解密可以使用上面的python代码:

tgs_rep, tgs_rep_enc = decrypt_tgs_rep(data1, subkey)
print tgs_rep_enc

kerberoasting和kerberoast是同一种攻击技术,只是叫法不一样

AP认证

AP_REQ

上面的过程是和KDC交互的步骤,这一步是用户与AP(Application Server)之间的认证。

  1. 我们从TGS_REP拿到了ST票据和Service Session Key,我们需要去访问ap的服务内容。
  2. 使用从上面拿到的ST票据,还有用户名、时间戳、Service Session Key一起发送给AP。
  3. AP收到后会去KDC确认信息和PAC权限

下面是AP_REQ的数据包,它不会像TGS、AS一样在Wireshark中显示,一般是通过服务的协议也就是DCERPC(Distributed Computing Environment / Remote Procedure Calls),也称作分散式运算环境/远端呼叫系统

这是另一个非常基础的Windows系统的通信协议,它比rdp协议更普遍,默认开启。它会把kerberos的认证信息封装起来一起发送,比如你用HTTP的kerberos协议认证也是封装在HTTP协议中一起发送。

8

我们来看主要部分:

9

我们可以看下rfc上面的介绍:

Neuman, et al.              Standards Track                    [Page 84]

RFC 4120                      Kerberos V5                      July 2005


   AP-REQ          ::= [APPLICATION 14] SEQUENCE {
           pvno            [0] INTEGER (5),
           msg-type        [1] INTEGER (14),
           ap-options      [2] APOptions,
           ticket          [3] Ticket,
           authenticator   [4] EncryptedData -- Authenticator
   }

   APOptions       ::= KerberosFlags
           -- reserved(0),
           -- use-session-key(1),
           -- mutual-required(2)

   pvno and msg-type
      These fields are described above in Section 5.4.1. msg-type is
      KRB_AP_REQ.

   ap-options
      This field appears in the application request (KRB_AP_REQ) and
      affects the way the request is processed.  It is a bit-field,
      where the selected options are indicated by the bit being set (1),
      and the unselected options and reserved fields by being reset (0).
      The encoding of the bits is specified in Section 5.2.  The
      meanings of the options are as follows:

   Bit(s)  Name             Description

   0       reserved         Reserved for future expansion of this field.

   1       use-session-key  The USE-SESSION-KEY option indicates that
                            the ticket the client is presenting to a
                            server is encrypted in the session key from
                            the server's TGT.  When this option is not
                            specified, the ticket is encrypted in the
                            server's secret key.

   2       mutual-required  The MUTUAL-REQUIRED option tells the server
                            that the client requires mutual
                            authentication, and that it must respond
                            with a KRB_AP_REP message.

   3-31    reserved         Reserved for future use.

   ticket
      This field is a ticket authenticating the client to the server.

里面的ticket就是从TGS_REP获取到的ST(TGS)票据,下面还有使用Service Session Key加密的authenticator,关于authenticator的介绍:

Neuman, et al.              Standards Track                    [Page 85]

RFC 4120                      Kerberos V5                      July 2005


   authenticator
      This contains the encrypted authenticator, which includes the
      client's choice of a subkey.

   The encrypted authenticator is included in the AP-REQ; it certifies
   to a server that the sender has recent knowledge of the encryption
   key in the accompanying ticket, to help the server detect replays.
   It also assists in the selection of a "true session key" to use with
   the particular session.  The DER encoding of the following is
   encrypted in the ticket's session key, with a key usage value of 11
   in normal application exchanges, or 7 when used as the PA-TGS-REQ
   PA-DATA field of a TGS-REQ exchange (see Section 5.4.1):

   -- Unencrypted authenticator
   Authenticator   ::= [APPLICATION 2] SEQUENCE  {
           authenticator-vno       [0] INTEGER (5),
           crealm                  [1] Realm,
           cname                   [2] PrincipalName,
           cksum                   [3] Checksum OPTIONAL,
           cusec                   [4] Microseconds,
           ctime                   [5] KerberosTime,
           subkey                  [6] EncryptionKey OPTIONAL,
           seq-number              [7] UInt32 OPTIONAL,
           authorization-data      [8] AuthorizationData OPTIONAL
   }

   authenticator-vno
      This field specifies the version number for the format of the
      authenticator.  This document specifies version 5.

   crealm and cname
      These fields are the same as those described for the ticket in
      section 5.3.

   cksum
      This field contains a checksum of the application data that
      accompanies the KRB_AP_REQ, computed using a key usage value of 10
      in normal application exchanges, or 6 when used in the TGS-REQ
      PA-TGS-REQ AP-DATA field.

   cusec
      This field contains the microsecond part of the client's
      timestamp.  Its value (before encryption) ranges from 0 to 999999.
      It often appears along with ctime.  The two fields are used
      together to specify a reasonably accurate timestamp.

   ctime
      This field contains the current time on the client's host.

本阶段如图所示:

KRB_AP_REQ

AP_REP

  1. AP(Application Server)接收到请求后,用自己的密钥(Service Session Key)解密TGS中的ticket->enc-part获取Service Session Key
  2. 然后使用Service Session Key解密新的Authentication,对TGS和authenticator进行验证,验证通过则返回新的时间戳(通过Service Session Key进行加密)
  3. 用户通过Service Session Key解密AP-REP返回的时间戳,并验证其是否正确。验证通过则证明客户端可以信赖服务器,并向服务器AP发送服务请求。
  4. 服务器(AP)向客户端提供相应的服务。

下面是AP_REP的数据包:

10

rfc的描述:

5.5.2.  KRB_AP_REP Definition

   The KRB_AP_REP message contains the Kerberos protocol version number,
   the message type, and an encrypted time-stamp.  The message is sent
   in response to an application request (KRB_AP_REQ) for which the
   mutual authentication option has been selected in the ap-options
   field.

   AP-REP          ::= [APPLICATION 15] SEQUENCE {
           pvno            [0] INTEGER (5),
           msg-type        [1] INTEGER (15),
           enc-part        [2] EncryptedData -- EncAPRepPart
   }

   EncAPRepPart    ::= [APPLICATION 27] SEQUENCE {
           ctime           [0] KerberosTime,
           cusec           [1] Microseconds,
           subkey          [2] EncryptionKey OPTIONAL,
           seq-number      [3] UInt32 OPTIONAL
   }

   The encoded EncAPRepPart is encrypted in the shared session key of
   the ticket.  The optional subkey field can be used in an
   application-arranged negotiation to choose a per association session
   key.

   pvno and msg-type
      These fields are described above in Section 5.4.1.  msg-type is
      KRB_AP_REP.

   enc-part
      This field is described above in Section 5.4.2.  It is computed
      with a key usage value of 12.

   ctime
      This field contains the current time on the client's host.

   cusec
      This field contains the microsecond part of the client's
      timestamp.

   subkey
      This field contains an encryption key that is to be used to
      protect this specific application session.  See Section 3.2.6 for
      specifics on how this field is used to negotiate a key.  Unless an
      application specifies otherwise, if this field is left out, the
      sub-session key from the authenticator or if the latter is also
      left out, the session key from the ticket will be used.

0x03 参考

https://www.t00ls.cc/viewthread.php?tid=55987

https://buaq.net/go-87488.html

https://www.tarlogic.com/blog/how-kerberos-works/

https://xz.aliyun.com/t/8690

https://daiker.gitbook.io/windows-protocol/kerberos/

https://www.modb.pro/db/167245