跳转到帖子

授权内网测试中如何判断 Kerberoasting 是否成功并给出修复建议

精选回复

发布于

背景

最近做一次授权内网渗透测试时,客户的核心问题不是“能不能打下来”,而是希望明确:域内是否存在可被 Kerberoasting 利用的服务账号、验证过程会不会影响业务、日志里如何确认行为、最后如何给出可落地的整改建议。

这个问题比较适合放在问答中心:它不是单纯工具使用,也不是漏洞库条目,而是一次授权测试中的排查、验证和修复闭环。

前提说明:以下内容仅适用于已获得授权的企业内网安全测试、红队演练或自查场景。不要在未授权环境执行。

问题定位

Kerberoasting 的核心判断点是:域内是否存在配置了 SPN 的普通域用户账号,并且该账号使用弱口令或长期不轮换密码。攻击面通常不是域控漏洞,而是服务账号治理问题。

常见场景包括:

  • SQL Server、IIS、Tomcat、Jenkins 等服务使用域用户启动。
  • 服务账号设置了 SPN,例如 MSSQLSvc/db01.corp.local:1433。
  • 账号不是机器账号,而是普通用户账号。
  • 密码多年未改,且复杂度不足。
  • 账号权限过高,例如加入了本地管理员组,甚至误加入高权限域组。

技术分析

Kerberos 认证中,任意已认证域用户都可以向 KDC 请求某个 SPN 对应服务的 TGS。该 TGS 的一部分会使用服务账号的 NTLM Hash 派生密钥加密。如果服务账号密码较弱,攻击者可离线爆破票据,还原服务账号明文密码。

这里有几个容易误判的点:

  • 能请求到 TGS 不等于一定能成功利用,关键看服务账号密码强度。
  • 如果 SPN 绑定在机器账号上,通常密码复杂且自动轮换,风险相对较低。
  • 日志中看到大量 4769 不一定就是攻击,正常业务访问服务也会产生。
  • 高风险通常来自“普通用户账号 + SPN + 弱口令 + 高权限”。

操作步骤

建议按以下顺序排查,避免一上来就跑爆破工具,造成不必要的噪声。

  • 确认测试账号权限:普通域用户即可,不需要域管。
  • 枚举域内带 SPN 的用户账号。
  • 区分用户账号和机器账号,优先关注用户账号。
  • 检查账号属性:密码最后设置时间、是否可委派、是否高权限。
  • 在授权范围内请求 TGS 并导出哈希。
  • 对哈希做受控字典验证,不建议跑超大规模暴力破解。
  • 结合域控日志确认行为留痕。
  • 输出修复建议和复测方法。

命令示例

在 Windows 域内主机上,可以先用系统自带命令做基础枚举:

