There are new articles available, click to refresh the page.
✇ 0patch Blog

Patching, Re-Patching and Meta-Patching the Jet Database Engine RCE (CVE-2018-8423)

By: Mitja Kolsek
Flawed Patches Will Always Happen, But We Can Change How They Get Fixed 

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 [email protected].



✇ 0patch Blog

One... Two... Three Micropatches For Three Windows 0days

By: Mitja Kolsek
A Short Micropatching Trilogy

by Mitja Kolsek, the 0patch Team

While we're busy ironing out the wrinkles before 0patch finally exits its adolescence (i.e., Beta) and becomes a fully responsible adult able to pay for its own rent, we did find some time to produce... not one, ... not two, ... but three 0day micropatches in the past few days. That's right, at this very moment you can get three 0days on your Windows computer micropatched for free! All you have to do is register a free 0patch account and install 0patch Agent.

Let's quickly go through each of these 0days and see what they allow attackers to do, and how we micropatched them. Then we can return to the wrinkle-ironing mode and bring you the best patching experience that we possibly can.

0day #1: the "angrypolarbearbug"

[Update 5/16/2019: Microsoft has fixed this issue with May 2019 Updates and assigned it CVE-2019-0863.]

This 0day, dubbed "angrypolarberbug" by its author SandboxEscaper who published it last month, allows a local unprivileged process to get any chosen file on the system overwritten with the content of a Windows Error Reporting XML file. The attacker has very little control over the content of this XML file so the demonstration provided by SandboxEscaper was a local denial of service by corrupting a critical system file pci.sys, which prevents the system from booting. One can imagine potentially finding some other file to overwrite that would lead to execution of attacker's code under higher privileges such as SYSTEM or Administrator - but to our knowledge, such example has not been published.

The crux of this vulnerability is in the fact that the C:\ProgramData\Microsoft\Windows\WER\Temp\ folder, where the Windows Error Reporting Service is creating a temporary XML file, has inheritable permissions that include read, write and delete access for Authenticated Users (which includes the local attacker). This means that whenever anyone creates a new file there without specifying its permissions, any process on the system, including a low-privileged malicious process, will be able to replace that file with another file. And that's what SandboxEscaper's proof-of-concept does: it waits for the XML file to appear, and then quickly replaces it with a hard link to the chosen target file (e.g., pci.sys). When Windows Error Reporting Service subsequently re-opens this XML file for writing, it actually opens the linked-to file, and writes to that file.

Our micropatch makes a small change: when Windows Error Reporting Service creates the XML file, it now specifies permissions that are otherwise exactly the same as before, except that Authenticated Users don't have delete permissions on it. This keeps error reporting working while preventing the exploit from deleting the XML file (and thus also from creating a hard link in its place).

We currently have this micropatch for fully updated 64-bit Windows 10 version 1803. (Contact [email protected] to express your interest in porting to other versions.) Note that this issue doesn't seem to affect Windows 7, where error reporting works a bit differently.

You can see this micropatch in action in the following video.

And here's the source code for this micropatch.

;Micropatch for wer.dll version 10.17134.471
;How it works:
; a vulnerable call CreateFileW responsible for creating a temporary report XML file
; which inherits loose C:\ProgramData\Microsoft\Windows\WER\Temp\ permissions is replaced by
; a call to ConvertStringSecurityDescriptorToSecurityDescriptor which creates a new security
; descriptor from ACE string that gets supplied to a new CreateFileW call.
; The new security descriptor has no DELETE permissions for AuthenticatedUsers group
; on report XML so a regular user can no longer change it to a hard link.

MODULE_PATH "..\AffectedModules\wer.dll_10.17134.471_64bit\wer.dll"
VULN_ID 4657

PIT kernel32.dll!CreateFileW,advapi32.dll!ConvertStringSecurityDescriptorToSecurityDescriptorA,kernel32.dll!LocalFree


  mov qword [rsp+10h], r8 ; dwShareMode
  mov qword [rsp+8h], rdi ; storing a global variable
  mov qword [rsp], rcx    ; lpFileName

  call arg0_StringSecurityDescriptor

  ; args for ConvertStringSecurityDescriptorToSecurityDescriptor
  ; we changed (A;;0x13019f;;;AU) to (A;;GRSD;;;AU) - meaning

  ; AuthenticatedUsers can Read and Delete only
  db "D:(A;;FA;;;BA)(A;;GRGW;;;AU)(A;;0x13019f;;;SU)(A;;0x13019f;;;LS)(A;;0x13019f;;;NS)(A;;0x13019f;;;WR)(A;;0x13019f;;;AC)(A;;0x13019f;;;S-1-15-2-2)",0
  pop rcx ; rcx=arg0_StringSecurityDescriptor
  mov rdx, 01h ; arg1: StringSDRevision=SDDL_REVISION_1
  ;arg2: this arg is part of SECURITY_ATTRIBUTES struct so we have to create this first

                   ; sa requires 18h of space
  sub rsp, 20h     ; but we're allocating 8 more than required nLength to keep stack alignment
  lea r8, [rsp+8h] ;arg2: SecurityDescriptor=&sa.lpSecurityDescriptor
  ;init sa:
  mov dword [rsp],18h    ;sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  mov dword [rsp+10h],1h ;sa.bInheritHandle=FALSE
  xor r9d,r9d ; SecurityDescriptorSize=NULL
  sub rsp, 20h ; allocate homespace

  call PIT_ConvertStringSecurityDescriptorToSecurityDescriptorA
  ;copy CreateFileW args 5,6 and 7 to a new stack frame
  mov rax, [rsp+60h] ; dwCreationDisposition
  mov qword [rsp],rax
  mov rax, [rsp+68h] ; dwFlagsAndAttributes
  mov qword [rsp+8h],rax
  mov rax, [rsp+70h] ; hTemplateFile
  mov qword [rsp+10h],rax
  ;obtain CreateFileW args 1,2,3,4
  mov rcx, [rsp+40h] ; lpFileName
  mov edx, 0C0000000h ; dwDesiredAccess
  mov r8, [rsp+50h] ; dwShareMode
  lea r9,[rsp+20h] ;lpSecurityAttributes
  sub rsp, 20h ; alloc homespace
  call PIT_CreateFileW
  mov [rsp+28h],rax ; store result

  ;free the security descriptor:
  mov rcx,[rsp+48h] ; sa.lpSecurityDescriptor
  call PIT_LocalFree ;LocalFree(sa.lpSecurityDescriptor)
  mov rax,[rsp+28h] ;restore result
  mov rdi,[rsp+68h] ;restore the global variable
  add rsp, 60h      ;restore stack


0day #2: the "readfile" (subsequently assigned

[Update 2/14/2019: Microsoft has fixed this issue with February 2019 Updates and assigned it CVE-2019-0636.]

The "readfile" 0day was also published by SandboxEscaper last month. This one allows an unprivileged process running on a Windows computer to obtain the content of arbitrary file, even if permissions on such file don't allow it read access. The proof-of-concept demonstrates reading the content of another user's desktop.ini file from user's desktop, but the author suggests reading Office history files (and other index or history files with known paths) could reveal further paths to interesting files belonging to other users.

The flaw lies in Windows Installer, more specifically in its advertisement functionality, which can be triggered using the MsiAdvertiseProduct function. We're not going to dive into details here; suffice it to say that when a product (i.e., its MSI installation package) is advertised, Windows Installer (running as SYSTEM) takes this MSI file, parses it, then creates a temporary MSI file in C:\Windows\Installer folder and copies the content of the original MSI file in it. (It does much more with it then but that's irrelevant for this issue.) SandboxEscaper noticed that the original MSI file is opened twice, and that a symbolic link can be made that points to a regular MSI file on the first open, but points to some other file on the second open - which results in the content of the latter file being copied to the temporary MSI file. Due to file permissions on the temporary MSI file, which allow Everyone read access, an attacker can thus trick the Windows Installer Service to copy the content of arbitrary file to the temporary MSI file, and then read that file to obtain said content.

Micropatching this issue required us to familiarize ourselves with the inner working of Windows Installer. It turned out that the function copying the source MSI file into the temporary MSI file already supports setting two different permission sets on the temporary file: (1) inherited permissions, and (2) permissions of the source MSI file. Its behavior in advertising a product uses the inherited permissions (which allow the attacker to read the file), so we used four strategically-placed patchlets to force it to use permissions of the source MSI file instead. With the micropatch in place, product advertisement still works as before, but since the permissions on the temporary MSI file are the same as on the file being copied, the attacker gains nothing from this process.

We currently have this micropatch for fully updated 64-bit Windows 10 version 1803 and fully updated 64-bit Windows 7. (Contact [email protected] to express your interest in porting to other versions.)

You can see this micropatch in action in the following video.

And here's the source code for this micropatch; four patchlets, each with a single instruction.

MODULE_PATH "..\AffectedModules\msi.dll_5.0.17134.228_64bit.dll\msi.dll"
; Windows 10 version 1803
VULN_ID 4658


 PATCHLET_OFFSET 0x002edb76 ; Injecting after eax is set to FlagsAndAttributes

                            ; in CMsiFileCopy::OpenDestination


   or r12d, 0x8000 ; we set the 15th bit of FlagsAndAttributes,
                   ; which will cause the execution to flow towards using

                   ; source file's ACL




 PATCHLET_OFFSET 0x002edbe9 ; Overwriting code that checks value #12 in 

                            ; MSI record, and setting eax to 1


   mov eax, 1 ; we set eax to 1 to simulate IsNull returning false




 PATCHLET_OFFSET 0x002edd0e ; Overwriting code that checks value #12 in

                            ; MSI record, and setting eax to 1


   mov eax, 1 ; we set eax to 1 to simulate IsNull returning false




 PATCHLET_OFFSET 0x002edd61 ; Overwriting code that checks value #12 in 

                            ; MSI record, and setting eax to 1


   mov eax, 1 ; we set eax to 1 to simulate IsNull returning false



0day #3: the "Windows Contacts arbitrary code execution"

This 0day was published by a ZDI researcher John Page after Microsoft had exceeded ZDI's 90-day window for fixing a reported issue. The issue was initially reported as related to VCF files (which are by default associated with the Windows Contacts application) but Page subsequently added that CONTACT files (also by default associated with Windows Contacts) can be used to achieve the same.

The issue is in the fact that almost any string provided via a VCF or CONTACT file in the web site URL or email value (yes, we figured this one out ourselves :) ends up being used as an argument to a ShellExecute call. While ShellExecute is a handy function for opening URLs in user's default browser, its problem is that before doing that, it tries to "launch" the provided string on the local computer; to illustrate, provided with "www.microsoft.com", ShellExecute would first attempt to locate and launch a local executable called www.microsoft.com, and only failing that, it would open www.microsoft.com in your browser. This behavior has produced many a vulnerability before (see this article for some examples) and will undoubtedly continue to bless us with more in the future. To exploit this issue, the attacker must get the user to open a malicious VCF or CONTACT file and click on the displayed web site or email link, which launches attacker's executable that must also be present on user's computer or a network share.

We analyzed what happens when the web site or email link is clicked, which led us to a SafeExecute function in wab32.dll. This function does some parsing of the URL to accommodate mshelp:// URLs, and then calls ShellExecute. We simply added some logic before this call to make sure that if the URL doesn't start with "mailto:", "http://" or "https://", it gets prepended with "http://" to prevent any possible launching of local executables. We have initially considered adding sanitization in the code that reads the file but then discovered that the code displaying the link is prone to, yes, HTML injection - which made any sanitization too complex and potentially bypassable.

We currently have this micropatch for fully updated 64-bit Windows 10 version 1803 and fully updated 64-bit Windows 7. (Contact [email protected] to express your interest in porting to other versions.)

You can see this micropatch in action in the following video. The video also nicely demonstrates how a micropatch can be applied to a running process: we enable the micropatch while Windows Contacts is displaying the malicious contact card, and the result of clicking on the link gets changed.

And here's the source code for this micropatch.

;Micropatch for wab32.dll version 6.1.7601.17699
;How it works:
; in SafeExecute an unsanitized pszUrl - a user-controlled parameter is passed to ShellExecute.
; This patch adds a series of checks for valid pszUrl prefixes and eventually,
; if no valid prefix is found, adds a http:// prefix to pszUrl.

MODULE_PATH "..\AffectedModules\wab32.dll_6.1.7601.17699\wab32.dll"
VULN_ID 4656

PIT SHLWAPI.dll!StrCmpNICW,msvcrt.dll!memmove


  ;store registers:
  push rsi
  push rcx
  push rdx
  push r8
  push r8                      ; extra space for prefix variable
  push rax                     ; store pszUrl
  ;check lpFile for valid prefixes:
  call mailto
  db __utf16__('mailto:'),0
  pop rcx                      ; pszStr1 = "mailto:"
  mov rdx, rax                 ; pszStr2 = pszUrl
  mov r8, 07h                  ; nChar
  sub rsp, 20h                 ; homespace
  call PIT_StrCmpNICW
  test rax,rax
  jz skip                      ; if found, exit patch
   call https
   db __utf16__('https://'),0
   pop rcx                     ; pszStr1 = "https://"
   mov rdx, [rsp+20h]          ; pszStr2 = pszUrl
   mov r8, 08h                 ; nChar
   call PIT_StrCmpNICW
   test rax,rax
  jz skip                      ; if found, exit patch
   call http
   db __utf16__('http://'),0
   pop rcx                     ; pszStr1 = "http://"
   mov [rsp+28h], rcx          ; store prefix
   mov rdx, [rsp+20h]          ; pszStr2 = pszUrl
   mov r8, 07h                 ; nChar
   call PIT_StrCmpNICW
   test rax,rax
  jz skip                      ; if found, exit patch
   mov r8, 1024h               ; num
   mov rdx, [rsp+20h]          ; Src = pszUrl
   lea rcx,[rdx+0eh]           ; Dst
   call PIT_memmove            ; moving pszUrl of max 1024h in size to *pszUrl+0eh
   mov rcx, [rsp+20h]          ; Dst = pszUrl
   mov rdx, [rsp+28h]          ; Src = "http://"
   mov r8, 0eh                 ; num
   call PIT_memmove            ; copying http:// to *pszUrl
   ;revert stack:
   add rsp, 20h                ; revert homespace
   pop rax
   pop r8                      ; blank pop
   pop r8
   pop rdx
   pop rcx
   pop rsi



So here they are, three micropatches for three 0days. We don't know if and when Microsoft is going to fix these issues (likely in the following months); meanwhile, if you have our Agent installed and registered, these micropatches are already on your computer and applied to all affected processes. Otherwise, register a free 0patch account and install 0patch Agent to get these micropatches applied. As always, once Microsoft fixes any of these 0days, its associated micropatch will automatically stop applying - in other words, you don't have to worry about future Windows updates.

Again, please note that we haven't ported these micropatches to all supported Windows versions (see each section above for version information); if you're interested in patching your particular version of Windows, don't hesitate contacting us at [email protected].



✇ 0patch Blog

Sorry, Adobe Reader, We're Not Letting You Phone Home Without User's Consent (CVE-2019-7089)

By: Mitja Kolsek
by Mitja Kolsek, the 0patch Team

