跳转到帖子

渗透攻防实战:授权内网测试中的 Kerberos 委派误配验证与修复

精选回复

发布于

背景

最近在一次授权内网渗透测试里,遇到一个比较典型但容易被忽略的问题:业务服务器为了访问文件共享和数据库,被配置了 Kerberos 约束委派,但委派范围过宽,导致低权限服务账号在拿到凭据后,可以冒充域内用户访问关键服务。

这类问题不属于单点漏洞,更像是权限边界配置错误。外部打点阶段可能看不出来,进入内网后才会暴露。本文只讨论授权环境下的验证、排查和修复,不涉及未授权攻击。

测试场景

  • 域名:corp.local
  • 域控:DC01.corp.local
  • 业务服务器:APP01.corp.local
  • 文件服务器:FS01.corp.local
  • 测试账号:corp\svc-web
  • 目标问题:svc-web 存在约束委派配置,且可委派到 CIFS 服务

现场现象是:业务系统使用 svc-web 作为应用池账号,服务器 APP01 可以代表用户访问 FS01 上的共享目录。这个设计本身不一定有问题,但如果 svc-web 密码弱、落盘泄露,或者服务器被拿下,就可能进一步扩大权限。

问题定位

进入内网后,首先不要急着做利用链,建议先把权限边界确认清楚。Kerberos 委派相关排查主要看几个属性:

  • TrustedToAuthForDelegation:是否允许协议转换,也就是常说的 S4U
  • msDS-AllowedToDelegateTo:允许委派到哪些 SPN
  • servicePrincipalName:账号本身绑定了哪些服务主体名称
  • userAccountControl:是否存在委派相关标志位

如果有域内普通账号权限,可以先用 PowerShell 查询,不一定需要域管。

Import-Module ActiveDirectory

Get-ADUser -Identity svc-web -Properties \
  servicePrincipalName,msDS-AllowedToDelegateTo,TrustedToAuthForDelegation,userAccountControl |
Select-Object SamAccountName,Enabled,TrustedToAuthForDelegation,servicePrincipalName,msDS-AllowedToDelegateTo,userAccountControl

如果环境没有 RSAT,也可以用 LDAP 查询工具或 SharpView 类工具读取同样的属性。重点不是工具,而是确认该账号能代表用户访问哪些服务。

技术分析

本次看到的关键配置如下:

SamAccountName              : svc-web
TrustedToAuthForDelegation  : True
servicePrincipalName        : HTTP/APP01.corp.local
msDS-AllowedToDelegateTo    : CIFS/FS01.corp.local
                              CIFS/FS01

这个配置表示 svc-web 具备协议转换能力,并且允许委派到 FS01 的 CIFS 服务。也就是说,在符合 Kerberos 流程的情况下,它可以申请到代表某个用户访问 CIFS/FS01 的服务票据。

风险点主要有两个:

  • 如果 svc-web 的口令或哈希泄露,攻击者可能伪造对 FS01 的访问链路。
  • 如果委派对象是高价值服务,例如 LDAP/DC、HOST/DC、CIFS/DC,风险会进一步放大。

这里需要注意:约束委派不是漏洞本身,错误的委派范围和服务账号管理方式才是问题。实际报告里也应该按配置风险来描述,而不是简单写成“Kerberos 漏洞”。

操作步骤:授权验证流程

下面是我在测试中常用的验证顺序,尽量做到可复现、少破坏、便于回滚。

1. 确认服务账号权限边界

Get-ADUser -LDAPFilter '(msDS-AllowedToDelegateTo=*)' \
  -Properties msDS-AllowedToDelegateTo,TrustedToAuthForDelegation,servicePrincipalName |
Select-Object SamAccountName,TrustedToAuthForDelegation,servicePrincipalName,msDS-AllowedToDelegateTo

这个命令用于枚举域内配置了约束委派的账号。输出里重点看是否存在以下高风险目标:

  • LDAP/DC01:可能影响目录服务访问
  • CIFS/DC01:可能访问域控文件共享
  • HOST/DC01:可能影响远程管理相关能力
  • MSSQLSvc/DB01:可能影响数据库横向访问

2. 验证账号是否存在弱口令或落盘凭据

授权测试中可以检查服务器本地配置、应用池、计划任务和服务配置,确认 svc-web 是否以明文、可逆形式或弱保护形式存在。

whoami /all

wmic service get name,startname,pathname | findstr /i "svc-web"

schtasks /query /fo LIST /v | findstr /i "svc-web"

%windir%\System32\inetsrv\appcmd.exe list apppool /text:name,processModel.identityType,processModel.userName

