November 05, 2008

Why use expression() when there's HTC

Intro

HTML Components (HTC) have first time found their way into implementation with Internet Explorer 5. Since then HTC has been a topic without a lot of light being shed on - almost similar to HTA. Meanwhile this feature has been almost forgotten - which is kind of a shame since this is the second way for IE browsers to execute JavaScript and other code being triggered and included by style sheets. We mentioned before that expression() will have a hard time on IE8 - so why not working with the alternative.

HTC files have to be located on the same domain the site using this feature is running from. That might sound like massively narrowing the attack window but almost similar to the earlier mentioned XBL issue it isn't. HTC files can be outfitted with an almost infinite amount of padding. As long as there is some HTC code inside the included file the browser meaning IE will accept and parse it and execute the nested code.

Some code

Let's have a look at a brief example. There's an inclusion of a HTC file with an almost arbitrary file name suffix - thanks to Apache again.

<html>
<head>
<style>
    body {
        behavior: url(test.gif.htc);
    }
</style>
</head>
<body>
<h1>CLICK ME!</h1>

</body>
</html>

The HTC file itself is actually a valid GIF file that is being processed without any problems by imaging tools, browsers and of course the usual method checking for the right MIME type, image dimensions et cetera. Here's the GIF.

GIF89ad�d����������!�Y,����d�d��s��������ڋ�޼���H�扦�ʶ���L������� �Ģ�L*�̦� �J�Ԫ��j�ܮ�����N���� ����������(8HXhx��������iX�

Above we see what the file looks like in a standard text editor. To reveal the payload the file has to be opened in a hex editor. It's also possible to choose almost random file types like archives, other image types, MP3s, videos etc.

Decoded the output will look like this

GIF89ad.d..........!.Y
<PUBLIC:COMPONENT>
<PUBLIC:ATTACH EVENT="onclick" ONEVENT="alert(1)" />
</PUBLIC:COMPONENT>
.,....d.d...s..................H...........L...
.............L*......J......j............N.....
................(8HXhx.........iX..;

Conclusion

Understanding and creating HTC files is easy - and it's even more easy to hide them in arbitrary file containers and manage to get those files uploaded to the targeted web server.

If Microsoft depends on this feature or fears breaking the web by removal there should be at least some validation that makes sure that a HTC is really a HTC - and nothing else being wrapped around the payload. Applications that provide uploads of images or whatever file types should make sure that the content of the uploaded files is being checked for suspicious patterns and blocked in case of a finding.

ShowModalDialog() and Firefox

Intro

Firefox has been "reverse engineering" a lot of features Internet Explorer ventured to release past the W3C specifications - including the already mentioned oncopy/oncut/onpaste events. A very special one of those is the implementation of showModalDialog(). Imagine this feature to be like an alert - but only filled with arbitrary HTML via a URL, dataURI or javascript: URI.

Code

<html>
<head>
<script>
onfocus = function() {
 name = 'javascript:with(this)with(document)write(cookie)';
 showModalDialog(
     name,
     null,
     'unadorned:no,dialogWidth:4000%,dialogHeight:2000%,scroll:0,status:0,resizable:0,edge:sunken'
 );
 onfocus = null;
}
</script>
</head>
<body>
</body>
</html>

Interesting is on the one hand that it's possible to circumvent the pop-up blockers in most recent browser releases by just choosing window.onfocus as triggering event. Firefox 3 shows a warning on the originating view that a pop up has been blocked - but renders the modal window anyway. If triggered early enough it also outruns a window.onload. Onfocus seems to be considered as an event that has to be triggered by user interaction so the pop up blocker lets it pass - like with onclick or ondblclick. And not to forget - onfocus on window fires as soon as the window's document is starting to load.

The major problem is the fact that the showModalDialog() method is either a member of window and can be parametrized. It's therefore possible to let a GUI element pop up that might give the user the impression that it's a browser instance itself. Just add most common browser buttons as image map - depending on the used user agent, give the window the right dimensions and position and most users will fall for it.

Furthermore the dialog being spawned cancels all code execution happening between the time of the spawning and the moment the modal is being closed again. The browser can access the origination window object as well as methods like dump().

Conclusion

ShowModalDialog() is one of the more or less useless and standard agnostic techniques that is predestined for fishing without even a real world use for most if not all applications. Security aware developers might want to make sure by overwriting this method that an XSS on their platform has less impact than necessary. Thanks to the flexibility of JavaScript it's more easy then expected - just set showModalDialog = null at the earliest point in your DOM that is possible - most perfectly at a spot where no user input is being expected before. Safari and Opera are by the way not affected - they just ignore the method call or throw an error since it's not implemented.