kerberos

发布于 2024-12-13  261 次阅读


前言

前面打了一个靶机,发现对于kerberos并不是很了解,但是kerberos在内网渗透中占有非常重要的地位,这篇文章原本早就应该写的,但是本人确实太懒,所以拖到了现在。

什么是kerberos

kerberos实际上就是一种基于ticket的身份认证协议,由于在认证过程中都没有涉及到密码,而是通过加密票据进行认证,所以普遍认为kerberos比较安全。

kerberos原理及认证过程

原理

kerberos实际上是由KDC、客户、服务三部分组成,而KDC又由AS(身份鉴别服务器)、TGS(票据授权服务器)

kerberos基本认证过程如下:

一些专业术语:

Client:访问服务的客户机

Server:提供服务的服务器

KDC(Key Distribution Center):密钥分发中心 
KDC中分成两个部分:Authentication Service和Ticket Granting Service
(1)Authentication Service(AS):身份验证服务器
AS的作用就是验证Client端的身份,验证通过之后,AS就会给TGT票据(Ticket Granting Ticket)给Client
(2)Ticket Granting Service(TGS):票据授予服务器
TGS的作用是通过AS发送给Client的TGT换取访问Server端的ST(Server Ticket)给Client.
(3)Ticket-granting cookie(TGC):存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用,是CAS Server用来明确用户身份的凭证。TGT封装了TGC值以及此Cookie值对应的用户信息.
(4)Ticket-granting ticket(TGT):TGT对象的ID就是TGC的值,在服务器端,通过TGC查询TGT.
(5)SEerver Ticket(ST):ST服务票据,由TGS服务发布.

Active Directory(AD):活动目录,充当集中存储库并存储与Active Directory 用户、计算机、服务器和组织内的其他资源等对象相关的所有数据

Domain Controller(DC):域控制器

过程

AS_REQ

域内客户端用户访问服务时,kerberos会先向KDC的AS发送一个AS_REQ请求,此请求主要是为了得到TGT,只有拿到TGT才能与TGS建立信任。该请求包含:用户名、主机名、加密类型、NTLM HASH加密的时间戳以及目标服务id等等

利用

PTH

由于在请求过程中会传递NTLM HASH,所以当我们截取到此哈希,那么就无需明文密码,伪造该用户进行哈希传递攻击该用户

用户枚举

在请求中会包含用户名,但是当用户启用、禁用或者不存在时,AS服务器响应的返回包是不同的,可以据此进行用户枚举。

密码喷洒

当知道密码时,可以对域内枚举的用户进行密码喷洒,这是因为密码正确和错误的响应包也不同

AS_REQ Roasting

如果关闭了预身份验证,那么此时向域控的88端口发送AS_REQ请求,域控将不会进行任何验证就将TGT和用户hash加密的login session key返回,那么可以在本地破解这个session key,甚至可以破解到明文密码,这在time那个靶场中有提到。

AS_REP

当AS收到AS_REQ后,通过AD查询该用户的密码hash值,利用client_hash中的Authenticator(就是NTLM hash加密的时间戳)进行解密,如果解密成功并且时间戳范围在5分钟内,那么返回krbtgt用户(域管用户,密码无法登陆且随机生成)hash加密的TGT,此TGT中包含了PAC,而PAC包含了client的sid和其所在的组。同时AS会在生成一个临时秘钥login session key,使用发起请求用户的NTLM HASH进行加密返回。

利用

黄金票据

当我们拥有krbtgt用户的hash时,那么就相当于我们拥有了域管权限,利用这点签发任意用户的TGT,直接跳过AS阶段,利用时需要的条件:

域名
域的sid值
域的krbtgt用户的ntlm hash
伪造的用户

TGS-REQ

此请求是已经获取了TGT以及临时的login session key,用户利用ntlm hash解密login session key ,在本地缓存该TGT票据以及login session key,当用户要访问某请求时,凭借TGT向TGS发起特定服务的TGS_REQ请求(由于安全性问题这里微软引入了两个扩展协议S4u2self和S4u2Proxy),这里的利用会涉及到委派,在靶机brute4road中有所体现

TGS_REP