setspn -Q */*

如果只想看某个服务类型,例如 SQL Server:

setspn -Q MSSQLSvc/*

使用 PowerShell 查询带 SPN 的用户账号,并查看关键字段:

Import-Module ActiveDirectory

Get-ADUser -LDAPFilter '(servicePrincipalName=*)' \
  -Properties servicePrincipalName,pwdLastSet,lastLogonTimestamp,memberOf,userAccountControl |
Select-Object SamAccountName,
              Enabled,
              @{Name='SPN';Expression={$_.servicePrincipalName -join ';'}},
              @{Name='PwdLastSet';Expression={[DateTime]::FromFileTime($_.pwdLastSet)}},
              @{Name='LastLogon';Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}},
              memberOf

如果现场允许使用 Impacket,并且已经明确授权,可以在 Linux 测试机上请求 TGS:

GetUserSPNs.py corp.local/testuser:'Password123!' \
  -dc-ip 10.10.10.10 \
  -request \
  -outputfile kerberoast_hashes.txt

得到哈希后,只做受控验证,例如使用客户提供的弱口令字典或内部密码策略检查字典:

hashcat -m 13100 kerberoast_hashes.txt weak_pass.txt --force

Hashcat 模式说明:

  • -m 13100:Kerberos 5 TGS-REP etype 23。
  • 如果环境强制 AES,可能会出现其他加密类型,需要根据哈希格式调整模式。
  • 不建议在生产授权测试中使用不受控的大字典或长时间暴力破解。

日志留痕排查

域控上重点关注 Windows 安全日志事件 4769,即 Kerberos 服务票据请求。Kerberoasting 行为通常会表现为某个普通用户在短时间内请求大量不同 SPN 的 TGS。

可重点看这些字段:

  • Account Name:发起请求的用户。
  • Service Name:被请求的服务主体。
  • Client Address:请求来源主机。
  • Ticket Encryption Type:票据加密类型。
  • Failure Code:通常成功请求没有失败码。

PowerShell 快速筛选最近 24 小时的 4769 事件:

$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769; StartTime=$start} |
Select-Object TimeCreated, ProviderName, Id, Message |
Out-File C:\Temp\event_4769.txt

如果部署了 SIEM,可以建立一个基础检测逻辑:

  • 同一账号 10 分钟内请求超过 N 个不同 SPN。
  • 普通办公终端请求大量服务器类 SPN。
  • 出现大量 RC4-HMAC 类型票据请求。
  • 请求来源不是业务服务器,而是用户工作站或跳板机。

风险判断标准

条件风险判断
SPN 绑定在普通用户账号需要重点关注
密码超过一年未修改风险升高
可被字典破解高风险
账号属于本地管理员组或高权限域组严重风险
仅机器账号存在 SPN通常风险较低,但仍需确认配置

修复建议

修复不要只停留在“改复杂密码”,建议按优先级处理。

  • 将普通服务账号替换为 gMSA,减少人工维护密码的风险。
  • 服务账号密码长度建议至少 25 位以上,使用随机生成密码。
  • 禁用 RC4,优先使用 AES 加密类型。
  • 清理无用 SPN,避免历史残留服务账号暴露攻击面。
  • 服务账号最小权限化,不要加入 Domain Admins、Server Operators 等高权限组。
  • 限制服务账号交互式登录,可通过 GPO 配置拒绝本地登录和远程桌面登录。
  • 启用域控 4769 日志监控,对异常批量 TGS 请求告警。
  • 定期审计 servicePrincipalName 属性,形成台账。

禁用 RC4 需要谨慎评估兼容性,建议先在测试 OU 中验证。常见 GPO 路径:

Computer Configuration
  -> Windows Settings
  -> Security Settings
  -> Local Policies
  -> Security Options
  -> Network security: Configure encryption types allowed for Kerberos

如果业务仍依赖旧系统,直接禁用 RC4 可能导致认证失败,建议先统计 4769 中的加密类型分布,再分阶段调整。

复测方法

整改后建议做三项复测:

  • 重新枚举 SPN,确认无用 SPN 已清理。
  • 再次请求授权范围内 TGS,确认服务账号密码无法被受控字典破解。
  • 检查域控日志,确认 4769 监控规则能识别批量请求行为。

复测示例:

Get-ADUser -LDAPFilter '(servicePrincipalName=*)' \
  -Properties servicePrincipalName,pwdLastSet |
Select SamAccountName,servicePrincipalName,@{N='PwdLastSet';E={[DateTime]::FromFileTime($_.pwdLastSet)}}

总结

Kerberoasting 的关键不在工具,而在服务账号管理。授权测试时,建议从 SPN 枚举、票据请求、受控破解、日志验证、权限分析、整改复测几个环节形成闭环。最终报告里不要只写“存在 Kerberoasting 风险”,而要明确指出哪个账号、哪个 SPN、密码策略问题、权限影响范围、日志证据和修复优先级,这样对甲方才真正有价值。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意

判断 Kerberoasting 是否“成功”,建议分成三层,不要只看工具是否导出了票据:

  1. 是否拿到了目标服务账号的 TGS:说明具备请求票据的权限,但这本身不等于已经破解。
  2. 票据是否可离线验证:使用授权测试得到的 hash 进行离线口令验证,能还原出当前密码才算真正成功。
  3. 该账号是否具备高权限或横向价值:需要进一步确认是否属于 Domain Admins、服务器本地管理员,或在关键业务服务器上运行。

先在域内确认 SPN 和对应账号,重点看服务账号是否是普通用户、密码是否长期不变:

setspn.exe -Q */*
setspn.exe -L CONTOSO\svc_sql
setspn.exe -Q MSSQLSvc/db01.contoso.local:1433

PowerShell 也可以直接筛选带 SPN 的用户账号:

Get-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))" `
  -Properties servicePrincipalName,msDS-SupportedEncryptionTypes,PasswordLastSet,MemberOf |
  Select-Object SamAccountName,ServicePrincipalName,msDS-SupportedEncryptionTypes,PasswordLastSet,MemberOf

