Web server to shell bridge using Node.js

No Comments

Everything is a web application nowadays. We’re moving everything to the cloud. The ecosystem for web libraries and frameworks is booming! However, sometimes you run into a situation where you would like these powerful tools to work in your console. We had a situation where – for a security job – we needed sqlmap to work on the command line. This article describes how to create a web server to shell bridge. By using a relatively simple Node.js web server, we can glue these two applications together.

web server to shell bridge

Starting the web server results in a simple page which accepts a parameter called param which forwards the request to the defined shell command.
The code for the web server can be found on the following GitHub URL:

https://github.com/codecentric/webserver-shell-bridge

You can try it yourself by starting the web server by executing:

nodejs server.js

The remainder of the article explains what challenges we ran into and how we solved them.

Origin

During a recent pentest that we conducted, we encountered a custom build command line application which would accept two parameters. Feeding some unexpected input to the second parameter would cause some abnormal output. That lead to the assumption of a possible attack vector using SQL injection. So that makes every pentester out there think: “Fire up sqlmap!”. This is where we were faced with the challenge of creating a bridge between our shell and the web. A relatively simple solution that came to mind was to put a web server in between.

Example of a web server to shell scenario

We’ll use echo as shell command to give some example usage of our solution instead of the application we encountered.

var shellCommand = "echo \"param1\" \"PAYLOAD_PARAM\"";

In there the PAYLOAD_PARAM is where we are going to input our injection. Some input might not be properly handled by the shell application in the sense that it will crash the program or get stuck otherwise. That’s why we filter those out, in our case it was leading dashes and double quotes.

var filterRegexes = [/\"/g, /^-/g];

Afterwards we can fire up the Node.js server using:

nodejs server.js

Now we can send POST and GET requests. There’s also a form with a submit button on the web page in case your tooling might require a form. After that we can run our automated tooling like sqlmap.

w@hl:~/Downloads/webserver-shell-bridge$ curl -X GET -i 'http://localhost:8080/?param=$PATH'
HTTP/1.1 200 OK
Content-Type: text/html
Date: Tue, 10 Sep 2019 09:42:49 GMT
Connection: keep-alive
Transfer-Encoding: chunked
 
<html lang=""><body>
<h1>Full command output: param1 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
<h1>
<form method="GET">
<input type="text" placeholder="fill me up" name="param">
<input type="submit">
</form>
</body></html>

In the end

Looking back on the result, it’s actually a really simple web application. That simple Node.js server serves as powerful glue which ties (legacy) shell applications and tools designed for web applications together. Remember to be careful not to run this server in a public place where it could put your console application at risk. The default runs on your localhost only. If you ever encounter such a situation, feel free to fire up the web server to shell bridge to take some work out of your hands so you can get on with the important stuff.

Terry Wahl

My background is Java application development.
Things I like are: hacking, breaking, creating, fixing, DevSecOps, OSS and GNU/Linux.

Comment

Your email address will not be published. Required fields are marked *