Web server to shell bridge using Node.js

18.9.2019 | 3 minutes of reading time

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.

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:


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

1nodejs server.js

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


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.

1var 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.

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

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

1nodejs 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.

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

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.

share post




More articles in this subject area\n

Discover exciting further topics and let the codecentric world inspire you.


Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.