On June 10, 2016, I published an XSS challenge on the hack.me platform called Small Youtube XSS. If you are here just for the solution and not interested in the write-up, here’s a link Here. Keep reading if you want to know the rules and hints.

Description

In this XSS challenge, you need to use many tricks to create a working vector. It is not that hard, but it is not easy either.

Rules

  • No user interaction allowed.
  • Use only modern browsers (IE11, FF49, etc.)
  • We need to see an alert box with the domain name.

Hints

  • Use (?xss=) as inject.
  • Find missing or weak “things” in the HTTP header and HTML source.
  • Have you ever been told you are too short to join the basketball team? Now you are too long to XSS this.
  • Watch the video for motivation “https://www.youtube.com/watch?v=hzBCI13rJmA”.

If you solve it, please contact me (a.hussam[at]isecur1ty.org), and enjoy!

The challenge has been running for months, and there are only two solvers; it has been started over 1100 times. So here is the solution.

Solution

I deleted the source code long ago, so I’ll try to guess or remember what I wrote before. I made this challenge based on the multi-step filters that do filtering in serial steps.

  • First, it replaces words like eval, setInterval, and setTimeout with (xss-event).
  • Second, it removes the script word (key of solution).
  • Third, it will replace event handler attributes with (xss-event), except for two of them.

HTML entities are enabled on the XSS parameter, so less than, greater than, and double quotation marks are useless.

1
2
3
4
<video width="450" height="400" controls name=injection_here>
  <source src="http://www.google.com/test.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>

Our injection point is at the video tags. Here’s the event handler for video tags HTML5 Video Events and API. You will find they have all been filtered except for two: onloadstart and onratechange. onratechange requires user interaction, so we excluded it.

xss

xss

xss

The domain is filtered, so we must use the script removal trick.

Another problem here is that the payload should be at most 26 characters.

xss

1
2
3
<?php
 $_GET['xss'] = substr( $_GET['xss'], 0, 26);
?>

Plot twist

We should use another method to alert document.domain since the regular payload is too long. We should use eval(). eval will make our string work as JS code, but where could we put a string? We can use window.name. eval is filtered, but we need to use the script trick again, so it will be evscriptal(name). The all-in-one will be:

<a href="http://s25504-102604-rmx.tarentum.hack.me/myvideo.php?xss=''onloadstart=evscriptal(name)" 
target="javascript:alert(domain);">click me</a>

And here we are: There are multiple ways to give a window a name, like window.open or name in the iframe tag, which I allowed to be framed, but I made a frame busting in the page that can be easily bypassed.

Solvers

  • Adam Simuntis (adam.simuntis[at]secforce.com) with a nice and expected solution.
  • Lucas Philippe (Bug in my code which is fixed).

I hope you enjoyed the write-up and the challenge. See you soon with another one. For questions or inquiries, contact me on my Twitter account @Abdulahhusam.