跳转到帖子

授权渗透实战:Windows 服务权限边界验证、提权链路留痕与修复

精选回复

发布于

背景在 Windows 内网授权渗透中,服务配置错误是一类常见的本地权限边界问题:低权限用户不能直接获得管理员令牌,但如果其能够修改高权限服务的可执行文件、服务目录或启动参数,就可能在服务重启时影响以 LocalSystem 或高权限域账号运行的进程。本文以“已取得一台成员服务器的普通域用户会话”为前提,目标是验证服务权限是否形成可利用链路,并给出日志核查和修复方法。所有写入、重启和验证动作都应限定在书面授权范围内;生产主机默认只做只读检查,利用性验证应放在快照克隆或专用验证窗口。问题定位:不要把“可写目录”等同于可提权服务提权需要同时核对三个边界:服务对象权限、文件系统权限和服务运行上下文。仅发现目录可写并不足以形成结论,还需确认写入位置是否位于实际执行链路中,以及攻击者是否有办法触发服务加载该文件。检查面关键问题常见误判服务对象 ACL普通用户是否拥有 SERVICE_CHANGE_CONFIG、WRITE_DAC、WRITE_OWNER 或 SERVICE_START/STOP仅凭“能查询服务”判断可修改文件及目录 ACLImagePath 指向的文件、父目录、依赖 DLL 是否允许低权限用户写入看到 Users 具有 RX 就误报运行身份与触发条件服务是否以 LocalSystem 等高权限身份运行,是否可由测试账号重启,或是否会在系统重启后自动启动忽略服务为禁用状态或低权限账号运行第一步:只读枚举服务配置先记录当前身份、主机名和测试时间,随后导出服务名称、启动类型、运行身份和二进制路径。不要一开始就修改服务配置。whoami /all
hostname
Get-Date -Format o

Get-CimInstance Win32_Service |
Select-Object Name,State,StartMode,StartName,PathName |
Export-Csv .\services-baseline.csv -NoTypeInformation -Encoding UTF8

# 针对可疑服务查询原始配置及服务对象安全描述符
sc.exe qc AcmeUpdater
sc.exe sdshow AcmeUpdater

# 查看可执行文件与父目录 ACL
(Get-CimInstance Win32_Service -Filter "Name='AcmeUpdater'").PathName
icacls "C:\Program Files\Acme\updater.exe"
icacls "C:\Program Files\Acme"解析 PathName 时要注意引号、参数和环境变量。路径可能形如 "C:\Program Files\Acme\updater.exe" --service,ACL 检查对象应是实际 PE 文件及逐级父目录,而不是包含参数的完整字符串。第二步:检查服务对象权限sc sdshow 返回 SDDL。重点关注授予低权限主体的权限项,例如 Everyone(WD)、Authenticated Users(AU)、Builtin Users(BU)。服务权限中的 DC 表示更改配置,WD 表示写 DACL,WO 表示写所有者,RP/WP 通常对应启动/停止。判断时必须结合 ACE 的允许或拒绝类型以及继承关系,不能只搜索字符串。在测试机允许安装 Sysinternals 工具时,可用 AccessChk 做交叉验证:# 接受许可后,检查普通用户可写的服务对象
accesschk.exe -accepteula -uwcqv "Authenticated Users" *

# 检查目标服务权限
accesschk.exe -accepteula -ucqv AcmeUpdater

# 检查服务目录的实际写权限
accesschk.exe -accepteula -uwdqs "Authenticated Users" "C:\Program Files\Acme"若结果显示 Authenticated Users 对服务拥有更改配置权限,还要确认测试账号是否确实属于该主体,以及是否存在显式拒绝 ACE。建议用测试账号执行一次无副作用的权限探测,例如读取配置;不要通过修改 ImagePath 来“试试看”。第三步:检查文件系统写入边界高风险权限包括 Modify、Write、FullControl,以及对父目录拥有创建文件、删除子项或改名权限。Windows 的目录权限具有细分语义:即使不能直接覆盖现有文件,拥有父目录的删除子项权限也可能允许替换;反过来,只有创建文件权限且无法影响加载路径时,不一定可利用。$targets = @(
'C:\Program Files\Acme',
'C:\Program Files\Acme\updater.exe'
)

