[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CVE-2015-0040: Microsoft Internet Explorer 11 MSHTML CMapElement::Notify use-after-free details

Throughout November, I plan to release details on vulnerabilities I
found in web-browsers which I've not released before. This is the
tenth entry in that series.

The below information is available in more detail on my blog at

Follow me on http://twitter.com/berendjanwever for daily browser bugs.

Microsoft Internet Explorer 11 MSHTML CMapElement::Notify use-after-free
(MS15-009, CVE-2015-0040)

A specially crafted web-page can cause MSIE 11 to interrupt the handling
of one `readystatechange` event with another. This interrupts a call to
one of the various `C<ElementName>Element::Notify` functions to make
another such call and at least one of these functions is non-reentrant.
This can have various repercussions, e.g. when an attacker triggers this
vulnerability using a `CMapElement` object, a reference to that object
can be stored in a linked list and the object itself can be freed. This
pointer can later be re-used to cause a classic use-after-free issue.

Known affected versions, attack vectors and mitigations
* 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.

When a `DocumentFragment` containing an applet element is added to the
DOM, all elements receive a notification that they are removed from the
`CMarkup`. Next, they are added to the DOM and receive notification of
being added to another `CMarkup`. When the applet is added, a
`CObjectElement` is created and added to the `CMarkup`. This causes a
`readystatechange` event to fire, which interrupts the current code.
During this `readystatechange` event, the DOM may be modified, which
causes further notifications to fire. However, elements in the
`DocumentFragment` that come after the applet element have already
received a notification that they have been remove from one `CMarkup`,
but not that they have been added to the new one. Thus, these elements
may receive another notification of removal, followed by two
notifications of being added to a `CMarkup`.

AFAICT, this event-within-an-event itself is the root cause of the bug
and allows memory corruption in various ways. I discovered the issue
because the code in `CMapElement::Notify` is non-reentrant and does not
handle this sequence of events well. This code maintains a singly linked
list of map elements that have been added to the document. An object
should never be added to this list twice, as this will cause a loop in
the list (a map element pointing to itself as the next in
the list). However, the event-within-an-event can be used to first cause
two consecutive calls to remove the same element from this list followed
by two calls to add the same element to the list. This results in the
following sequence of events:

* The first call to remove the element will remove it from the list.
* The second call to remove the element will do nothing.
* The first call to add the element will add it to the list.
* The second call to add the element will try to add it to the list
  again,  causing the list to contain a loop. This list is now corrupt.

At this point, an attacker can remove the `CMapElement`, causing the
code to try to remove it from the list and free it. However, because of
the loop in the list, the above code will not actually remove it from
the list. After this, the pointer in the list points to freed memory and
an attacker can force MSIE to reuse it.

* *September 2014*: This vulnerability was found through fuzzing.
* *September 2014*: This vulnerability was submitted to ZDI.
* *September 2014*: This vulnerability was acquired by ZDI.
* *February 2015*: Microsoft address this issue in MS15-009.
* *November 2016*: Details of this issue are released.



Attachment: 0x2557C5AA.asc
Description: application/pgp-keys

Attachment: signature.asc
Description: OpenPGP digital signature