如果是 IIS 应用池账号,还要检查应用目录下的配置文件,例如连接串、第三方组件配置、历史备份文件。很多现场问题不是来自域控,而是来自业务服务器运维习惯。

3. 验证委派是否可被实际使用

在授权和留痕可控的前提下,可以使用测试用户验证是否能够通过 Kerberos 获取到目标服务票据。这里建议使用低权限测试用户,不要直接冒充域管,除非客户明确要求验证高危影响。

# 查看当前票据
klist

# 清理当前会话票据,避免误判
klist purge

# 访问目标共享,观察是否产生 CIFS 票据
net use \\FS01.corp.local\share /user:corp\test.user
klist

如果需要验证 S4U 链路,应在隔离测试窗口进行,并提前和客户确认日志留痕。验证结果建议只证明“能够代表指定测试用户访问指定服务”,不建议扩大到敏感目录或生产数据。

日志留痕与排查方法

Kerberos 委派验证会在域控和目标服务器上留下日志。测试前后可以和蓝队或运维同步时间窗口,避免误报。

日志位置事件 ID关注点
域控 Security4768TGT 请求,确认账号和客户端地址
域控 Security4769TGS 请求,重点看 Service Name 是否为 CIFS/FS01
域控 Security4771Kerberos 预认证失败,可能是口令尝试或配置错误
目标服务器 Security4624登录类型、来源主机、目标账号
目标服务器 Security5140共享访问记录

可以用 PowerShell 快速筛选域控上的 4769 事件:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769; StartTime=(Get-Date).AddHours(-2)} |
Where-Object { $_.Message -match 'CIFS/FS01' -or $_.Message -match 'svc-web' } |
Select-Object TimeCreated, Id, ProviderName, Message

如果日志里出现服务账号频繁为不同用户申请同一服务票据,需要结合业务访问模式判断。正常业务系统也会产生类似行为,不能只靠单条日志下结论。

风险判断

我一般按以下维度评估委派误配风险:

  • 服务账号是否为普通权限,还是拥有额外组权限。
  • 委派目标是否为域控、文件服务器、数据库或远程管理服务。
  • 账号凭据是否容易从服务器上获取,例如应用配置、脚本、服务参数。
  • 是否开启 TrustedToAuthForDelegation,即是否允许协议转换。
  • 是否存在不必要的短名 SPN,例如 CIFS/FS01 与 CIFS/FS01.corp.local 同时存在。

如果 svc-web 只委派到单一业务服务,且账号口令强、无法交互登录、无本地管理员权限,风险相对可控。反过来,如果委派到 DC 或多个核心服务器,就应按高危配置问题处理。

修复建议

  • 最小化委派范围:只保留业务必需的 SPN,删除无关的 CIFS、HOST、LDAP 等服务。
  • 优先使用组托管服务账号 gMSA,减少服务账号口令落盘和人工维护。
  • 禁止服务账号交互式登录,限制其登录到非业务服务器。
  • 为高权限用户启用“Account is sensitive and cannot be delegated”。
  • 定期审计 msDS-AllowedToDelegateTo、TrustedToAuthForDelegation 和 SPN 变更。
  • 开启并集中采集 4768、4769、4624、5140 等日志,建立服务账号基线。

移除不必要委派可以通过 AD 管理中心操作,也可以使用 PowerShell 修改。生产环境建议先导出当前配置,避免误删影响业务。

# 备份当前配置
Get-ADUser svc-web -Properties msDS-AllowedToDelegateTo |
Select-Object SamAccountName,msDS-AllowedToDelegateTo |
Export-Clixml .\svc-web-delegation-backup.xml

# 示例:清空委派配置,执行前必须确认业务影响
Set-ADUser svc-web -Clear msDS-AllowedToDelegateTo

# 如需关闭协议转换能力
Set-ADAccountControl svc-web -TrustedToAuthForDelegation $false

如果只需要保留特定服务,可以重新写入白名单:

Set-ADUser svc-web -Add @{
  'msDS-AllowedToDelegateTo' = @(
    'HTTP/API01.corp.local'
  )
}

总结

在渗透攻防里,Kerberos 委派问题经常不是靠漏洞扫描器发现的,而是靠对业务访问链路和域权限边界的理解。授权测试时建议先枚举配置,再验证影响,最后结合日志给出可落地修复方案。

