Wednesday, April 17, 2019

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

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:

msie-xss-0day-1.mht

[ZoneTransfer]
ZoneId=3
 

msie-xss-0day-2.mht

[ZoneTransfer]
ZoneId=3
ReferrerUrl=http://www.acrossecurity.com/test/
HostUrl=http://www.acrossecurity.com/test/msie-xxe-0day-2.mht


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:

S-1-15-3-3624051433-2125758914-1423191267-1740899205-1073925389-
3782572162-737981194:(OI)(CI)(R)
                    S-1-15-2-3624051433-2125758914-1423191267-1740899205-1073925389-
3782572162-737981194:(OI)(CI)(R)


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
PATCH_ID 362
PATCH_FORMAT_VER 2
VULN_ID 5000
PLATFORM win32

patchlet_start

 PATCHLET_ID 1
 PATCHLET_TYPE 2
 PATCHLET_OFFSET 0x00034507 ; Injecting after the call to GetZoneFromAlternateDataStreamEx

 code_start

   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
 
  pass:
 
 code_end

patchlet_end


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 support@0patch.com.


* [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.


Cheers!

@mkolsek
@0patch

Tuesday, April 2, 2019

PRESS RELEASE: ACROS Security Announces the Launch of 0patch PRO


ACROS Security Announces the Launch of 0patch PRO



Maribor, Slovenia, April 2nd 2019 – ACROS Security, a globally recognized provider of security micropatches, is excited to announce the launch of 0patch PRO, a service that simplifies security patching on Windows platform for Enterprises and individuals.

The official launch date is April 2nd 2019.

0patch PRO is a first commercial platform of its kind to enable micropatches (microscopic pieces of binary code that replace only vulnerable parts) to rapidly and unobtrusively fix the most important security vulnerabilities. By using an innovative approach, 0patch reduces the “security update gap” in enterprises from months to days or even hours.

Micropatching, implemented by 0patch PRO, enables quick fixes of "0days" and unpatched vulnerabilities, end-of-life and unsupported products (for instance, vulnerable old Java versions) and fixes vulnerable 3rd party components and customized software. 0patch PRO provides patches for legacy operating systems and applications, and eliminates vulnerabilities that are being exploited in the wild.

0patch makes software patching almost imperceptible, without unnecessary system or application reboots and with minimal footprint.

The company is offering 0patch FREE service for personal and non-profit educational use that will implement the same technology as 0patch PRO, but with a limited set of micropatches.


ABOUT ACROS Security

ACROS Security, with two decades of presence on international markets, is a leading provider of in-depth security research, realistic penetration testing, code review and security patches for customers with highest security requirements.

ACROS Security serves customers across a wide range of industries, including global software vendors, financial institutions, online service providers, cloud providers, virtualization solutions providers and others who consider security of their products, information and services critical.


MEDIA Contact:

ACROS Security
Stanka Salamun
Tel: +38623000280
Email: lab@acrossecurity.com
https://0patch.com
https://twitter.com/0patch
https://acrossecurity.com

Link to original press release file

Thursday, February 21, 2019

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

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.



Patching



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:

C:\some_folder\some_file.ext

or

C:../some_folder\some_file.exe

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

C:\tempC:\some_folder\some_file.ext

or

C:\tempC:../some_folder\some_file.exe

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"
PATCH_ID 353
PATCH_FORMAT_VER 2
VULN_ID 4852
PLATFORM win32

patchlet_start

 PATCHLET_ID 1
 PATCHLET_TYPE 2
 PATCHLET_OFFSET 0x000CC13
 JUMPOVERBYTES 10 ; We remove mov and call
 N_ORIGINALBYTES 1

 code_start

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

 code_end

patchlet_end
 


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:





Conclusion

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.


Cheers!

@mkolsek
@0patch



Monday, February 11, 2019

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

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.


Analysis


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"
PATCH_ID 349
PATCH_FORMAT_VER 2
VULN_ID 4694
PLATFORM win32

patchlet_start

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

 code_start

  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
 get_lpCaption:
  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
 get_lpText:
  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

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

 code_end

patchlet_end
 

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:




Conclusion


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.]

Cheers!

@mkolsek
@0patch
 


Tuesday, January 22, 2019

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

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"


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 support@0patch.com 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"
PATCH_ID 344
PATCH_FORMAT_VER 2
VULN_ID 4657
PLATFORM win64

patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PIT kernel32.dll!CreateFileW,advapi32.dll!ConvertStringSecurityDescriptorToSecurityDescriptorA,kernel32.dll!LocalFree
PATCHLET_OFFSET 0x00059bd7
JUMPOVERBYTES 11
N_ORIGINALBYTES 2

 code_start

  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
 
  arg0_StringSecurityDescriptor:
  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
 
 code_end

patchlet_end
 


0day #2: the "readfile" (subsequently assigned
CVE-2019-0636)

[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 support@0patch.com 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
PATCH_ID 345
PATCH_FORMAT_VER 2
VULN_ID 4658
PLATFORM win64

patchlet_start

 PATCHLET_ID 1
 PATCHLET_TYPE 2
 PATCHLET_OFFSET 0x002edb76 ; Injecting after eax is set to FlagsAndAttributes

                            ; in CMsiFileCopy::OpenDestination

 code_start

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

                   ; source file's ACL

 code_end

patchlet_end


patchlet_start

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

                            ; MSI record, and setting eax to 1
 JUMPOVERBYTES 20

 code_start

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

 code_end

patchlet_end


patchlet_start

 PATCHLET_ID 3
 PATCHLET_TYPE 2
 PATCHLET_OFFSET 0x002edd0e ; Overwriting code that checks value #12 in

                            ; MSI record, and setting eax to 1
 JUMPOVERBYTES 22

 code_start

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

 code_end

patchlet_end


patchlet_start

 PATCHLET_ID 4
 PATCHLET_TYPE 2
 PATCHLET_OFFSET 0x002edd61 ; Overwriting code that checks value #12 in 

                            ; MSI record, and setting eax to 1
 JUMPOVERBYTES 6

 code_start

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

 code_end

patchlet_end
 



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 support@0patch.com 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"
PATCH_ID 347
PATCH_FORMAT_VER 2
VULN_ID 4656
PLATFORM win64

patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x00087f7a
PIT SHLWAPI.dll!StrCmpNICW,msvcrt.dll!memmove
JUMPOVERBYTES 0
N_ORIGINALBYTES 1

 code_start
 

  ;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
  mailto:
  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
   https:
   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
   http:
   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
  skip:
   ;revert stack:
   add rsp, 20h                ; revert homespace
   pop rax
   pop r8                      ; blank pop
   pop r8
   pop rdx
   pop rcx
   pop rsi
 

 code_end
 

patchlet_end
 


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 support@0patch.com.

Cheers!

@mkolsek
@0patch