Sunday, April 10, 2016

Abusing docmode inheritance: EasyXDM 2.4.19 DOMXSS

In this post, I would like to explain an XSS issue of EasyXDM 2.4.19.
I reported it and it was fixed by the developer.

If you are users, you should update it to EasyXDM 2.4.20.

Release Security update - 2.4.20 · oyvindkinsey/easyXDM · GitHub
https://github.com/oyvindkinsey/easyXDM/releases/tag/2.4.20


This bug is different from the following @kkotowicz's bugs.

http://blog.kotowicz.net/2013/09/exploiting-easyxdm-part-1-not-usual.html
http://blog.kotowicz.net/2013/10/exploiting-easyxdm-part-2-considered.html
http://blog.kotowicz.net/2014/01/xssing-with-shakespeare-name-calling.html

Technical Details

To reproduce this bug, we need a little unusual trick. This bug works on only MSIE. Also, the document mode should be old (IE7 or 5). This is because XSS exists in the part where only buggy browser can pass through. And only old document mode can meet this condition.

Let's look at the code. XSS occurs in the following createElement() part:

https://github.com/oyvindkinsey/easyXDM/blob/2.4.19/src/Core.js#L507-509
    if (HAS_NAME_PROPERTY_BUG) {
        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
    }

The HAS_NAME_PROPERTY_BUG variable of the if statement condition becomes true on an only buggy browser. It is assigned in the following function:

https://github.com/oyvindkinsey/easyXDM/blob/2.4.19/src/Core.js#L474-482
function testForNamePropertyBug(){
    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
    document.body.removeChild(form);
    // #ifdef debug
    _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
    // #endif
}
This code creates a form element and a input element with a name attribute and tries to access to a input element via the name. It seems that IE7 mode cannot access to a element created dynamically with JavaScript via the name. And this code is for testing it.

I created a page for testing this part. You can confirm that the HAS_NAME_PROPERTY_BUG variable becomes true from MSIE.

http://vulnerabledoma.in/easyxdm/name_property_test.html

So, let's confirm this XSS using the vulnerable EasyXDM.

Go to the following URL and change IE7 mode via F12 Developer Tools( F12 -> Emulation tab ). You should see an alert dialog.

http://vulnerabledoma.in/easyxdm/2.4.19_index.html?xdm_e=http%3A%2F%2Fvulnerabledoma.in&xdm_c=%22onload%3dalert(document.domain)//&xdm_p=0

OK, we knew that it actually works. But it works on only IE7 mode so far. This means that an opportunity of attack is very limited.

So, we use the trick called "document mode inheritance" which I took up in my slides recently.



Let's use this!

http://l0.cm/easyxdm/poc.html
<meta http-equiv="x-ua-compatible" content="IE=5">
<iframe src="//vulnerabledoma.in/easyxdm/2.4.19_index.html?xdm_e=http%3A%2F%2Fvulnerabledoma.in&xdm_c=%22onload%3dalert(document.domain)//&xdm_p=0"></iframe>
<script>document.write("document.documentMode: "+document.documentMode)</script>
You still cannot see an alert dialog. The parent window is running in IE5 mode by the meta tag. But the iframe is running in IE8 mode. This is because the iframe page has <!DOCTYPE html>. If it exists, IE11 can bring down the document mode until IE8 mode. To XSS, we somehow have to bring down to IE7 mode.

No worries! Recently I found that IE has the strong inheritance ability at the specific place. You can test this from:

http://l0.cm/easyxdm/poc.eml

Finally, you can see an alert dialog. A difference between the former and this page is that the page is a Content-Type: message/rfc822 format, not text/html. As I have shown in the following my slides, IE/Edge still can open a message/rfc822 document into the browser.


It seems that a message/rfc822 document is rendered in IE5 mode by default. And it seems its docmode inheritance ability is stronger more than a text/html page. Even if the page has <!DCOTYPE html>, we can bring down the document mode until IE7 mode. Due to this, we can reach the vulnerable code. w00t! :)

Using this technique, it can extend the impact. The problem affecting only IE7 mode becomes the problem affecting all IE11 users without being changed to an old document mode by users. It's very useful technique, isn't it? :)

I wrote about XSS in EasyXDM 2.4.19.
That's all. Thank you for reading my post!