by Mitja Kolsek, the 0patch Team
TL;DR: Microsoft patched CVE-2018-8423 eighteen days after we had micropatched it. Their official patch turned out to be incomplete so we re-micropatched it.
This is a story about a Windows vulnerability that was reported to Microsoft, published as "0day" before the official patch was available, micropatched by us one day later, subsequently patched by Microsoft, found to be incorrectly patched, and now micropatched again over the flawed official patch. Confused? It's actually a nice case study to demonstrate... not how we are smarter than Microsoft (we really aren't) but how micropatching is a much more suitable technology for fixing vulnerabilities on billions of computers than the current de-facto standard of what we call "fat updates".
The story begins with the ZDI reporting a memory corruption vulnerability in Jet Database Engine (subsequently assigned CVE-2018-8423) to Microsoft, which then led to a public 0day drop 135 days later without Microsoft having issued an official fix for it. We at 0patch took ZDI's proof-of-concept exploit and created a free micropatch for our users just 24 hours later. For more details up to that point see our previous blog post.
Now, a few days ago, Microsoft issued their fix for this issue as part their October 2018 Monthly Update. As expected, the update brought a modified msrd3x40.dll binary: this is the binary with the vulnerability, which we had micropatched with 4 CPU instructions (one of which was just for reporting purposes). The version of msrd3x40.dll changed from 4.0.9801.0 to 4.0.9801.5 and of course its cryptographic hash also changed - which resulted in our micropatch for this issue no longer getting applied to msrd3x40.dll. This is a welcome automatic side effect of in-memory patching, unburdening users from doing anything beyond applying the official vendor update once it becomes available. It also nicely demonstrates how traditional "module-replacing" updating can safely co-exist with in-memory micropatching.
Naturally we were curious whether Microsoft's fix was identical to our micropatch. Two months ago, we compared Microsoft's fix with our own micropatch for the famous Sandbox Escaper's 0day and found them to be functionally identical.
So we BinDiff-ed the patched msrd3x40.dll to its vulnerable version and reviewed the differences. At this point we will only state that we found the official fix to be slightly different to our micropatch, and unfortunately in a way that only limited the vulnerability instead of eliminating it. We promptly notified Microsoft about it and will not reveal further details or proof-or-concept until they issue a correct fix.
We have, however, issued a micropatch that corrects Microsoft's patch. Namely, in an ironical twist of fate Microsoft's October update actually re-opened the CVE-2018-8423 vulnerability for 0patch users who were previously protected by our micropatch. This new micropatch, which has already been distributed to all online users by now, resumes their protection. At the time of this writing, it is confirmed to be applicable to fully updated 32-bit and 64-bit Windows 10, Windows 8.1, Windows 7, Windows Server 2008 and Windows Server 2012. We suspect all other affected Windows versions also share the same version of msrd3x40.dll, in which case the micropatch will apply there as well. (We'll update this information as we go.)
We all know that many Windows users and admins don't immediately apply Windows updates as they become available. This begs the question: What will happen if you have 0patch Agent installed and haven't applied the October Windows Updates yet? Obviously, you're currently protected by our micropatch for msrd3x40.dll version 4.0.9801.0, which is getting applied to this module whenever the module gets loaded in any running process. When you decide to apply the October Windows Updates, they will make you restart your computer, after which there will be a new version of msrd3x40.dll there, version 4.0.9801.5. But our new micropatch for it will also already be there installed and waiting in your 0patch Agent, so whenever the new msrd3x40.dll gets loaded, it will immediately be micropatched in memory. Bottom line: you don't have to do anything!
You can see our micropatch in action in the video clip below. The video shows that after the official vendor fix for CVE-2018-8423 has been applied, the original proof-of-concept published by the ZDI really doesn't work anymore (WScript.exe correctly detects invalid input data and displays an error message), but a slightly modified POC still manages to cause an out-of-bounds write and crashes the process. ("Page heap" must be enabled for the process to actually crash, while memory corruption occurs without that as well.) Finally, the video shows that our micropatch fixes the vulnerability for the modified POC as well.
Now what does this story tell us? A couple of things.
1) In-memory micropatching nicely co-exists with traditional "fat" updating. Not only does a micropatch that is currently getting applied get automatically obsoleted when the target binary is replaced by a new version, but a micropatch for a future binary version can also be patiently waiting for you to apply a vendor update, and automatically start getting applied to it when you do. All without you so much as lifting a finger.
2) Flawed patches will always happen. This time it was Microsoft, next time it will be someone else, and then we will make a flawed micropatch ourselves. The possibility of flawed micropatches is designed into our model though; by now you already know that a micropatch gets distributed to all online agents within 60 minutes of issuance, and gets instantly applied to vulnerable modules on your computer. But in case something went terribly wrong with it and it broke something (like this vendor patch did), we could also have it revoked on all online agents within 60 minutes, causing it to stop applying. Meanwhile, you would be able to manually disable the micropatch via 0patch Console.
3) Micropatching is quick and user-friendly. All of the above - deployment, application, removal, and revocation or a micropatch - happens instantly, without restarting the computer or even having to re-open running applications. Compare this with today's standard approach to patching: first you download a ridiculous amount of bytes, which often forever take disk space on your computer, and then you have to at least restart patched applications (with all the documents you're working on) if not restart the computer, to actually get a handful of code changes applied. When something goes wrong, it takes at least as much time to revert to the pre-patched state, and that's only in the ideal case.
4) In-memory micropatching is a superior method to "fat" updates for fixing most security issues. We're not saying we could entirely do away with the concept or replacing modules on your computer and just keep micropatching it into eternity. No, software products periodically need significant modifications, but that's mostly for functional or user interface-related changes - and these really don't need to come on a monthly basis. Security fixes, however, actually need to be delivered faster if we ever want to outrun the attackers, and applied in a less user-hostile way than what we're all used to experiencing today, ideally so that users won't even notice their vulnerabilities disappearing under their feet. We can envision a product update model that includes annual or semi-annual fat updates, and lots of intermediate micropatches for security issues and occasional functional ones.
Our micropatches, including this current one, are still completely free for everyone, and can be obtained by installing and registering 0patch Agent from https://0patch.com. We highly welcome your feedback on firstname.lastname@example.org.