Firewall Evasion Lab
Copyright © 2022 by Wenliang Du.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
License. If you remix, transform, or build upon the material, this copyright notice must be left intact, or
reproduced in a way that is reasonable to the medium in which the work is being re-published.
1 Overview
There are situations where firewalls are too restrictive, making it inconvenient for users. For example, many
companies and schools enforce egress filtering, which blocks users inside of their networks from reaching
out to certain websites or Internet services, such as game and social network sites. There are many ways
to evade firewalls. A typical approach is to use the tunneling technique, which hides the real purposes
of network traffic. There are a number of ways to establish tunnels. The two most common tunneling
techniques are Virtual Private Network (VPN) and port forwarding. The goal of this lab is to help students
gain hands-on experience on these two tunneling techniques. The lab covers the following topics:
• Firewall evasion
• VPN
• Port forwarding
• SSH tunneling
Readings and videos. Detailed coverage of the tunneling technology and how to use it to evade firewalls
can be found in the following:
Chapter 9 of the SEED Book, Internet Security: A Hands-on Approach, 3rd Edition, by Wenliang Du.
See details at https://www.handsonsecurity.net.
Lab environment. This lab has been tested on our pre-built Ubuntu 20.04 VM, which can be downloaded
from the SEED website. Since we use containers to set up the lab environment, this lab does not depend
much on the SEED VM. You can do this lab using other VMs, physical machines, or VMs on the cloud.
2 Task 0: Get Familiar with the Lab Setup
We will conduct a series of experiments in this chapter. These experiments need to use several computers
in two separate networks. The experiment setup is depicted in Figure 1. We use docker containers for these
machines. Readers can find the container setup file from the website of this lab. In this lab, the network
10.8.0.0/24 serves as an external network, while 192.168.20.0/24 serves as the internal network.
The host 10.8.0.1 is not a container; this IP address is given to the host machine (i.e., the VM
in our case). This machine is the gateway to the Internet. To reach the Internet from the hosts in both
192.168.20.0/24 and 10.8.0.0/24 networks, packets must be routed to 10.8.0.1. The routing
has already been set up. SEED Labs - Firewall Evasion Lab
10.8.0.1
Internet
A1
#ip -br address
lo
10.8.0.5
ethl@if1907
eth0@if1909
B
UP
UP
A2
UNKNOWN
10.8.0.0/24
10.8.0.6
A
192.168.20.99
10.8.0.99
192.168.20.0/24
Figure 1: Network setup
Identify which services are running on each of the inside and outside hosts
B1
192.168.20.5
Router configuration: setting up NAT. The following iptables command is included in the router
configuration inside the docker-compose.yml file. This command sets up a NAT on the router for
the traffic going out from its eth0 interface, except for the packets to 10.8.0.0/24. With this rule,
for packets going out to the Internet, their source IP address will be replaced by the router's IP address
10.8.0.11. Packets going to 10.8.0.0/24 will not go through NAT.
iptables -t nat -A POSTROUTING ! -d 10.8.0.0/24 -j MASQUERADE -o eth0
127.0.0.1/8
192.168.20.11/24
10.8.0.11/24
10.8.0.11 (eth0)
In the above command, we assume that eth0 is the name assigned to the interface connecting the router
to the 10.8.0.0/24 network. This is not guaranteed. The router has two Ethernet interfaces; when the
router container is created, the name assigned to this interface might be eth1. You can find out the correct
interface name using the following command. If the name is not eth0, you should make a change to the
command above inside the docker-compose. yml file, and then restart the containers.
Router
(Firewall)
// Ingress filtering: only allows SSH traffic
iptables -A FORWARD -i eth0 -p tcp -m conntrack \
--ctstate ESTABLISHED, RELATED -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp -j DROP
192.168.20.11 (eth1)
// Egress filtering: block www.example.com
iptables -A FORWARD -i eth1 -d 93.184.216.0/24 -j DROP
B2
192.168.20.6
2
Router configuration: Firewall rules. We have also added the following firewall rules on the router.
Please make sure that eth0 is the interface connected to the 10.8.0.0/24 network and that eth1 is the
one connected to 192.168.20.0/24. If not, make changes accordingly. SEED Labs - Firewall Evasion Lab
The first rule allows TCP packets to come in if they belong to an established or related connection. This
is a stateful firewall rule. The second rule allows SSH, and the third rule drops all other TCP packets if they
do not satisfy the first or the second rule. The fourth rule is an egress firewall rule, and it prevents the internal
hosts from sending packets to 93.184.216.0/24, which is the network for www.example.com.
Lab task. Please block two more websites and add the firewall rules to the setup files. The choice of
websites is up to you. We will use them in one of the tasks. Keep in mind that most popular websites have
multiple IP addresses that can change from time to time. After adding the rules, start the containers, and
verify that all the ingress and egress firewall rules are working as expected.
Block the following: www.miami.edu (has multiple addresses) and www.fpl.com
3 Task 1: Static Port Forwarding
3
The firewall in the lab setup prevents outside machines from connecting to any TCP server on the internal
network, other than the SSH server. In this task, we would like to use static port forwarding to evade this
restriction. More specifically, we will use ssh to create a static port forwarding tunnel between host A (on
the external network) and host B (on the internal network), so whatever data received on A's port X will be
sent to B, from where the data is forwarded to the target T's port Y. In the following command, we use ssh
to create such a tunnel. you do not need the < and > in your command, these just indicate a field that you must fill in
// -4: use IPv4 only, or we will see some error message.
// -N: do not execute a remote command.
// -T: disable pseudo-terminal allocation (save resources).
run the command on A
Regarding A's IP, typically we use 0.0.0.0, indicating that our port forwarding will listen to the
connection from all the interfaces on A. If want to limit the connection from a particular interface, we should
use that interface's IP address. For example, if we want to limit the connection to the loopback interface,
so only the program on the local host can use this port forwarding, we can use 127.0.0.1:
simply omit the IP address (the default IP address is 127.0.0.1).
4 Task 2: Dynamic Port Forwarding
use 0.0.0.0 for A's ip address and 9000 for A's port number, the Target, T, is B1 so B1_address:telnet_port_number
Lab task. Please use static port forwarding to create a tunnel between the external network and the internal
network, so we can telnet into the server on B1. Please demonstrate that you can do such telnet from hosts A,
A1 and A2. Moreover, please answer the following questions: (1) How many TCP connections are involved
in this entire process. You should run wireshark or tcpdump to capture the network traffic, and then point
out all the involved TCP connections from the captured traffic. (2) Why can this tunnel successfully help
users evade the firewall rule specified in the lab setup?
Draw a diagram of the connections and the tunnel between the machines
In the static port forwarding, each port-forwarding tunnel forwards the data to a particular destination. If we
want to forward data to multiple destinations, we need to set up multiple tunnels. For example, using port
forwarding, we can successfully visit the blocked example.com website, but what if the firewall blocks
many other sites, how do we avoid tediously establishing one SSH tunnel for each site? We can use dynamic
port forwarding to solve this problem.
In the lab setup, the router already blocks example.com, so hosts on the internal network cannot
access the example.com website. Please add firewall rules to the router, so two more websites are blocked.
Remember to shutdown the port forwarding between each task SEED Labs - Firewall Evasion Lab
The choice of the websites is up to individual students. Please provide evidences to show that the websites
are indeed blocked. Block the following: www.miami.edu (has multiple addresses) and www.fpl.com
4.1 Task 2.1: Setting Up Dynamic Port Forwarding
We can use ssh to create a dynamic port-forwarding tunnel between B and A. We run the following com-
mand on host B. In dynamic port forwarding, B is often called proxy.
Regarding B's IP, typically we use 0.0.0.0, indicating that our port forwarding will listen to the
connection from all the interfaces on B. After the tunnel is set up, we can test it using the curl command.
We specify a proxy option, so curl will send its HTTP request to the proxy B, which listens on port X. The
proxy forwards the data received on this port to the other end of the tunnel (host A), from where the data
will be further forwarded to the target website. The type of proxy is called SOCKS version 5, so that is why
we specify socks5h.
$ curl --proxy socks5h://:
Lab task. Please demonstrate that you can visit all the blocked websites using curl from hosts B, B1, and
B2 on the internal network. Please also answer the following questions: (1) Which computer establishes the
actual connection with the intended web server? (2) How does this computer know which server it should
Draw a diagram of the connections and the tunnel between the machines
connect to?
4.2 Task 2.2: Testing the Tunnel Using Browser
We can also test the tunnel using a real browser, instead of using curl. Although it is hard to run a browser
inside a container, in the docker setup, by default, the host machine is always attached to any network created
inside docker, and the first IP address on that network is assigned to the host machine. For example, in our
setup, the host machine is the SEED VM; its IP address on the internal network 192.168.20.0/24 is
192.168.20.1.
To use the dynamic port forwarding, we need to configure Firefox's proxy setting. To get to the setting
page, we can type about:preferences in the URL field or click the Preference menu item. On the
General page, find the "Network Settings" section, click the Settings button, and a window
will pop up. Follow Figure 2 to set up the SOCKS proxy.
Lab task. Once the proxy is configured, we can then browse any website. The requests and replies will
go through the SSH tunnel. Since the host VM can reach the Internet directly, to make sure that our web
browsing traffic has gone through the tunnel, you should do the following: (1) run tcpdump on the router/-
firewall, and point out the traffic involved in the entire port forwarding process. (2) Break the SSH tunnel,
and then try to browse a website. Describe your observation.
Cleanup. After this task, please make sure to remove the proxy setting from Firefox by checking the "No
proxy" option. Without a proper cleanup, future labs may be affected. SEED Labs - Firewall Evasion Lab
Configure Proxy Access to the Internet
No proxy
Auto-detect proxy settings for this network
Use system proxy settings
Manual proxy configuration
HTTP Proxy
OOO
HTTPS Proxy
FTP Proxy
req
SOCKS Host
SOCKS v4
#!/bin/env python3
import socks
Also use this proxy for FTP and HTTPS
Connection Settings
»
B
SOCKS V5
Figure 2: Configure the SOCKS Proxy
s = socks.socksocket ()
s.set_proxy (socks.SOCKS5, "
s.connect (("
print (response.split (b"\r\n") )
response s.recv (2048)
Port
Port
Port
0
0
4.3 Task 2.3: Writing a SOCKS Client Using Python
For port forwarding to work, we need to specify where the data should be forwarded to (the final destination).
In the static case, this piece of information is provided when we set up the tunnel, i.e., it is hard-wired into
the tunnel setup. In the dynamic case, the final destination is dynamic, not specified during the setup, so
how can the proxy know where to forward the data?
Applications using a dynamic port forwarding proxy must tell the proxy where to forward their data.
This is done through an additional protocol between the application and the proxy. A common protocol for
such a purpose is the SOCKS (Socket Secure) protocol, which becomes a de facto proxy standard.
Since the application needs to interact with the proxy using the SOCKS protocol, the application soft-
ware must have a native SOCKS support in order to use SOCKS proxies. Both Firefox and curl have such
a support, but we cannot directly use this type of proxy for the telnet program, because it does not provide a
native SOCKS support. In this task, we implement a very simple SOCKS client program using Python.
0
Port
E
hostname = "www.example.com"
b"GET / HTTP/1.0\r\nHost: + hostname.encode('utf-8′) + b″\r\n\r\n"
s.sendall (req)
response = s.recv (2048)
while response:
this is what we
discussed in class
5