This is a story of a temporarily flawed Microsoft patch.
CVE-2024-38213 is a vulnerability that causes files copied from WebDAV shared folders to Windows machine to not have the Mark of the Web (MotW) applied. This results in such files being overly trusted by Windows Explorer, Defender, SmartScreen and possibly other security products, and vulnerabilities like this are being exploited in the wild.
The vulnerability was discovered by security researcher Peter Girnus and Simon Zuckerbraun with the ZDI and reported to Microsoft, who provided a patch for it with July 2024 updates. Their advisory was, however, not released until August 2024, which was also when Peter published their detailed analysis. and nicknamed the vulnerability "copy2pwn".
We were naturally interested in the vulnerability as it was likely also affecting security-adopted legacy Windows systems for which Microsoft was no longer providing security patches.
Our review of Microsoft's patch, however, revealed something interesting:
It didn't work.
Analysis of the Flaw
CVE-2024-38213 manifests itself on a vulnerable Windows computer when we copy a file using Ctrl-C & Ctrl-V from a WebDAV share, or drag-and-dropping a file from such share. The latter results in a warning (Image 1), but both methods fail to flag the file with Mark of the Web (MotW).
![]() |
Image 1: Security warning when drag-and-dropping a file from a network folder |
For some reason, even a fully patched testing Windows computer was still behaving the same: no MotW on the copied file.
Analyzing Microsoft's patch, we found that the code for preventing exploitation of CVE-2024-38213 was there, but for some reason it didn't make a difference. Going further, we discovered that all Windows versions updated to August 2024, except Windows 11 and Server 2022, were still vulnerable.
Let's take a look at a relevant section of this code.
![]() |
Image 2: _StampMotWonDestFileIfNeeded function |
The _StampMotwOnDestFileIfNeeded function, added by the patch, has a very descriptive name when we consider CVE-2024-38213 and what it exploits. The function calls MapUrlToZone, based on which it should mark files with MotW when they come from the internet - but fails to do that. Halting execution with WinDbg we could see the execution flow went left (green arrow) after the first function code block (Image 2), which resulted in jumping to the exit block without setting the MotW.
This jump was caused by the compare instruction in the first block: cmp [rcx+89h], 0 so we wanted to know where the value at address rcx+89h came from. In situations like this, esReverse, a powerful reversing and binary analysis solution from eShard, saves the day. Its taint analysis functionality allowed us to take rcx+89h, track it through execution history, and quickly find all places where it was changed and by who. The taint path can traverse processes in case the data we're interested in gets sent from one process to another, tracing it all the way through the kernel.
![]() |
Image 3: esReverse's Taint analysis window |
We set up tainting from our current "transition" 447150053, to the very first transition as shown on Image 3. "Tag0" represents the data we're interested in tracing: 0xead25c9 is actually rcx+89h at the time of the execution entering function _StampMotwOnDestFileIfNeeded, and 1 is the number of bytes we care about at that location. Once we had the taint results, we analyzed all transitions and found that the last one was in the CTSTransfer constructor where rcx+89h location is initialized to 0. Then we needed to find the last change that affected location rcx+89h and caused the MotW logic in _StampMotwOnDestFileIfNeeded to be skipped.
![]() |
Image 4: Instruction that sets the relevant variable to 0 |
The last executed instruction before _StampMotwOnDestFileIfNeeded compares the value at [rcx+89h] to 0 is: mov [rbx+89h], dil (Image 4) in the CTSTransfer constructor. We now only needed to find who sets the value of dil (the low 8 bytes of register rdi) and why.
Analyzing all transitions, we found the bug in function _InitializeZoneIdentifierInterfaces, called from the CTSTransfer constructor: when calling CoCreateInstance, the return value was compared to 0, and if equal, the function exited assuming CoCreateInstance had failed (Image 5).
![]() |
Image 5: Return value of CoCreateInstance is compared to zero |
But this is wrong: 0 is the value of S_OK, a.k.a. "Operation successful," while the code is treating it as an error.
We had our culprit! This bug in _InitializeZoneIdentifierInterfaces resulted in critical IInternetSecurityManager interface code being skipped, which left the interface uninitialized, resulting in _StampMotwOnDestFileIfNeeded determining that it could not use function MapUrlToZone - and deciding to bail out instead of setting a Mark of the Web on the copied file.
Fortunately, Microsoft must have also noticed this flaw and corrected it with the next Windows Update.
![]() |
Image 6: comparison of fixed code (left) and flawed code (right) |
Image 6 shows Microsoft's fix for this flaw. As is often the case, Microsoft's patch comes with a "patch switch" allowing for "enabling" the new code via a registry value. This makes sense in cases where the new code has a potential to cause functional problems so individual patches can be "turned off". We're not sure why this could be the case here (with the obvious programming error), but we appreciate the opportunity to show both pre-patch and post-patch code on the same image.
As you can see, the only difference between vulnerable pre-patch code and fixed post-patch code is in a single instruction: jz ("jump if zero") in pre-patch code results in erroring out when the call to CoCreateInstance succeeds (which is wrong), while js ("jump if signed", i.e., jump if negative) in post-patch code errors out when the call fails.
Our Micropatch
Our patch for legacy Windows systems - Windows 7, Server 2008 R2, and several Window 10 versions - was logically identical to Microsoft's (the corrected one, of course). This video shows it in action.
Vulnerabilities like this one get discovered on a regular basis, and
attackers know about them all. If you're using Windows that aren't
receiving official security updates anymore, 0patch will make sure these
vulnerabilities won't be exploited on your computers - and you won't
even have to know or care about these things.
If you're new to 0patch, create a free account in 0patch Central, then install and register 0patch Agent from 0patch.com, and email sales@0patch.com for a trial. Everything else will happen automatically. No computer reboot will be needed.
To learn more about 0patch, visit our Help Center.We'd like to thank Peter Girnus with the ZDI for sharing vulnerability details, which allowed us to reproduce it and create a micropatch. We also encourage all security researchers who want to see their vulnerabilities patched to share them with us or alert us about their publications.
Did
you know 0patch will security-adopt Windows 10 as well as Office 2016 and Office 2019 when they all go out of
support in October 2025, allowing you to keep using them for at least 5
more years? Read more about it here.
Analysis was performed and written by our reverse engineering and patching expert Ziga Sumenjak.