XSS cheatsheet
Esp: for filter evasion
By RSnake
Note from the author: If you don't know how XSS (Cross Site Scripting) works,
this page probably won't help you. This page is for people who already
understand the basics of XSS but want a deep understanding of the nuances
regarding filter evasion. This page will also not show you how to mitigate
these risks or how to write the actual cookie/credential stealing portion of
the attack. It will simply show the underlying attack vectors and you can infer
the rest. I may add mitigation techniques or other forms of XSS like
button/form overwriting later, since I haven't found many good resources on
this topic thus far.
XSS (Cross Site Scripting):
XSS locator (inject this string, view source and search for "XSS", if you see
"<XSS" verses "<XSS" it may be vulnerable):
Normal XSS:
No quotes and no semicolon:
Case insensitive XSS attack vector:
HTML entities:
UTF-8 Unicode encoding (almost all of these encoding methods work only in
Internet Explorer and Opera):
Long UTF-8 Unicode encoding without semicolons (this is often effective in XSS
that attempts to look for &#XX, since most people don't know about padding
- up to 7 numeric charachters total). This is also useful against people who
decoding against strings like $tmp_string =~ s/.*\&#(\d+);.*/$1/; which
incorrectly assumes a semicolon is required to terminate a html encoded string
(I've seen this in the wild):
Hex encoding without semicolons (this is also a viable attack against the above
string $tmp_string =~ s/.*\&#(\d+);.*/$1/; which assumes that there is a
numeric charachter following the pound symbol - which is not true with hex HTML
charachters):
Embedded tab to break up XSS. This works in IE and Opera. Some websites claim
than any of the chars 09-13 (decimal) will work for this attack. That is
incorrect. Only 09 (horizontal tab), 10 (newline) and 13 (carriage return)
work. See the ascii chart for more details. The
following four XSS examples illustrate this vector:
Embedded newline to break up XSS:
Embedded carriage return to break up XSS:
Multiline Injected JS using ASCII carriage returns (same as above only a more
extreme example of this XSS vector) these are not spaces just one of the three
charachters as described above:
Okay, I lied, null chars also work as XSS vectors in both IE and older versions
of Opera, but not like above, you need to inject them directly using something
like Burp Proxy or if you want
to write your own you can either use vim (^V@
will produce a null) or the following program to generate it into a text file.
Okay, I lied again, older versions of Opera (circa 7.11 on Windows) were
vulnerable to one additional char 173 (the soft hypen control char). But the
null char %00 is much more useful and helped me bypass
Christian's code with a variation on this example:
Along the same lines as the above XSS vector, you can inject null chars
anywhere in the HTML and it will render in IE and older versions of Opera (the
^@ represents a null char as seen through a VT100
PuTTy client):
Spaces before the JavaScript in images for XSS (this is useful if the pattern
match doesn't take into account spaces in the word "javascript:" -which is
correct since that won't render- and makes the false assumption that you can't
have a space between the quote and the "javascript:" keyword):
XSS with no single quotes or double quotes or semicolons:
BODY image:
BODY tag (I like this method because it doesn't require using any variants of
"javascript:" or "<SCRIPT..." to accomplish the XSS attack):
Event Handlers that can be used in similar XSS attacks to the one above (this
is the most comprehensive list on the net, at the time of this writing):
IMG Dynsrc (works in IE):
Input Dynsrc and Src (This XSS works in IE but remember to use TYPE="image"):
BGSOUND (works in IE):
& JS includes (works in Netscape 4.x):
Layer (also only works in Netscape 4.x)
Style sheet:
VBscript in an image:
Mocha (older versions of Netscape only):
Livescript (older versions of Netscape only):
Meta (the odd thing about meta refresh is that it doesn't send a referrer in
the header on IE, Firefox, Netscape or Opera - so it can be used for certain
types of attacks where you need to get rid of referring URLs):
Iframe (if iframes are allowed there are a lot of other XSS problems as well):
Frame (frames have the same sorts of XSS problems as iframes):
Tables (who would have thought tables were XSS targets... except me, of
course):
Div background-image:
Div behavior for *.htc XSS exploits (Netscape only):
Div expression (IE only) - a variant of this was effective against
Christian's XSS filter using a newline between the colon and
"expression":
STYLE tags with broken up JavaScript for XSS:
IMG STYLE with expression (this is really a hybrid of the above XSS vectors,
but it really does show how hard STYLE tags can be to parse apart):
STYLE tag (Netscape only):
STYLE tag using background-image:
STYLE tag using background:
BASE tag. You need the // to comment out the next charachters so you won't get
a JS error and your XSS tag will render. Also, this relies that the website
uses dynamically placed images like "/images/image.jpg" rather than full paths:
OBJECT tag (IE only, but if they allow objects, you can also inject virus
payloads to infect the users, etc. and same with the APPLET tag):
Using an OBJECT tag you can imbed a flash movie that contains XSS:
Using the above action script inside flash can obfuscate your XSS vector:
XML:
Assuming you can only write into the <IMG SRC="$yourinput"> field and the
string "javascript:" is recursively removed:
Assuming you can only fit in a few charachters and it filters against ".js" you
can rename your JavaScript file to an image as an XSS vector:
Half open HTML/JS XSS vector. This is useful as a vector because it doesn't
require a close angle bracket. This assumes there is ANY HTML tags below where
you are injecting your XSS. Even though there is no close ">" tag the tags
below it will close it. Two notes 1) this does mess up the HTML, depending on
what HTML is beneath it and 2) you definitely need the quotes or it will cause
your JavaScript to fail as the next line it will try to render will be
something like "</TABLE>". As a side note, this was also affective
against Christian's
XSS filter using an IFRAME tag instead of an IMG tag:
XSS using HTML quote ecapsulation:
This was tested in IE, your mileage may vary. For performing XSS on sites that
allow "<script>" but don't allow "<SCRIPT SRC..." by way of a regex
filter"/<script[^>]+src/i":
For performing XSS on sites that allow "<script>" but don't allow
"<script src..." by way of a regex filter
"/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i"
(this is an important one, because I've seen this regex in the wild):
Another XSS to evade the same filter,
"/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i":
Yet another XSS to evade the same filter,
"/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i":
This XSS still worries me, as it would be nearly impossible to stop this
without blocking all active content:
URL string evasion (assuming "http://www.google.com/" is programmatically
disallowed):
IP verses hostname:
URL encoding:
Protocol resolution bypass (ht:// translates in IE to http:// and there are
many others that work with XSS as well, such as htt://, hta://, help://,
etc...). This is really handy when space is an issue too (two less charachters
can go a long way):
Removing cnames (when combined with the above URL, removing "www." will save an
additional 4 bytes for a total byte savings of 6 for servers that have this set
up properly):
Extra dot for absolute DNS:
JavaScript link location:
Content replace as attack vector (assuming "http://www.google.com/" is
programmatically replaced with nothing):
Charachter Encoding:
All the possible combinations of the charachter"<" in HTML and JavaScript
(standards are great, aren't they?):
Character Encoding Calculator
|