[Update 2/12/2019: Just one day after we had issued this micropatch, Adobe released an update of Adobe Reader DC that fixed the vulnerability. We strongly recommend all users of Adobe Reader to apply Adobe's update, at which point our micropatch will automatically no longer get applied.]

Today we'll look at a fairly simple vulnerability in Adobe Reader DC that allows a PDF document automatically send an SMB request to attacker's server as soon as the document is opened. The vulnerability was published by Alex Inführ along with a proof-of-concept in a detailed report on Alex's blog and hasn't been patched at the time of this writing. [Update 2/12/2019: the vulnerability was subsequently assigned CVE ID CVE-2019-7089.]

This vulnerability, similar to CVE-2018-4993, the so-called Bad-PDF reported by CheckPoint in April last year, allows a remote attacker to steal user's NTLM hash included in the SMB request. It also allows a document to "phone home", i.e., to let the sender know that the user has viewed the document. Obviously, neither of these is desirable.

At the time of this writing, the latest version of Adobe Reader DC, 2019.010.20069, is affected but older versions are likely in the same boat too.


To understand the problem, let's start with the above-mentioned Bad-PDF (CVE-2018-4993). The malicious PDF included a certain element that triggered automatic loading of another PDF from a remote share. Until Adobe Reader got patched, this happened without the user noticing anything, or being able to prevent it.

Adobe patched this issue by adding a security warning that was shown to the user before making the request to a remote share:

Security warning added to fix the Bad-PDF issue.

This warning allowed the user to decide whether to allow the potentially malicious document to "phone home" or not.

Now on to the issue at hand: it is functionally identical (for attacker), just in a different place. While Bad-PDF used an /F entry to load a remote file, this issue exploits loading a remote XML style sheet via SMB. Interestingly, if the document tries to do so via HTTP, there is a security warning there:

Attempting to load a remote style sheet via HTTP triggers a warning.

However, when using a UNC path (the type of path that denotes a resource in a shared folder), the loading occurs without a warning

The Micropatch

The Reader already implies the correct behavior by showing a security warning on loading a remote style sheet via HTTP, so we decided to add our own security warning for loading style sheets via UNC as well.

We started by locating the point where the HTTP-loading and UNC-loading execution paths diverge, and patch-in a warning for UNC paths. Finding said divergence point was relatively easy using Process Monitor: we caught CreateFile events on both HTTP and UNC loads, then compared their call stacks to see where the two execution paths said good-bye to each other. This turned out to be in function sub_208B3C53, the relevant code block of which is shown here:

Both HTTP- and UNC-based style sheet loads reach the above code block, whereby an HTTP-based load never returns from the first call marked in red (it triggers an exception that Reader handles somewhere else), and a UNC load is implemented inside the second call marked in red.

As you can see from the comments in the code, we found where the file path resides before the second call (this required a little digging on the stack at that point). We verified it by changing said path on-the-fly in debugger to make sure the path-loading code actually uses that, and then we were ready to inject our patch.

There exists a handy Windows function called PathIsUNCA, which is already being used by Reader elsewhere to check whether a path is a UNC path (the "A" at the end denotes an ASCII path in contrast to a wide-char path). So we decided to first call this function to see if we have a UNC path, and then if we do, issue a prompt to the user. To do the latter, we used another well-known Windows function MessageBoxA. Based on user's response, we would then allow the UNC path to be loaded or not. The only thing to decide at this point was how to implement the "not", i.e., how to prevent the UNC path from loading if the user decided not to trust the document.

In such cases, we always want to keep things simple and minimize possible surprises. We therefore decided to simply empty the path string by putting a zero at its beginning, resulting in Reader trying to load an empty path. It does complain that it can't load it though but the exploit is blocked and, frankly, we're fairly confident that loading style sheets form UNC paths doesn't work at all because as much as we tried, Reader always encountered an error. So maybe UNC style sheets are not a supported use case at all but they did turn out to be a vulnerability.

Here is the source code of our micropatch:

MODULE_PATH "..\AffectedModules\AcroForm.api_19.10.20064.48846_32bit\AcroForm.api"
VULN_ID 4694


 PATCHLET_OFFSET 0x000b3f6b ; Injecting before the call towards loading
                            ; a non-HTTP URL
 PIT Shlwapi.dll!PathIsUNCA,User32.dll!MessageBoxA


  push ecx ; save ecx so we don't corrupt it

  mov eax, dword [eax+10h] ; at this point, the address of path
                           ; is at [eax+10h]+4
  add eax, 4
  push eax
  push eax ; we push the address of path twice as we may need it

           ; in remediation too
  call PIT_PathIsUNCA ; is it a UNC path?
  test eax, eax
  jz skip ; not a UNC path - skip the warning dialog

  push 0x00000134 ; uType = MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2
  call get_lpCaption
  db "Security Warning",0
  call get_lpText
  db "This document is trying to access a file on the network. If you trust this document, choose Yes. If you do not trust this document, choose No.",0
  push 0 ; hWnd = NULL
  call PIT_MessageBoxA
  cmp eax, 6 ; Did user click "Yes"?
  je skip ; if so, skip remediation

  ; Remediation: we'll simply delete the entire URL string by putting
  ; a 0 at the beginning
  pop eax ; pop the previously pushed path address
  mov byte [eax], 0 ; put a 0 at the start of path
  push eax ; we need to re-push something because we have a pop in the epilogue

  pop eax ; pop the additional address of path 
  pop ecx ; restore original ecx and continue to execute the call
          ; towards loading the provided URL



With this micropatch in place, opening the malicious document results in the following warning before a request is made to the remote server:

The security dialog that was micropatched into Adobe Reader.

If the user selects "Yes", the remote style sheet is loaded (whereby the SMB request delivers your NTLM hash to the remote server), and if they select "No", Reader complains about not being able to load the style sheet from and empty path. Done.

We asked Alex, the security researcher who found this issue, to test our micropatch and he was kind enough to confirm its efficiency against this attack. (Thanks, Alex, for your help! We encourage all security researchers to collaborate on creating and testing micropatches.)

For the visual types among you, here is a video of our micropatch in action:


As always, if you have our Agent installed and registered, this micropatch is already on your computer - and applied to Adobe Reader whenever it loads AcroForm.api (that only happens when certain documents are opened). Otherwise, you can register a free 0patch account and install 0patch Agent to get this micropatch applied to your Reader.

Note that Adobe might issue an official fix for this issue tomorrow as they release their monthly Reader update, but if not, we'll quickly port the micropatch to the new Reader version to keep the vulnerability patched on your computers. [Update 2/12/2019: Adobe did issue an official fix the next day.]



✇ 0patch Blog

No Source Code For a 14-Year Old Vulnerable DLL? No Problem. (CVE-2018-20250)

By: Mitja Kolsek
Why It Makes Sense To Micropatch a Vulnerability When Official Fix Is Available

by Mitja Kolsek, the 0patch Team

Yesterday, Checkpoint published a detailed vulnerability report about a serious vulnerability in WinRAR (reportedly used by 500+ million users) which allowed a malicious archive, when extracted, to create an arbitrary file in a chosen location on user's computer. This includes,for instance, user's Startup folder where said file would get executed when the user logged in to Windows again.
Nadav Grossman, the researcher who found the vulnerability and wrote the report, nicely described    
the flow of his analysis, including the problems he stumbled into, and tools he used to analyze the vulnerability. Anyone interested in analyzing vulnerabilities, or in details of this particular one, is advised to read his report.

The vulnerability (CVE-2018-20250) was present in WinRAR's extracting of ACE archives, whereby said extracting was actually done using a dynamic library UNACEV2.DLL written by e-merge GmbH, maintainer of WinACE software. This DLL, interestingly, hasn't changed since 2005 - which actually attracted Nadav's attention.

At the time the report was published, WinRAR producer RARLAB was already offering a fixed version of  WinRAR (5.70 beta 1) on their download page, and their fix was very simple: being unable to fix the vulnerability, they dropped support for ACE format. (You might remember Microsoft doing something similar with the 17-year old Equation Editor last year.)

To Micropatch Or Not To Micropatch?

For us at 0patch, a vulnerability like this is inherently interesting: it allows for a remote code execution, it potentially affects millions of users, and the product doesn't auto-update so it is likely to be present for a long time. And while we've micropatched a bunch of 0days lately, 0patch is primarily meant to bridge the security update gap by fixing vulnerabilities that may already have an official fix.

In deciding whether to micropatch this one, we came up with the following supporting arguments:

  1. This vulnerability is a perfect candidate for malicious phishing campaigns. "Please review the attached purchase order PO.rar."
  2. WinRAR is a really widely used product. Maybe it doesn't actually have 500 million users but still.
  3. No auto-update means that most users will never update it. In fact, unless one has actually read about this vulnerability (surely most users haven't) and feels threatened by it, why would one take the time to update?
  4. Some users may actually need the ACE format support. Granted, there is still WinACE, but in contrast to WinRAR, its maintainer seems long gone.
  5. From defensive perspective, blocking exploits of this vulnerability is not as simple as rejecting files with .ace extension, as a malicious file can also be renamed to .rar or .zip (or likely any other supported extension) as long as it's extracted with WinRAR. The user can't even tell that a ZIP file is actually an ACE file.
  6. Some of 0patch users are probably also users of WinRAR. By creating a micropatch, we will protect them without them even being aware of this WinRAR vulnerability, or the fact that we micropatched it. (Letting users not worry about patches and not disturbing them with patching is a core concept of 0patch.)
  7. Admins with multiple 0patch Agents on users' computers would like the fact that whichever version of WinRAR, even if old and vulnerable, their users use or "temporarily" install, they will be protected against this issue.
  8. Other products than WinRAR may be using this particular version of UNACEV2.DLL, and our micropatch would protected from a similar attack too, without us even knowing what these products are.

As you suspected, we decided to go ahead.


Fortunately, Nadav's analysis provided most of the details we needed (big thanks, Nadav!) and a potential solution was fairly obvious. If you look at Figure 15 in his report and the accompanying text, you'll see that the exploit causes the execution through a branch that allows the malicious file path to remain a relative path by prepending it with... well, an empty string. So the idea was to always force the execution through the other branch, which prepends the malicious path with the target directory.

This way, instead of allowing malicious paths like:




to pass unmodified, they would become (when extracted to C:\temp):




These are both invalid paths and an application can't create a file using them.

One question remained open, however: Do any legitimate use cases need the code branch we were planning to "amputate"? Such use case would include intentionally extracting a file to a location specified with full path on user's computer; which would be considered a vulnerability of equal severity as the issue we're fixing here. So we concluded that removing this branch is an acceptable approach, and wrote this single-instruction micropatch:

MODULE_PATH "..\AffectedModules\UNACEV2.DLL_2.6.0.0_32bit\UNACEV2.DLL"
VULN_ID 4852


 JUMPOVERBYTES 10 ; We remove mov and call


  mov eax, 0 ; making sure to proceed via the "absolute path" branch,
             ; not the "empty string" branch



When the micropatch is applied, extracting a malicious ACE archive results in a number of warnings as shows below, and files aren't extracted.

Here's a video showing our micropatch in action:


By micropatching this vulnerability in a 14-year old closed-source DLL we demonstrated how suitable in-memory micropatching is for quickly fixing a critical vulnerability, even when fixing it in source code is literally impossible.

One nice side-effect of micropatching a third-party DLL is that while our micropatch was targeted at WinRAR, it actually protects all products using this particular version of UNACEV2.DLL from a similar attack. The DLL will be patched no matter who loads it. If you come across one, do let us know!

As always, if you have our Agent installed and registered, this micropatch is already on your computer - and applied to WinRAR whenever it loads UNACEV2.DLL (enable popups via 0patch Console to see when that happens). Otherwise, you can register a free 0patch account and install 0patch Agent to get this micropatch applied to your WinRAR.

Nevertheless - if you don't need support for ACE format in WinRAR, we recommend you update WinRAR to a fixed version (currently 5.70 beta 1). There may be other vulnerabilities there in UNACEV2.DLL which are more likely to be found now that it's been put in the spotlight.



✇ 0patch Blog

Microsoft Edge Uses a Secret Trick And Breaks Internet Explorer's Security

By: Mitja Kolsek
Edge Decided To Use An Undocumented Security Feature.
Internet Explorer Didn't Get The Memo.


by Mitja Kolsek, the 0patch Team

Five days ago, security researcher John Page published details and a proof-of-concept for a vulnerability in Internet Explorer that he had previously reported to Microsoft but received a response that "...a fix for this issue will be considered in a future version of this product or service."

In this article we will explain why we think Microsoft has underestimated the severity of this vulnerability, how one Microsoft product inadvertently sabotaged another Microsoft product's security, and what you can do to protect yourself while waiting for Microsoft to fix this bug.

The Vulnerability

The vulnerability is a classic: an XML External Entity ("XXE") attack can  be mounted in Internet Explorer using an XML block inside a MHT file. As a result, a user opening such MHT file will have one or more of their local files sent to attacker's web server. Similar XXE vulnerabilities have been found in hundreds of products before, and exploited for exfiltrating local files.

The attack is nicely demonstrated in John's video, where you can see the user downloading an MHT file with Edge and then opening it with Internet Explorer - resulting in their system.ini file being sent to attacker's server.

But... What About The Mark-Of-The-Web?

After watching John's video we tried to reproduce the issue, and a Windows 7 machine was at hand. We downloaded the MHT file with Internet Explorer, then double-clicked it, and... nothing. Process Monitor showed that system.ini was in fact read, but it didn't get sent to the remote server. Then we created the same MHT file locally instead of downloading it, and the exploit worked.

This looked like a classic "mark-of-the-web" situation: when a file is obtained from the Internet, well-behaved Windows applications like web browsers and email clients add a mark to such file in form of an alternate data stream named Zone.Identifier, containing a line ZoneId=3. This allows other applications to know that the file has come from an untrusted source - and should thus be opened in a sandbox or an otherwise limited environment.

Indeed, Internet Explorer does put a mark-of-the-web on the downloaded MHT file, and when rendering that file, notices said mark and decides not to make the request to the remote server. Deleting the mark from the file effectively turns the file into a "trusted" file and the exploit works.

Okay, this is all good and well, but why does the exploit work with a downloaded file on John's video?

To answer that, we moved our analysis over to Windows 10 in order to replicate John's demo more closely. We downloaded the MHT file, this time with Edge, and opened it locally with Internet Explorer: Surprise! The exploit worked, just like in the demo!

But why? Does Edge not put the mark-of-the-web on downloaded files, or does it do it differently and somehow confuses Internet Explorer? That would be a serious flaw.

It was time for some differential analysis. We had two MHT files downloaded from the same location; one downloaded with Internet Explorer (msie-xss-0day-1.mht) and the other with Edge (msie-xss-0day-2.mht). Same content, when opened with an editor, but slightly different Zone.Identifier data streams:





It turned out Edge does, unsurprisingly, put a mark-of-the-web on the file - but apparently stores some additional data there compared to Internet Explorer. Could this additional data somehow confuse Internet Explorer? It was easy to check; we copied the content of the Zone.Identifier stream from file #1 to file #2 and saved it.

Result: no difference; file #2 was still able to launch the exploit.

What Now?

So we had two identical files with identical data streams, and one of them executed the exploit while the other one didn't. After a bit of frustration, mixed with wild fantasies of Internet Explorer somehow remembering its downloaded files and tracking them on the computer, our Twitter buddy Eric Lawrence proposed checking the permissions on these files.

That was a silly proposal, of course, as obviously they would have identical permissions, inherited from the Downloads folder they were stored in. Obviously.

Wait, what?

Permissions on the file downloaded
with Internet Explorer
Permissions on the file downloaded
with Edge

Strange. Edge seemed to have added two entries to the downloaded file's AC, both for some SIDs that Windows can't or won't translate to a friendly name:


To see whether these ACL entries affected the exploit's execution in Internet Explorer, we decided to delete them one by one and retry the exploit. It turned out that removing the second one, SID S-1-15-2-*, resulted in exploit not working anymore. How weird: what looks like Read access permission (see the (R) above) for some unknown user account prevents the exploit from working.

Not finding anything useful about this SID on the Internet (although the AppContainer SID looks related)*, we turned to Process Monitor hoping to see some interesting differences between the execution of both files. And differences we have found, the most obvious being that Internet Explorer got a lot of ACCESS DENIED's on Edge-downloaded MHT file (the one where exploit was working), while it got none on Internet Explorer-downloaded MHT file.

Low Integrity iexplore.exe process gets ACCESS DENIED errors on opening the Zone.Identifier stream

Remember that Internet Explorer works with multiple iexplore.exe processes, some running with Medium Integrity and some with Low Integrity (i.e. in a sandbox). Low Integrity processes are not allowed to write or change files with higher integrity even if user account they're running as otherwise has permissions to do that. They are allowed to read files with higher integrity though.

All the ACCESS DENIED's were happening to Low Integrity iexplore.exe processes on read access, and that was clearly caused by the mysterious S-1-15-2-* SID we had found above because removing that ACL entry from file's permissions also removed all ACCESS DENIED's.

It became clear that we have stumbled upon an undocumented Windows 10 feature, a flag that can be set on a file to prevent Low Integrity processes from even reading its content or its attributes. We theorize that Edge is using this feature to further tighten the security of saved files against malicious code executing in its Low Integrity sandbox. Nothing wrong with that.

But why does this flag help the exploit to execute in Internet Explorer? We looked at some of the ACCESS DENIED events and noticed that two of them occurred on attempting to read MHT file's Zone.Identifier data stream. Remember the mark-of-the-web discussed above? It's stored in this data stream - and Internet Explorer was unable to read it. What if failing to read it made Internet Explorer assume that there is no mark-of-the-web on the file (which is true for all locally created files), resulting in treating it as a "trusted" file?

It turned out that's exactly what happened. In order to understand why, we need to dive into the code. The stack trace on one of the ACCESS DENIED events includes a call to a function with an extremely interesting name: GetZoneFromAlternateDataStreamEx.

The ACCESS DENIED event includes a call to GetZoneFromAlternateDataStreamEx

A quick look at the function in IDA, combined with observing its calls in WinDbg, tells us it takes two arguments: (1) path to a file, and (2) pointer to the Zone Id value. It tries to read the file's Zone.Identifier stream and parse the ZoneId value from it, storing it to the provided address if found. Its return value is the error code, typically 0 if the stream was found and read, or 80070002 ("File not found") if the stream doesn't exist.

GetZoneFromAlternateDataStreamEx resides in urlmon.dll and is only called from one place. That call, however, is not followed by any checking of the error code returned by the function. The calling code simply assumes that if GetZoneFromAlternateDataStreamEx can't read the Zone Id from the file for whatever reason, the file must be "trusted". This logic was probably correct until the new feature we had discovered above got introduced.

Namely, when the MHT file permissions include the mysterious S-1-15-2-* SID, GetZoneFromAlternateDataStreamEx gets an ACCESS DENIED on attempting to read the file's Zone.Identifier stream, stores no Zone Id, and returns the error code 80070005 ("Access denied"). The calling code, not caring about the error, understands this as the file not having a mark-of-the-web, subsequently allowing it to make a request to attacker's server.

See the irony here? An undocumented security feature used by Edge neutralized an existing, undoubtedly much more important feature (mark-of-the-web) in Internet Explorer.

This is clearly a significant security issue, especially since the attack can be further improved from what was originally demonstrated. We have found that:

  1. the malicious MHT file doesn't have to be downloaded and manually opened by the user - just opening it directly from Edge can be made to work as well;
  2. the exploit can be enhanced so that it works more silently, and extracts many local files using a single MHT file.

On the upside, only Edge users are at risk. No other leading web browsers and email clients we've tested are using the undocumented security flag on the downloaded files, which effectively blocks the exploit.

The Micropatch

While we believe Microsoft will update their original severity assessment of this issue and provide a fix for it, we wanted to give our users a micropatch to allow them to protect themselves. Namely, published 0days often start getting exploited, especially when no vendor fix is available.

Let's look at the code that calls GetZoneFromAlternateDataStreamEx and ignores the error returned by it.

The code calling GetZoneFromAlternateDataStreamEx

Fixing this seems pretty straight-forward: we need to add some error checking immediately after the call to GetZoneFromAlternateDataStreamEx to detect if the error was 80070005 ("Access denied"), and if so, set Zone Id to 3 ("untrusted"). This will effectively make Internet Explorer aware of Edge's security feature. Such is the source code of our micropatch for Windows 10 version 1803:

MODULE_PATH "..\AffectedModules\urlmon.dll_11.0.17134.648_32bit\urlmon.dll"
; Windows 10 version 1803
VULN_ID 5000


 PATCHLET_OFFSET 0x00034507 ; Injecting after the call to GetZoneFromAlternateDataStreamEx


   cmp eax, 0x80070005 ; did we get ACCESS DENIED on reading the MOTW?
   jne pass            ; nope, all is OK
   ; we got ACCESS DENIED
   mov dword [ebp-4], 3   ; we set the ZoneID to 3 if we had ACCESS DENIED


Here's  video if you'd like to see how the micropatch affects the exploit.

As always, if you have 0patch Agent installed and registered, this micropatch is already on your computer - and applied to urlmon.dll in Internet Explorer and other processes loading it. "Why not just Internet Explorer?" you might ask. Well, while we now know that Internet Explorer is vulnerable, there are other products using urlmon.dll, and in case some of them happen to be using its (flawed) logic we'll automatically fix them as well.
If you don't have the 0patch Agent yet, you can register a 0patch account and install it to get this micropatch applied.

Following our guidelines on which patches to provide for free, this micropatch affects many home and education users, and is therefore included in both FREE and PRO 0patch license until Microsoft provides an official fix. After that the micropatch will only be included in the PRO license.

We are currently providing this micropatch for fully updated:
  1. Windows 10 version 1803
  2. Windows 10 version 1809
  3. Windows 10 version 1709 [added on 4/18/2019]
0patch PRO users are welcome to request porting this micropatch to other Windows 10 versions at [email protected].

* [Update 4/18/2019] James Forshaw of Google Project Zero has subsequently noted the mysterious undocumented SIDs are "capability and group SIDs for the Microsoft.MicrosoftEdge_8wekyb3d8bbwe package." We trust James so let's put it here as some day this will help someone researching a similar issue. You're welcome ;)

[Update 4/23/2019] User itman on a Wilders Security Forums thread about this issue has provided a lot of useful additional information on said SIDs in multiple posts that are well worth reading.We generally agree with itman on everything stated there (including our then "clueles[ness] to the fact that Edge in essence always operates in equivalent IE11 EPM mode,"), except on the risk introduced by modifying "code that is loaded by multiple Win system processes". While urlmon.dll is in fact being loaded by many processes, not all are using it for determining the Zone identifier (the DLL has many other exported functions). For those that are, and are faced with the same situation of being unable to read the Zone.Identifier stream due to running with Low Integrity or in a different AppContainer, we believe our added code that checks for errors has a net positive effect as it prevents such apps from overly trusting downloaded files.


✇ 0patch Blog

Another Task Scheduler 0day, Another Task Scheduler Micropatch (The SandboxEscaper Saga)

By: Mitja Kolsek
Backward Compatibility is Hard, and so is Stacked Impersonation

by Simon Raner and Mitja Kolsek, the 0patch Team

[Update 6/12/2019: Yesterday's Windows Updates include a fix for this vulnerability, 12 days after our micropatch has been released. The issue was assigned CVE-2019-1069.]

Last August we issued a micropatch for a local privilege escalation 0day in Task Scheduler, published by SandboxEscaper. The vulnerability allowed a local attacker on a Windows machine to change permissions of any chosen file, including system executables, such that the attacker would subsequently be able to modify that file. This obviously allowed for privilege escalation, although many system files can't be changed even with suitable permissions either due to being owned by TrustedInstaller or due to being in use. Nevertheless, at least one such file can always be found.

Fast forward to last week. SandboxEscaper has dropped three Windows 0days, one of which is again a local privilege escalation in Task Scheduler. We tested it and it worked on a fully patched Windows 10 machine. According to Will Dormann of CERT/CC, the exploit "functions reliably on 32- and 64-bit Windows 10 platforms, as well as Windows Server 2016 and Windows Server 2019. While Windows 8 still contains this vulnerability, exploitation using the publicly-described technique is limited to files where the current user has write access, in our testing. As such, the impact on Windows 8 systems using the technique used by the public exploit appears to be negligible. We have not been able to demonstrate the vulnerability on Windows 7 systems."


Analysis always starts with reproducing the POC.  It comes as a Windows executable that takes two arguments, username and password of a local low-privileged user. Let's see what it does when we run it as a low-privileged user test:


C:\Temp\Vuln-5172_bearlpe\Exploit>icacls "c:\Windows\system32\drivers\pci.sys"
c:\Windows\system32\drivers\pci.sys NT AUTHORITY\SYSTEM:(I)(F)

Successfully processed 1 files; Failed processing 0 files

C:\Temp\Vuln-5172_bearlpe\Exploit>polarbear.exe test test
SUCCESS: The parameters of scheduled task "bear" have been changed.
SUCCESS: The parameters of scheduled task "bear" have been changed.

C:\Temp\Vuln-5172_bearlpe\Exploit>icacls "c:\Windows\system32\drivers\pci.sys"
c:\Windows\system32\drivers\pci.sys NT AUTHORITY\SYSTEM:(Rc,S,X,RA)
                                    NT AUTHORITY\SYSTEM:(I)(R,W,D,WDAC,WO)
Successfully processed 1 files; Failed processing 0 files

Obviously, the POC was able to change permissions on pci.sys. Furthermore, in contrast to the last year's Task Scheduler 0day we had micropatched, this one also changed the ownership of the target file; not being owned by TrustedInstaller any more, pci.sys could be modified freely by the attacker.

Its operation is fairly simple; when launched with credentials of a low-privileged user test with password test, the POC performs these steps (as seen from its source code):

  1. Copy file bear.job to c:\windows\tasks\bear.job
  2. Execute schtasks.exe /change /TN \"bear\" /RU test /RP test
    (This instructs Task Scheduler to take bear.job created above and create a new scheduled tasks - resulting in a new file c:\windows\system32\tasks\Bear. Note that a legacy schtasks.exe from Windows XP is used, which uses legacy RPC interface for that.)
  3. Delete  c:\windows\system32\tasks\Bear.
  4. Create a hard link c:\windows\system32\tasks\Bear, pointing to system file c:\windows\system32\drivers\pci.sys.
  5. Again, execute schtasks.exe /change /TN \"bear\" /RU test /RP test
    (This time, since the task already exists, Task Scheduler sets full permissions and ownership for user test on the task file. Since the task file is actually a hard link to pci.sys, it apparently changes permissions and ownership on that file.)

Observing operations against c:\windows\system32\tasks\Bear with Process Monitor during POC execution told us more:

Apparently, there were two SetSecurityFile operations performed on the file, with the following call stacks:

Both of these SetSecurityFile operations stem from function _SchRpcSetSecurity in schedsvc.dll, and based on our prior experience with Task Manager's impersonation issues we assumed this function was responsible for calling SetSecurityInfo without proper impersonation. Next step: debugger.

We set a breakpoint at _SchRpcSetSecurity and traced its execution towards the call to SetSecurityInfo - its first call being made from function SetJobFileSecurityByName. Therein, before the call to SetSecurityInfo was made, we checked the thread's access token, expecting it to be not-impersonated.

0:030> !token
TS Session ID: 0
User: S-1-5-18 

 14 0x000000012 SeRestorePrivilege                Attributes - Enabled
Impersonation Level: Impersonation

But surprise! The token was impersonated. Only the user it was impersonating was not the attacker's user test, but Local System (S-1-5-18). What was going on?

Was function _SchRpcSetSecurity broken and incorrectly impersonated the caller? We found an impersonation call in it and it looked okay. Clearly we needed to understand this function better, and it's natural to start with the documentation when available. The specification of function  _SchRpcSetSecurity describes its behavior in detail, including this step that is relevant for our analysis (the path parameter being the Bear file in our case.):

This makes sense: if someone asks Task Scheduler to change permissions on a task file, said someone should have write permissions on that file. A typical use case for this is when the user who created a task subsequently decides to have that task executed as some other user, which requires that user to have at least read access to the task file. And this is also the use case triggered by the schtasks.exe's /change option, where /RU and /RP parameters specify the "run-as" user's credentials.

We then reverse engineered _SchRpcSetSecurity to find where this security check is implemented and find out why it doesn't work as specified.

Except we found that it does work as specified: the code attempts to open the Bear file with permissions to change its DACL and its owner - and if that succeeds, actually does that. Which would work great if only it was impersonating the low-privileged attacker instead of Local System (who obviously can do all that on the linked-to pci.sys file).

So why didn't the function impersonate the attacker? After some head-scratching, we remembered that this attack only works with the legacy schtasks.exe, and not with the new one. Could it be that the old schtasks.exe was calling some other RPC function than _SchRpcSetSecurity, which then in turn called _SchRpcSetSecurity via RPC? While still paused inside the _SchRpcSetSecurity call, we looked at other threads in the same process - and found an interesting one with this call stack:

0:037> k
ChildEBP RetAddr 
08d1dbf4 775e058a ntdll!KiFastSystemCallRet
08d1dbf8 76e35bde ntdll!NtAlpcSendWaitReceivePort+0xa
08d1dc88 76e359f4 RPCRT4!LRPC_BASE_CCALL::DoSendReceive+0xde
08d1dca4 76e156dc RPCRT4!LRPC_CCALL::SendReceive+0x54
08d1e118 6ff9fa7a RPCRT4!NdrClientCall2+0xa4c
08d1e130 6ffbd524 taskcomp!SchRpcSetSecurity+0x24
08d1e17c 6ffa8536 taskcomp!RpcSession::SetSecurity+0x25
08d1ecd0 6ffa8669 taskcomp!CompatibilityAdapter::Register+0xef4
08d1ed00 6ffb13a9 taskcomp!CompatibilityAdapter::RegisterWithRetry+0x28
08d1f1f4 76e67544 taskcomp!SASetAccountInformation+0x4a9
08d1f21c 76e1665d RPCRT4!Invoke+0x34
08d1f688 76e17399 RPCRT4!NdrStubCall2+0x86d
08d1f6a4 76e48712 RPCRT4!NdrServerCall2+0x19
08d1f6e4 76e4832b RPCRT4!DispatchToStubInCNoAvrf+0x52
08d1f758 76e47d6f RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x17b
08d1f78c 76e36b6f RPCRT4!RPC_INTERFACE::DispatchToStub+0x8f
08d1f7f4 76e37e4d RPCRT4!LRPC_SCALL::DispatchRequest+0x2ef
08d1f884 76e37915 RPCRT4!LRPC_SCALL::HandleRequest+0x37d
08d1f8d0 76e36501 RPCRT4!LRPC_ADDRESS::HandleRequest+0x325
08d1f9a8 76e324e6 RPCRT4!LRPC_ADDRESS::ProcessIO+0x211
08d1f9e8 775827f8 RPCRT4!LrpcIoComplete+0xa6
08d1fa20 775819da ntdll!TppAlpcpExecuteCallback+0x188
08d1fbe8 74d7e529 ntdll!TppWorkerThread+0x3da
08d1fbf8 775a9ed1 KERNEL32!BaseThreadInitThunk+0x19
08d1fc54 775a9ea5 ntdll!__RtlUserThreadStart+0x2b
08d1fc64 00000000 ntdll!_RtlUserThreadStart+0x1b

Hmm, a thread in taskcomp.dll, which was itself triggered via an RPC call (as suggested by RPCRT4!Invoke) called a function named SchRpcSetSecurity, which invoked another RPC call (as suggested by RPCRT4!NdrClientCall2), and was now waiting for it to return. A few debugging sessions later, we could confirm that this is indeed what is happening: the legacy schtasks.exe makes a RPC call to a legacy RPC endpoint SASetAccountInformation implemented in taskcomp.dll, which implements the old task scheduler instructions with RPC calls to the new ones implemented in schedsvc.dll, such as SchRpcRegisterTask and SchRpcSetSecurity.

Our focus thus turned to taskcomp.dll. Namely, RPC calls can be stacked: process A can RPC-call process B, and then the code processing said call in process B can further RPC-call process C. In our case, schtasks.exe (running as attacker) calls RPC endpoint taskcomp!SASetAccountInformation in Task Scheduler's process svchost.exe (running as Local System), which in turn calls RPC endpoint schedsvc!_SchRpcSetSecurity in the same svchost.exe (still running as Local System). When the latter impersonates its caller, it actually impersonates the access token of the thread in taskcomp.dll that called it, and if that thread had previously impersonated its own caller (i.e., attacker), the final impersonated token would also be attacker's. However, taskcomp.dll does not impersonate its caller; it impersonates self (Local System) to enable the SeRestorePrivilege privilege that is needed for it to set DACL and ownership on any file:

This impersonation breaks the tie with attacker's identity, and causes the subsequently executed schedsvc!_SchRpcSetSecurity to believe it was Local System, not the attacker, who requested the change of DACL and owner on pci.sys. It was time to patch.


Correcting the behavior of someone else's code in a complex environment is always tricky, and legacy support + task scheduling = complex, we believe it was actually an error to impersonate self in taskcomp.dll instead of impersonating the client. The latter would in fact allow the security check in schedsvc!_SchRpcSetSecurity to perform correctly and work as intended on a regular file as well as on a hard-linked system file (correctly failing when invoked by a low-privileged user).

We therefore decided to replace self-impersonation with client-impersonation, and to do that, we removed the call to ImpersonateSalfWithPrivilege and injected a call to RpcImpersonateClient in its place.

We wrote a micropatch for this and tested it.

The POC still worked.

It turned out that there was another RPC call to SchRpcSetSecurity in taskcomp.dll, which got called when the first one was unsuccessful:

The call stack was:

0:005> k
ChildEBP RetAddr
044ffc20 6ff9a3dd taskcomp!CompatibilityAdapter::

044ffc60 6ff9a2a4 taskcomp!JournalReader::HandleWaitTimer+0x11d
044ffef0 74d7e529 taskcomp!CompatibilityAdapter::MonitorThread+0x104
044fff00 775a9ed1 KERNEL32!BaseThreadInitThunk+0x19
044fff5c 775a9ea5 ntdll!__RtlUserThreadStart+0x2b
044fff6c 00000000 ntdll!_RtlUserThreadStart+0x1b

It looked like some monitoring thread was used for getting the job done when the original call failed, but this thread was not called via RPC, and client impersonation could not be used there. We therefore decided on a more drastic approach and simply amputated the call to SetSecurity.

After that, we got the desired behavior: The legacy schtasks.exe was behaving correctly when creating a new task from a job file, and when setting a "run-as" user for an existing task that the user was allowed to change permissions on. On the other hand, the hard link trick no longer worked because the Task Scheduler process correctly identified the caller and determined that it doesn't have sufficient permissions to change DACL or ownership on a system file. Since we didn't even touch schedsvc.dll, the new (non-legacy) Task Scheduler functionality was not affected at all.

With our micropatch in place, re-launching the POC and observing the Bear task file in Process Monitor only showed two CreateFile operations from SchRpcSetSecurity's security check described above, and both ended with an ACCESS DENIED error due to correct impersonation.

This is the source code of our micropatch for 32bit Windows 10 version 1809:

;Micropatch for taskcomp.dll version 10.0.17763.1
MODULE_PATH "..\AffectedModules\taskcomp.dll_10.0.17763.1_x86\taskcomp.dll"
VULN_ID 5172

 PIT rpcrt4.dll!RpcImpersonateClient
 JUMPOVERBYTES 16 ; we skip the call to ImpersonateSelfWithPrivilege

  mov dword [ebp-0b20h], 0 ; token (set to 0 to force the ImpersonateSelfWithPrivilege
                           ; destructor to call RpcRevertToSelf)
  push 0                   ; Impersonating the client that made the request
  call PIT_RpcImpersonateClient


 JUMPOVERBYTES 5 ; we skip the call to [email protected]

  add    esp, 0ch       ; 3 x pop
  mov eax, 00000000h   ; simulate that [email protected]() function
                       ; returned 0 (as on successfull call)


And here it is in action:

As always, if you have 0patch Agent installed and registered, this micropatch is already on your computer - and applied to taskcomp.dll in your Task Scheduler service. If you don't have the 0patch Agent yet, you can register a 0patch account and install it to get this micropatch applied.

Following our guidelines on which patches to provide for free, this micropatch affects many home and education users, and is therefore included in both FREE and PRO 0patch license until Microsoft provides an official fix. After that the micropatch will only be included in the PRO license.

We are currently providing this micropatch for fully updated:
  1. Windows 10 version 1809 32bit
  2. Windows 10 version 1809 64bit
  3. Windows Server 2019
0patch PRO users are welcome to request porting this micropatch to other Windows 10 or Server versions at [email protected]. (Note that Windows 8, Windows 7, and their Server counterparts 2012 and 2008 don't seem to be affected.)


One final question: Does the attacker really need a local user's password?

We seriously doubt that. While running the legacy schtasks.exe with an incorrect password via argument /RP results in an error, the documentation for IScheduledWorkItem::SetAccountInformation method (which actually gets called by legacy schtasks.exe) states: "If you set the TASK_FLAG_RUN_ONLY_IF_LOGGED_ON flag, you may also set pwszPassword to NULL for local or domain user accounts." We haven't tested this but it sounds reasonable that for "run only if logged on" tasks a password would not be needed. Since attacker's goal is not to have the task executed but to have Task Scheduler change permissions on a target file, we believe executing the attack should also be possible without knowing any password.


Simon Raner

✇ 0patch Blog

Micropatching Keeps Windows 7 and Windows Server 2008 R2 Secure After Their End-Of-Support

By: Mitja Kolsek
Becoming an Adoptive Parent For Abandoned Windows

by Mitja Kolsek, the 0patch Team

Hello people, it's nice to step out for a moment and see the daylight. Those of you following us have noticed our near radio silence in the past months. To stop you from worrying I'd like to just quickly update you all on what's going on inside our walls (spoiler: a lot) and what our plans are (spoiler: big).

As you know, Windows 7 and Windows Server 2008 R2 are reaching their end-of-support on January 14 next year, which is causing a lot of headaches for people and companies who are entirely happy with the way these OSs work, or have compatibility requirements preventing them from upgrading. If they want to keep receiving security fixes, their options are: (a) to upgrade to Windows 10 and a newer server version, or (b) to buy Extended Security Updates from Microsoft (conditions apply, and 3rd party patch management solutions cannot be used for delivery).

NetMarketShare shows that last month, 5 months before end-of-support, 30% of desktop OSs were running Windows 7. With the current upgrading trend, we can safely forecast that the number of Windows 7 machines on February 11, 2020 (the first Patch Tuesday to exclude them) will be approximately somewhere between huge and vast. There are few public stats on how Windows Server 2008 R2 is doing but judging from what our users are saying, it's not going to get extinct anytime soon.
You see where we're going with this. Back in January 2018, we at 0patch "security-adopted" Microsoft Office Equation Editor, a program integrated into Microsoft Word with which scientists, teachers and students had written millions of equations. They were all suddenly left without a way to edit their equations when Microsoft decided to delete Equation Editor from their computers.

What we did was create micropatches for all known Equation Editor vulnerabilities and made instructions for users to bring back Equation Editor on their computers so they could continue using it while keeping Office regularly updated with Microsoft's security patches.

But that was just a trial run for becoming an adoptive parent of a vendor-abandoned product. This time we're going bigger: we're going to security-adopt Windows 7 and Windows Server 2008 R2 for those of you who want to keep them patched after their official security updates have dried out.

What does this mean, exactly?

It means that after the last official security update has been issued for Windows 7 and Windows Server 2008 R2 in January 2020, we'll start doing the following:

  1. Each Patch Tuesday we'll review Microsoft's security advisories to determine which of the vulnerabilities they have fixed for supported Windows versions might apply to Windows 7 or Windows Server 2008 R2 and present a high-enough risk to warrant micropatching.
  2. For the identified high-risk vulnerabilities we'll inspect Windows Updates for supported Windows versions (e.g., Windows 10) to confirm whether the vulnerable code that was fixed in Windows 10 is actually present on Windows 7 or Windows Server 2008 R2. (For all intents and purposes, such vulnerabilities will be considered 0days for these OSs.)
  3. If the high-risk vulnerable code is found to be present on Windows 7 or Windows Server 2008 R2, we'll start a process of obtaining a proof-of-concept (POC) for triggering the vulnerability. Sometimes a POC is published by security researchers soon after the official vendor fix is out (and sometimes even before); other times we can get one from our partner network or threat intelligence sources; occasionally researchers share a POC with us privately; and sometimes we have to create a POC ourselves by analyzing the official patch and working our way out towards the input data that steers the execution to the vulnerability.
  4. Once we have a POC and know how the vulnerability was fixed by the people who know the vulnerable code best (i.e., Microsoft developers), we'll port their fix, functionally speaking, as a series of micropatches to the vulnerable code in Windows 7 and Windows Server 2008 R2, and test them against the POC. After additional side-effect testing we'll publish the micropatches and have them delivered to users' online machines within 60 minutes. (Which by the way means that many Windows 7 and Windows Server 2008 R2 will be patched sooner than those with still-supported Windows versions where organizations will continue to prudently test Windows updates for days or weeks before having them applied to all computers.)

We expected you might have questions at this point; please see our FAQ about Windows 7 and Windows Server 2008 R2 Post-End-of-Support Security Micropatches

Okay - but what are we so busy with now? A lot of things:
Firstly, in order for large organizations to be able to use 0patch efficiently, we're developing a central management service (think WSUS for 0patch, but nice and fast) which will allow admins to organize computers in groups and apply different policies to these groups. Admins will thus be able to set up "testing" groups where new micropatches will be applied immediately, and subsequently have them applied to the rest of their computers with a few clicks (and of course, without users ever noticing anything). Naturally they'll also be able to un-apply any micropatches just as easily and quickly should they choose to. There will be alerts, graphs, reports, and drill-downs, and the very next step will be an on-premises version of 0patch server which so many organizations are asking for.

Secondly, we're growing our team: things are buzzing in our 0patch bootcamp and a nice side effect of passing one's knowledge onto others is that one has to neatly organize and document it. Consequently, adding further new members to the team afterwards will be even smoother and quicker.

Lastly, we're enhancing our reversing, patch analysis, vulnerability analysis, micropatch development and micropatch porting processes with new tools and techniques. Suffice to say that we've never had as many disassemblers, debuggers, decompilers, plugins and concurrently opened reversing projects running as we have now. But the thing I'm personally most excited about is our introduction of symbolic execution in micropatch creation, verification and porting processes. We've been aiming for eventual formal verification of our micropatches since the beginning and we're finally working on that. But not only that: symbolic execution and emulation will help us avoid errors sooner during micropatch development and allow us to perform unit testing against micropatched code even before we have a POC. Goosebumps!

This concludes our news from the 0patch lab. If you're interested in getting early access to 0patch central management (in November), or have any questions about our service, please consult Frequently Asked Questions or send an email to [email protected].


✇ 0patch Blog

Micropatching a Workaround for CVE-2020-0674

By: Mitja Kolsek
A Kill Switch for Vulnerable jscript.dll

by Mitja Kolsek, the 0patch Team

Last Friday, Microsoft published an advisory about a remotely exploitable memory corruption vulnerability (CVE-2020-0674) that was reported to them by Qihoo 360 as being exploited in the wild. These attacks were reportedly limited so Microsoft decided not to rush with issuing a patch but will rather provide one as part of February's Patch Tuesday. They did, however, provide a workaround.

Because the provided workaround has multiple negative side effects, and because it is likely that Windows 7 and Windows Server 2008 R2 users without Extended Security Updates will not get the patch at all (their support ended this month), we decided to provide a micropatch that simulates the workaround without its negative side effects.

The vulnerability is in jscript.dll, which is the scripting engine for legacy JScript code; note that all "non-legacy" JScript code (whatever that might be), and all JavaScript code gets executed by the newer scripting engine implemented in jscript9.dll.

Microsoft's workaround comprises setting permissions on jscript.dll such that nobody will be able to read it. This workaround has an expected negative side effect that if you're using a web application that employs legacy JScript (and can as such only be used with Internet Explorer), this application will no longer work in your browser.

There also several other negative side effects:

Microsoft's advisory states that the provided workaround will have to be reverted when they issue a patch for jscript.dll. However, note that some additional side effects may result from changing the ownership on jscript.dll (from TrustedInstaller to the user you're implementing the workaround as).

Test Case

Finding a test case that triggers the loading of jscript.dll was not difficult - Google Project Zero has one published in an advisory from November last year. (It won't be at all surprising if the vulnerability at hand is either a clone of that one, or a bypass for its patch - but we'll know soon enough.)

So we took Google's example, simplified it to only cause the loading of jscript.dll for executing a single alert call. Note the important part is to specify JScript.Encode as language. (By the way, read the Wikipedia article on JScript.Encode for a primer on how to underestimate intelligent adversaries.)

 <meta http-equiv="X-UA-Compatible" content="IE=8"></meta>
<script language="Jscript.Encode">
 alert("jscript.dll was loaded");

The test was then simple: opening this file in IE without mitigation or patch should result in a popup saying "jscript.dll was loaded". With a patch, we would want the loading of jscript.dll to fail and consequently no popup to appear. Ideally, in a graceful manner without any ugly error messages or crashed processes.


Sabotaging some functionality is usually a simple thing to do with a micropatch: you locate the code that implements or initializes said functionality, and make it fail. This was a case here too.

We first used Process Monitor to locate the code in Internet Explorer which loads jscript.dll. This was trivial as Process Monitor records a call stack for every operation, and it was obvious that mshtml.dll causes the loading of jscript.dll through a call to CoCreateInstance.

lea     eax,[esp+3Ch]
xor     edi,edi
push    eax
push    offset MSHTML!_GUID_bb1a2ae1_a4f9_11cf_8f20_00805f2cd064 (631bf2a8)
push    1
push    edi
lea     eax,[esp+0B4h]
push    eax
call    dword ptr [MSHTML!_imp__CoCreateInstance (641c301c)]
mov     ebx,eax
test    ebx,ebx

When this code is reached as a result of rendering a Jscript.Encode script block, the first argument (the last one pushed to the stack) points to a ClassID f414c262-6ac0-11cf-b6d1-00aa00bbbb58, which instantiates a jscript.dll object.

Great, could we just sabotage this call and be done with it? Unfortunately not; this same function is being used for instantiating other objects as well, so we need to be selective here.

We decided to make a micropatch that checks, before the call to CoCreateInstance is made, whether its first argument equals f414c262-6ac0-11cf-b6d1-00aa00bbbb58, and if so, sabotages the call by setting its last argument (pvv) to NULL, causing CoCreateInstance to return error 0x80070057 (E_INVALIDARG). This has the same effect as making jscript.dll impossible to read.

But before settling with that, we wanted to check if there were any other ways in which a malicious web page could have code executed by jscript.dll. So we scanned the Registry for all ClassIDs associated with jscript.dll that were loadable via a script tag - and found Jscript.Compact to be such an alternative. So we made another HTML test file:

 <meta http-equiv="X-UA-Compatible" content="IE=8"></meta>
<script language="Jscript.Compact">
 alert("jscript.dll was loaded");

And sure enough, this one also executed the alert with jscript.dll.We therefore had to add another ClassID check to our micropatch, also preventing cc5bbec3-db4a-4bed-828d-08d78ee3e1ed from getting instantiated.

The final micropatch then became:

MODULE_PATH "..\Affected_Modules\mshtml.dll_11.0.17763.831_32bit\mshtml.dll"
PATCH_ID 1000004
VULN_ID 5897




  ; At this point, ClassID is stored at address pointed to by [esp+0ACh]
  ; If we want to sabotage the call, we put 0 at [esp+0ch] (argument ppv), which
  ; will cause error 0x80070057 (E_INVALIDARG)

  ; Compare ClassID with f414c262-6ac0-11cf-b6d1-00aa00bbbb58 (Jscript.Encode)
  cmp dword [esp + 0ACh], 0xf414c262
  jne skip1
  cmp dword [esp + 0ACh + 4h], 0x11cf6ac0
  jne skip1
  cmp dword [esp + 0ACh + 8h], 0xaa00d1b6
  jne skip1
  cmp dword [esp + 0ACh + 0Ch], 0x58bbbb00
  jne skip1
  mov dword [esp + 0xc], 0 ; Sabotage the call to CoCreateInstance by setting ppv to 0

 ; Compare ClassID with cc5bbec3-db4a-4bed-828d-08d78ee3e1ed (Jscript.Compact)
  cmp dword [esp + 0ACh], 0xcc5bbec3
  jne skip2
  cmp dword [esp + 0ACh + 4h], 0x4beddb4a
  jne skip2
  cmp dword [esp + 0ACh + 8h], 0xd7088d82
  jne skip2
  cmp dword [esp + 0ACh + 0Ch], 0xede1e38e
  jne skip2
  mov dword [esp + 0xc], 0 ; Sabotage the call to CoCreateInstance by setting ppv to 0


We ported this micropatch to the following platforms, both 32-bit and 64-bit:

  • Windows 7,
  • Windows 10 v1709,
  • Windows 10 v1803, 
  • Windows 10 v1809, 
  • Windows 10 v1903, [issued on 1/30/2020]
  • Windows 10 v1909, [issued on 1/30/2020]
  • Windows Server 2008 R2, 
  • Windows Server 2019 

If you're a 0patch user, you already have this micropatch downloaded to all your online computers with 0patch Agent, and - depending on your settings - already automatically applied to all processes using the Internet Explorer 11 engine for rendering content. This includes Internet Explorer (obviously), Microsoft Word, Microsoft Outlook, and a variety of other applications.

As all our micropatches, you can switch this micropatch on or off and have it instantly applied to, or removed from running applications - effectively making it a "kill switch" for jscript.dll.

If you're using other Windows versions or older Internet Explorer versions and are interested in having this micropatch ported to your systems, please contact us at [email protected].


Here's our micropatch in action:

Frequently Asked Questions

Q: Why would we apply your micropatch instead of Microsoft's recommended workaround?

Our micropatch is designed to avoid negative side effects of Microsoft's workaround (see above). It can also be easily reverted (un-applied) with a switch of a button without leaving any traces, while the workaround changes the ownership on jscript.dll.

Q: Will Microsoft provide a patch for CVE-2020-0674 to Windows 7 and Windows Server 2008 R2 users without Extended Security Updates?

We don't know but these systems are now officially out of support and Microsoft has historically only issued security patches for unsupported systems in extreme cases (e.g., the Shadow Brokers leak, or BlueKeep / CVE-2019-0708).

We at 0patch have committed to provide post-end-of-service security micropatches for Windows 7 and Windows Server 2008 R2 for three additional years, which is why we're also issuing this micropatch for these platforms. (Read FAQ for more information.)

Q: What will happen if I apply your micropatch, and then apply Microsoft's patch for CVE-2020-0674 when it comes out?

When Microsoft issues a patch for this vulnerability, we'll inspect it and decide whether to replace our current micropatch (which resides in mshtml.dll and disables jscript.dll entirely) with a more targeted micropatch in jscript.dll (which will only fix that vulnerability but keep jscript.dll available). It might happen that we do so on supported Windows platforms but keep the current micropatch on Windows 7 and Windows Server 2008 R2. This also depends on user feedback (i.e., whether our micropatch causes anyone problems).

In any case, you won't have to do anything - Microsoft's patch will have precedence over our micropatch.

Q: I suspect your micropatch is causing problems on my computer. What should I do?

Make a quick test: Disable 0patch Agent and execute your affected process - if the problem is still there, it's unlikely the cause of your problem is our micropatch. However, if your problem goes away, please report that to [email protected] and temporarily disable micropatches 402-405 on your 0patch Agent.

Users on the Enterprise plan can enable and disable individual patches centrally through 0patch Central.

Q: Are there any applications using jscript.dll directly (not though Internet Explorer browser component) that could still be used as attack vector?

We're aware of one - Windows Media Player (WMP) uses jscript.dll directly and will still be able to do so when our micropatch is applied. WMP allows displaying a remote web site when playing certain files but the user has to confirm a security warning for that. This was the reason we decided not to micropatch WMP as well.

Q: How can I deploy this micropatch in my organization's network?

Contact [email protected] for our Enterprise offering (including central management, setting patching policies, group management etc.). We'll set you up with some trial licenses and technical support for making your deployment smooth and quick.



✇ 0patch Blog

Letter To 0patch Users (February 10, 2020)

By: Mitja Kolsek

Subject: 0patch - What you need to know about Windows 7 and Windows Server 2008 R2 security micropatches

Dear 0patch user,

Thank you for putting your trust in 0patch to supply your computers with security micropatches. Tomorrow is the first Patch Tuesday when Windows 7 and Windows Server 2008 R2 systems that aren't registered for Microsoft's Extended Security Updates will not receive official Windows security patches, and instead depend on us to provide security micropatches for the most critical vulnerabilities.

We'd like to set your expectations and help you stay well-informed during our journey.

Whenever we become aware of a critical vulnerability affecting Windows 7 or Windows Server 2008 R2 (whether through Microsoft issuing a patch for it, or from any other source), we'll create an article for that vulnerability on our Support site (https://0patch.zendesk.com) that will provide information such as:

    - CVE ID
    - Our own risk assessment (with explanation)
    - Status of our micropatch (e.g., "in development", "waiting for test case", "issued")
    - Possible (and reported) side effects of our micropatch
    - Workarounds (for when micropatch is not available, or if you don't want to apply it)
    - Frequently asked questions
    - Links to our own and external articles related to this issue
    - Procedure for testing our micropatch (optionally)
    - Credits to people helping us with the micropatch

We will continually update these articles as new information gets available.

We will also start sending Patch Tuesday updates and alerts about issued micropatches to "0patch News" mailing list (newsletter) so we highly recommend you subscribe to it to know which vulnerabilities we have micropatched and whether we recommend applying any workarounds for issues we can't (yet) micropatch.

To subscribe to "0patch News", visit https://0patch.com/contact.html, provide your email address to the form on the right side, tick the "0patch Newsletter" box and press Subscribe.

We will make our best effort to provide users will timely, accurate, and actionable information for keeping their Windows 7 and Windows Server 2008 R2 systems as secure as possible.

Thank you again,

Mitja Kolsek
0patch co-founder
✇ 0patch Blog

Our First Weeks of Securing Windows 7 and Windows Server 2008 R2

By: Mitja Kolsek
A quick status update

by Mitja Kolsek, the 0patch Team

[Update 2/22/2020: More details on the exploit code for CVE-2020-0674 were published, making exploitation by new malicious actors more likely.]

Hi 0patch users and supporters around the globe!

With February 2020 Patch Tuesday we began our three-year journey of providing critical security micropatches for Windows 7 and Windows Server 2008 R2 to our users, who could not - or decided not to - use Microsoft's Extended Security Updates.

Status of Windows 7 and Windows Server 2008 R2 micropatches

This first Patch Tuesday brought a large number of security fixes for these platforms, and we've set up a status page for public tracking of our progress on providing associated micropatches, which you can always find at this address:

Status of Windows 7 and Windows Server 2008 R2 micropatches

As you know, it is not our goal to provide micropatches for all vulnerabilities fixed by Microsoft - instead, our goal is to provide micropatches for high-risk vulnerabilities: those that are likely to get exploited (e.g., because details are published), that allow for a remote attack (e.g., through visiting a malicious web page, or opening a malicious email or document). This doesn't mean we won't micropatch publicly detailed local privilege escalation issues, but they will have a lower priority.

Improved Micropatch for CVE-2020-0674

You will remember that after January Patch Tuesday, Microsoft issued an advisory about a remotely exploitable vulnerability in Scripting Engine CVE-2020-0674 that was detected as being used in the wild. There was no official patch from Microsoft and their workaround had some unpleasant side effects, so we stepped in and created a micropatch without such side effects. Both the workaround and our micropatch did prevent functioning of legacy JScript code, so any web page still using it (and we hear from our enterprise users that JScript is still very much alive in internal corporate web applications) would not work properly.

As expected, Microsoft fixed this issue with February Patch Tuesday, but not for Windows 7 and Windows Server 2008 R2 users without Extended Security Updates. In addition, the original reporters of this issue, a Chinese security company Qihoo 360, published a technical article which provided sufficient information about the vulnerability that anyone skilled in this game could easily reproduce it. The latter changed our risk assessment - before the exploitation was limited, but now anyone motivated can build an exploit and start targeting vulnerable Windows computers.

And there are at least as many vulnerable Windows computers out there as there are Windows 7 computers without Extended Security Updates.

So we reproduced the issue and traced the root cause to JScript function sort(), specifically when called using a sorting function, and its binary code implementation in function JsArrayFunctionHeapSort.  This function has changed significantly with February updates, but so have many, many others, and we know from previous analyses of jscript.dll that many of these changes are not security related. (One is impressed with how much development effort Microsoft continues to invest in this legacy scripting engine.)

While we understood what the root cause of the issue was and knew what had to be done to fix it, we did not find a sufficiently risk-free method of doing it, at least not yet, and thus decided on a compromise: we would remove the exploitable part of sort()'s functionality, effectively causing


to become


It was our assessment that this change should not have a significant impact on majority of web applications using JScript. (If any 0patch users do experience a significant impact, please contact [email protected]!)

Our primary target for this micropatch were Windows 7 and Windows Server 2008 R2 computers, for which we also revoked our initial "workaround" micropatch. However, we subsequently learned that February Windows Updates were causing severe problems for Windows 10 v1903/v1909 users, prompting many of them to likely delay or forgo applying of these updates. Since that would leave them vulnerable to CVE-2020-0674, we ported our micropatch to Windows 10 v1903/v1909 as well (and revoked the associated "workaround" micropatch).

Online Test For 0patch Users

Once we had micropatched this web-deliverable vulnerability, we were able to construct an online test for all our 0patch users to check whether the micropatch is getting properly applied. This is particularly important for Windows 7 and Windows Server 2008 R2 users, who need to have their computers fully updated in order for our post-end-of-service micropatches to apply.

The online test page is located here:


To use it, you have to visit it with Internet Explorer 11; Internet Explorer is the only browser using jscript.dll, and we only provided a micropatch for version 11 as this is the only still-supported version on Windows 7 and Server 2008.

Once you open the test page, you will see one of the following:

This means everything is okay; your computer is properly updated for 0patch, and 0patch has applied the micropatch for CVE-2020-0674 to your Internet Explorer, making you not-vulnerable.

This message indicates that our micropatch did not get applied. You may have not applied the January 2020 rollup update on your computer, or are using Internet Explorer version other than 11. Or, you may be on Extended Security Updates, in which case this test doesn't apply to you.

Go ahead, use this test and let us know ([email protected]) if our micropatch isn't getting applied.

What's Next?

Being that CVE-2020-0674 was the only remote code execution vulnerability with a published proof of concept, micropatching it was our priority. There are a couple of other issues in our status table that are already making us busy with either recreating a proof-of-concept or already analyzing the vulnerability, but there is one issue that stands out: the LNK vulnerability (CVE-2020-0729), which has "massive exploitation" written all over it. It also reportedly has a proof-of-concept successfully reproduced in the security research community, so once those details are available, we'll have to respond quickly to protect our users.



✇ 0patch Blog

Micropatching Unknown 0days in Windows Type 1 Font Parsing

By: Mitja Kolsek
We can't fix what we don't know, but we can block exploitation in a highly convenient way

by Mitja Kolsek, the 0patch Team

Three days ago, Microsoft published a security advisory alerting about two vulnerabilities in Windows font parsing, which were noticed as being exploited in "limited targeted Windows 7 based attacks." These vulnerabilities currently don't have an official vendor fix.

As we've done before in a similar situation, we decided to provide our users with a micropatch to protect themselves against these vulnerabilities in a "0patch fashion", i.e., completely automatically and without disturbing users even in the slightest.

Our micropatch is currently available for fully updated Windows 7 64-bit and Windows Server 2008 R2 without Extended Security Updates (ESU), which means with January 2020 Windows Updates installed. This provides protection for our users who continue using these Windows versions but were unable or unwilling to obtain ESU, and are now, somewhat ironically, the only Windows users with a patch for these vulnerabilities.

Of course our next step will be to port the micropatch to other affected Windows versions including Windows 7 and Windows Server 2008 R2 with ESU, Windows 8.1 and Windows Server 2012, both 32-bit and 64-bit. We will likely not port the micropatch to Windows 10 and newer Servers as the risk from these vulnerabilities is much lower there.

[Update 4/3/3020: We ported this micropatch to Windows 7 and Windows Server 2008 R2 with Extended Security Updates applied.]

What Does Microsoft's Advisory Tell Us?

Microsoft's advisory provides scarce details, for obvious reasons, but here's what we think is important:

  1. Both vulnerabilities are in font parsing, which provides powerful attack vectors such as just viewing font files in Windows Explorer, or opening a malicious document. We initially thought that Internet Explorer could be an attack vector too while visiting a malicious web site that would provide its own malformed font to the browser. However, we were unable to find any confirmation that Adobe Type 1 PostScript fonts could be provided by a web site at all, and therefore consider Internet Explorer unlikely to be an attack vector. Other major browsers like Firefox or Chrome are certainly not attack vectors for these vulnerabilities. In addition, Microsoft's advisory states that Outlook preview is not an attack vector.
  2.  On Windows systems before Windows 10 v1709 and their server counterparts, font parsing is performed in the kernel, which provides immediate code execution with highest privileges, potentially even from a sandboxed document-viewing application. On Windows 10 v1709 and later, and their server counterparts, font parsing was moved to a sandboxed user-space process fontdrvhost.exe. On these systems, a remote code execution issue in font parsing will get attacker's code executed in an AppContainer sandbox, which requires another vulnerability to escape it.
  3. Vulnerabilities are in ATMFD.DLL, a kernel font driver responsible for processing Adobe Type 1 PostScript and OpenType fonts. Based on this comparison by Didier Stevens, fontdrvhost.exe likely has the same code for processing Adobe Type 1 PostScript and OpenType fonts as ATMFD.DLL, which explains why newer Windows 10 systems that do not have ATMFD.DLL at all, are also affected. (Note that Microsoft subsequently updated the severity of Windows 10 client and server products from Critical to Important, with which we agree.)
  4. Microsoft's advisory provides three mitigation approaches that, in varying degrees, prevent exploitation of these vulnerabilities. We list them here in some detail and provide pros and cons for each.

Microsoft's Recommended Mitigations

  1. Disable the Preview Pane, the Details Pane and thumbnails in Windows Explorer. When displaying a folder with any font files, Windows Explorer automatically parses all displayed font files to be able to show sample font characters in font files' thumbnails. In addition, if any font file is selected, a small thumbnail shown in the Details Pane and sample text shown in the Preview Pane also employ automatic parsing of font file's content (see image below). This is probably the most worrying attack vector, as all the attacker has to do is get the victim to view a folder with malicious font files. This can be a shared folder in victim's network, a USB drive, or a ZIP file delivered via any channel and extracted to local computer be the victim. Or it could be a shared folder on the Internet, but more on that in the next bullet.

    Pros: Simple to implement for individual users on their own computers; Relatively simple to deploy network-wide via GPO or any other central deployment via registry changes; No reboot needed.

    Other attack vectors remain open, such as malicious documents, or opening a malicious font file in Font Viewer; Users who are used to seeing thumbnails, preview, and/or file details in Windows Explorer may suffer productivity impact; In a network deployment, it's hard to prevent users from re-enabling these Explorer features and re-opening the attack vector.

  2. Disable the WebClient service. The WebClient service is installed and running by default on all Windows workstations (but not servers), and works like this: when you try to open a network share anywhere in or outside your network (e.g., on the Internet), and it can't be accessed via SMB protocol, WebClient attempts to access the shared folder using WebDAV, an HTTP-based protocol - and therefore goes through all corporate and home firewalls that allow web browsing from users' computers. This provides a powerful attack vector for these vulnerabilities as all the attacker would have to do is get the victim to click a link to a network share hosted on attacker's computer somewhere on the Internet, and Windows Explorer would (after some delay) display font files in it. The link could be hosted on attacker's web site, or sent to the victim via email. (Note that only Internet Explorer and Edge would actually open the link from a web page in Windows Explorer.) If you don't need this feature, Microsoft recommends disabling the WebClient service.

    Simple to implement for individual users on their own computers; Relatively simple to deploy network-wide via GPO or other central deployment via registry changes; No reboot needed.

    Other attack vectors remain open, such as malicious documents, or opening a malicious font file in Font Viewer.

  3. Rename ATMFD.DLL. This is the most effective mitigation, because it eliminates the vulnerable code. On older Windows systems, this code is in the kernel driver called ATMFD.DLL, while on newer ones it's in a sandboxed user-space process called fontdrvhost.exe. It makes sense that Microsoft recommended renaming the former but not the latter, as remote code execution vulnerabilities in the kernel are critical, while running malicious code inside an AppContainer is far from "game over". Note that on Windows 8.1 and earlier, it is also possible to disable ATMFD via registry as described in the advisory, with the same end result as renaming ATMFD.DLL.

    Pros: Reliably blocks all remote and local attacks using these vulnerabilities.

    Cons: A non-trivial procedure for individual users; Prevents
    Adobe Type 1 PostScript fonts and OpenType fonts from working in applications employing the Windows-integrated support for Adobe Type 1 PostScript and OpenType; Requires a reboot.

Windows Explorer on Windows 7 showing a font file's glyphs in the thumbnail and in both Preview and Details Panes. All three require sending the font to the kernel and having it rendered there.

Obviously we can't patch these vulnerabilities because we don't know what they are, but we can infer from Microsoft's advisory that blocking Adobe Type 1 PostScript fonts from reaching the vulnerable kernel parsing code would block attacks.

So we decided to find the common execution point that various Windows applications such as Windows Explorer, Font Viewer, and applications using Windows-integrated font support are using to pass a font to Windows, then place a bouncer there that would keep Adobe Type 1 PostScript fonts out.

Windows are offering font-related functions under the Windows graphics device interface (GDI), most notably the AddFontResourceA function and its extended and wide character siblings. Looking into their implementations, we found they all end up calling an undocumented GdiAddFontResourceW function, which in turn calls NtGdiAddFontResourceW. The latter makes a system call to transfer execution to the kernel, whereby register rcx points to the font path string provided by the application.

Note that the font path string contains one or more paths to font files (delimited with a '|' character), and that Adobe Type 1 PostScript fonts are identified by three file extensions: .mmm, .pfb, and .pfm. All Adobe Type 1 PostScript fonts require a .pfm file and a .pfb file, and multi-master files require an additional .mmm file.

Our plan was then simple: we would inject our patch right before the syscall instruction in function NtGdiAddFontResourceW, where it would look for any occurrences of ".pfm" or ".mmm" in the font path string - and bypass the syscall if any were found. In order to make this comparison case-insensitive (we wouldn't want attackers to bypass our patch with a font file named malicious.PfM, would we?), we would first change the entire font path string to upper case, and then search for ".PFM" or ".MMM". While this simple check would also block non-Type-1-PostScript font files containing ".PFM" or ".MMM" elsewhere in their filenames (e.g., OpenType.MMMregular.otf which I've just made up for illustration), we decided to rather keep the patch code small and not account for such unlikely cases.

The Micropatch

This is the micropatch we created for 64-bit Windows 7 without ESU:

MODULE_PATH "..\Affected_Modules\gdi32.dll_6.1.7601.24540_64bit\gdi32.dll"
VULN_ID 6050

    PATCHLET_OFFSET 0x00009c00  ; Beginning of function NtGdiAddFontResourceW
        ; font path string (wide char) is in rcx
        ; example: "\??\C:\Analysis\ADV200006\SOSUE___.pfm|\??\C:\Analysis\ADV200006\SOSUE___.PFB"
        ; we make sure to restore rcx after we're done
        ; we can pollute rax because the original code doesn't use its value after our patch

        ; first upper-case the whole string

        push rcx
        cmp word [rcx], 0
        je END1
        cmp byte [rcx], 'a' ; if below 'a', no need to upper-case
        jb SKIP1
        cmp byte [rcx], 'z' ; if above 'z', no need to upper-case
        ja SKIP1
        sub byte [rcx], 0x20 ; make it upper-case
        add rcx, 2 ; next wide-char character
        jmp LOOP1
        pop rcx

        ; now search for ".PFM" and ".MMM" in the string
        push rcx
        cmp word [rcx], 0          ; did we reach end of the string?
        je END2                    ; note that we don't care if we test for four
                                   ; characters a bit beyond the buffer;
                                   ; there's always readable memory there and there can't be an
                                   ; unwanted match because the string is null-terminated
        mov rax, 004D00460050002Eh ; ".PFM" (in LSB byte order)
        cmp qword [rcx], rax       ; is there ".PFM" at [rcx]?
        je BLOCK                   ; if ".PFM" is found, we block the loading of the font
        mov rax, 004D004D004D002Eh ; ".MMM" (in LSB byte order)
        cmp qword [rcx], rax       ; is there ".MMM" at [rcx]?
        je BLOCK                   ; if ".MMM" is found, we block the loading of the font
        add rcx, 2                 ; next wide-char character
        jmp LOOP2
        pop rcx
        mov rax, 0                 ; simulate the syscall returning an error when trying to
                                   ; load the font
        retn                       ; return and avoid syscall being called
        pop rcx

With this micropatch in place, all applications using Windows GDI for font-related operations will find any Adobe Type 1 PostScript fonts rendered invalid and unable to load. For example, Windows Explorer will start looking like this when viewing a folder with a pair of otherwise valid PFM and PFB files:

With our micropatch in place, Windows Explorer no longer shows glyphs from Adobe Type 1 PostScript fonts in thumbnails or in Preview or Details Pane.

Of course, other types of fonts, including OpenType fonts, remain valid.


Here's our micropatch in action:

Frequently Asked Questions

Q: What are advantages of your micropatch compared to Microsoft's recommended workarounds?

Our micropatch requires zero user interaction for existing 0patch users - they do not even need to know there is some vulnerability out there and that they should do something to neutralize it. For Enterprise users, deploying this micropatch is as simple as enabling it in 0patch Central and waiting for 0patch Agents to sync. (Disabling it is just as simple, should it be needed.)

Q: Any disadvantages of your micropatch compared to Microsoft's recommended workarounds?

Renaming ATMFD.DLL or disabling ATMFD via registry makes the vulnerability unreachable even for a local attacker who has ability to execute low-privileged arbitrary code on the computer. Our micropatch doesn't protect against a local attacker: they can write their own program that makes a direct system call to the kernel and thereby avoid our micropatch. Our micropatch protects against remote attack vectors. 

Q: Will Microsoft provide a patch for these vulnerabilities to Windows 7 and Windows Server 2008 R2 users without Extended Security Updates?

Microsoft's advisory clearly states that they won't. This makes our micropatch especially important for 0patch users on these Windows systems. We at 0patch have committed to provide post-end-of-service security micropatches for Windows 7 and Windows Server 2008 R2 for three additional years. (Read FAQ for more information.)

Q: What will happen if I apply your micropatch, and then apply Microsoft's patch for these issues when it comes out?

Microsoft patch for these vulnerabilities  will likely be in ATMFD.DLL, not in GDI32.DLL which we patched. If April Windows Updates also happen to change GDI32.DLL, our micropatch will automatically stop applying. If not, our micropatch will keep getting applied to GDI32.DLL and will keep blocking Adobe Type 1 PostScript fonts from reaching the kernel. Most users have no need for such (very old) fonts and will not be affected by our micropatch. Users who need to use Adobe Type 1 PostScript fonts will be advised to disable our micropatch after they have applied Microsoft's fix for these issues.

Q: Is this a PRO-only micropatch, or is it also available to 0patch FREE users?

To help people and organizations in these difficult times, we decided to make this micropatch available to everyone, so it is included in 0patch FREE until Microsoft issues their official update. At that time, we'll limit availability of this micropatch to 0patch PRO license holders. (And, as always, recommend everyone to apply the official update.)

Q: How can I deploy this micropatch in my organization's network?

Contact [email protected] for our Enterprise offering (including central management, setting patching policies, group management etc.). We'll set you up with some trial licenses and technical support for making your deployment smooth and quick.



✇ 0patch Blog

Micropatch Available for User-Mode Power Service Memory Corruption (CVE-2020-1015)

By: Mitja Kolsek

by Mitja Kolsek, the 0patch Team

Windows 7 and Server 2008 R2 users without Extended Security Updates have just received a micropatch for CVE-2020-1015, a memory corruption vulnerability in User-Mode Power Service that could allow a local attacker to execute arbitrary code as Local System.

This vulnerability was patched by Microsoft with April 2020 Updates, but Windows 7 and Server 2008 R2 users without Extended Security Updates remained vulnerable.

Security researcher 0xeb_bp analyzed the official patch, wrote an in-depth analysis, determined the root cause of the vulnerability, and published a tool that crashes the Power Service.
The vulnerability provides a "race condition" in requests for a legacy RPC function because the code processing these requests was not properly enclosed in critical sections. Multiple concurrent requests can corrupt memory and result in arbitrary code execution in the service.
Microsoft's patch effectively enclosed most of the legacy RPC function (UmpoRpcLegacyEventRegisterNotication) into a critical section. Our micropatch does logically the same with two patchlets, 5 instructions in each.

MODULE_PATH "..\Affected_Modules\umpo.dll_6.1.7601.24525_64bit\umpo.dll"
VULN_ID 6152

PIT kernel32.dll!EnterCriticalSection,kernel32.dll!GetModuleHandleA
; The critical section object is stored at umpo.dll+0x25aa0


    call STRING1
    db 'umpo.dll',0
    pop rcx ; rcx points to 'umpo.dll' string
    call PIT_GetModuleHandleA
    lea rcx, [rax + 0x25aa0]
    call PIT_EnterCriticalSection

PIT kernel32.dll!LeaveCriticalSection,kernel32.dll!GetModuleHandleA
; The critical section object is stored at umpo.dll+0x25aa0


    call STRING2
    db 'umpo.dll',0
    pop rcx ; rcx points to 'umpo.dll' string
    call PIT_GetModuleHandleA
    lea rcx, [rax + 0x25aa0]
    call PIT_LeaveCriticalSection

We'd like to thank @0xeb_bp for an excellent analysis and POC for this issue, which allowed us to create a micropatch for Windows users without security updates.

This micropatch is immediately available to all 0patch users with a PRO license. To obtain the micropatch and have it applied on your computer(s) along with other micropatches included with a PRO license, create an account at 0patch Central, install 0patch Agent and register it to your account. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.

✇ 0patch Blog

Micropatch is Available for Windows LNK Remote Code Execution Vulnerability (CVE-2020-1299)

By: Mitja Kolsek

by Mitja Kolsek, the 0patch Team

Windows 7 and Server 2008 R2 users without Extended Security Updates have just received a micropatch for CVE-2020-1299, another "Stuxnet-like" critical LNK remote code execution issue that can get code executed on user's computer just by viewing a folder with Windows Explorer.

This vulnerability was patched by Microsoft with June 2020 Updates, but Windows 7 and Server 2008 users without Extended Security Updates remained vulnerable.

Security researcher Lê Hữu Quang Linh (@linhlhq) found this vulnerability, published a detailed analysis and shared a POC with us so we could reproduce the issue and create a micropatch.

We narrowed the root cause down to the order in which method CKnownFoldersFolder::_ClearCachedObjects (1) deletes a DSA object using a call to DSA_DestroyCallback and (2) NULLs a pointer to said object. In vulnerable code, it does it in this order; in patched code, vice versa, as seen on the image below.

Unpatched (left) and patched (right) function CKnownFoldersFolder::_ClearCachedObjects

Microsoft's patch also moved a CoTaskMemFree call to another code block but we determined that to have no relevant consequence. Therefore, our micropatch only needed one single instruction to NULL the pointer to the DSA object before the call to DSA_DestroyCallback.

MODULE_PATH "..\Affected_Modules\shell32.dll_6.1.7601.24468_64bit\shell32.dll"
VULN_ID 6281




    and qword[rbx+0xb8], 0 ; put 0 at rbx+0xb8, which contains a circular pointer to the same
; structure and is going to be deleted twice.
                           ; When the function tries to recursively delete this structure, it follows
                           ; this pointer and causes a double free

Here's a video of our micropatch in action:

We'd like to thank security researcher Lê Hữu Quang Linh (@linhlhq) for a detailed analysis and for sharing their POC with us, which allowed us to quickly reproduce the issue and produce this micropatch for Windows users without official security updates..

This micropatch is immediately available to all 0patch users with a PRO license, and is targeted at Windows 7 and Windows Server 2008 R2 users without Extended Security Updates. To obtain the micropatch and have it applied on your computer(s) along with other micropatches included with a PRO license, create an account in 0patch Central, install 0patch Agent and register it to your account. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.
✇ 0patch Blog

Remote Code Execution Vulnerability in Zoom Client for Windows (0day)

By: Mitja Kolsek
by Mitja Kolsek, the 0patch Team

[Update 7/13/2020: Zoom only took one (!) day to issue a new version of Client for Windows that fixes this vulnerability, which is remarkable. We have reviewed their fix and can confirm that it efficiently resolves the vulnerability. With an official vendor fix available to all users, we made our micropatches for this issue PRO-only according to our guidelines. Meanwhile, after issuing micropatches for this issue targeted at Zoom Client for Windows versions 5.0.3 to 5.1.2, we noticed a lot of our users being on all of these versions despite Zoom's highly persistent update mechanism. We had expected most users to be on version 5.1.2., but this indicates many users may still be on even older Zoom Client versions. We therefore ported our micropatch to the remaining supported versions of Zoom Client: 5.0.0., 5.0.1, and 5.0.2. We're now covering all vulnerable supported clients.]

Earlier this week a security researcher shared a remote code execution "0day" vulnerability in Zoom Client for Windows with our team. The vulnerability allows a remote attacker to execute arbitrary code on victim's computer where Zoom Client for Windows (any currently supported version) is installed by getting the user to perform some typical action such as opening a document file. No security warning is shown to the user in the course of attack.

The researcher (who wants to keep their identity private) stated that they did not report the vulnerability to Zoom either directly or through a broker, but would not object to us reporting it to Zoom.


We analyzed the issue and determined it to be only exploitable on Windows 7 and older Windows systems. While Microsoft's official support for Windows 7 has ended this January, there are still millions of home and corporate users out there prolonging its life with Microsoft's Extended Security Updates or with 0patch.

We then documented the issue along with several attack scenarios, and reported it to Zoom earlier today along with a working proof of concept and recommendations for fixing. Should a bug bounty be awarded by Zoom, it shall be waived in favor of a charity of researcher's choice.


On the micropatching side, we were able to quickly create a micropatch that removes the vulnerability in four different places in the code. The micropatch was then ported from the latest version of Zoom Client for Windows (5.1.2) to previous five versions back to 5.0.3 released on May 17, 2020. Zoom Client features a fairly persistent auto-update functionality that is likely to keep home users updated unless they really don't want to be. However, enterprise admins often like to keep control of updates and may stay a couple of versions behind, especially if no security bugs were fixed in the latest versions (which is currently the case).

Our micropatches have already been released and distributed to all online 0patch Agents; Zoom users with 0patch installed are therefore no longer affected by this issue.

According to our guidelines, we're providing these micropatches to everyone for free until Zoom has fixed the issue or made a decision not to fix it. To minimize the risk of exploitation on systems without 0patch, we're not publishing details on this vulnerability until Zoom has fixed the issue, or made a decision not to fix it, or until such details have become public knowledge in any way.

To obtain the free micropatch for this issue and have it applied on your computer(s), create a free account in 0patch Central, install 0patch Agent and register it to your account. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.

Exploit without and with the micropatch

This video demonstrates how an actual attack could look like, and how 0patch blocks the attack. When 0patch is disabled (or absent), user's clicking on the "Start Video" button triggers the vulnerability and leads to a "HACKED" dialog being shown (of course anything else could be executed instead). With 0patch enabled, the vulnerability is removed from the running Zoom.exe process and clicking on the "Start Video" button does not result in execution of malicious code.

Note that in order to prevent revealing too much information, some prior user activity inside Zoom Client user interface is not shown in the video.

Frequently Asked Questions

Q: Am I affected by this vulnerability if I'm using Windows 10 or Windows 8?
A: No, this vulnerability is only exploitable on Windows 7 and earlier Windows versions. It is likely also exploitable on Windows Server 2008 R2 and earlier though we didn't test that; either way, our micropatch will protect you wherever you're using Zoom Client.

Q: Am I affected by this vulnerability if I'm using Windows 7 fully updated with Extended Security Updates?
A: Yes.

Q: Are other Zoom products affected by this vulnerability too?
A:We did not test any other Zoom products, however only those running on Windows could potentially be affected by this vulnerability.

Q: Is your micropatch for this vulnerability completely free?
A: Yes. If you already have 0patch Agent installed and registered, everything will happen automatically. If not, you only need to create a free account in 0patch Central, install 0patch Agent and register it to your account, then all FREE micropatches will be automatically downloaded to your computer and applied as needed. Once Zoom has fixed this issue, this micropatch will no longer be free and will only be available to 0patch PRO license holders.

Q: If I use 0patch to fix this vulnerability, what will happen when Zoom issues an updated version of Zoom Client for Windows?
A: 0patch is designed such that when a vulnerable executable module is replaced by a new version, any micropatches that were made for that vulnerable module automatically stop applying (because the cryptographic hash of the module changes). When Zoom issues an updated Client for Windows and you install it on your computer, our micropatch will become obsolete. In case this updated Zoom Client does not fix this vulnerability, we'll port the micropatch and make it available for free as quickly as possible.

Q: How do I know that the micropatch was actually applied to my Zoom Client?
A: First launch Zoom, then open 0patch Console and view the log. You should be able to find log entries like "Patch ... applied in application Zoom.exe"

Q: I installed 0patch Agent to fix this vulnerability but it is showing a large amount of popups notifying me about missing patches regardless of popup settings in 0patch Console. What can I do to make this stop?
A: We're aware that popups in the FREE plan have become pretty disturbing due to the increased amount of patches, and are fixing that in the next agent version scheduled to be out next week. If you can't wait, feel free to download the current 0patch Agent release candidate and install it on top of your already installed 0patch Agent. When this release candidate is installed, 0patch Console will show that a “New agent is available”. Please ignore that – the server simply tells the agent that the version it is running is not the current official version. The message will stop appearing when the new agent is officially released.

[Below FAQ added on 7/13/2020]

Q: Why did you drop a 0day without giving the vendor the usual 90 days to fix the issue?
A: We have to be perfectly clear here: we did not "drop a 0day". We took extra care not to reveal any technical details. "Dropping a 0day" implies publishing details that allow anyone skilled to reproduce the bug and create an exploit. In over two decades of existence, our company has never "dropped a 0day", moreover we have never published details of unpatched vulnerabilities we had reported to various vendors even if they took extremely long to fix them (while it is standard practice to publish after 90 days). We took the time to write up a detailed report we sent to Zoom, and we took care of our users by providing them with a micropatch. This is what every antivirus/antimalware company does for their users, e.g., by immediately providing signatures for 0days.

Q: Now that Zoom has issued a new version of Client for Windows that fixes this issue, will you publish vulnerability details and proof-of-concept?
A: Our data shows that on the day we issued our micropatches, many 0patch users have been using all supported versions of Zoom Client for Windows instead of the latest one despite of its highly persistent auto-update mechanism. Taking our user base as a statistical sample of the global Zoom user base, this implies a significant amount of Zoom Clients will likely remain vulnerable even though a fixed version is now available. To prevent putting Zoom users who don't also use 0patch at risk, we will not publish any additional details at this time.

Q: Does this vulnerability show that Windows 7 is an insecure operating system?
A: While it may sound so, it really does not. This vulnerability is not a fault of Windows 7 in any way, but just happens to be exploitable there. It is not blocked by some security feature or exploit mitigation on Windows 8 and Windows 10 which isn't there on Windows 7, but by sheer coincidence.

Q: Isn't Windows 7 insecure anyway because Microsoft stopped supporting it?
A: Not really - Microsoft is still providing all critical and important security updates for Windows 7 until January 2023; from security perspective, Windows 7 is therefore effectively just as supported as Windows 10 as long as you're using Microsoft's Extended Security Updates, or, alternatively and less expensively, 0patch.

Community Outreach

We'd like to thank the security researcher who shared the vulnerability with us so we could provide quick protection for our existing users and everyone else affected. We're very pleased to see an increase of such collaboration within security community and call upon all security researchers to help us protect users and share vulnerability information with us, whether or not they have also shared it with the original vendor. We'll do our best to turn your reports into patches as quickly as possible. Thank you all!

✇ 0patch Blog

Micropatch is Available for Memory Corruption in DHCP Message Processing (CVE-2020-0662)

By: Mitja Kolsek

by Mitja Kolsek, the 0patch Team

Windows 7 and Server 2008 R2 users without Extended Security Updates have just received a micropatch for CVE-2020-0662, a remote memory corruption vulnerability in DHCP message processing.

This vulnerability was patched by Microsoft with February 2020 Updates, but Windows 7 and Server 2008 users without Extended Security Updates remained vulnerable.

Security researcher Spencer McIntyre (@zeroSteiner) analyzed this vulnerability and published a POC, from which we could reproduce the issue and create a micropatch.

The vulnerability lies in accepting a hardware address in a DHCP packet that is longer than 20h bytes, resulting in out-of-bounds read or write, depending on the Windows version. Our micropatch is logically identical to Microsoft's: it adds a check for the HW address length:

MODULE_PATH "..\Affected_Modules\ipnathlp.dll"
VULN_ID 5909

    PIT ipnathlp.dll!0x1AB94   
    ; Added check for Hardware address length, must be <= 20
        mov al, [rsi+0xE6] ; [rsi+0xE6] = value of hardware address length
        cmp al, 0x20 ; compare hardware address length with 0x20
        jbe RestoreCodeFlow ; jump if hradware address length is <= 20
        call PIT_ExploitBlocked ; exploit blocked shown if hardware address length is > 20
        call GetText ; get address for Error text
        db 'DhcpProcessMessage: ignoring message since HWAdderLength is greater than MAX_HARDWARE_ADDRESS_LENGTH',0 ; Error message
        pop rdx ; set rdx to error code address like MS org patch
        jmp PIT_0x1AB94 ; jump to ensure same code flow like MS patch

We'd like to thank Spencer McIntyre (@zeroSteiner) for sharing their analysis and POC, and for additional assistance in reproducing the bug, which allowed us to create this micropatch for Windows users without official security updates.

This micropatch is immediately available to all 0patch users with a PRO license, and is targeted at Windows 7 and Windows Server 2008 R2 users without Extended Security Updates. To obtain the micropatch and have it applied on your computer(s) along with other micropatches included with a PRO license, create an account in 0patch Central, install 0patch Agent and register it to your account. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.
✇ 0patch Blog

Micropatch Available for "SIGRed", the Wormable Remote Code Execution in Windows DNS Server (CVE-2020-1350)

By: Mitja Kolsek

by Mitja Kolsek, the 0patch Team

This month's Patch Tuesday included a fix for CVE-2020-1350, a critical memory corruption vulnerability in Windows DNS Server affecting all Windows Server versions from long-unsupported Server 2003 to the latest Server 2019.

After Microsoft's initial announcement and security advisory, the CheckPoint research team published a detailed article about the issue, describing the attack vector and providing enough information for other security researchers to trigger the vulnerability. Just one day later, the first real proof-of-concept was published, developed by Max Van Amerongen (@maxpl0it) from F-Secure Labs, and later several other researchers have shown their own tools triggering the vulnerability.

We can safely assume that offensive teams worldwide are currently trying to develop a reliable arbitrary code execution exploit as they know that Windows Updates take anywhere from long to eternity before getting applied to most Windows Servers out there. Their job will not be trivial, with various exploit mitigations in place on modern Windows servers, but counting on them to fail would be a risky strategy. In addition, many companies are still using Windows Server 2008 machines with no security updates past January this year.

Numerous 0patch customers have one or more Windows 2008 Servers and we wanted to take care of them as quickly as possible. With a working proof-of-concept at hand we could easily create a micropatch for this issue. Let's look at Microsoft's patch first:


The image above shows the difference between vulnerable function SigWireRead (left) and its patched counterpart (right). This function was one of only three functions in dns.exe modified by the July update, and the other two were not relevant for the issue at hand.

Microsoft's patch (gray code blocks) introduced three integer overflow/underflow checks, for one subtraction and two addition operations. When faced with Max's proof-of-concept, it is the third check (the lowest gray code block) that detects the overflow and redirects execution towards function's exit instead of processing the DNS packet further - which would lead to memory corruption. 

Our micropatch does logically the same, with one difference - when integer overflow/underflow is detected, it also displays and logs an exploit attempt, allowing admins to know that their server was targeted by an exploit:

MODULE_PATH "..\Affected_Modules\dns.exe_6.1.7601.24437_64bit\dns.exe"
VULN_ID 6390

    PIT dns.exe!0x4EC68
        push rdi ; push to ensure normal code flow after patch
        push rax ; push to ensure normal code flow after patch
        ;First check
        sub rdi, rax
        cmp rdi, 0xFFFF
        ja ExploitBlocked ; the TCP packet is not valid, jump to Exploit Blocked
        ;Second check
        movzx eax, byte[rsp+30h+2*8] ; added 2*8 to the original offset to compensate for the 2 pushes at the beginning
        add ax, 0x14
        cmp ax, 0x12
        jb ExploitBlocked ; the TCP packet is not valid, jump to Exploit Blocked
        ;Third check
        lea ecx, [rax+rdi]
        cmp cx, ax
        jb ExploitBlocked ; the TCP packet is not valid, jump to Exploit Blocked
        jmp End ; the TCP packet is valid, continue with original code
        pop rax ; restore rax to its previous value
        pop rdi ; restore rdi to its previous value
        call PIT_ExploitBlocked ; Exploit Blocked pop up
        jmp PIT_0x4EC68 ; Exit function, TCP packet not valid
        pop rax ; restore rax to its previous value
        pop rdi ; restore rdi to its previous value

We released our micropatch early afternoon CET today and it got applied to all online computers with 0patch PRO worldwide within 60 minutes without restarting the computer or DNS service.

This is how it looks like when a DNS server is attacked without and with 0patch:

The first instance of our micropatch is targeted at Windows Server 2008 R2 without Extended Security Updates, and we plan to port it to Windows Server 2003 next for our users who are for various reasons still using this unsupported server. [Update 7/20/2020: Micropatch is now ported to 32-bit and 64-bit Windows Server 2003.]

Although free official updates exist for all supported Windows servers, admins may not be able to apply them immediately or restart the computer; for such cases, requests for porting our micropatch to specific versions of dns.exe running on affected computers can be sent to [email protected].

If you have 0patch Agent with PRO license installed on your Windows Server 2008 R2 or Server 2003 computer, our micropatch is already downloaded and applied to your DNS server. Otherwise, to obtain the micropatch and have it applied on your computer(s) along with other micropatches included with a PRO license, create an account in 0patch Central, purchase a PRO license or request a trial at [email protected], install 0patch Agent and register it to your account.

Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.

We'd like to thank Max Van Amerongen (@maxpl0it) from F-Secure Labs for publishing their analysis and POC, and for providing additional assistance in triggering the vulnerability and simplifying our test case, thereby allowing us to create this micropatch for Windows users without official security updates.

✇ 0patch Blog

New 0patch Agent is Released - Version

By: Mitja Kolsek

Dear 0patch users,

We have just released a new 0patch Agent. We don't do that very often, for two reasons: (1) we like the software we're using to be stable, to favor reliability over novelty, and to not introduce unnecessary changes - so that's what we try to do for you; and (2) building and thoroughly testing a piece of software that needs to work reliably on multiple platforms is pretty expensive. Because of the latter, we've micropatched two functional bugs in our previous Agent version (see here and here) instead of hastily issuing a new one. Micropatching is vastly superior to the traditional rebuild-test-distribute model when fixing simple bugs (which most security bugs and many functional ones are) as it incurs minimal risk of breaking something outside the patched bits, requires only narrowly-focused testing, and allows for inexpensive and unobtrusive deployment (and revocation, if needed). 

Nevertheless, bugs and feature requests have piled up, and our server is evolving too, prompting the agent to learn a couple of new tricks.

What's new in the new 0patch Agent? If you like details, please refer to release notes, but otherwise the main changes are:

  • Annoying popups in 0patch FREE are now gone and replaced by a summary popup that will tell you how many patches you're missing out on that would be relevant on your computer.
  • Log is now displayed much faster in 0patch Console.
  • Pop-ups are no longer shown when any application is in full screen mode.
  • The above-mentioned functional bugs that we've previously micropatched have now been patched in the code, so there is no need to apply a micropatch to every process anymore.
  • Failed syncs immediately after system startup (which many of you have noticed, and thankfully reported) have been fixed.

May we remind you that the agent is still very small, just over 4MB on the file system.

We recommend you update your agent to this new version at your earliest convenience. The update process will not require a computer restart.

Locally Managed 0patchAgents

If you're using 0patch locally on your computer, 0patch Agent has already started notifying you about a new version. To update the agent, launch 0patch Console and in the "AGENT VERSION" box, click on "GET LATEST VERSION" and let the update process complete. Note that the console will disappear in the process, and will get re-launched when the new agent version is installed.

Remotely Managed 0patch Agents

If you're managing 0patch Agents in your organization remotely through 0patch Central, your group settings will determine whether/which agents will get updated automatically and which will require a manual action on your part. To make sure all agents are updated, you can open the All Computers group, select all computers, and under ACTIONS, select "Update agent to new version."

Thank you for using 0patch! As always, we'll appreciate your feedback, bug reports, feature requests and musical recommendations at [email protected].

The 0patch Team

✇ 0patch Blog

Micropatch is Available for Windows Task Scheduler Security Feature Bypass (CVE-2020-1113)

By: Mitja Kolsek

by Mitja Kolsek, the 0patch Team

Windows 7 and Server 2008 R2 users without Extended Security Updates have just received a micropatch for CVE-2020-1113, a Windows Task Scheduler Security Feature Bypass.

This vulnerability was patched by Microsoft with May 2020 Updates, but Windows 7 and Server 2008 users without Extended Security Updates remained vulnerable.

Security researcher Sylvain Heiniger (@sploutchy) of @compasssecurity analyzed this vulnerability and subsequently published a POC, from which we could reproduce the issue and create a micropatch. 
The vulnerability lies in Task Scheduler accepting RPC requests that can be relayed. An attacker can piggyback on such requests by having some logged-on user send an SMB request to their computer, and then act as man-in-the-middle.
Microsoft's patch makes sure the authentication level of the RPC request received by Task Scheduler is RPC_C_AUTHN_LEVEL_PKT_PRIVACY, which prevents such piggybacking. Our micropatch does effectively the same, with just six CPU instructions on 32-bit Windows, and two CPU instructions on 64-bit Windows:

MODULE_PATH "..\Affected_Modules\schedsvc.dll_6.1.7601.24470_64bit\schedsvc.dll"
VULN_ID 6220


PIT schedsvc.dll!0x3b449


    ;This patch is inserted right after the RpcServerInqCallAttributesW call.
    ;The call fills the RPC_CALL_ATTRIBUTES_V2_W structure with data, and at
    ; address rsp+78h we can find
    ;the RPC_CALL_ATTRIBUTES_V2_W.AuthenticationLevel value, which describes
    ;the level of RPC authentication
    ;used. The range of this variable is form 0x0 to 0x6, where 0x6 is
    ;authentication with integrity (signature)

    cmp dword[rsp+78h], 6     ;Check if the RPC_CALL_ATTRIBUTES_V2_W.AuthenticationLevel
                              ; value is equal to 6
    jb PIT_0x3b449            ;If the value is less than 6, jump to the
                              ;"access denied error" block


And a video of the micropatch in action:

We'd like to thank Sylvain Heiniger (@sploutchy) for sharing their analysis and POC, which allowed us to create this micropatch for Windows users without official security updates. We also encourage security researchers to privately share their analyses with us for micropatching.

This micropatch is immediately available to all 0patch users with a PRO license, and is targeted at Windows 7 and Windows Server 2008 R2 users without Extended Security Updates. To obtain the micropatch and have it applied on your computer(s) along with other micropatches included with a PRO license, create an account in 0patch Central, install 0patch Agent and register it to your account. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center.
✇ 0patch Blog

Micropatch for Zerologon, the "perfect" Windows vulnerability (CVE-2020-1472)

By: Mitja Kolsek



by Mitja Kolsek, the 0patch Team
The Zerologon vulnerability allows an attacker with network access to a Windows Domain Controller to quickly and reliably take complete control of the Windows domain. As such, it is a perfect vulnerability for any attacker and a nightmare for defenders. It was discovered by Tom Tervoort, a security researcher at Secura and privately reported to Microsoft, which issued a patch for supported Windows versions as part of August 2020 updates and assigned it CVE-2020-1472.

Secura has subsequently released a detailed technical paper and a proof-of-concept tool that anyone could use to test whether their domain controllers were vulnerable or not. The paper revealed the underlying cryptographic flaw in Netlogon remote protocol, a legacy protocol that is still supported on all Windows servers to allow old Windows machines to work in a domain environment. The flaw is described in detail in the above-mentioned paper, but the jist of it is that the attacker has a 1:256 chance that if sending a "challenge" of all zeroes, and all subsequent values in the protocol also containing only zeroes, the request will reset server's password to an empty password. Making a sufficient number of attempts, say 2000 as in the proof-of-concept tool, will succeed with extremely high probability, which we can safely approximate to 100%.

Microsoft's Fix

While most of the security community is interested in the vulnerability and its exploitation, we at 0patch care more about the fix. Critical Windows vulnerabilities are most often of memory corruption flavor, and thus generally easy to fix, but when a cryptographic flaw comes by, there's a possibility that the fix will introduce a lot of new complex code. (Spoiler: not in this case.)

Since Netlogon remote protocol still holds together many production environments with old Windows computers, we knew that Microsoft's fix couldn't include any significant design changes unless it was also ported to long-unsupported Windows versions such as Server 2003, Server 2008 and Windows NT; breaking these systems on a global scale would, with only moderate dramatization, take us back to the dark ages.

Fortunately, Microsoft is highly disciplined when it comes to documentation: the Netlogon remote protocol page shows that the protocol specification was last changed in August 2020 - a good sign for us. Furthermore, they provide a handy "diff" document for every version so it's easy to find changes. The August 2020 diff document contains the following relevant changes:

  1. Page 102: A new setting VulnerableChannelAllowList was introduced: "A setting expressed in Security Descriptor Definition Language (SDDL) ([MS-DTYP] section 2.5.1) of Netlogon client allowed to not use secure bindings, see section (VulnerableChannelAllowList is not supported in Windows NT, Windows 2000, Windows Server 2003, and Windows Server 2008.)"

  2. Page 104: A step was added to the session-key negotiation process: "If none of the first 5 bytes of the client challenge is unique, the server MUST fail session-key negotiation without further processing of the following steps. (Windows NT, Windows 2000, Windows Server 2003, and Windows Server 2008 allow the call to succeed.)"

  3. Page 110: Two steps were added to the session-key establishment process: "4. If secure bind is not used, the server MUST deny the request unless client is in the VulnerableChannelAllowList setting. (Windows NT 4.0, Windows 2000, Windows Server 2003, and Windows Server 2008 allow the call to succeed.)" and "6. If none of the first 5 bytes of the ClientStoredCredential computation result (step 1, section is unique, the server MUST fail session-key negotiation without further processing of the following steps. (Windows NT, Windows 2000, Windows Server 2003, and Windows Server 2008 allow the call to succeed. )"


The relevant change for Zerologon is obviously this: "If none of the first 5 bytes of the client challenge is unique, the server MUST fail session-key negotiation without further processing of the following steps." However, what exactly does "if none of the first 5 bytes of the client challenge is unique" mean? The reader is challenged to make a mental image of what this phrase means, as anyone implementing the protocol would have to - and then read on to see how that mental image compares to Microsoft's code.

Diffing of netlogon.dll between July 2020 and August 2020 versions on Windows Server 2012 shows that function NetrServerAuthenticate3 was extended with a call to a previously non-existent function NlIsChallengeCredentialPairVulnerable and a subsequent branch to terminate the protocol in case the latter returns a non-zero value (implying that the challenge-credential pair was vulnerable).


Function NetrServerAuthenticate3 got a new security check in August 2020

Now let's look at the new function, NlIsChallengeCredentialPairVulnerable. The client-provided challenge is stored in a buffer pointed to by rcx. First, some global variable is checked: if it is 1, the function returns 0 ("not vulnerable"). We don't know what this global variable is and we found no write references to it, only three places where it is being read. We suspect it might be an #ifdef'ed global variable that is hard-coded depending on the target Windows version so that even if Microsoft rebuilds netlogon.dll for, e.g., Windows Server 2003, this security check will not work - which would be consistent with the current Netlogon remote protocol specifications.

Then, rcx is checked to be non-null (kind of important, we don't want to cause access violation reading from it), and rdx is also checked to be non-null. We don't know what rdx points to and decided not to go there as rdx's value is not used at all (the register is overwritten with 1 shortly thereafter).

Now to the meat of the function: the first byte of the challenge is stored into r9d, then the next four bytes are compared to it in a loop. If any of these four bytes is different from the first byte, the function returns 0 ("not vulnerable"). Otherwise, it returns 1 ("vulnerable"). This covers the case from the proof-of-concept tool, where the challenge is all zeroes, but it also covers challenges starting with 11111, 22222, 33333, etc., which would also be deemed malicious by this logic. We assume Microsoft asked one of its crypto experts how to fix this and they at least thought it possible (if not outright feasible) that challenges consisting of equal non-zero bytes could also be used for an attack, perhaps a less trivial one. [Update 9/18/2020] If we were any good at reading, we would notice this part in Secura's report: "When an IV consists of only zeroes, there will be one integer 0 ≤ X ≤ 255 for which it holds that a plaintext that starts with n bytes with value X will have a ciphertext that starts with n bytes with value 0. X depends on the encryption key and is randomly distributed." This explains the logic of Microsoft's patch, and all-zero challenge is just the simplest challenge to exploit. 


NlIsChallengeCredentialPairVulnerable checks if the first five challenge bytes are equal.

And why check only the first 5 bytes? We assume it's either because (a) Microsoft calculated that even if a legitimate random challenge could occasionally begin with 5 equal bytes, this would only break approximately 1 in 4 billion requests, or (b) their challenge-generating code in the client makes sure that the first five bytes are not the same (which would only break 1 in 4 billion requests from non-supported Windows computers).

Now, how does this implementation match your mental image of  "if none of the first 5 bytes of the client challenge is unique"? We think something like "if all of the first 5 bytes of the client challenge are identical" would more accurately describe it, and hereby call on Microsoft to reword this sentence in a future version of the protocol.


Our Micropatch

The micropatch we wrote is logically identical to Microsoft's fix. We injected it in function NetrServerAuthenticate3 in roughly the same place where Microsoft added the call to NlIsChallengeCredentialPairVulnerable, but since the latter doesn't exist in old versions of netlogon.dll,  we had to implement its logic in our patch.

The source code of our Zerologon micropatch for Windows Server 2008 R2


The video below shows how 0patch blocks a "Zerologon" attack. The Zerologon test tool is launched against a fully patched Windows Server 2008 R2 without Extended Security Updates (i.e., patched up to January 2020) while 0patch Agent is disabled. As expected, the test tool discovers that the server is vulnerable. After enabling 0patch Agent, which applies an in-memory micropatch for CVE-2020-1472 to lsass.exe without having to reboot the system, the Zerologon test tool no longer succeeds.

This micropatch is immediately available to all 0patch users with a PRO license, and is primarily targeted at Windows Server 2008 R2 users without Extended Security Updates (updated with January 2020 updates!). By the time you're reading this it has already been distributed to all online 0patch Agents with a PRO license and also automatically applied except where Enterprise policies prevented that. If you're not a 0patch user and would like to use this micropatch on your computer(s) along with other micropatches included with a PRO license, create an account in 0patch Central, install 0patch Agent and register it to your account, then purchase a PRO license or contact [email protected] for a free trial. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch.

To learn more about 0patch, please visit our Help Center
We'd like to thank Tom Tervoort from Secura for sharing their analysis and POC, which allowed us to create this micropatch for Windows users without official security updates. We also encourage security researchers to privately share their analyses with us for micropatching and further increase the positive impact of their work.
Most of the analysis was done by our young micropatching experts Blaz Satler and Ziga Sumenjak.

Frequently Asked Questions

Q: Does applying this micropatch require a computer restart?
A: No, both installation of 0patch Agent and application of the patch (to process lsass.exe) are done without restarting the computer, or restarting any process on the computer.

Q: Do we need this micropatch on a server that is not a domain controller?
A: No. Only domain controllers are vulnerable, both according to Microsoft's advisory and our own testing.

Q: How do we know this micropatch actually works on our server?
A: The best way to test is to use a non-destructive test such as the proof-of-concept tool from Secura. You should be able to replicate what is shown in the video above.
Q: Is Windows Server 2008 (non-R2) or Windows Server 2003 (any flavor) or Small Business Server 2008 also affected by this vulnerability?
A: To the best of our knowledge, these servers are not vulnerable to Zerologon.
Q: Does your micropatch work on Small Business Server 2011?
A: We're not specifically testing with SBS2011, but users are telling us that our micropatch applies to this Server 2008 R2-based Windows version. 
Q: We have a Windows Server 2008 R2 but your micropatch doesn't seem to be getting applied as the vulnerability test still succeeds. What is wrong?
A: The most common cause for this problem is the server not fully updated with January 2020 updates.

Q: We have a still-supported Windows server but can't apply the official update for reasons which leaves us vulnerable to Zerologon. Can you help us?
A: Please contact [email protected] and we'll port the micropatch to your specific version
Q: Is there anything else we need to know?
A: If your organization still has Windows Server 2008 R2 machines, you might also have some Windows 7 systems that aren't getting security patches anymore, so you should know that we're providing critical post-end-of-support security micropatches for both Windows Server 2008 R2 and Windows 7. Here is the list of micropatches we've issued so far as part of this service.