收到客户端发来的TGS_REQ后,TGS检查是否有该服务,如果有,那么利用krbtgt用户的ntlm hash对TGT票据进行解密拿到login session key,再利用login session key解密Authenticator,解密成功且时间戳在范围内那么验证成功,返回用login session key加密的与服务器通讯的server session key,生成用server hash加密的TGS票据,只要TGT正确即使用户没有权限也会返回TGS。

利用

白银票据

TGS_REP中ticket部分的加密部分是利用服务hash进行加密,如果有服务hash,那么就能任意为任意用户签发TGS,此票据成为白银票据,白银票据只能访问特定的服务,且伪造的白银票据是没有有效的KDC签名的PAC,所以将目标主机直接配置为KDC PAC签名将没有任何作用,利用条件:

1.域名
2.域sid
3.目标服务FQDN
4.服务名
5.服务账号的NTML HASH
6.伪造的用户名

AP_REQ

收到TGS_REP后用户获得了TGS票据,想要访问某个服务,则需要拿着TGS票据去请求服务。

AP_REP

服务使用自己的Server_Hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限,至此kerberos认证过程便完成了

PAC

原始的kerberos认证过程有一个很大的问题,那就是TGS_Rep这一步,无论用户是否拥有对应服务的访问权限,只要验证用户身份通过都会返回TGS票据,这导致后续过程里用户可以直接拿着TGS票据访问任何服务了,因此这个认证只解决了身份验证的问题,没有解决权限验证的问题。

为此微软引入了PAC,在AS_Req这个过程里,用户验证成功返回krbtgt hash加密的TGT票据,TGT里面包含PAC,而PAC中包含用户的sid,用户所在的组。在后续TGS_Req的过程里,KDC会验证TGT中的PAC的签名,判断PAC是否被篡改,如果PAC完好,则重新构造新的PAC放在TGS票据中,到最后一步AP_Rep这里,服务会拿着PAC去KDC那边询问用户有没有访问权限,KDC解密PAC。获取用户的sid,以及所在的组,再判断用户是否有访问服务的权限,有访问权限就允许用户访问。

PAC对于用户和服务全程都是不可见的,只有KDC能制作和查看PAC,这也确保了PAC的安全性。当然从这里我们就能看出来为什么白银票据是有局限性的了,上面我们提到过伪造的白银票据没有带有有效KDC签名的PAC,如果将目标主机配置为验证KDC PAC签名,则银票将不起作用,因为即使我们拥有Server_Hash也没法伪造有效KDC签名的PAC,毕竟PAC的整个过程无论对于用户还是服务都是不可见,只有KDC那里才能签发。

利用:MS14-068

委派

域委派是指将域内用户的权限委派给服务账户,使得服务账号能够以用户的权限在域内展开活动。简单的说就是如果一个服务账号上设置了委派属性,那么这个服务就能够以用户权限在域内进行其他操作。翻译过来就是服务能够被(某个用户)委派来进行其他操作。

委派大概被分成三种,分别是非约束性委派、约束性委派和基于资源的约束性委派(RBCD)

非约束性委派

任何用户都可以委派该服务账号代替自己去访问任何服务,流程:

1、服务1向KDC请求用户的可转发票据TGT
2、服务1使用TGT向KDC申请服务2票据TGS

利用

诱使高权限用户访问机器

当域管理员使用net use等远程访问命令,模拟域控管理员访问WIN7主机,设置了非约束性委派的主机可以抓取到域控管理员的TGT。但是需要满足以下条件:

1、需要Administrator权限
2、域内主机的机器账户开启非约束委派
3、高权限用户远程访问

过程:
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
然后使用kerberos::ptt导入票据即可伪造
mimikatz.exe "kerberos::ptt [0;4bbb6]-2-0-60a10000-Administrator@krbtgt-HACKME.COM.kirbi" "exit"

约束委派

限制了访问的服务类型与主机,但不能限制谁能对主机进行委派,也就是任意用户可以委派服务用户访问指定主机指定服务

微软在这里引入了Kerberos协议扩展,也就是之前提到过的S4U2Self 和S4U2Proxy。配置它后,约束委派将限制指定服务器可以代表用户执行的服务。这需要域管理员特权(其实严谨一点是SeEnableDelegation特权,该特权很敏感,通常仅授予域管理员)才能为服务配置域帐户,并且将帐户限制为单个域。

S4U2self协议(协议转换)允许服务代表任意用户请求访问自身服务的ST服务票据。这使得服务可以获得用户的授权(可转发的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy)。S4U2proxy协议允许服务在已取得ST服务票据下代表任意用户获取另一个服务的服务票据。

这是为了在用户以不使用 Kerberos 的方式对服务进行身份验证的情况下使用。
当用户以其他方式(如NTLM认证,基于表单的认证等方式)与服务器进行认证后,用户是无法向服务器提供请求该服务的服务票据TGS的,因而服务器也无法进一步使用S4U2Proxy协议请求访问服务B。
S4U2Self协议便是解决该问题的方案,被设置为TrustedToAuthForDelegation的服务能够调用S4U2Self向认证服务器为任意用户请求访问自身的可转发的服务票据,此后,便可通过S4U2Proxy使用这张TGS向域控制器请求访问B的票据

配置了约束委派的用户的userAccountControl属性有个FLAG位TrustedToAuthForDelegation。除此之外,还有一个msDS-AllowedToDelegateTo属性位,用于配置对哪个SPN进行委派。过程即:收到用户的请求之后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF),拿着这个票据向KDC请求访问特定服务的可转发的TGS(S4U2PROXY),并且代表用户访问特定服务,而且只能访问该特定服务。

具体步骤为:

1、服务1使用自己的hash向KDC申请一个TGT票据,注意在KDC-Options里面选择FORWARDABLE标志位,这样的话请求的TGT票据就是可转发的TGT票据。
2、服务1代表用户申请一个获得针对服务1自身的kerberos服务票据(这一步就是S4U2SELF),这一步生成的TGS票据是可转发的TGS票据。
3、服务1可以使用来自用户的授权(在S4U2SELF阶段获得的可转发的TGS),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的TGS

利用

使用机器账户已存在的TGT票据

约束性委派攻击的关键就是获得可转发的服务票据TGS,而约束性委派在向KDC申请可转发TGS时,需要提供可转发的TGT(自身的hash申请的)。获取根据约束性委派的执行过程可知,只要控制配置约束性委派服务的机器,并获得了它的密码,那么我们就可以劫持这台主机的kerberos请求过程,最终获得任意用户权限的ticket,过程:

# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"

# 使用Rubeus申请服务票据
.\Rubeus.exe asktgt /user:MSSQLSERVER$ /rc4:NTLM哈希 /domain:xiaorang.lab /dc:DC.xiaorang.lab /nowrap

# 注入票据
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:CIFS/DC.xiaorang.lab /dc:DC.xiaorang.lab /ptt /ticket:你上面抓到的服务票据

# 访问
dir \\DC.xiaorang.lab\c$

可以看看靶机brute4road

基于资源的约束性委派(RBCD)

基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派不需要通过具备SeEnableDelegationPrivilege权限的域管理员进行修改,而是将设置属性的权限给了服务资源本身,资源本身可以为自己配置资源委派信任关系,资源本身决定可以信任谁。

以从Service A到Service B的委派作为例子,传统的约束性委派需要域管理员将Service A的 msDS-AllowedToDelegateTo属性指定为Service B,而在基于资源的约束性委派中无需域管理员参加,只需要在Service B上把msDS-AllowedToActOnBehalfOfOtherIdentity属性设置为Service A即可完成委派。配置RBCD的关键在于设置msDS-AllowedToActOnBehalfOfOtherIdentity属性,一般而言拥有设置权限的用户为:

将主机加入域的用户 (机器账户中会有一个 msDS-CreatorSID 属性, 使用非域管账户加入域时才会显示)
Account Operators (能修改任意域内非域控机器的委派属性)
NT AUTHORITY\SELF (该主机的机器账户)

利用

提权

如果我们现在已经获取到一个域账户bob,其具备机器win2019的属性修改的权限,那我们就可以获取win2019的管理员权限

攻击步骤:
1、利用bob域用户创建一个机器账户test(每个域用户默认可以创建10个)
2、然后修改win2019的msDS-AllowedToActOnBehalfOfOtherIdentity 为新创建的机器用户的sid
3、利用该机器账户的凭证通过S4U协议伪造Administrator用户委派至目标主机的ST票据, 实现本地提权/横向移动

简单来说就是创建新用户伪造成Administrator的委派

变种黄金票据

