PowerShell扫描Windows服务.exe筛选用户有完全控制权的服务代码求助
PowerShell 服务可执行文件权限扫描代码修正
原代码错误点
- 管道末尾追加了
Out-Null,导致$services变量被赋值为空,没有任何服务数据可遍历 - 服务路径解析逻辑错误:多数服务的
PathName属性带双引号、启动参数,直接按.exe拆分后拼接会生成无效路径,触发Get-Acl报错 - 权限匹配逻辑完全错误:
Get-Acl返回的Access属性是权限规则对象集合,不能直接和字符串做包含匹配;且BUILTIN\Utilisateurs是法语系系统的用户组名,多语言环境下通用度极低,应该用固定不变的Users组SID(S-1-5-32-545)做判断 - 存在冗余无用的
foreach ($right in $var )循环,$var为单一路径字符串,不需要遍历 - 语法错误:
if判断的右括号缺失,代码无法正常解析运行
修正后代码
# 获取所有调用exe的服务,替换已弃用的Get-WmiObject为Get-CimInstance,保留返回数据 $services = Get-CimInstance Win32_Service | Where-Object { $_.PathName -like "*.exe*" } | Select-Object Name, State, PathName, StartName # 预先获取普通用户组的安全标识符,适配多语言系统 $usersSid = [System.Security.Principal.SecurityIdentifier]::new("S-1-5-32-545") $usersGroupName = $usersSid.Translate([System.Security.Principal.NTAccount]).Value foreach ($service in $services) { # 解析服务的exe真实路径,处理带引号、带启动参数的情况 $rawPath = $service.PathName.Trim() if ($rawPath.StartsWith('"')) { $exePath = $rawPath -split '"', 3 | Select-Object -Index 1 } else { $exePath = $rawPath -split '\.exe', 2 | Select-Object -Index 0 $exePath += ".exe" } # 过滤掉不存在的无效路径 if (-not (Test-Path -Path $exePath -PathType Leaf)) { continue } # 读取文件ACL,跳过无权限访问的路径 $acl = Get-Acl -Path $exePath -ErrorAction SilentlyContinue if (-not $acl) { continue } # 匹配普通用户组的允许完全控制权限 $hasVulnRight = $acl.Access | Where-Object { $_.IdentityReference.Value -eq $usersGroupName -and $_.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl -and $_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow } if ($hasVulnRight) { Write-Warning "检测到风险服务:" Write-Output "服务名称:$($service.Name)" Write-Output "服务状态:$($service.State)" Write-Output "启动账户:$($service.StartName)" Write-Output "exe路径:$exePath" Write-Output "匹配到的权限配置:" $hasVulnRight | Format-List Write-Output "-------------------------" } }
运行说明
- 建议以管理员权限运行PowerShell执行该脚本,避免部分系统服务路径无权限读取ACL
- 脚本自动适配多语言系统的普通用户组名,不会因为系统语言不同导致匹配失效
- 自动处理带引号、带启动参数的服务路径,排除无效路径避免报错
内容的提问来源于stack exchange,提问作者Boosted bug
相关产品推荐
相关产品推荐

