Pentesting 101: Shells

Up until now, we've discussed using Nmap to scan for open ports, web fuzzers that enumerate directories and files, hash cracking, and we've even taken it a little further toward the victim with brute force attacks where we were able to login to a web application.  But even with the successful login to a web application, I feel like we're sort of just pecking around the perimeter.  Shells take us to that next level where we're able to pierce the skin and get below the surface.

This can be a tricky subject to wrap ones mind around so rather than jumping into the idea of shells immediately, let's start off with leveraging a tool, Netcat, for two way communication.  

To better help (I hope!) keep this straight, I've colored each side.

I'm using the same machine for both sides of this conversation. 

On one side, we have red:





I've listed my IP address and I'm using Netcat setup as a listener.  It's listening for inbound connections on port 443.

On the blue side:





I've also listed my IP address, the same address, and I'm opening an outbound connection to the 192.168.86.99 using port 443.

Moving back to the red side:




We see the inbound connection on the last line.  At this point, we have two way communication between the two sides.





When I type hello? on the red side, we move over to the blue side:





We see our hello?





From the blue side, we reply back:  yes, i am here!





On the red side, we see blue's response.

We've just created a chat session using Netcat.  The back and forth between the two sides is not much different than bind or reverse shells.  The difference is that instead of channeling text back and forth, we channel a Bash shell.

I've moved to a different machine, my ID is vmatteo, my IP address is 192.168.86.203, and with this operating system, I'm required to use sudo to call Netcat in this way.  Not unlike with the homemade chat session from above, I'm calling Netcat to listen on port 443:





Moving over to the blue side, I'm on my original machine but this time, when I call Netcat to reach out, I'm using the -e option which executes an application after the connection:





The blue side is reaching out and after a successful connection, it's going to execute /bin/bash. 

On our red side:





We catch the connection and we have what is called a "reverse shell".  The environment is stable but it's not perfect.  To keep from getting sidetracked, let's just say that the following two commands will clean up the session:

python -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm

Now let's do the same thing but this time, we're going in the opposite direction, a bind shell.  Our red side is listening on port 443 and when the connection is made, we are going to execute /bin/bash:




On our blue side, we're going to connect to our red side on port 443:





When we connect, we catch our shell, I won't bother to clean it up, I just want to check the ID.

Finishing out this topic, I'll discontinue using red and blue.  I think you get the idea and seeing this in the real world makes the connection more than someone explaining it. 

The main difference between the bind and reverse shells is this -- with a bind shell, the victim is listening on a port but with a reverse shell, the victim is reaching out to the attacker.  Why do we often hear more about reverse shell than bind shells?  Firewalls prevent inbound traffic.  If the victim is listening on a port but the firewall is blocking inbound traffic, the connection can't be made.  But in a typical network, outbound traffic is allowed and the reverse shell is an outbound connection.

Up until now, I've been using Netcat but there are a number of other applications that can communicate in a similar fashion.  Python, for example, can also perform bind and reverse shells.  

Webshells are available to us in many languages and a few come stock with Kali Linux.  If we take a look under:  /usr/share/webshells:





We see many options.  The php-reverse-shell.php file, written by Pentestmonky, is very popular.  When we open it up:





We want to change the IP address and port to that of our attacking machine.  For example, our attacking machine is on the IP address of 192.168.86.99 and we're listening on port 443.

If we move this reverse shell, which I've renamed because I'm lazy and I hate typing that long name, into the victim's web directory:





We can point to that file from any web browser:





And over on our attacking machine:





Our listener is setup and it catches that inbound connection -- a reverse shell.  Just to recap this one more time before I move on, if we look at this last screenshot from top to bottom:





1.  Our attacking IP is 192.168.86.99
2.  Our attacking ID is root
3.  Our listener is setup:  nc -lvp 443
4.  We catch the inbound connection from 192.168.86.203 (victim)
5.  When we execute ID, we're no longer on our attacking machine, we're on the victim machine.  Since the web server is running as the user www-data, the response to ID is www-data.

Again, this can be a confusing subject -- at least it was for me.  It didn't really sink in until I started getting my hands dirty.