在获取到域控权限后,可以对krbtgt用户设置委派属性,以实现维持权限的目的

新一代Kerberos攻击

常规的后渗透思路里,票据攻击常用于域内横向,最常见的就是黄金票据和白银票据,前面已经提过了,白银票据局限性是最大的,只能访问指定服务,并且目标主机不能开启验证KDC PAC签名,因为白银票据伪造不了这玩意儿;而黄金票据在如今很容易被识别,因为一旦KDC服务收到TGT/ST,并且在SIEM中收到日志,现在的安全设备就能检测出来。

砖石票据

与黄金票据相似,黄金票据和钻石票据都需要Krbgtg密钥,不同之处在于,黄金票据是利用krbtgt用户的hash直接伪造新的TGT,而钻石票据攻击请求普通票证、解密 PAC、修改、重新计算签名并再次加密,生成与合法 PAC 高度相似的 PAC。利用条件:

1、域krbtgt的hash

2、当前域用户的账号密码

3、域名

4、域控的名称

过程:

首先用mimikatz获取krbtgt的aes256密钥
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:de1ay.com /user:krbtgt" "exit"

假设我们现在知道:
krbkey:42e65a58c000dab8d353b1ff2bee93383f27f0966767afa8c1f32fc51122d118
user:mssql
password:1qaz@WSX
domain:de1ay.com
dc:dc.de1ay.com
ticketuser:administrator

接下来可以用Rubeus进行钻石票据攻击
Rubeus.exe diamond /krbkey:42e65a58c000dab8d353b1ff2bee93383f27f0966767afa8c1f32fc51122d118 /user:mssql /password:1qaz@WSX /enctype:aes /domain:de1ay.com /dc:dc.de1ay.com /ticketuser:administrator /ptt /nowrap

然后可以获取ticket.kirbi
Rubeus.exe asktgs /ticket:ticket.kirbi的内容 /service:cifs/dc.de1ay.com /ptt /nowrap

这样就以低权限机器访问了域控,前面提到过,windows引入PAC是为了判断用户有没有访问权限,理论上应该只有KDC能制作和查看PAC,对用户和服务器都透明,这里我们劫持了这个过程给自己修改PAC增加了高权限,所以在对TGT影响较小的情况下实现了提权,较为隐蔽。

蓝宝石票据

蓝宝石票据和钻石票据相似,票据不是伪造的,而是基于正常请求后得到的合法票据。区别只在于PAC的修改方式,钻石票据修改了合法的PAC,在蓝宝石票据里通过S4U2self+u2u实现,与钻石票据相似,生成的票据是合法元素的集合,并遵循标准票据请求,这使得它成为最难检测的银/金票据变体。

由于钻石票据会动态修改PAC来包含任意组ID,理论上来说某些软件或许能检测出PAC值与实际AD关系之间的差异(例如PAC指示用户属于某些组),虽然事实上这样并不可行。而蓝宝石票据通过在票据中包含合法强大用户的PAC来以更隐秘的方式获取类似票据的替代方案,因此PAC中的内容与AD中的内容之间将不再有任何差异。

在某些特定场景中,S4U2self和U2U可以组合,在这种情况下,这两种机制在其请求中包含的标志和结构被组合。这允许

  • 操作来自无 SPN 帐户的 RBCD 攻击
  • 进行unPAC-the hash攻击
  • 检索并解密任何帐户的PAC,可以用来获得蓝宝石票据。

过程(工具都在impacket里):

假设我们知道:
domain admin:snapattack
domain:snapattcker.labs
user:vgullible
pass:Passw0rd1
aesKey:fec5d... ....
domain-sid:S-1-5 ... ...
DC:arrakis.snapattack.labs

利用ticketer.py
python3 ticketer.py -request -impersonate 'snapattack' -domain 'snapattack.labs' -user 'vgullible' -password 'Passw0rd1' -aesKey 'fec5d... ....' -domain-sid 'S-1-5-21-... ...' 'snapattcker'

export KRB5CCNAME=snapattcker.cache

python3 psexec.py snapattack.labs/snapattack@arrakis.snapattack.labs cmd.exe -k debug -n

这样之后就接管了域控,文章在拜读学长文章基础上修改,对于砖石票据和蓝宝石票据攻击还没找到合适环境,只能日后搭建一个了,先留个坑。


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。