Today we released Security Advisory 2501696 to alert customers to a publicly disclosed vulnerability in the MHTML protocol handler. This vulnerability could allow attackers to construct malicious links pointing to HTML documents that, when clicked, would render the targeted document and reflected script in the security context of the user and target location. The end result of this type of vulnerability is script encoded within the link executed in the context of the target document or target web site.
How could I know if my machine is affected?
By default, the MHTML protocol handler is vulnerable on Windows XP and all later supported Windows versions. Internet Explorer is an attack vector, but because this is a Windows vulnerability, the version of IE is not relevant.
How could I protect client systems?
The security advisory lists steps to lock down the MHTML protocol handler for either all Internet Zone scenarios or to disable it altogether. We have previously blogged about the Network Protocol Lockdown workaround here. You can also click the button below to enable the Network Protocol Lockdown for mhtml: for all security zones:
More information about this FixIt at KB 2501696.
What would be the side-effect of MHTML lockdown workaround?
In our testing, the only side effect we have encountered is script execution and ActiveX being disabled within MHT documents. We expect that in most environments this will have limited impact. While MHTML is an important component of Windows, it is rarely used via mhtml: hyperlinks. Most often, MHTML is used behind the scenes, and those scenarios would not be impacted by the network protocol lockdown. In fact, if there is no script content in the MHT file, the MHT file would be displayed normally without any issue. Finally, for legitimate MHT files with script content that you would like to be rendered in IE, users can click the information bar and select “Allow All Protocols”, as shown below.
Doing so would temporarily allow the script content in the MHT file, and thus keep MHT files rendered correctly. Please note here that selecting “Allow All Protocols” will not undo the MHTML workaround permanently.
How can I know whether my service is at risk?
Any service that allows user input to be reflected back to the user could be affected by this issue. However the impact of scripting injected into a service is dependent on how the service itself is implemented. In this way, the impact is the same a server-side cross-site scripting issue but the vulnerability lies in the client.
What actions could service provider owners take?
First, please recommend that your customers apply the client-side workaround in the Security Advisory. This will prevent customers from being affected no matter how an attacker chooses to craft the link.
There are potential server-side workarounds that a service owner could employ. We’re working with service providers like Google and others as we explore these options. Some of these ideas are listed below. Each of these approaches is worth exploring and we continue to do so. However, they may be difficult for websites to implement comprehensively. For example, while newline filtering might be introduced in certain scenarios, low-level HTTP error response pages could reflect data in a way that is difficult to identify and mitigate. Each of the ideas are intended to break the parsing of MIME content and include:
Additionally, client/server interactions and decoding behavior may mean that in certain configurations these approaches are not fully effective.
We will continue to investigate server-side workarounds, and will continue to update with guidance as more are discovered. However, for the reasons above we recommend using the client-side workaround listed in the advisory, which can block exploits regardless of the service.
How can I test that a client system is protected?
Here are the steps to set up a test to ensure that a machine on which the workaround is enabled is protected from this vulnerability.
Step 1: Create the test.mht with the following content:
From: "Test"Subject: Date: Mon, 1 Jan 1111 11:11:11 -0800MIME-Version: 1.0Content-Type: text/html; charset="utf-8"Content-Transfer-Encoding: quoted-printableX-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16543 =EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><META content=3D"text/html; charset=3Dutf-8" http-equiv=3DContent-Type><SCRIPT>function foo(){alert("hello");}</SCRIPT> <META name=3DGENERATOR content=3D"MSHTML 8.00.7600.16700"></HEAD><BODY onload=3Dfoo()>test MHTML protocol </BODY></HTML>
From: "Test"
Subject:
Date: Mon, 1 Jan 1111 11:11:11 -0800
MIME-Version: 1.0
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16543
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Dutf-8" http-equiv=3DContent-Type>
<SCRIPT>
function foo()
{
alert("hello");
}
</SCRIPT>
<META name=3DGENERATOR content=3D"MSHTML 8.00.7600.16700"></HEAD>
<BODY onload=3Dfoo()>test MHTML protocol </BODY></HTML>
Step 2: Upload the test.mht to a web server.
Before applying the workaround, when you navigate to Error! Hyperlink reference not valid., the following screen pops up:
As shown, the script within MHTML content is running.
After applying the workaround and restarting IE, when you navigate to Error! Hyperlink reference not valid., the following screen pops up:
The information bar indicates that the MHTML protocol is locked down so the script is not allowed to run.
- Dave Ross and Chengyun Chu, MSRC Engineering
We have just updated Security Advisory 2488013 for the publicly-disclosed Internet Explorer CSS vulnerability. It now reflects the fact that limited attacks attempting to exploit this vulnerability are present in-the-wild. The advisory also includes a new workaround that can help protect your computers until a security update is available. This workaround is different from the workarounds that we typically recommend, and so we wanted to give you more detail about it here.
Vulnerability Recap
This vulnerability requires an attacker to provide a CSS style sheet that includes a reference to itself with an @import command. When Internet Explorer tries to load this recursive style sheet, it corrupts memory in a way that could be exploited for arbitrary code execution. Unfortunately, there is no way to selectively disable this functionality, which is why the best workaround up to this point is to enable EMET to block aspects of the known exploits from being successful.
The new workaround
This workaround is an MSI package (Microsoft "FixIt") that uses the Windows application compatibility toolkit to make a small change to MSHTML.DLL every time it is loaded by Internet Explorer. This change causes Internet Explorer to refuse to import a CSS style sheet if it has the same URL as the CSS style sheet from which it is being loaded. Simply put, the workaround inserts a check to see if a style sheet is about to be loaded recursively, and if it so, it aborts the load of the style sheet. You can read more about the Windows infrastructure that allows this type of workaround here: http://technet.microsoft.com/en-us/library/cc748912(WS.10).aspx
It’s important to note that the workaround will protect Internet Explorer only if the latest security updates have been applied, including MS10-090 which was released on December 14, 2010. You can find MS10-090 at http://www.microsoft.com/technet/security/bulletin/MS10-090.mspx.
To install the workaround, click here: http://download.microsoft.com/download/E/5/6/E56904FD-3370-479D-B14A-E5481222C59C/MicrosoftFixit50591.msi
If you’d like to uninstall the workaround after you have installed it, click here: http://download.microsoft.com/download/3/3/3/33346329-840F-4B9F-B54E-9AE1114EA331/MicrosoftFixit50592.msi
How the workaround works
Internet Explorer represents CSS style sheets with an instance of the mshtml!CStyleSheet class. The CStylesheet Create() method is called on every style sheet import and has access to the URL of both the parent and child style sheets. To get the absolute URL of the child style sheet, it calls the function ExpandUrlWithBaseUrl, as in the following assembly and graphic:
mshtml!CStyleSheet::Create+0x197: 6ebb7065 50 push eax 6ebb7066 8d95f0dfffff lea edx,[ebp-2010h] 6ebb706c e8326a1a00 call mshtml!ExpandUrlWithBaseUrl (6ed5daa3)
The workaround replaces this function call with a call to a new function the workaround introduces. This new function does the following things:
Now you may ask, where is this new function implemented? The workaround overwrites a function which is only used on process shut down to clean up debugging resources. It changes the first instruction to a ret, so normal calls to this function will simply return, and then implements the workaround check. Here’s a graphic representing the new flow:
What the workaround changes look like
After the workaround is applied, the relevant part of CStyleSheet::Create() is updated to:
mshtml!CStyleSheet::Create+0x197: 6ebb7065 50 push eax 6ebb7066 8d95f0dfffff lea edx,[ebp-2010h] 6ebb706c e8a0f51b00 call mshtml!DeinitScriptDebugging+0x1 (6ed76611)
Note it calls into DeinitScriptDebugging() + 1.
DeinitScriptDebugging() is changed to:
mshtml!DeinitScriptDebugging: //when this function is called by other code, return immediately 6ed76610 c3 ret //call ExpandUrlWithBaseUrl() to translate the child’s relative URL to an absolute one 6ed76611 50 push eax 6ed76612 52 push edx 6ed76613 50 push eax 6ed76614 e88a74feff call mshtml!ExpandUrlWithBaseUrl (6ed5daa3) //if the call failed, return the failure code 6ed76619 85c0 test eax,eax 6ed7661b 751a jne mshtml!DeinitScriptDebugging+0x2f (6ed76637) //call _wcsicmp() to compare the parent and child’s absolute URLs 6ed7661d 5a pop edx 6ed7661e 8b12 mov edx,dword ptr [edx] 6ed76620 58 pop eax 6ed76621 e8748ff8ff call mshtml!_wcsicmp (6ecff59a) //if they are equal, return 80004005h, otherwise, return 0 6ed76626 85c0 test eax,eax 6ed76628 7405 je mshtml!DeinitScriptDebugging+0x27 (6ed7662f) 6ed7662a 31c0 xor eax,eax 6ed7662c c20400 ret 4 6ed7662f b805400080 mov eax,80004005h 6ed76634 c20400 ret 4 6ed76637 5a pop edx 6ed76638 5a pop edx 6ed76639 c20400 ret 4
Why the workaround is safe to install
The workaround does all of the following checks before modifying MSHTML.DLL:
This ensures that it is not applied to the wrong version of MSHTML.DLL and that the results of the change are what were intended by the workaround. If a certain MSHTML.DLL does not pass all of these checks, it will not be modified.
Applying this workaround will not interfere with the installation of the final security update to address this issue. However, applying the workaround will have a small effect on the startup time of Internet Explorer. In our testing, we found that it added approximately 150ms to the process start time. Therefore, as you are applying the final security update, you should uninstall the workaround as it will no longer be needed. We also recommend that you test this workaround with any internal line-of-business applications before deploying it. The final security update to address this issue will be fully tested and ready for broad deployment.
What about CSS style sheet loops?
During our investigation, the question came up: what about A.css importing B.css which then imports A.css? In other words, would a CSS style sheet loop trigger the vulnerability too? Fortunately, through testing and code review we’ve determined that this configuration of CSS style sheets will not trigger the vulnerability, so simply checking that the child style sheet has a different absolute URL from the parent style sheet is sufficient to detect and block attacks.
Acknowledgements
Special thanks to Bruce Dang, Jonathan Ness, and Matt Miller for their work on this workaround. Thanks to Robert Hensing for his championing of this type of workaround starting in 2009. (/wave Rob)
- Kevin Brown, MSRC Engineering
*Posting is provided "AS IS" with no warranties, and confers no rights.*
At Microsoft, as at most large software vendors, we are likely to have publicly known issues under investigation at any given time. This is what we do on the Security Research & Defense team. Recently we’ve seen confusion from folks trying to make sense of some of the current public issues. To help clear that up, we offer this table of information to help customers make a risk assessment for their particular environment. Note that applying the Microsoft-recommended workaround for any issue in the table removes the risk posed by the issue entirely.
(CVE-2010-3971)
Anti-virus and IDS/IPS signatures developed by our MAPP partners for this issue have also been quite effective at detecting and blocking attacks.
(CVE-2010-3970)
Proof-of-concept code we have seen so far requires a user to browse to an attacker-writable folder using Windows Explorer. If Explorer is set to display thumbnails or a preview of contained files (neither setting is the default), the chance of code execution exists. Current proof-of-concept code is not successful when Explorer is set to display files in the default List mode.
(SRD blog post)
If you have enabled IIS FTP service, consider disabling it, if possible, until a security update is available.
The real-world risk to most customers from this issue is expected to be quite low.
The attached .txt file, if renamed to .reg and opened, will apply the killbit to the affected clsid’s.
We hope that this helps customers make a risk assessment for your environment. We are closely monitoring each of these issues, and we will update or issue advisories if the threat landscape changes.
Thanks to each of the case managers and security engineers who worked over the holidays to respond appropriately to these public disclosures!
- Jonathan Ness, MSRC Engineering