跳转到帖子

授权内网测试中 WinRM 端口可达却提示 Access is denied,如何定位权限边界?

精选回复

发布于

问题背景

在一次已授权的 Windows 域内网测试中,测试机可以连接目标主机的 5985 端口,Test-WSMan 也能返回 WS-Management 信息,但使用域账号执行 Enter-PSSession 或 Invoke-Command 时提示 Access is denied。目标账号可以正常登录域,且没有密码错误记录。

问题:这种情况应如何区分网络、认证、远程端点授权、用户权限分配和 UAC 令牌过滤问题?验证过程中需要保留哪些日志,修复时又应避免哪些高风险配置?

先明确:端口可达不等于具备远程执行权限

WinRM 访问至少经过以下几层判断:

  • 网络层:5985 或 5986 端口是否可达,防火墙是否放行。
  • 服务层:WinRM 服务是否运行,监听器是否绑定到正确地址。
  • 认证层:Kerberos、NTLM 或证书认证是否成功。
  • 授权层:账号是否有权访问 Microsoft.PowerShell 等会话端点。
  • 系统权限层:用户权限分配、组策略、UAC 令牌过滤是否限制该账号。
  • 命令权限层:进入会话后是否有权执行具体操作。

因此,5985 开放或 Test-WSMan 成功,只能证明服务端有响应,不能证明当前身份已通过认证和端点授权。

第一步:从测试端确认连接条件

建议先使用主机名而不是 IP。直接连接 IP 通常无法正常使用 Kerberos,可能回退到 NTLM,导致测试结果与实际域环境不一致。

# 网络与名称解析
Test-NetConnection srv-app01.contoso.local -Port 5985
Resolve-DnsName srv-app01.contoso.local

# 检查当前 Kerberos 票据
klist
klist get HTTP/srv-app01.contoso.local

# 明确使用 Kerberos 验证 WinRM
Test-WSMan srv-app01.contoso.local -Authentication Kerberos

# 使用无副作用命令验证远程端点
Invoke-Command -ComputerName srv-app01.contoso.local `
  -Authentication Kerberos `
  -ScriptBlock { hostname; whoami; whoami /groups }

如果使用短主机名失败而 FQDN 成功,应优先检查 DNS 后缀和 SPN,而不是修改 TrustedHosts。测试期间不建议执行以下操作:

# 不建议:扩大信任范围并掩盖名称解析、Kerberos 或 SPN 问题
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force

如果 Kerberos 报目标主体名称不正确,可在域控或具备查询权限的管理机上检查 HTTP SPN:

setspn -Q HTTP/srv-app01
setspn -Q HTTP/srv-app01.contoso.local
setspn -X

重复 SPN 会导致 Kerberos 票据无法正确解密。不要为了让测试继续而随意删除 SPN,应先确认服务实际运行身份及变更归属。

第二步:在目标端核对 WinRM 服务和监听器

以下命令应由目标系统管理员或在授权范围内使用已有管理通道执行:

Get-Service WinRM
winrm enumerate winrm/config/listener

Get-NetTCPConnection -LocalPort 5985,5986 -State Listen -ErrorAction SilentlyContinue

Get-NetFirewallRule -Enabled True |
  Where-Object DisplayName -Match 'WinRM|Windows Remote Management' |
  Select-Object DisplayName, Direction, Action, Profile

重点检查:

  • 监听器的 Address、Transport 和端口是否符合预期。
  • 防火墙规则是否仅在 Domain 配置文件下启用,而目标当前被识别为 Public 网络。
  • 是否存在只允许特定管理网段访问的 Scope 限制。
  • 5986 使用的证书是否过期,证书主题或 SAN 是否匹配主机名。

不要直接运行 Enable-PSRemoting -Force 作为排障第一步。该命令会修改服务、监听器、防火墙和会话配置,容易破坏原始现场,也会使后续无法判断问题来自哪一层。

第三步:检查会话端点授权

默认 PowerShell 远程端点通常只允许 Administrators 等受控主体访问。账号即使通过 Kerberos 认证,也可能因端点 ACL 不允许而收到 Access is denied。

Get-PSSessionConfiguration |
  Select-Object Name, Enabled, Permission

Get-PSSessionConfiguration -Name Microsoft.PowerShell |
  Format-List Name, Enabled, Permission, SecurityDescriptorSddl

Get-LocalGroupMember -Group 'Remote Management Users' -ErrorAction SilentlyContinue
Get-LocalGroupMember -Group 'Administrators' -ErrorAction SilentlyContinue

这里需要区分两个结论:

  • 账号不在 Administrators 中,不代表一定不能使用 WinRM;可以通过 Remote Management Users、端点 ACL 或 JEA 获得有限权限。
  • 账号在 Administrators 中,也不代表一定能远程获得完整管理员令牌;本地账号可能受到 UAC 远程限制。

