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 decode 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 certain real world filters with a variation on this example:
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 a
real world 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 on the
fact 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 a
real world XSS filter I came accross using an open ended IFRAME tag
instead of an IMG tag:
SSI (Server Side Includes) requires SSI to be installed on the server:
IMG Embedded commands - this works when the webpage where this is
injected (like a web-board) is behind password protection and that
password protection works with other commands on the same domain. This
can be used to delete users, add users (if the user who visits the page
is an administrator), send credentials elsewhere, etc.... This is one
of the lesser used but most useful XSS vectors:
XSS using HTML quote encapsulation: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".
I know I said I wasn't goint to discuss mitigation techniques but the
only thing I've seen work for this XSS example if you still want to
allow <SCRIPT> tags but not remote script is a state machine (and
of course there are other ways to get around this if they allow
<SCRIPT> tags):
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). I actually used a similar
attack vector against a real world XSS filter by using the conversion
filter itself to help create the attack vector (IE:
"java&#x09;script:" was converted into
"java	script:", which renders in IE and Opera):
Charachter Encoding:
All the possible combinations of the charachter "<" in HTML and JavaScript (standards are great, aren't they?):
Character Encoding Calculator
|