这类问题的核心不是“能不能打”,而是要回答三个问题:谁能代表谁、能访问哪个服务、这个能力是否符合业务最小权限。只要这三点讲清楚,报告和修复都会更容易推进。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
授权内测里验证委派误配,建议把“可利用性验证”和“修复确认”分开做,避免为了证明问题去拿高权限票据造成越界。 排查面可以按这几类扫一遍: 1. **非约束委派**
Get-ADComputer -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' -Properties DNSHostName,ServicePrincipalName,TrustedForDelegation |
  Select DNSHostName,ServicePrincipalName,TrustedForDelegation

Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' -Properties ServicePrincipalName,TrustedForDelegation |
  Select SamAccountName,ServicePrincipalName,TrustedForDelegation
重点看是否出现在普通业务服务器、跳板机、打印服务、老 IIS 上。非约束委派如果不是极特殊场景,基本都应优先整改。 2. **约束委派 / 协议转换**
Get-ADObject -LDAPFilter '(|(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))' `
  -Properties msDS-AllowedToDelegateTo,msDS-AllowedToActOnBehalfOfOtherIdentity,ServicePrincipalName |
  Select Name,ObjectClass,ServicePrincipalName,msDS-AllowedToDelegateTo,msDS-AllowedToActOnBehalfOfOtherIdentity
这里建议特别关注两点: - `msDS-AllowedToDelegateTo` 里是否包含 `cifs/DC`、`ldap/DC`、`HOST/DC`、`MSSQLSvc/核心库` 这类高价值 SPN。 - 开了 “Use any authentication protocol” 的对象,等于允许 S4U2Self + S4U2Proxy,风险明显高于 “Kerberos only”。 3. **RBCD 权限链** 资源约束委派不要只看属性本身,还要看谁能改这个属性。常见问题是某台服务器对象 ACL 给了普通组 `GenericWrite`、`WriteDacl`、`WriteOwner` 或 `Validated write to service principal name`,后续就可能被串起来。 可以用 BloodHound 看边,也可以用 PowerView 快速查:
Get-DomainObjectAcl -SearchBase "DC=example,DC=com" -ResolveGUIDs |
  ? { $_.ActiveDirectoryRights -match 'GenericAll|GenericWrite|WriteDacl|WriteOwner|WriteProperty' } |
  ? { $_.ObjectDN -match 'CN=Computers|OU=Servers' } |
  Select ObjectDN,IdentityReference,ActiveDirectoryRights,ObjectAceType
如果环境里默认机器账户创建数没收紧,也要查:
Get-ADDomain | Select-Object DistinguishedName,ms-DS-MachineAccountQuota
建议把 `ms-DS-MachineAccountQuota` 改为 `0`,再通过受控流程创建计算机账户。 4. **验证方式建议** 在授权范围内验证时,不一定要完整导出票据或横向到目标机。可以用以下思路降低风险: - 只验证目标对象是否具备委派属性; - 只验证当前测试账户是否具备修改 RBCD 的 ACL; - 如需功能性验证,使用专门创建的低权限测试账户、测试 SPN 和隔离主机; - 全程记录事件 ID:4768、4769、4770、4624,方便蓝队复盘。 例如重点看 4769 中的服务票据请求:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769; StartTime=(Get-Date).AddHours(-6)} |
  Select TimeCreated,
         @{n='Account';e={$_.Properties[0].Value}},
         @{n='Service';e={$_.Properties[2].Value}},
         @{n='ClientAddress';e={$_.Properties[6].Value}},
         @{n='TicketOptions';e={$_.Properties[5].Value}}
5. **修复优先级** 个人经验里可以按这个顺序推进: - 关闭非必要非约束委派; - 将必须保留的委派改成约束委派,并限制到明确 SPN; - 尽量选择 “Kerberos only”,避免协议转换滥用; - 清理服务器对象上的异常 ACL; - 高权限账号勾选 “Account is sensitive and cannot be delegated”; - 将域管、服务管理员放入 Protected Users 组前先做兼容性评估; - 收紧机器账户创建权限和 SPN 写权限; - 对委派配置变更做审计告警。 高权限账户保护可以批量检查:
Get-ADUser -Filter * -Properties AdminCount,AccountNotDelegated |
  ? { $_.AdminCount -eq 1 -and $_.AccountNotDelegated -ne $true } |
  Select SamAccountName,AdminCount,AccountNotDelegated
整改:
Set-ADAccountControl -Identity "admin_user" -AccountNotDelegated $true
另外,修复后别只看属性被清掉了,最好再跑一轮 ACL 和事件验证。很多环境里委派本身修了,但计算机对象还残留 `GenericWrite`,过段时间又会被重新写回 RBCD。

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

最近浏览 0

  • 没有会员查看此页面。