[<prev] [next>] [day] [month] [year] [list]
Message-ID: <98e1b321-0bfc-a55c-18ba-6b2a746861cf@nwever.nl>
Date: Thu, 24 Nov 2016 09:52:07 +0100
From: Berend-Jan Wever <berendj@...ver.nl>
To: fulldisclosure@...lists.org, Bugtraq <bugtraq@...urityfocus.com>
Subject: [FD] Microsoft Internet Explorer 11 MSHTML
CGeneratedContent::HasGeneratedSVGMarker type confusion
Throughout November, I plan to release details on vulnerabilities I
found in web-browsers which I've not released before. This is the
eighteenth entry in that series. Unfortunately I won't be able to
publish everything within one month at the current rate, so I may
continue to publish these through December and January.
The below information is available in more detail on my blog at
http://blog.skylined.nl/20161124001.html. There you can find a repro
that triggered this issue, reversed snippets from the vulnerable code
and more details in addition to the information below.
Follow me on http://twitter.com/berendjanwever for daily browser bugs.
MSIE 11 MSHTML CGeneratedContent::HasGeneratedSVGMarker type confusion
=======================================================
(The fix and CVE number for this issue are unknown)
Synopsis
--------
A specially crafted web-page can cause a type confusion in HTML layout
in Microsoft Internet Explorer 11. An attacker might be able to exploit
this issue to execute arbitrary code.
Known affected software and attack vectors
------------------------------------------
+ Microsoft Internet Explorer 11
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.
Description
-------
Internally MSIE uses various lists of linked `CTreePos` objects to
represent the DOM tree. For HTML/SVG elements a `CTreeNode` element is
created, which embeds two `CTreePos` instances: one that contains
information about the first child of the element and one that indicates
the next sibling or parent of the element. For text nodes an object
containing only one `CTreePos` is created, as such nodes never have any
children. `CTreePos` instances have various flags set. This includes a
flag that indicates if they are the first (`fTPBegin`) or second
(`fTPEnd`) `CTreePos` instance for an element, or the only instance for
a test node (`fTPText`).
The `CTreePos::Branch` method of an `CTreePos` instance embedded in a
`CTreeNode` can be used to calculate a pointer to the `CTreeNode`. It
determines if the `CTreePos` instance is the first or second in the
`CTreeNode` by looking at the `fTPBegin` flag and subtract the offset of
this `CTreePos` object in a `CTreeNode` object to calculate the address
of the later. This method assumes that the `CTreePos` instance is part
of a `CTreeNode` and not a `TextNode`. It will yield invalid results
when called on the later. In a `TextNode`, the `CTreePos` does not have
the `fTPBegin` flag set, so the code assumes this is the second
`CTreePos` instance in a `CTreeNode` object and subtracts 0x24 from its
address to calculate the address of the `CTreeNode`. Since the
`CTreePos` instance is the first element in a `TextNode`, the returned
address will be 0x24 bytes before the `TextNode`, pointing to memory
that is not part of the object.
Note that this behavior is very similar to another issue I found around
the same time, in that that issues also caused the code to access memory
0x24 bytes before the start of a memory region containing an object.
Looking back I believe that both issues may have had the same root cause
and were fixed at the same time. You can find more details about that
other issue in my blog post here:
http://blog.skylined.nl/20161104001.html
The `CGeneratedContent::HasGeneratedSVGMarker` method walks the DOM
using one of the `CTreePos` linked lists. It looks for any descendant
node of an element that has a `CTreePos` instance with a specific flag
set. If found, the `CTreePos::Branch` method is called to find the
related `CTreeNode`, without checking if the `CTreePos` is indeed part
of a `CTreeNode`. If a certain flag is set on this `CTreeNode`, it
returns true. Otherwise it continues scanning. If nothing is found, it
returns false.
The repro creates a situation where the
`CGeneratedContent::HasGeneratedSVGMarker` method is called on an SVG
path element which has a `TextNode` instance as a descendant with the
right flags set to cause it to call `CTreePos::Branch` on this
`TextNode`. This leads to type confusion/a bad cast where a pointer that
points before a `TextNode` is used as a pointer to a `CTreeNode`.
Exploit
-------
I did not find any code path that could lead to exploitation. However, I
did not do a thorough step through of the code to find out if and how I
might control execution flow upwards in the stack. Also, it appears
trivial to have MSIE survive the initial crash by massaging the heap. It
might be possible that other methods are affected by a similar issue and
that further DOM manipulations can be used to trigger a more interesting
code path.
Time-line
---------
* *July 2014*: This vulnerability was found through fuzzing.
* *September 2014*: This vulnerability was submitted to ZDI.
* *September 2014*: This vulnerability appears to have been fixed.
* *October 2014*: This vulnerability was rejected by ZDI.
* *November 2016*: Details of this issue are released.
Cheers,
SkyLined
Download attachment "0x2557C5AA.asc" of type "application/pgp-keys" (2036 bytes)
Download attachment "signature.asc" of type "application/pgp-signature" (820 bytes)
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/
Powered by blists - more mailing lists