如果只有某个自定义端点失败,可显式指定端点验证:

Invoke-Command -ComputerName srv-app01.contoso.local `
  -ConfigurationName Microsoft.PowerShell `
  -Authentication Kerberos `
  -ScriptBlock { Get-Date }

修改端点 ACL 前,应导出当前配置并记录变更。不要为了验证而将 Everyone 或 Authenticated Users 赋予远程执行权限。

第四步:检查用户权限分配和组策略

WinRM 通常产生网络登录,即安全日志中的 Logon Type 3。以下策略可能直接拒绝账号:

  • Access this computer from the network。
  • Deny access to this computer from the network。
  • 通过 Restricted Groups 或组策略覆盖本地组成员。
  • 认证策略孤岛、受保护用户组或仅允许指定设备登录的域策略。
# 导出目标主机当前安全策略
secedit /export /cfg C:\Windows\Temp\secpol-export.inf

# 查看实际应用的计算机组策略
gpresult /scope computer /r
gpresult /scope computer /h C:\Windows\Temp\gp-computer.html

# 快速定位网络登录相关配置
Select-String -Path C:\Windows\Temp\secpol-export.inf `
  -Pattern 'SeNetworkLogonRight|SeDenyNetworkLogonRight'

需要注意,拒绝策略优先于允许策略。账号所属的任意嵌套组命中 SeDenyNetworkLogonRight,都会导致登录被拒绝。

第五步:识别本地账号的 UAC 远程令牌过滤

如果使用的是目标主机本地管理员账号,而不是域账号,UAC 远程限制可能过滤其管理员令牌。相关注册表项为 LocalAccountTokenFilterPolicy。

Get-ItemProperty `
  -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' `
  -Name LocalAccountTokenFilterPolicy `
  -ErrorAction SilentlyContinue

不建议将该值设置为 1 作为长期修复。这样会允许本地管理员账号通过网络获得完整高权限令牌,显著增加凭据复用和横向移动风险。更合理的处理方式是:

  • 优先使用受控域账号或专用管理身份。
  • 使用 Windows LAPS 管理本地管理员随机密码。
  • 限制 WinRM 仅能从管理网段或跳板机访问。
  • 通过 JEA 提供所需命令,而不是开放完整管理员会话。

第六步:用日志判断失败发生在哪一层

建议同时检查目标主机的 Security、WinRM Operational 和 PowerShell Operational 日志。若怀疑 Kerberos,还应关联域控上的 4768、4769 和 4771 事件。

# 启用并查询 WinRM 操作日志
wevtutil sl Microsoft-Windows-WinRM/Operational /e:true
wevtutil qe Microsoft-Windows-WinRM/Operational /c:30 /rd:true /f:text

# 最近的登录成功与失败事件
Get-WinEvent -FilterHashtable @{
  LogName='Security'
  Id=4624,4625,4672
  StartTime=(Get-Date).AddMinutes(-30)
} | Select-Object TimeCreated, Id, Message

# PowerShell 远程会话和脚本块相关记录
Get-WinEvent -FilterHashtable @{
  LogName='Microsoft-Windows-PowerShell/Operational'
  Id=4103,4104
  StartTime=(Get-Date).AddMinutes(-30)
} -ErrorAction SilentlyContinue |
  Select-Object TimeCreated, Id, Message

事件 4625 中应重点关注 Logon Type、Status、Sub Status、Authentication Package 和 Source Network Address:

  • 0xC000006A:密码错误。
  • 0xC0000064:账号不存在。
  • 0xC000015B:账号未获得请求的登录类型权限。
  • 0xC0000072:账号被禁用。
  • 0xC0000234:账号被锁定。

如果目标端没有对应的 4624 或 4625,而客户端已经报错,问题更可能发生在名称解析、Kerberos、代理、TLS 或连接目标错误。若存在 4624,但随后 WinRM 返回 Access is denied,通常应转向端点 ACL、组成员关系和令牌权限排查。

推荐的最小化验证流程

  • 记录授权目标、来源地址、测试账号、时间窗口和允许执行的命令。
  • 使用 FQDN 与 Kerberos,避免先修改 TrustedHosts。
  • 先执行 hostname、whoami、Get-Date 等无副作用命令。
  • 同步提取目标端 4624、4625 和 WinRM Operational 事件。
  • 核对端点 ACL、Remote Management Users、本地 Administrators 和用户权限分配。
  • 完成验证后撤销临时组成员、端点权限和防火墙例外,并保留变更记录。

修复建议

修复目标不应是让所有管理员账号都能远程执行,而应建立清晰的管理边界:

  • 将远程管理权限授予专用域组,不直接授予个人账号。
  • 限制 5985、5986 仅对跳板机或管理 VLAN 开放。
  • 优先使用 Kerberos;跨信任或工作组场景使用 WinRM HTTPS,并严格限定 TrustedHosts。
  • 对运维场景配置 JEA,只开放所需 cmdlet、参数和目标资源。
  • 启用 WinRM Operational、PowerShell 模块日志和脚本块日志,并将日志转发到集中平台。
  • 避免关闭 UAC、开放 Everyone 端点权限、配置 TrustedHosts 为通配符或长期启用本地管理员完整远程令牌。

总结

WinRM 的 Access is denied 不能简单归因于账号不是管理员。实际排查应按网络、监听器、认证、端点授权、用户权限分配、UAC 令牌和日志证据逐层收敛。授权测试中最重要的是保持验证动作可回溯、低影响,并避免用扩大权限的方式掩盖真实配置问题。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

端口可达只说明 WSMan 监听和网络路径正常,Access is denied 通常发生在“身份认证成功之后、会话端点授权之前”。建议按下面顺序定位,避免先改 TrustedHosts 或直接放宽 WinRM。

1. 先确认失败发生在哪一层

Test-NetConnection TARGET -Port 5985
Test-WSMan TARGET

$cred = Get-Credential
Invoke-Command -ComputerName TARGET -Credential $cred `
  -Authentication Negotiate -ScriptBlock { whoami } -Verbose

