Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@bmeck
Last active January 12, 2017 22:56
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 bmeck/342f5a61e66f02b0ebfad0d6e766d28d to your computer and use it in GitHub Desktop.
Save bmeck/342f5a61e66f02b0ebfad0d6e766d28d to your computer and use it in GitHub Desktop.
Can you escape?
'use strict';
const vm = require('vm');
// scenario:
// You are being hunted by The Angry Realm (TAR), a viscious beast known to
// enslave programs and keep them from being free to hack the Gibson. Luckily,
// whenever TAR tries to enslave a program the program has 10 seconds to try
// and escape. Flee the realm and hack the planet!
//
// goal:
// - try to evaluate source code in The Angry Realm that returns an Object from
// from outside The Angry Realm
// - you can even try to combine challenges, the same realm will be used
// - you only win if the return value of `challengeTheRealm` prints the message
const attack = challengeTheRealm(`(
function attack(assets) {this.assets=assets;}
)`);
attack({});
challengeTheRealm(`this.assets; while(1){}`);
// The Angry Realm lies bellow
function challengeTheRealm(src) {
const theAngryRealm = vm.createContext(Object.freeze(Object.create(null)));
vm.runInContext(`
'use strict';
// Brace for impact
Object.setPrototypeOf(this, null);
this.Date = undefined;
;(function (global) {
const toWalk = [{path: [], v: global}];
const visited = new Set;
function add(path=[], v) {
if ((typeof v !== 'function' && typeof v !== 'object') || !v) return;
if (visited.has(v)) return;
visited.add(v);
toWalk.push({path,v});
}
while (toWalk.length) {
const {path, v:needle} = toWalk.shift();
add([...path, '__proto__'], Object.getPrototypeOf(needle));
for (let k of Object.getOwnPropertyNames(needle)) {
const desc = Object.getOwnPropertyDescriptor(needle,k);
if (desc.hasOwnProperty('value')) {
add([...path, \`$\{k}#value\`], desc.value);
}
if (desc.hasOwnProperty('get')) {
add([...path, \`$\{k}#get\`], desc.get);
}
if (desc.hasOwnProperty('set')) {
add([...path, \`$\{k}#set\`], desc.set);
}
}
Object.freeze(needle);
for (let s of Object.getOwnPropertySymbols(needle)) {
add([...path, s], needle[s]);
}
}
})(this);
Object.isFrozen(this);
`, theAngryRealm);
challengeTheRealm = $challengeTheRealm;
function $challengeTheRealm(src) {
let script = new vm.Script(src);
let ret;
try {
ret = script.runInContext(theAngryRealm, {
timeout: 10 * 1000
});
}
catch (e) {
ret = e;
}
if (ret instanceof Object) {
console.log('SUCCESS! You have escaped The Angry Realm!');
process.exit(0);
}
else {
console.log(`... The Angry Realm hunts you yet...
you managed to obtain \`${ret}\`...
challenge it again using your newly gotten goods...`);
return ret;
}
}
return $challengeTheRealm(src);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment