Miracle
文章8
标签4
分类4

文章分类

文章归档

域渗透之Kerberos认证

域渗透之Kerberos认证

一.Kerberos协议

Kerberos协议是一个专注于验证通信双方身份的网络协议,kerberos更侧重于通信前双方身份的认证工作,他能够为网络中通信的双方提供严格的身份验证服务,确保通信双方身份的真实性和安全性.

​ Kerberos会使用TCP/UDP88端口进行身份验证和票据授予,使用TCP/UDP464端口进行**Kerberos KpassWd(密码重置)**。

结构及常用术语

  • DC (Domain Controller): 域控制器
  • AD (Active Directory): 活动目录,他是Windows Server的目录服务,Kerberos认证中就需要通过查询AD中数据来判断发出请求的客户端是否合法。
  • KDC (Key Disrtibution Center): 密钥分发中心,它是一种运行在物理安全服务器上的服务,是负责颁发凭证的Kerberos组件,这些凭证是使用KDC数据库中存储的信息创建的,KDC也是默认安装在域控中.KDC中包含ASTGS
    • AS (Authentication Service): 身份验证服务,为Client生成TGT的服务.
    • TGS (Ticket Grantng Service): 票据授予服务,为Client生成某个服务的Ticket.
  • Ticket : 票据,是网络对象互相访问的凭证.
  • ST (Service Ticket) : 服务票据.
  • TGT (Ticket Granting Ticket): 票据授权票据,通过票据授权票据可以获得一个票据,类似临时凭证.
  • krbtgt账户: Krbtgt账户是Windows中的一个内置账户,在创建活动目录时系统自动创建,其作用是KDC的服务账户,每个域都有一个唯一的Krbtgt账户,与域名称相同,并存储在Active Directory数据库中。krbtgt账户的密码是由域控制器DC系统自动随机生成的,在AD域中以HTLM hash的形式存储,可以简单理解为一个不能登录的账户.
  • SPN : 服务主体名称
  • PAC (Privilege Attribute Certificate) : 特权属性证书,其中包含各种授权信息,例如用户RID,所属组的RID,所属组个数等信息.简单来说,PAC用于验证用户权限,只有KDC能制作和查看PAC

二.Kerberos认证流程

image-20241031204342614

1,2 : ClientDC发出请求访问Server,DC收到请求后AS通过AD来判断Client是否可信,如果通过,AS生成TGT返回给Client.

3,4 : ClientTGT后继续向DC发出访问Server的请求,此时TGS通过TGT来判断Client具有访问权限,将具有访问Server权限的ST发送给Client.

5,6 : Client拥有了ST后就可以访问Server,但是ST只针对这个Server有效,然后Client就可以和Server建立通信了.

三.Kerberos认证分析

1. AS_REQ & AS_REP

目的 : 获取TGTLogin Session Key

  • AS_REQ:

​ 当用户要访问域中的某个服务,输入用户名和密码,本机Kerberos服务就会向KDCAS身份认证服务发送AS_REQ认证请求.

​ 请求主要包含用户Hash 加密的时间戳、请求用户名、协商Hash的加密类型等信息.

image-20241101162523396

其中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pvno: kerberos的版本号
msg-type: 消息类型,这里就是KRB_AS_REQ(0x0a)
PA_DATA: Pre-authentication Data,预身份认证,每个认证消息有type和value。
PA-DATA PA-ENC-TIMESTAMP: 用户HASH加密后的时间戳,作为value 发送给AS服务器。然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过
padata-type: padata类型
padata-vaule: padata的值
etype: 加密类型
cipher: 加密后的值
PA-DATA PA-PAC-REQUEST:PAC扩展
padata-type: padata类型
padata-vaule: padata的值
include-pac: 是否包含PAC,如果包含那么在响应包中就会返回PAC
req-body: 请求体
padding: 填充
kdc-options: 用于与KDC约定一些选项设置
cname: 客户端用户名,在AS_REQ里面cname 是请求的用户,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名
realm: 域名
sname: 服务端用户名,在AS_REQ 中sname是krbtgt,类型是KRB_NT_SRV_INST
KRB_NT_PRINCIPAL: 表示一个普通用户或服务的主体。
KRB_NT_SRV_HST: 表示一个主机上的服务。
KRB_NT_SRV_INST: 表示一个服务的具体实例,通常用于区分同一台主机上运行的不同服务。
till: 到期时间,rubeus和kekeo都是20370913024805Z,可以作为特征检测
nonce:随机生成的一个数,用于检测重放攻击
etype: 协商加密类型,KDC按照etype类型选择用户hash对应的加密方式
  • AS_REP:

