# CVE-2023-38146: Arbitrary Code Execution via Windows Themes

Windows 11 theme loader verifies a signed _vrf.dll then reopens it, allowing a TOCTOU swap for arbitrary code execution via a malicious .theme file.

- Payout: $5,000
- Severity: high
- Program: Microsoft
- Credited: gabe_k
- Disclosed: 2023-09-13
- CVE: CVE-2023-38146
- Write-up quality: 8/10
- Original: https://exploits.forsale/themebleed/
- Library page: https://bugbountylibrary.com/r/blog%3Aexploits-forsale-themebleed
- Tags: domain:desktop impact:rce kind:bounty platform:blog sev:high tech:windows technique:race-window technique:source-review vuln:race-condition vuln:rce vuln:signature-replay

**Target:** Windows 11 uxtheme.dll theme loader (.theme/.msstyles/.themepack)
**Root cause:** ReviseVersionIfNecessary verifies the signature of a _vrf.dll then closes and reopens it via LoadLibrary, creating a TOCTOU window; the version-999 path in LoadThemeLibrary triggers this.
**Steps:**
1. Create a .theme file referencing an attacker-controlled SMB path for the .msstyles file via `themebleed.exe make_theme <attacker_ip> exploit.theme`
2. Run the attacker SMB server: `themebleed.exe server`
3. On target, open exploit.theme (or a .themepack to bypass MotW)
4. SMB server returns a validly signed _vrf.dll for the signature check, then a malicious unsigned _vrf.dll when LoadLibrary reopens it
5. Malicious DLL's VerifyThemeVersion executes, launching calc.exe
**How found:** Researcher was poking at unusual Windows file formats, read uxtheme.dll's LoadThemeLibrary and noticed the special version-999 path calling ReviseVersionIfNecessary, then observed the verify-close-reopen pattern creating a race window.
**Exploitation:** Attacker hosts an SMB share; the .theme points its msstyles path there. The server serves a signed _vrf.dll during verification and swaps to a malicious DLL before LoadLibrary loads it, achieving code execution. Packaging in a .themepack bypasses the Mark-of-the-Web warning.
**Escalation:** Chained MotW bypass via .themepack with the TOCTOU to go from opening a downloaded theme to code execution without memory corruption.
**Insight:** Look for special-case version/magic values that route into legacy verification code; when a file is signature-checked then closed and reopened by path, a remote SMB share lets you swap content between check and use.
