- Introduction
- Requirements
- Assumptions
- Setup Before Port Forwarding
- Setup After Port Forwarding
- Did it work?
- No love for Windows?
1. Introduction
During my preparation for the PWK/OSCP course (starting late January), I had a hard time understanding how port forwarding/tunneling works. Most guides I found were too theoretical for my taste, this guide will allow you to mimic a strict corporate firewall and how to bypass it.
So what is port forwarding? It’s a technique that allows you to redirect traffic from one port to another port/IP. What the hell does that mean?
Imagine the following scenario:
Your corp firewall only allows outbound connections to web servers running on standard ports (port 80 for HTTP / port 443 for HTTPS). Your favorite security news website for some reason is run on port 8000. Given the strict corp firewall you won’t be able to browse the site any more.
You decide to use your knowledge of port forwarding to still be able to browse your favorite site. We’ll be using rinetd as TCP forwarder.
2. Requirements
To follow this guide you’ll need the following:
- Host machine capable of running 2 Linux VMs.
- LAN network.
- Some patience.
3. Assumptions
All machines are on the same network for simplicity, thus no router
configuration is needed.
Machine | IP |
---|---|
abatchy-work | 192.168.20.130 |
abatchy-proxy | 192.168.20.131 |
abatchy-http | 192.168.20.132 |
-
192.168.20.130: Work machine, ideally it’s behind a NAT and firewalled. For simplicity it’s in the same LAN and iptables is used instead.
-
192.168.20.131: Home machine, used as proxy to forward inbound traffic on port 80 to 192.168.20.132 on port 8000.
-
192.168.20.132: Web server running your favorite site on non-standard port 8000, inaccessible directly from your work machine because of firewall.
4. Setup Before Port Forwarding
We’ll be configuring the following setup:
4.1 Setting up Apache server
We’ll start by setting up our Apache server on 192.168.20.132 (Web server)
// Install Apache server
abatchy@abatchy-http:~$ sudo apt-get install apache2
// Change default port Apache is listening on to 8000
abatchy@abatchy-http:~$ sudo nano /etc/apache2/ports.conf
// Change virtual host from
// <VirtualHost *:80>
// to
// <VirtualHost *:8000>
abatchy@abatchy-http:~$ sudo nano /etc/apache2/sites-enabled/000-default
// Restart Apache server
abatchy@abatchy-http:~$ sudo service restart apache2
Now let’s verify it’s working as expected.
//sudo is needed since netstat won't show processes not owned by abatchy
abatchy@abatchy-http:~$ sudo netstat -antp | grep apache2
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 4523/apache2
4.2 Configuring iptables
Next, we’ll configure iptables on 192.168.20.130
(work machine) to drop any
outgoing traffic except for ones using TCP port 80 and 443.
// Verify that there are no rules defined yet
abatchy@abatchy-work:~$ sudo iptables -L
[sudo] password for abatchy:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
// Block all traffic
abatchy@abatchy-work:~$ sudo iptables -I OUTPUT -j DROP
// Allow outbound traffic on port 80
abatchy@abatchy-work:~$ sudo iptables -I OUTPUT -p tcp --dport 80 -j ACCEPT
// Allow outbound traffic on port 443
abatchy@abatchy-work:~$ sudo iptables -I OUTPUT -p tcp --dport 443 -j ACCEPT
// View current rules defined
abatchy@abatchy-work:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
**ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere tcp dpt:http**
DROP all -- anywhere anywhere
Notice the order the rules were applied. -I
was used to put the rules on top of the chain, thus overriding the “block all traffic” rule. One more thing is that you can’t make DNS requests / resolve URLs since UDP port 53 is included in the rule.
Next, let’s ensure that the current rules work properly.
abatchy@abatchy-work:~$ wget http://192.168.20.132:8000
--2017-01-12 03:01:24-- http://192.168.20.132:8000/
Connecting to 192.168.20.132:8000... ^C
As expected, we’re not able to connect to http://192.168.20.132:8000
. In case you want to see logs of the dropped packets check this.
5. Setup After Port Forwarding
5.1 Data flow
(1) Outgoing traffic to 192.168.20.131:80
which our firewall will let through to our switch.
(2) On our proxy machine, we will have rinetd
listening on port 80.
(3) and (4) Traffic is forwarded by rinetd
to our webserver, listening on 192.168.20.132:8000
.
(5) and (6) Web server replies back to our proxy machine.
(7) Proxy replies back to our work machine, traffic still flowing as it’s on port 80.
5.2 Rinetd on proxy machine
Rinetd is a very light-weight, simple-to-use TCP forwarder, we will set it up so it redirects incoming traffic on port 80 to 192.168.20.132:8000
(our web server).
// Install rinetd
abatchy@abatchy-proxy:/home$ sudo apt-get install rinetd
// Add the following rule below the comment
abatchy@abatchy-proxy:/home$ sudo nano /etc/rinetd.conf
# bindadress bindport connectaddress connectport
192.168.20.131 80 192.168.20.132 8000
// Restart the service
abatchy@abatchy-proxy:/home$ sudo service rinetd restart
6. Did it work?
abatchy@abatchy-work:~$ wget http://192.168.20.131:80
--2017-01-12 19:56:35-- http://192.168.20.131/
Connecting to 192.168.20.131:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20 [text/html]
Saving to: ‘index.html’
100%[======================================>] 20 --.-K/s in 0s
2017-01-12 19:56:35 (6.33 MB/s) - ‘index.html’ saved [20/20]
abatchy@abatchy-work:~$ cat index.html
Super cool website!
It worked! A wireshark capture below on the proxy shows the traffic flow.
2266-2268: Three way handshake between Work and Proxy:80.
2269-2270: GET request and ACK.
2271-2273: Three way handshake between Proxy and WebServer:8000.
2274-2275: GET request and ACK
2276-2277: WebServer responds and Proxy acknowledges.
2278-2279: Proxy forwards received packet back to Work.
2280-2285: Work terminates connection with Proxy and Proxy terminates connection with WebServer.
7. No love for Windows?
Rinetd supports Windows and is pretty straight-forward as on Linux as well. Binary can be found here.
Assuming rinetd is installed in: C:\rinetd
, just add the same rule to rinetd.conf
:
192.168.20.131 80 192.168.20.132 8000
Then run rinetd:
C:\rinetd>rinetd.exe -c rinetd.conf
And done.
Hopefully this guide sheds some light on port forwarding and more advanced traffic manipulation.