发布于48分钟前48分钟 背景Windows 服务通常由 LocalSystem、LocalService 或 NetworkService 账户运行。如果普通用户对服务可执行文件、上级目录或服务对象拥有写入权限,就可能跨越本地权限边界。典型结果是:攻击者先获得普通域用户或本地用户权限,再借助服务重启或系统重启,使受控文件以高权限账户执行。该问题通常属于安装程序 ACL 配置不当,可参考 CWE-732 和 CWE-276。它不同于“未加引号的服务路径”:前者关注文件、目录和服务对象权限,后者关注路径解析顺序,排查时不应混为一谈。适用场景:已获得明确授权的 Windows 终端或服务器检查。生产环境验证应避免替换服务文件,优先使用 ACL、服务 DACL 和日志证据完成确认。典型漏洞场景某资产管理代理安装在 C:\Program Files\Acme Agent\agent.exe,服务名为 AcmeAgent,登录账户为 LocalSystem。安装程序错误地向 Users 或 Authenticated Users 授予了目录 Modify 权限。漏洞成立通常需要同时满足以下条件:服务运行账户权限高于当前测试账户,例如 LocalSystem。低权限主体可修改服务二进制文件,或可在其目录中删除、重命名并重新创建该文件。攻击者能够重启服务、等待管理员重启服务,或等待主机重启。终端防护、应用控制或文件完整性机制未阻止异常文件执行。另一条独立链路是服务对象 DACL 过宽。如果普通用户具有 SERVICE_CHANGE_CONFIG,并且还能启动服务,就可能修改 ImagePath。即使原始服务目录不可写,这种情况仍应按高危权限边界问题处理。问题定位首先记录服务名称、运行账户、启动方式和原始二进制路径。不要只检查注册表中的 ImagePath,因为环境变量、参数和引号可能影响最终解析结果。whoami /user whoami /groups sc.exe qc AcmeAgent sc.exe sdshow AcmeAgent powershell.exe -NoProfile -Command "Get-CimInstance Win32_Service -Filter 'Name=''AcmeAgent''' | Format-List Name,DisplayName,State,StartMode,StartName,PathName" reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\AcmeAgent" /v ImagePath重点核对以下三类权限:二进制文件 ACL:普通用户是否拥有 Write、Modify、Delete、ChangePermissions 或 FullControl。父目录 ACL:即使文件本身仅允许读取,只要目录允许删除、重命名或创建文件,也可能完成替换。服务对象 DACL:普通用户是否拥有修改配置、启动、停止或完全控制服务的权限。批量筛查高权限服务的弱 ACL下面的 PowerShell 脚本枚举由内置高权限账户运行的服务,并检查服务文件及其父目录中授予 Everyone、Authenticated Users 和本地 Users 组的允许型写权限。脚本只做读取,不修改服务配置。$weakSids = @( 'S-1-1-0', # Everyone 'S-1-5-11', # Authenticated Users 'S-1-5-32-545' # BUILTIN\Users ) $writeMask = [System.Security.AccessControl.FileSystemRights]::WriteData ` -bor [System.Security.AccessControl.FileSystemRights]::AppendData ` -bor [System.Security.AccessControl.FileSystemRights]::WriteAttributes ` -bor [System.Security.AccessControl.FileSystemRights]::WriteExtendedAttributes ` -bor [System.Security.AccessControl.FileSystemRights]::Delete ` -bor [System.Security.AccessControl.FileSystemRights]::ChangePermissions ` -bor [System.Security.AccessControl.FileSystemRights]::TakeOwnership Get-CimInstance Win32_Service | Where-Object { $_.StartName -match 'LocalSystem|LocalService|NetworkService' } | ForEach-Object { $svc = $_ $raw = [Environment]::ExpandEnvironmentVariables($svc.PathName.Trim()) $bin = $null if ($raw -match '^"([^"]+)"') { $bin = $Matches[1] } elseif ($raw -match '^([A-Za-z]:\\.*?\.exe)\b') { $bin = $Matches[1] } if (-not $bin -or -not (Test-Path -LiteralPath $bin)) { return } $targets = @($bin, (Split-Path -LiteralPath $bin -Parent)) | Select-Object -Unique foreach ($target in $targets) { try { $acl = Get-Acl -LiteralPath $target -ErrorAction Stop } catch { continue } foreach ($ace in $acl.Access) { if ($ace.AccessControlType -ne 'Allow') { continue } try { $sid = $ace.IdentityReference.Translate( [System.Security.Principal.SecurityIdentifier] ).Value } catch { continue } if (($weakSids -contains $sid) -and (($ace.FileSystemRights -band $writeMask) -ne 0)) { [pscustomobject]@{ Service = $svc.Name RunAs = $svc.StartName Target = $target Principal = $ace.IdentityReference Rights = $ace.FileSystemRights Inherited = $ace.IsInherited } } } } } | Format-Table -AutoSize该脚本用于发现候选项,不等同于 Windows 的最终有效权限计算。显式拒绝 ACE、组嵌套、所有者权限和特殊权限可能改变结果。发现候选项后,应使用 icacls 或 AccessChk 复核。非破坏性验证步骤在授权维护窗口内,可按以下顺序验证。建议先保存 ACL、文件哈希和服务配置,便于回滚和审计。sc.exe qc AcmeAgent > C:\Windows\Temp\AcmeAgent_sc_qc.txt sc.exe sdshow AcmeAgent > C:\Windows\Temp\AcmeAgent_sddl.txt icacls.exe "C:\Program Files\Acme Agent" icacls.exe "C:\Program Files\Acme Agent\agent.exe" powershell.exe -NoProfile -Command "Get-FileHash -Algorithm SHA256 -LiteralPath 'C:\Program Files\Acme Agent\agent.exe'"随后切换到待验证的低权限账户,只在目标目录创建并删除一个探针文件。该操作可以证明目录创建权限,但不会证明一定能够覆盖正在运行且被锁定的服务文件。whoami cmd.exe /c "echo acl_probe>C:\Program Files\Acme Agent\.acl_probe" type "C:\Program Files\Acme Agent\.acl_probe" del "C:\Program Files\Acme Agent\.acl_probe"如果探针文件创建成功,再检查该账户是否具有服务控制权限。不要直接停止生产服务,也不要修改 ImagePath。sc.exe query AcmeAgent sc.exe stop AcmeAgent正常情况下,普通用户执行停止操作应返回 Access is denied。如果业务不允许实际发出停止请求,可以使用 Sysinternals AccessChk 只读检查服务对象权限:accesschk64.exe -accepteula -uwcqv "Authenticated Users" AcmeAgent accesschk64.exe -accepteula -uwcqv "BUILTIN\Users" AcmeAgent判定时应区分以下情况:普通用户可修改服务二进制文件,并可停止和启动 LocalSystem 服务:通常判定为严重。普通用户可修改二进制文件,但无法控制服务,服务会随主机启动:通常判定为高危,利用依赖重启条件。普通用户具有 SERVICE_CHANGE_CONFIG 和启动服务权限:通常判定为严重,即使服务目录不可写。仅具有读取、读取并执行权限:不构成该漏洞。仅路径未加引号,但路径各级目录均不可写:应单独记录为配置缺陷,不能直接认定可利用。日志留痕与溯源服务弱权限被利用时,最有价值的证据通常位于服务注册表项、目标目录和进程创建日志中。Windows 默认日志未必完整,关键服务器建议预先启用进程创建命令行、注册表对象审核和目标目录 SACL。可优先检查以下事件:System 7035、7036:服务收到控制请求及状态变化。System 7045、Security 4697:新服务安装。它们不能覆盖所有现有服务配置修改场景。Security 4657:注册表值被修改,需要提前配置注册表审核。Security 4688:新进程创建,建议启用命令行记录。Security 4663:文件对象访问,需要对服务目录配置 SACL。Sysmon 1、11、13:进程创建、文件创建和注册表值设置。wevtutil.exe qe System /q:"*[System[(EventID=7035 or EventID=7036 or EventID=7045)]]" /f:text /c:50 powershell.exe -NoProfile -Command "Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4657,4688,4697} -MaxEvents 100 | Format-List TimeCreated,Id,Message" reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\AcmeAgent" /v ImagePath调查时应将服务状态变化时间、ImagePath 修改时间、二进制文件创建时间、SHA-256 哈希和 4688/Sysmon 1 中的父子进程关系进行关联。如果服务进程的父进程、签名或文件路径与软件基线不一致,应先隔离资产并保全文件,不要立即覆盖现场。修复建议修复重点是收紧文件系统 ACL 和服务对象 DACL,而不是简单删除可疑文件。修改前应确认软件升级程序、补丁代理和专用服务账户是否需要写权限。服务程序目录仅向 SYSTEM、Administrators 和受控的软件更新账户授予写权限。普通 Users 通常只需 ReadAndExecute,不应拥有 Modify、Delete 或 Write。从父目录继承了过宽权限时,应在软件部署模板或安装包中修正,避免升级后再次出现。服务对象 DACL 应从同版本、同组件的可信主机或厂商基线恢复,不建议盲目套用通用 SDDL。非必要服务不要以 LocalSystem 运行,优先使用虚拟服务账户或权限受限的专用账户。结合 WDAC、AppLocker、代码签名校验和 EDR 文件完整性监控限制异常二进制执行。以下命令展示一种常见的 ACL 收敛方式。使用 SID 可以避免中英文系统组名差异,但执行前仍需核对应用更新机制,并先在测试环境验证。icacls.exe "C:\Program Files\Acme Agent" /save C:\Windows\Temp\AcmeAgent_acl_backup.txt /t icacls.exe "C:\Program Files\Acme Agent" /remove:g *S-1-1-0 *S-1-5-11 icacls.exe "C:\Program Files\Acme Agent" /grant:r "*S-1-5-18:(OI)(CI)F" "*S-1-5-32-544:(OI)(CI)F" "*S-1-5-32-545:(OI)(CI)RX" icacls.exe "C:\Program Files\Acme Agent" icacls.exe "C:\Program Files\Acme Agent\agent.exe"其中 S-1-5-18 为 SYSTEM,S-1-5-32-544 为本地 Administrators,S-1-5-32-545 为本地 Users。若软件使用专用更新账户,应单独为该账户配置最小必要权限,而不是重新向 Authenticated Users 开放写入。修复验证修复后应重新执行候选项筛查,并使用原低权限账户重复探针文件测试。预期结果是创建文件失败,服务仍可正常启动,软件升级和自更新功能不受影响。确认普通用户无法在服务目录创建、删除或重命名文件。确认普通用户无法修改、停止或启动高权限服务。确认服务二进制哈希和数字签名与可信版本一致。重启服务或测试主机,检查服务功能及依赖项。将修复后的 ACL、服务 SDDL、文件哈希和验证时间写入整改记录。总结Windows 服务弱权限的核心不是“服务以 SYSTEM 运行”本身,而是低权限主体获得了影响高权限执行路径的能力。排查时需要同时覆盖服务二进制、父目录和服务对象 DACL,并结合服务重启条件判断实际风险。生产环境优先采用只读枚举、ACL 复核和日志关联完成验证;修复后还需测试软件更新流程,防止安装程序再次写回过宽权限。 服务器、云资产与权限边界梳理示意 代码审计、调用链与关键函数定位示意
创建帐户或登录后发表意见