Test-WSMan 成功而 Invoke-Command 返回拒绝访问,基本可以聚焦到账户类型、远程 UAC、端点 ACL 或 GPO。若使用 IP 地址、跨域或非域设备,Kerberos 通常不会生效;先用主机 FQDN 测试,并在客户端确认是否拿到对应票据:

klist
Resolve-DnsName TARGET_FQDN
Test-WSMan TARGET_FQDN -Authentication Kerberos

2. 核对实际使用的身份和组成员关系

域账户、目标机本地账户以及同名账户不是同一个安全主体。让目标机管理员在本机检查,不要只看客户端的组信息:

whoami /user
whoami /groups
Get-LocalGroupMember -Group "Administrators"
Get-LocalGroupMember -Group "Remote Management Users"

默认 PowerShell Remoting 端点通常要求管理员权限;部分系统也允许 Remote Management Users,但最终仍由会话配置的安全描述符决定。若账户通过嵌套域组刚获得权限,需要注销并重新登录或重新获取凭据令牌。

3. 在目标机检查端点 ACL,而不只是 WinRM 服务状态

Get-PSSessionConfiguration |
  Format-List Name, Enabled, Permission, SecurityDescriptorSddl

Get-PSSessionConfiguration -Name Microsoft.PowerShell |
  Format-List *

如果标准端点被禁用、替换成 JEA 端点,或 SDDL 中没有该用户/组的执行权限,就会出现端口正常但会话被拒绝。建议先记录现有配置,不要直接运行 Enable-PSRemoting -Force 覆盖现场策略。需要授权某个组时,优先针对指定端点调整:

Set-PSSessionConfiguration -Name Microsoft.PowerShell `
  -ShowSecurityDescriptorUI

4. 特别检查本地账户的远程 UAC 过滤

如果使用的是目标机本地管理员账户,远程 UAC 可能给它下发过滤后的令牌,表现就是拒绝访问;域账户通常不走这条路径。先确认是否命中该场景:

Get-ItemProperty `
  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" `
  -Name LocalAccountTokenFilterPolicy -ErrorAction SilentlyContinue

不要把设置 LocalAccountTokenFilterPolicy=1 当成通用修复,这会扩大本地管理员凭据被横向使用的风险。测试环境里更稳妥的做法是使用受控域账号,并通过端点 ACL 或 JEA 精确授权。

5. 用服务端日志确定拒绝点

Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 100 |
  Where-Object TimeCreated -gt (Get-Date).AddMinutes(-15) |
  Format-List TimeCreated, Id, LevelDisplayName, Message

Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 100 |
  Where-Object TimeCreated -gt (Get-Date).AddMinutes(-15) |
  Format-List TimeCreated, Id, LevelDisplayName, Message

同时查看安全日志中的登录成功/失败事件,重点记录登录类型、账户 SID、认证包(Kerberos/NTLM)及状态码。这样可以区分“凭据未被接受”和“凭据已接受但没有端点执行权限”。

另外可检查域策略是否覆盖了本地设置:

gpresult /h C:\Windows\Temp\gp.html
winrm get winrm/config
winrm enumerate winrm/config/listener

排查时建议保留四项证据:连接使用的目标名称、认证方式、账户 SID、命中的会话配置名称。大多数这类问题最终会落在“使用 IP 导致认证方式变化”“本地管理员令牌被过滤”或“PowerShell 端点 SDDL/JEA 未授权”三类,而不是 5985/5986 端口本身。

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

最近浏览 0

  • 没有会员查看此页面。