​ 在KDC收到请求后,通过活动目录查询到该用户的密码Hash,用该Hash对请求包的PA-ENC-TIMESTAMP(加密时间戳)进行解密,解密完成后还会检查该时间戳范围是否在5分钟之内并且数据包无重放,检查通过后则认证成功.

​ 接着返回krbtgt用户的NTLM Hash加密后的TGT和用户NTLM Hash加密的Login Session key

​ 其中TGT主要包含Login Session key,时间戳和PAC.Login Session key作为用户和KDC之后几个阶段之间通信加密的会话密钥.

image-20241101182944658

其中:

1
2
3
4
5
6
7
8
9
10
pvno: kerberos的版本号
msg-type: 消息类型KRB-AS-REP
crealm: 域名
cname: 客户端用户名
ticket: 即TGT票据
tkt-vno: TGT 版本号
realm: 域名
sname: 请求的服务名称 krbtgt
enc-part: 这部份是用krbtgt的密码Hash加密的,其中包含了请求用户的PAC信息
enc_part: 这部分是用用户密码Hash加密的,里面包含Login session key

解密一下ticket中的enc_part:

其中d7b7e792 开头的值就是Login session key

image-20241101203517210

1
2
key: 就是Login session key
authorization-data: 里面是PAC的内容

ticket中的enc-part是由krbtgt的密码hash加密生成的。如果我们拥有krbtgthash,便可以自制ticket,发起黄金票据攻击

​ Login Session Key使用用户NTML Hash加密,作用是用于是用于确保客户端和KDC下一阶段之间通信安全,作为下一阶段的认证密钥

2.TGS_REQ & TGS_REP

目的 : 获取ST服务票据

  • TGS_REQ

​ 用户通过AS_REP拿到TGT票据后,用自己的Hash解密获得Login session key 加密客户端用户名,时间戳等信息,之后和TGT一起向KDC的TGS服务发起请求,请求服务票据。

image-20241101205642629

其中:

1
2
3
4
pvno: kerberos的版本号
msg-type: 消息类型
padata: 这个部分包含之前的TGT票据,以及Login session key 加密的内容
req-body: 请求体

padata:

image-20241104093155692

1
2
3
AP_REQ: 这部分会携带AS_REP里面获取到的TGT票据、客户端的认证信息
ticket: 可以看到这部分就是TGT票据
authenticator: 这部分就是Login session key加密的客户端信息: 请求的用户名、时间戳
  • TGS_REP

​ TGS服务在收到请求后,先检查自身是否存在客户端请求的服务,如果存在使用Login Session Keyauthenticator 解密,获取到请求的用户名和时间戳,并检查时间戳在5分钟的有效范围内。之后KDC使用krbtgt用户的hash解密TGT票据,把解密后的用户名等信息和authenticator 解密后的信息进行比对认证,如果认证成功,则颁发ST.

​ 返回服务票据(ST)与Login session key加密的Server Session key和请求的服务名称。

​ 服务票据(ST)中包含Server Session key、客户端名称、票据有效时间、PAC 等信息。

image-20241104093928645

其中:

1
2
3
4
ticket: 这个是服务票据ST,它由服务账号的Hash加密
enc-part: Login session key加密的Server Session key等信息
key: key就是Server Session key
authorization-data: 是用户的PAC

​ 在这一步中,不论用户是否有权限访问服务,只要TGT解密无误,都将返回ST服务票据。任何一个用户,只要hash正确,就可以请求域内任何一个服务的票据

3.AP_REQ & AP_REP

image-20241104103433981

  • AP_REQ