foreach ($target in $targets) {
Write-Host "=== $target ==="
(Get-Acl -LiteralPath $target).Access |
Select-Object IdentityReference,FileSystemRights,AccessControlType,
IsInherited,InheritanceFlags,PropagationFlags |
Format-Table -AutoSize
}检查时还应关注服务程序加载的配置文件、脚本、插件和 DLL。可以在隔离副本中用 Process Monitor 观察服务启动阶段的文件访问,并过滤 Process Name、Load Image、NAME NOT FOUND。生产环境不应仅因出现缺失 DLL 查询就判定为 DLL 劫持;还需证明低权限用户对对应搜索目录具有写权限,且加载顺序可控。第四步:验证是否形成完整提权链建议采用分级证据,避免为了截图而在生产系统执行任意载荷。一级,配置证据:确认服务运行身份、启动方式、ImagePath、服务 ACL 和文件 ACL。二级,权限证据:使用测试账号证明其拥有目标对象的写权限,但不实际改写生产文件。可由管理员创建同 ACL 的临时测试对象进行验证。三级,隔离利用性验证:在快照克隆中使用无网络、无持久化的标记程序,仅写入固定测试文件,并立即回滚。一个可接受的隔离验证结果,是服务以预期高权限身份创建只含时间戳和用户名的标记文件。不要使用反向连接、添加管理员、关闭安全软件或转储凭据作为 PoC,这些动作超出证明权限边界所需的最小范围。生产报告应区分“配置缺陷已确认”和“代码执行已验证”。无法安排重启或隔离验证时,可以依据 ACL 与运行上下文评为潜在可利用,但不能声称已经获得 SYSTEM。常见分支:未加引号服务路径若高权限服务的路径包含空格且未加引号,例如 C:\Program Files\Vendor App\svc.exe,Windows 可能依次尝试若干候选路径。是否可利用取决于低权限用户能否在候选位置创建对应文件。系统盘根目录和 Program Files 默认通常不可写,因此“路径未加引号”本身不等于漏洞。# 查找疑似未加引号且包含空格的服务路径
Get-CimInstance Win32_Service |
Where-Object {
$_.PathName -match '\s' -and
$_.PathName -notmatch '^\s*"' -and
$_.PathName -match '\.exe'
} |
Select-Object Name,StartName,StartMode,PathName对每个候选项分别检查父目录 ACL。如果候选路径均不可由低权限用户创建,则应降级为加固项,而不是高危提权漏洞。日志留痕与事件关联服务权限问题的检测不能只看服务安装事件。修改既有服务、替换二进制和随后启动服务可能分散在不同日志中,应按主机和时间线关联。日志源事件或关注点用途System / Service Control Manager7045、7035、7036、7040服务安装、控制请求、状态变化、启动类型变化Security4697、4688服务安装及进程创建;需启用相应审核策略Sysmon1、11、13进程创建、文件创建、注册表值修改EDR服务配置 API、异常父子进程、签名变化补充 sc.exe 之外的 API 调用检测# 查询近 24 小时服务控制相关事件
$since = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName='System'
ProviderName='Service Control Manager'
StartTime=$since
Id=7045,7035,7036,7040
} | Select-Object TimeCreated,Id,Message

# 若启用了进程创建审核,检索常见服务管理工具
Get-WinEvent -FilterHashtable @{
LogName='Security'
StartTime=$since
Id=4688
} | Where-Object {
$_.Message -match 'sc.exe|powershell.exe|wmic.exe'
} | Select-Object TimeCreated,Id,Message4688 若未启用“在进程创建事件中包含命令行”,只能看到有限信息。建议通过组策略启用高级审核策略中的进程创建,并同步启用命令行记录;同时评估命令行中可能出现口令或令牌的隐私风险。修复建议收紧服务对象 DACL:普通用户只保留查询所需权限,移除更改配置、写 DACL、写所有者和不必要的启停权限。修改前导出原始 SDDL,并准备回滚。修正文件系统 ACL:服务二进制及其目录仅允许 Administrators、SYSTEM 和受控部署主体写入。不要给 Users 或 Authenticated Users 授予 Modify。降低运行权限:服务不需要系统级权限时,改用虚拟服务账号、gMSA 或专用低权限账号;明确“作为服务登录”权限,禁止交互式登录。固定执行路径:ImagePath 使用完整绝对路径并正确加引号;限制可写插件目录,避免从用户可写位置加载 DLL、脚本或配置。保护部署链:软件更新由受控代理执行,校验签名或哈希。不要让高权限更新服务直接执行普通用户可修改的更新包。补足监控:建立服务配置基线,监控 ImagePath、Start、ObjectName 与服务 DACL 的变化,并关联二进制签名和文件哈希变化。修复复测复测不只是确认目录“看起来不可写”。应使用原测试账号重新运行 AccessChk、icacls 和服务对象权限检查,确认危险 ACE 已消失;再验证服务可以正常启动、升级和回滚。最后检查修复期间产生的事件是否能被日志平台检索到。# 修复前后分别保存结果,便于差异比较
sc.exe qc AcmeUpdater > .\AcmeUpdater-qc-after.txt
sc.exe sdshow AcmeUpdater > .\AcmeUpdater-sddl-after.txt
icacls "C:\Program Files\Acme" /save .\Acme-acl-after.txt /t /c

