How to code your own backdoor?
The best way to understand this security issue is by creating your own backdoor in a system.
What we want to achieve is the ability to execute arbitrary commands on a foreign computer system.
In the end, the entire hack will look like this:
- On the left is the hacker’s server, which acts as a receiver for the output of the commands.
- On the right is the victim server.
- In the middle is where the attack takes place.
If things are clear, let’s build our own simple backdoor in a NodeJS application.
Because we don’t have a big legacy code to hide our vulnerability in, we’ll go with the second case and we’ll pretend that we have a popular npm package for logging messages.
The victim’s application is a simple express based web app that uses our package.
To get what we set out to do, we need to bind our backdoor to the request object. In this way, we can intercept all the incoming requests with our malware. Even just like this and we already have great leverage and we can find out all the user credential or all the secret tokens when they authenticate against an application which uses our package.
To bind to the request object, our backdoor needs to be part of a middleware. Therefore I’ve created an npm package called logger whose purpose is to prettyprint all the incoming requests.
This way, everyone who will use our module will have to connect it to the server as a middleware.
This line of code will trigger our backdoor.
Now by default, these are the parameters:
- req – request is the incoming request to the server
- res – is the response, but this is not interset for us
- next – will call the next middleware in the chain (aka callback)
console.log() – is used as a decoy, because we said our package is used to prettyprint incoming requests, so it has to do something to look legit.
The workflow is the following: we send a request to the victim’s web server with a command and our backdoor will execute that command on the victim’s system.
To do so, we’ll make use of the exec method from child_process which is a default module in NodeJS.
We’ll send the command we want to run on the foreign host as a query parameter along with a password. This way we protect our backdoor from other hackers and we’ll inform the script to omit this request and don’t print it. The developer will never see this attack coming.
To exploit this, we can send a get request formatted like this:
In this way, our password will be validated and the ls (list files) command will be executed against the host.
All we need to do now is to somehow capture the output of the command. There is almost no point to run a command without seeing the output of it.
To see the result of our hack, we’ll make a request to one of our personal servers with the output of the command.
Our personal server, which acts as a receiver, will have the following code:
And to complete our backdoor, we’ll send the output of the commands in the body of a POST request to our server:
There is one last problem: how do we know the address of a victim? To create an attack, we need to know the web address of the victim.
To do so, we add one more handler in our receiver:
Now in our backdoor, we send a request when a new application uses our library.
To do so, complete the previous code with the following snippet:
This way, each time a foreign application uses your npm package and someone accesses that application for the first time, a request will be sent to our receiver which informs us about the URL of the target.
How to protect yourself?
You might be asking yourself, if it is so easy to do it, then why don’t we hear more about this type of attack?
As I said before, the hard part is to hide or in this case to inject the vulnerability. Most of the time, these packages are scanned for vulnerabilities using third-party applications or are manually verified.
To protect yourself against this type of attacks, try to do your best in the following aspects:
- encapsulate your code and give it as little access to the system as you can,
- use well-known and maintained open source components,
- use a good monitoring tool (preferably your own) to keep track of all the request are made to your server.