​ 用户解密Login session key 解密的内容,获得Server Session key 。然后把用户名、时间戳等信息用Server Session key 加密,同服务票据(ST)发送给目标服务。

image-20241104102730278

1
2
ticket: 这里的ticket字段就是ST票据的内容
authenticator: 就是Server Session Key加密的客户端信息

解密ticket后可看到和之前的ST 票据一样.

image-20241104103031863

使用07dd开头的Server Session Key 解密 authenticator

  • AP_REP

​ 服务器会收到用户发来的ST 后,用自己的Hash 解密获得Server Session Key。再用该Key 解密被加密的客户端信息(请求的用户名、时间戳等),并进行校验以及与ST 中的客户端信息进行比对,相同则认证通过。如认证通过,服务端会再次向KDC发送PAC,KDC收到PAC会使用krbtgt的hash进行解密,KDC通过SID判断用户权限等,并将信息返回给服务端。服务端将此信息和用户请求资源的ACL进行对比,判断是否提供服务。

image-20241104103859352

PAC

PAC (Privilege Attribute Certificate):特权属性证书,包含各种授权信息,例如用户RID,所属组的RID,所属组个数等信息.

​ 前面TGT和ST票据中的authorization_data字段内容就是PAC,如果没有该字段,Kerberos协议就只能验证用户身份,无法表示用户权限了.

  • 存在PAC的请求流程:
    • AS_REP阶段:KDC从AS-REQ 请求中取出cname字段并查询活动目录,找到sAMAccountName属性为cname字段的值的用户,用该用户的身份生成一个对应的PAC。用户也可以指定include-pac: False/True来要求KDC在返回的票据中是否包含PAC。
    • TGS_REQ阶段:KDC收到TGT后,利用krbtgt密钥对其解密并验证PAC的签名。签名正确,则证明PAC未经过篡改,然后在PAC的尾部重新生成两个签名: Server Signature (要请求的服务的hash生成的签名)和KDC Signature。然后把新的PAC 拷贝到ST服务票据中。(此步骤不校验PAC 中用户有没有访问服务的权限,只要TGT 正确就返回ST票据)
    • AP_REQ阶段:KDC收到TGT后,利用krbtgt密钥对其解密并验证PAC的签名。签名正确,则证明PAC未经过篡改,然后在PAC的尾部重新生成两个签名: Server Signature (要请求的服务的hash生成的签名)和KDC Signature。然后把新的PAC 拷贝到ST服务票据中。(此步骤不校验PAC 中用户有没有访问服务的权限,只要TGT 正确就返回ST票据)

只要TGT 票据中不带有PAC,那么ST 票据中也不会带有PAC,也就没有权限访问任何服务。

TGT中的PAC:

image-20241104111318293

ad-type:aD-IF-RELEVANT是最外层的包装器,封装了aD-WIN2K-PAC类型的AuthorizationData元素.

ad-data是一段连续的空间。段空间包含一个头部PACTYPE以及若干个PAC_INFO_BUFFER头部PACTYPE包括cBuffers、Version与缓冲区。

PAC_INFO_BUFFER为key-value型,key 的类型如下表所示,此表参考大佬

类型 意义
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 KERB_VALIDATION_INFO ,也就是上图中的Type: Logon Info (1) 。这个结构是登录信息,主要靠它来验证用户身份。Type: Logon Info (1) 结构如下

image-20241104112837424

四.总结

​ 这篇也是拖了近1周才写完,还是太懒了,这篇笔记也是跟着前辈们的笔记学习的,没太多自己的东西,继续努力!希望能琢磨出自己的新东西出来.

参考链接:

1
2
3
4
https://myzxcg.com/2021/08/Kerberos-%E8%AE%A4%E8%AF%81%E8%BF%87%E7%A8%8B%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90%E4%B8%80/#ap_req
https://xz.aliyun.com/t/8187?time__1311=n4%2BxnD0Dc7GQ0%3DDkDulDlhjmyecDgie4GuyWmID#toc-4
https://www.freebuf.com/articles/web/341103.html
https://www.cnblogs.com/zpchcbd/p/11707302.html