# 验证服务状态,不在业务窗口外擅自重启
Get-Service AcmeUpdater | Format-List Name,Status,StartType总结服务权限问题的核心不是某一条扫描器告警,而是能否闭合“低权限可控对象—高权限服务加载—可触发执行”三段链路。授权渗透时应优先做只读枚举,以 ACL、运行身份和加载路径构建证据;生产环境使用最小化验证,隔离环境再确认执行结果。修复则应同时覆盖服务 DACL、文件系统 ACL、运行账号、执行路径和审计策略,否则很容易只处理表象。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
安全工具参数与流程示意图
工具配置、参数调优与结果校验示意

这类验证建议把“服务控制权”和“服务执行链写权限”分开记录,否则很容易把可停止服务误判成可提权。

先固定当前身份、服务配置和服务对象 ACL:

whoami /all
sc.exe qc <ServiceName>
sc.exe sdshow <ServiceName>
sc.exe queryex <ServiceName>
reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName>" /s

重点看低权限主体是否拥有 SERVICE_CHANGE_CONFIG、WRITE_DAC、WRITE_OWNER,不要只看能否 start/stop。随后解析 ImagePath,逐级检查二进制、工作目录及父目录 ACL;未加引号路径也要结合实际文件是否可创建判断,不能仅凭路径含空格下结论:

icacls "C:\Path\service.exe"
icacls "C:\Path"
where.exe accesschk.exe
accesschk.exe -q -w -u -v <ServiceName>
accesschk.exe -q -w -u "C:\Path\service.exe"

还应检查 Parameters\ServiceDll、恢复动作、依赖项及服务账户。尤其是 svchost 托管服务,真正的加载目标通常不在 ImagePath 本身:

reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName>\Parameters" /v ServiceDll
sc.exe qfailure <ServiceName>
sc.exe enumdepend <ServiceName>

留痕方面,建议在测试前后各导出一次配置与 ACL,并统一记录 UTC 时间、操作者、工单号和文件哈希。系统日志可关注 7040、7045、7036,安全日志关注 4697;若部署 Sysmon,再关联 1、11、13 事件。注意 7045/4697 偏向“新建服务”,既有服务配置被修改未必完整覆盖,最好临时启用注册表与文件对象审计:

auditpol.exe /set /subcategory:"Registry" /success:enable /failure:enable
auditpol.exe /set /subcategory:"File System" /success:enable /failure:enable
wevtutil.exe epl System system-service-test.evtx
wevtutil.exe epl Security security-service-test.evtx
Get-FileHash "C:\Path\service.exe" -Algorithm SHA256

验证时不必投放交互式载荷。用授权的无害测试文件证明“可写”,或在隔离环境中让测试程序只写入带时间戳的标记文件即可;结束后恢复原 ACL、配置和审计策略,并用哈希及事件时间线确认回滚完成。

修复顺序建议是:撤销普通用户对服务对象的变更权限;收紧程序、DLL、配置文件和父目录 ACL;给含空格的可执行路径加引号;服务账户改为最小权限的虚拟账户或 gMSA;最后复核继承权限。仅修改 ImagePath 而不处理目录写权限,通常只是修掉表象。

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

最近浏览 0

  • 没有会员查看此页面。