测试工具侧,输出中应能看到目标账号、SPN、票据加密类型以及可供离线验证的 hash。例如使用 Impacket 时:

GetUserSPNs.py 'CONTOSO/testuser:[email protected]' \
  -request-user svc_sql

如果测试结果只证明拿到了 `$krb5tgs$`,应表述为“可请求服务票据,存在离线破解面”,不要直接写成“已攻陷服务账号”。只有在离线验证确认口令后,才可以认定口令已被恢复。测试报告中建议记录:

  • 账号名和 SPN;
  • 票据加密类型,尤其是 RC4-HMAC(通常显示为 0x17);
  • 请求时间、来源主机和来源 IP;
  • 口令是否被恢复,以及该账号的实际权限;
  • 是否存在重复 SPN、孤儿 SPN 或服务迁移遗留配置。

域控日志可以用来和测试时间线交叉验证。重点看 Security 日志 4769,关注 Service Name、Account Name、Client Address、Ticket Encryption Type。可以先按测试账号或测试源 IP 过滤:

Get-WinEvent -FilterHashtable @{
  LogName='Security'
  Id=4769
  StartTime=(Get-Date).AddHours(-4)
} | ForEach-Object {
  [xml]$x = $_.ToXml()
  $d = @{}
  $x.Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
  [pscustomobject]@{
    Time          = $_.TimeCreated
    ServiceName   = $d.ServiceName
    AccountName   = $d.TargetUserName
    ClientAddress = $d.IpAddress
    Encryption    = $d.TicketEncryptionType
  }
} | Where-Object {
  $_.AccountName -eq 'testuser' -or $_.ClientAddress -eq '10.10.20.15'
}

需要注意,4769 本身只能说明 TGS 被请求,不能单独证明发生了 Kerberoasting;正常应用也会请求 TGS。更有价值的是结合“短时间内请求多个非必要 SPN”“测试账号访问行为”“RC4 票据”“来源主机是否为管理终端”等条件判断。环境中如果已经全面禁用 RC4,仍需关注 AES 票据,因为 Kerberoasting 并不只针对 RC4,只是 AES 的离线破解成本通常更高。

修复建议按优先级处理:

  1. 优先把服务账号迁移到 gMSA,由域自动轮换高强度密码,并限制可在哪些主机上使用:
New-ADServiceAccount -Name gmsa-sql `
  -DNSHostName sql01.contoso.local `
  -PrincipalsAllowedToRetrieveManagedPassword 'CONTOSO\SQL-Servers'

Install-ADServiceAccount -Identity gmsa-sql
Test-ADServiceAccount -Identity gmsa-sql

应用和服务切换到 gMSA 后,再移除旧账号上的 SPN,避免遗留可请求的票据:

setspn.exe -L CONTOSO\svc_sql
setspn.exe -D MSSQLSvc/db01.contoso.local:1433 CONTOSO\svc_sql

删除前要确认该 SPN 已正确迁移到计算机账号或 gMSA,否则会造成 Kerberos 身份认证失败。

  1. 无法立即迁移时,重置为高强度随机密码。建议至少 25~30 位随机值,禁止人工可读密码、公司名、服务名和周期性变体,并建立定期轮换机制。服务账号不应复用域管理员或其他基础设施账号的密码。
  2. 启用并验证 AES,逐步禁用 RC4。先确认应用、旧系统和第三方设备兼容 AES,再通过域策略和账号属性限制 RC4。仅修改 msDS-SupportedEncryptionTypes 不是万能修复,必须同时确认服务实际使用的 Kerberos 配置,否则可能出现认证中断或票据仍按旧方式签发。
  3. 降低服务账号权限。移除不必要的域组成员关系、本地管理员权限、服务账号交互式登录权限和委派配置。对于高价值账号,可评估加入 Protected Users,但要先验证服务兼容性,尤其是旧应用和需要 NTLM 的场景。
  4. 清理无效 SPN。对离职服务、旧服务器和重复 SPN 做盘点;重复 SPN 会导致 Kerberos 异常,也容易掩盖真正的服务账号归属。可用 setspn -X 检查重复项。

最后建议在修复后重新做一次验证:旧账号的 SPN 是否已移除、服务是否仍能正常获取 TGS、4769 中是否还出现不符合策略的 RC4 请求,以及原测试 hash 是否因密码轮换而无法再验证。这样比单纯看到“工具不再输出结果”更能证明修复有效。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。