This is a fun bug I found while poking around at weird Windows file formats. It’s a kind of classic Windows style vulnerability featuring broken signing, sketchy DLL loads, file races, cab files, and Mark-of-the-Web silliness. It was also my first experience submitting to the MSRC Windows bug bounty since leaving Microsoft in April of 2022.
这是我在浏览奇怪的Windows文件格式时发现的一个有趣的错误。这是一种经典的Windows风格的漏洞,具有损坏的签名,粗略的DLL加载,文件争用,cab文件和Web标记的愚蠢行为。这也是我自 2022 年 4 月离开 Microsoft 以来第一次向 MSRC Windows 漏洞赏金提交。
In the great tradition of naming vulnerabilities, I’ve lovingly named this one ThemeBleed (no logo as of yet but I’m accepting submissions.)
在命名漏洞的伟大传统中,我亲切地将这个命名为ThemeBleed(目前还没有徽标,但我正在接受提交。
Overall it was a lot of fun finding and PoC-ing this vulnerability, and MSRC was incredibly fast in responding and judging it for bounty :^]
总的来说,发现和PoC处理这个漏洞很有趣,MSRC在响应和判断它的赏金方面非常快:^]
Below is a slightly modified version of the report I sent to Microsoft. After the report is a timeline and my notes on their fix.
以下是我发送给Microsoft的报告的略微修改版本。报告之后是时间表和我对修复的注释。
Summary 总结
A series of issues exist on Windows 11 which can lead to arbitrary code being executed when a user loads a .theme
file.
Windows 11 上存在一系列问题,这些问题可能导致在用户加载 .theme
文件时执行任意代码。
Bug Details 错误详细信息
1. Background 1. 背景
On Windows, .theme
files allow customization of the OS appearance. The .theme
files themselves are ini files, which contain configuration details. Clicking on a .theme
file on Windows 11 will invoke the following command:
在 Windows 上, .theme
文件允许自定义操作系统外观。文件本身是包含配置详细信息的 ini .theme
文件。单击 Windows 11 上的 .theme
文件将调用以下命令:
"C:\WINDOWS\system32\rundll32.exe" C:\WINDOWS\system32\themecpl.dll,OpenThemeAction <theme file path>
This vulnerability specifically deals with the handling of .msstyles
files. These are PE (DLL) files that contain resources such as icons to be used in a theme, but (should) contain no code. A .msstyles
file can be referenced in a .theme
file in the following way:
此漏洞专门处理 .msstyles
文件的处理。这些是 PE (DLL) 文件,其中包含要在主题中使用的图标等资源,但(应)不包含任何代码。可以通过以下方式在 .theme
文件中引用 .msstyles
文件:
[VisualStyles]
Path=%SystemRoot%\resources\Themes\Aero\Aero.msstyles
When the .theme
file is opened, the .msstyles
file will also be loaded.
打开 .theme
文件时, .msstyles
文件也将加载。
2. The “Version 999” Check
2. “版本 999”检查
When loading a .msstyles
file, the LoadThemeLibrary
in uxtheme.dll
will check the version of the theme. It will do this by loading the resource named PACKTHEM_VERSION
from the binary. If the version it reads is 999, it will then call into another function ReviseVersionIfNecessary
. A decompiled version of this function with the relevant parts commented can be seen below:
加载 .msstyles
文件时, LoadThemeLibrary
in uxtheme.dll
将检查主题的版本。它将通过加载从二进制文件命名 PACKTHEM_VERSION
的资源来执行此操作。如果它读取的版本是 999,它将调用另一个函数 ReviseVersionIfNecessary
。下面可以看到此函数的反编译版本,其中包含相关部分注释:
__int64 __fastcall LoadThemeLibrary(const WCHAR *msstyles_path, HMODULE *out_module, int *out_version)
{
HMODULE module_handle;
signed int result;
int version;
signed int return_val;
unsigned int resource_size;
__int16 *version_ptr;
if ( out_version )
*out_version = 0;
module_handle = LoadLibraryExW(msstyles_path, 0, 2u);
if ( !module_handle )
return (unsigned int)MakeErrorLast();
result = GetPtrToResource(
module_handle,
L"PACKTHEM_VERSION",
(const unsigned __int16 *)1,
(void **)&version_ptr,
&resource_size); // !!! [1] version number is extracted from resource "PACKTHEM_VERSION"
if ( result < 0 || resource_size != 2 )
goto LABEL_22;
version = *version_ptr;
if ( out_version )
*out_version = version;
return_val = -2147467259;
if ( version >= 4 )
{
if ( version > 4 )
result = -2147467259;
return_val = result;
}
if ( return_val < 0 && (_WORD)version == 999 ) // !!! [2] special case for version 999
{
resource_size = 999;
return_val = ReviseVersionIfNecessary(msstyles_path, 999, (int *)&resource_size); // !!! [3] call to `ReviseVersionIfNecessary`
...
}
3. Time-of-Check-Time-of-Use in ReviseVersionIfNecessary Allows Signature Bypass
3. 检查时间在修订版中使用时间如有必要允许绕过签名
The ReviseVersionIfNecessary
function which is called by the previous step performs several actions. Given a path to a .msstyles
file, it will perform the following:
上一步调用的 ReviseVersionIfNecessary
函数执行多个操作。给定 .msstyles
文件的路径,它将执行以下操作:
- Create a new file path by appending
_vrf.dll
to the.msstyles
file path.
通过追加_vrf.dll
到文件路径来创建新的.msstyles
文件路径。 - Check if this new
_vrf.dll
file exists. If not, exit.
检查此新_vrf.dll
文件是否存在。如果没有,请退出。 - Open the
_vrf.dll
file 打开_vrf.dll
文件 - Verify the signature on the
_vrf.dll
file. If the signature is invalid, exit.
验证_vrf.dll
文件上的签名。如果签名无效,请退出。 - Close the
_vrf.dll
file 关闭_vrf.dll
文件 - Load the
_vrf.dll
file as a DLL and call theVerifyThemeVersion
function.
将_vrf.dll
文件作为 DLL 加载并调用VerifyThemeVersion
函数。
The goal of this appears to be to attempt to safely load a signed DLL and call a function. This implementation is flawed however, because the DLL is closed after verifying the signature in step 5, and then re-opened when the DLL is loaded via a call to LoadLibrary in step 6. This provides a race window between those two steps where an attacker may replace the _vrf.dll
file that has had its signature verified, with a malicious one that is not signed. That malicious DLL will then be loaded and executed.
这样做的目标似乎是尝试安全地加载已签名的 DLL 并调用函数。但是,此实现存在缺陷,因为在步骤 5 中验证签名后关闭 DLL,然后在步骤 6 中通过调用 LoadLibrary 加载 DLL 时重新打开。这在这两个步骤之间提供了一个竞争窗口,攻击者可以在其中将已验证其签名 _vrf.dll
的文件替换为未签名的恶意文件。然后,将加载并执行该恶意 DLL。
4. Mark-of-the-Web Bypass
4. 网络标记绕过
If a user downloads a .theme
file, upon launching it they will receive a security warning due to the presence of Mark-of-the-Web on the file. It turns out this can be bypassed by packaging the .theme
file in a .themepack
file.
如果用户下载文件 .theme
,在启动文件时,由于文件上存在 Web 标记,他们将收到安全警告。事实证明,这可以通过将 .theme
文件打包到 .themepack
文件中来绕过。
A .themepack
file is a cab file containing a .theme
file. When a .themepack
file is opened, the contained .theme
file will be loaded. When opening a .themepack
file with Mark-of-the-Web, no warning is displayed, so the warning that would normally be seen is bypassed.
文件是包含 .theme
文件的 cab .themepack
文件。打开 .themepack
文件时,将加载包含 .theme
的文件。使用 Web 标记打开 .themepack
文件时,不会显示任何警告,因此通常会绕过通常看到的警告。
Proof of Concept 概念验证
I developed a PoC for this issue. The PoC consists of two components, an SMB server executable to be run on an attacker’s machine, and a .theme
file to be opened on the target’s machine.
我为这个问题开发了一个 PoC。PoC 由两个组件组成:一个要在攻击者计算机上运行的 SMB 服务器可执行文件,以及一个 .theme
要在目标计算机上打开的文件。
I chose to use an attacker controlled SMB server for this because a .theme
file may point to a .msstyle
path on a remote SMB share. Since the SMB share is attacker controlled, it can easily exploit the TOCTOU bug in ReviseVersionIfNecessary
by returning a validly signed file when the client first requests it to check the signature, and then a malicious one when the client loads the DLL.
为此,我选择使用攻击者控制的 SMB 服务器,因为 .theme
文件可能指向远程 SMB 共享上的 .msstyle
路径。由于 SMB 共享受攻击者控制,因此它可以轻松利用 TOCTOU 错误 ReviseVersionIfNecessary
,方法是在客户端首次请求它检查签名时返回有效签名的文件,然后在客户端加载 DLL 时返回恶意文件。
The PoC can be found here: https://github.com/gabe-k/themebleed
PoC可以在这里找到:https://github.com/gabe-k/themebleed
Environment Prep 环境准备
To run the PoC you will need two machines, one attacker machine which will run the SMB server, and one target machine where you will load the .theme
file. Below are the requirements for the respective machines:
要运行 PoC,您将需要两台计算机,一台将运行 SMB 服务器的攻击者计算机,以及一台将加载 .theme
文件的目标计算机。以下是相应机器的要求:
Attacker machine 攻击者计算机
- Windows 10 or 11
视窗 10 或 11 - Disable “Server” service to free up the SMB port (disable and restart, do not just stop the service)
禁用“服务器”服务以释放SMB端口(禁用并重新启动,不要只是停止服务) - Up to date .NET
最新的 .NET - Accessible to target machine on the network
网络上的目标计算机可访问
Target machine 目标机器
- Latest Windows 11 最新视窗 11
Repro Steps 重现步骤
- Create the
.theme
file by running:themebleed.exe make_theme <attacker machine ip> exploit.theme
通过运行以下命令创建.theme
文件:themebleed.exe make_theme <attacker machine ip> exploit.theme
- On the attacker machine run:
themebleed.exe server
在攻击者计算机上运行:themebleed.exe server
- On the target machine open
exploit.theme
在目标计算机上打开exploit.theme
This should result in the calculator opening on the target machine. This shows that arbitrary code has been executed.
这应该会导致计算器在目标计算机上打开。这表明已执行任意代码。
Credits 学分
The PoC makes use of the SMBLibrary by Tal Aloni
PoC利用了Tal Aloni的SMBLibrary。
Conclusion 结论
This is a reliable vulnerability that goes from loading a theme to downloading and executing code without memory corruption. Additionally this vulnerability appears to be new and only present in Windows 11. I would request that this submission be considered for bounty.
这是一个可靠的漏洞,从加载主题到下载和执行代码,而不会损坏内存。此外,此漏洞似乎是新的,仅存在于 Windows 11 中。我请求考虑给予这项赏金。
To fix this vulnerability I would recommend:
要修复此漏洞,我建议:
- Removing the “version 999” functionality altogether, but I’m not entirely sure what it’s intended use is.
完全删除“版本 999”功能,但我不完全确定它的预期用途是什么。 - Signing and verifying the
_vrf.dll
binary in the standard way Windows verifies other code, rather than this which is vulnerable to these kinds of race conditions.
以 Windows 验证其他代码的标准方式对_vrf.dll
二进制文件进行签名和验证,而不是容易受到此类争用条件影响的这种代码。 - Disallow loading resources from remote shares in theme files.
禁止从主题文件中的远程共享加载资源。 - Add Mark-of-the-Web warnings to
.themepack
files.
向.themepack
文件添加 Web 标记警告。
End of original report
原始报告结束
Reporting Timeline 报告时间表
- 5/15/2023 – Report and PoC submitted to Microsoft.
2023 年 5 月 15 日 – 向Microsoft提交报告和 PoC。 - 5/16/2023 – Acknowledgement of vulnerability by Microsoft.
2023 年 5 月 16 日 – Microsoft承认漏洞。 - 5/17/2023 – $5,000 bounty rewarded
2023 年 5 月 17 日 – 奖励 5,000 美元赏金 - 9/12/2023 – Fix released.
2023 年 9 月 12 日 – 修复已发布。
Microsoft Fix Analysis Microsoft修复分析
Microsoft’s released fix for the issue removed the “version 999” functionality entirely. While that migitates this specific exploit, it still does not address the TOCTOU issue in the signing of .msstyles
files.
Microsoft发布的该问题修复程序完全删除了“版本 999”功能。虽然这会迁移此特定漏洞,但它仍然没有解决 .msstyles
文件签名中的 TOCTOU 问题。
Additionally Microsoft has not added Mark-of-the-Web warnings on .themepack
files.
此外,Microsoft 尚未在文件上 .themepack
添加 Web 标记警告。
原文始发于gabe_k:CVE-2023-38146: Arbitrary Code Execution via Windows Themes
转载请注明:CVE-2023-38146: Arbitrary Code Execution via Windows Themes | CTF导航