Kerberos域认证机制剖析
Kerberos概念
Kerberos是一种网络认证协议,其设计目标是通过密钥系统为Client / Server
应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。
在以上情况下, Kerberos作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享 密钥)执行认证服务的。
域认证所参与的角色
Kerberos的标志是三只狗头,狗头分别代表以下三个角色
-
- 访问服务的Client
-
- 提供服务的Server
-
- KDC(Key Distribution Center)密钥分发中心 kerberos 测试工具介绍
其中KDC服务默认会安装在一个域的域控中,而Client
和Server
为域内的用户或者是服务,如HTTP服务
,SQL服务
。在Kerberos
中Client
是否有权限访问Server
端的服务由KDC(Key Distribution Center)
发放的票据来决定。
Kerberos认证协议
TGT(Ticket Granting Ticket)
由身份认证服务
AS(Authentication Service)
授予的票据,TGT
用于身份认证,存储在内存,默认有效期为10小时,通过TGT
能够获得票据(Ticket)
,TGT
是一种 临时凭证 的存在,伪造的TGT
又被称为 黄金票据。
票据(Server Ticket/Ticket)
是网络对象互相访问的 凭证,
伪造的ST\Ticket
又被称为 白银票据。
KDC(Key Distribution Center)
负责管理票据、认证票据、分发票据,但是
KDC
不是一个独立的服务,它由以下服务组成:
- AS(Authentication Service): 身份认证服务,为
Client
生成TGT(Ticket Granting Ticket)
的服务。 - TGS(Ticket Granting Service): 票据授予服务,为
Client
生成某个服务的Ticket
的服务。
AD(Account Database)
一个类似于本机
SAM
的一个数据库,存储所有Client
的白名单,只有存在于白名单的Client
才能顺利申请到TGT
。
※补充:从物理层面看,AD与KDC均为域控制器(Domain Controller)。
域认证粗略流程
过程简述
①-②:Client
向kerberos
服务请求,希望获取访问Server
的权限。 kerberos
得到了这个消息,首先得判断Client
是否是可信赖的, 也就是白名单黑名单的说法。
这就是AS(Authentication Service)
服务完成的工作,通过在AD(Account Database)
中存储黑名单和白名单来区分Client
。
成功后,AS(Authentication Service)
返回TGT(Ticket Granting Ticket)
给Client
。
③-④:Client
得到了TGT(Ticket Granting Ticket)
后,继续向kerberos
请求,希望获取访问 Server
的权限。kerberos
又得到了这个消息,这时候通过Client
消息中的TGT
,判断出了Client
拥有了这个权限,给了Client
访问Server
的权限Ticket
。
⑤-⑥:Client
得到Ticket
后,终于可以成功访问Server
。这个Ticket
只是 针对这个Server
,其他Server
需要向TGS(Ticket Granting Service)
申请。
较详简述
-
AS_REQ:
Client
向KDC
发起AS_REQ
,请求凭据是Client hash
加密的时间戳 -
AS_REP:
KDC
使用Client hash
进行解密,如果结果正确就返回用krbtgt hash
加密的TGT
票据,TGT
里面包含PAC
,PAC
包含用户Client
的sid
和用户Client
所在的组
。 -
TGS_REQ:
Client
凭借TGT
票据向KDC
发起针对特定Server
的TGS_REQ
请求 -
TGS_REP:
KDC
使用krbtgt hash
进行解密,如果结果正确,就返回用Server hash
加密的TGS
票据 [Ticket
](这一步不管用户有没有访问Server
的权限,只要TGT
正确,就返回TGS
票据 [Ticket
]) -
AP_REQ:
Client
拿着TGS
票据(Ticket
)去请求Server
-
AP_REP:
Server
使用自己的hash
解密TGS
票据(Ticket
)。如果解密正确,就拿着PAC
去KDC
那边问Client
有没有访问权限,域控解密PAC
。获取Client
的sid
,以及所在的组
,再根据该服务的ACL
,判断Client
是否有访问Server
的权限。
域认证详细流程
AS_REQ & AS_REP
AS_REQ
1 |
1. pvno |
AS_REP
1 |
1. msg-type |
TGS_REQ & TGS_REP
TGS_REQ
1 |
1. msg-type |
TGS_REP
1 |
1. msg-type |
S4U2SELF
s4u2self的过程如下图所示(前提条件是服务已经有通过KDC验证的TGT)
S4U2self 使得服务可以代表用户获得针对服务自身的kerberos服务票据。这使得服务可以获得用户的授权( 可转发 的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy),这是为了在用户以不使用 Kerberos 的方式对服务进行身份验证的情况下使用。这里面很重要的一点是服务代表用户获得针对服务自身的kerberos票据这个过程,服务是不需要用户的凭据的
S4U2PROXY
s4u2proxy的过程如下图所示
s4u2proxy 使得服务1可以使用来自用户的授权( 在S4U2SELF阶段获得),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的TGS,并且代表用户访问服务2,而且只能访问服务2。
委派
在Windows 2000 Server首次发布Active Directory时,Microsoft必须提供一种简单的机制来支持用户通过Kerberos向Web Server进行身份验证并需要代表该用户更新后端数据库服务器上的记录的方案。这通常称为“ Kerberos双跳问题”,并且要求进行委派,以便Web Server在修改数据库记录时模拟用户。
需要注意的一点是接受委派的用户只能是
服务账户
或者计算机用户
。
非约束委派
例子:
服务(如JACKSON-PC$
) 被配置了非约束的委派,那么JACKSON-PC$
可以接受任何用户的委派的去请求其他所有服务。在协议层面的实现就是,某个用户委托JACKSON-PC$
去访问某个服务,那么这个用户会将 TGT(在TGS里面)
发送到JACKSON-PC$
并缓存到LSASS
中,以方便以后使用。 然后JACKSON-PC$
模拟用户去请求某个服务。
配置了非约束委派的用户的userAccountControl
属性有个FLAG
位 TrustedForDelegation
关于userAccountControl 每一位对应的意义可以看Converting AD UserAccountControl Attribute Values,(我们在LDAP篇也会详细介绍),其中 TRUSTED_FOR_DELEGATION 对应是 0x80000 ,也就是 524288 。
约束委派
微软很早就意识到非约束委派并不是特别安全,在 Windows 2003上发布了”约束”委派。
其中包括一组 Kerberos 协议扩展
,就是本文之前提到的两个扩展 S4U2Self
和 S4U2Proxy
。配置它后,约束委派将限制指定服务器可以代表用户执行的服务。这需要SeEnableDelegation
特权(该特权很敏感,通常仅授予域管理员)才能为服务配置域帐户,并且将帐户限制为单个域。
例子:
计算机用户(即JACKSON-PC$
) 被配置了约束的委派,那么JACKSON-PC$
可以接受任何用户的委派的去请求特定的服务。具体过程是收到用户的请求之后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF)
,拿着这个票据向KDC
请求访问特定服务的可转发的TGS(S4U2PROXY)
,并且代表用户访问特定服务,而且只能访问该特定服务。
相较于非约束委派,约束委派最大的区别也就是配置的时候选择某个特定的服务,而不是所有服务。
配置了约束委派的用户的userAccountControl 属性有个FLAG位 TrustedToAuthForDelegation 。
关于userAccountControl 每一位对应的意义可以看Converting AD UserAccountControl Attribute Values,其中 TRUSTED_TO_AUTH_FOR_DELEGATION 对应是 0x1000000 ,也就是 16777216 。
基于资源的约束委派
为了配置受约束的委派,必须拥有SeEnableDelegation
特权(该特权很敏感,通常仅授予域管理员)。为了使用户/资源更加独立,Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派将委派的控制权交给拥有被访问资源的管理员。
基于资源的约束委派只能在运行Windows Server 2012 R2和Windows Server 2012的域控制器上配置,但可以在混合模式林中应用。
这种约束委派的风格与传统约束委派非常相似,但配置相反。
传统约束委派在msDS-AllowedToDelegateTo
属性中的帐户A
上配置,并定义从A
到B
的“传出”信任。
基于资源的约束委派在S-AllowedToActOnBehalfOfOtherIdentity
属性中的帐户B
上配置,并定义从A
到B
的“传入”信任。
PAC
微软为了访问控制而引进的一个扩展
PAC
,PAC
在历史上出现过的一个严重的,允许普通用户提升到域管的漏洞MS14068
。
引进PAC
之后的kerberos
流程
- 用户向
KDC
发起AS_REQ
,请求凭据是用户hash
加密的时间戳,KDC
使用用户hash
进行解密,如果结果正确返回用krbtgt hash
加密的TGT票据
,TGT
里面包含PAC
,PAC
中包含用户的sid
、用户所在的组
。
-
用户凭借
TGT
向KDC
发起针对特定服务的TGS_REQ
请求,KDC
使用krbtgt hash
进行解密,如果结果正确,就返回用服务hash
加密的ST\Ticket
(这一步不管用户有没有访问服务的权限,只要TGT
正确,就返回ST\Ticket
,这也是kerberoating
能利用的原因:任何一个用户,只要hash
正确,就可以请求域内任何一个服务的ST\Ticket
,具体内容可以参考Windows内网协议学习Kerberos篇之TGSREQ& TGSREP) -
用户拿着
ST\Ticket
去请求服务,服务使用自己的hash
解密ST\Ticket
。如果解密正确,就拿着PAC
去KDC
那边询问用户有没有访问权限,域控解密PAC
。获取用户的sid
、用户所在的组
,再判断用户是否有访问服务的权限,有访问权限就允许用户访问(有用户hash
,可以制作ST\Ticket
,但是不能制作PAC
,PAC
自然也验证不成功,但是有些服务不去验证PAC
,这是白银票据成功的前提)。
特别说明的是,PAC对于用户和服务全程都是不可见的。只有KDC能制作和查看PAC。
相关的安全问题
AS_REQ & AS_REP
PTH\ PTK
连接配置的时候允许使用hash进行认证,不是只有账号密码才能认证。
由于在进行认证的时候,是使用用户hash
加密时间戳,所以在使用密码进行登录的情况下,也是先把密码加密成hash
后再进行认证。
因此在只有用户hash,没有明文密码的情况下也是可以进行认证的。
不管是rubeus
还是impacket
里面的相关脚本都是支持直接使用hash
进行认证。
1 |
如果 hash 是 ntlm hash ,然后加密方式是 rc4 ,这种就算做是 pass the hash |
在很多地方,不支持rc4加密
方式的时候,使用pass the key
不失为一种好方法。
用户名枚举
域内没有域账号的情况下进行用户名枚举
有域账号的情况的下可以直接通过LDAP查询(域机器提到System权限后,其机器账号也是域账号)
进行AS_REQ时,用户名存在但密码错误
与用户名不存在
的相应包有不同,通过这个比较就可以写脚本改变cname的值进行用户名枚举(https://daiker.gitbook.io/windows-protocol/kerberos/1#2.-yong-hu-ming-mei-ju)。
Password Spraying(密码喷洒)
在已有用户名的时候,可以尝试爆破密码。
进行AS_REQ时,用户名存在且密码正确
与用户名存在但密码错误
的相应包有不同。
实战中,都会使用“密码喷洒(Password Spraying)”的技术来进行测试和攻击。因为针对同一个用户的连续密码猜测会导致帐户被锁定,所以只有对所有用户同时指定唯一的密码去登录尝试,消除帐户被锁定的概率从而增加破解成功率。
AS-REPRoasting(用户明文口令爆破)
对于域用户,设置了选项
Do not require Kerberos preauthentication(不要求Kerberos预身份验证)
此时向域控制器的88
端口发送AS_REQ
请求,对收到的AS_REP内容重新组合(enc-part
底下的ciper
,因为这部分是使用用户hash
加密session-key
,我们通过进行离线爆破就可以获得用户hash
),能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,可以使用hashcat对其破解,最终获得该用户的明文口令。
黄金票据
AS
确认Client
端登录者用户身份,通过伪造的TGT
,可以获取任意Kerberos
的访问权限,由krbtgt NTLM Hash
加密。
伪造条件
1 |
1、域名称 |
在Kerberos
认证中,Client
通过AS(Authentication Service)
认证后,AS
会给Client
一个Logon Session Key
和TGT
,而Logon Session Key
并不会保存在KDC
中,krbtgt
的NTLM Hash
又是固定的(此账户一般不会改密码),所以只要得到krbtgt
的NTLM Hash
,就可以伪造TGT
和Logon Session Key
来进入下一步Client
与TGS
的交互。
有了金票后,就可以跳过AS
验证,直接同KDC
交互,不用验证账户和密码,所以也不用担心域管密码被修改。
TGS_REQ & TGS_REP
PTT(pass the ticket)
Kerbreos
除了第一步AS_ERQ
是使用 时间戳 加密用户hash
验证之外,其他的步骤的验证都是通过票据
,这个票据可以是TGT(Ticket Granting Ticket)
或者TGS票据(Server Ticket/Ticket)
。因为票据里面的内容主要是session_key
和ticket(使用服务hash加密的,服务包括krbtgt)
,拿到票据之后,我们就可以用这个票据来作为下阶段的验证了。
kerberosting(服务hash爆破)
因为
TGS_REP
里面ticket
里的enc_part(是ticket里面的enc_part,不是最外层的enc_part,最外层的enc_part是使用AS_REP里面的session_key加密的,这个session_key我们已经有了,没有意义)
,是使用要请求的服务的hash
加密的,所以我们可以通过爆破获得服务的hash
。
这个问题存在的另外一个因素是因为用户向KDC
发起TGS_REQ
请求,不管用户对服务有没有访问权限,只要TGT
正确,那么肯定会返回TGS
。
其实AS_REQ
里面的服务就是krbtgt
,也就是说这个同样用于爆破AS_REP
里面的ticket
部分的encpart
得到krbtgt的hash
,但网上没出现这种攻击方式是因为krbtgt
的密码是随机生成的,我们也跑不出来.
白银票据
Client
向Server
发送服务请求,通过伪造的Ticket
,只能访问指定的服务,如cifs、http、mssql等
,由服务账号NTLM Hash
加密。
伪造条件
1 |
1、域名称 |
在Kerberos
认证中的第⑤-⑥步,Client
带着Ticket
和Authenticator3
向Server
上的某个服务进行请求,Server
接收到Client
的请求之后,通过自己的Master Key
解密Ticket
,从而获得Session Key
。通过Session Key
解密Authenticator3
,进而验证对方的身份,验证成功就允许Client
访问Server
上的指定服务了。
所以我们只需要知道Server
用户的Hash
就可以伪造出一个Ticket
,且不会经过KDC
,但是伪造的Ticket
只对部分服务起作用(已经在TGT
的PAC
里,通过SID
的值限定了给Client
授权的服务)。
非约束委派攻击
如果我们找到配置了 非约束的委派的账户,比如
JACKSON-PC$
,并且通过一定手段拿下该账户的权限,然后诱导域管访问该JACKSON-PC$
,这个时候域管会将自己TGT
发送到JACKSON-PC$
并缓存到LSASS
中,那我们就可以从LSASS
中导出域管的TGT票据
,然后通过PTT
,从而拥有域管的权限。
约束委派攻击
如果我们找到配置了 约束委派的服务账号,比如
JACKSON-PC$
,并且通过一定手段拿下该账号所在的机子。我们就可以利用这个服务账号代表任意用户 (重点:服务代表用户获得针对服务自身的kerberos票据
这个过程,服务不需要用户凭据) 进行s4u2self
获得一个可转发的票据
,然后把获取到的票据
用于s4u2proxy(作为AddtionTicket)
,从而获取一个可转发的TGS
,服务就可以代替任意用户访问另外一个服务(既被配置的约束委派的服务:cifs/WIN-JQO4OSMOGK2.JMU.com
)。
相较于非约束的委派,约束的委派并不需要用户过来访问就可以代表该用户,但是只能访问特定的服务,不像非约束的委派哪个可以访问任意服务。
1 |
对于 HOST SPN,可以实现完全的远程接管。 |
基于资源的约束委派攻击
基于资源的约束委派具有传统的约束委派的所有安全问题,但是相较于传统的约束委派。基于资源的约束委派的利用又相对较为简单。
主要体现为,普通的约束委派的配置需要SeEnableDelegation权限,而这个权限通常仅授予Domain Admins
。因此我们对普通的约束委派的利用,往往在于寻找域内已有的约束委派,再利用。
但是对于基于资源的约束委派,假如我们已经拥有服务账号1,那么只要具备用户2的LDAP权限,这样就可以配置服务1对服务2的约束委派(在服务账户2的用户属性上配置S-AllowedToActOnBehalfOfOtherIdentity
为1
的sid
),服务1就可以控制服务2。
PAC
MS14068
补丁编号是KB3011780,域里面最严重的漏洞之一,它允许任意用户提升到域管权限。
该漏洞最本质的地方在于Microsoft Windows Kerberos KDC
无法正确检查Kerberos票证
请求随附的特权属性证书(PAC)
中的有效签名,这里面的签名就是上面提到的服务检验和
和KDC校验和
。导致用户可以自己构造一张PAC
。 签名原本的设计是要用到HMAC
系列的checksum
算法,也就是必须要有key
的参与,我们没有krbtgt的hash
以及服务的hash
,就没有办法生成有效的签名,但是问题就出在,实现的时候允许所有的checksum
算法都可以,包括MD5
。那我们只需要把PAC
进行md5
,就生成新的校验和。这也就意味着我们可以随意更改PAC
的内容,完了之后再用md5
给他生成一个服务检验和
以及KDC校验和
。在MS14-068
修补程序之后,Microsoft
添加了一个附加的验证步骤,以确保校验和类型为KRB_CHECKSUM_HMAC_MD5
。
https://daiker.gitbook.io/windows-protocol/kerberos/3
参考文章
https://daiker.gitbook.io/windows-protocol/kerberos
https://payloads.online/archivers/2018-11-30/1/
https://www.cnblogs.com/0x7e/p/13862453.html
https://www.jianshu.com/p/4936da524040
- source:se7ensec.cn
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论