Lab Instruction DNS
Lab Instruction DNS
1. Overview
Domain Name System (DNS) is the Internet’s phone book; it translates hostnames to IP
addresses (and vice versa). This translation is through DNS name resolution, which happens
behind the scene. DNS attacks manipulate this resolution process in various ways, with an
intent to misdirect users to alternative destinations, which are often malicious.
The learning objective of this lab is for students to understand how DNS response spoofing
attack and cache poisoning attack work. Students will first set up the lab environment, and
then launch those DNS attacks on a target machine with Scapy and Python.
To set up the containers for this lab, first download the Labsetup.zip file to the VM from
Canvas, unzip it. Then, open a new Terminal window and enter the Labsetup folder. Run the
following command to build the containers:
$ dcbuild
$ dcup
You should see the results like the following. Leave the Terminal window open.
All the containers will be running in the background. To run commands in a container, we
need to enter the shell in that container. To do that, open a new Terminal window. Then use
the "docker ps" command to find out the ID of the container, and use "docker exec" to
start a shell in that container. We have also created the following aliases for them in the
.bashrc file.
When you run the dockps command in this lab, you will see a list of IDs for five containers, as
shown in the following example. Here, “seed-attacker” is the attacker container and “attacker-
ns-10.9.0.153” is the container for the attacker’s nameserver. Then, we can use docksh to enter
a container we want. Note that the containers’ IDs at different VMs are often different. Hence,
you will need to find out the IDs of the containers at your VM first.
$ dockps
1092902fef38 seed-router
84c944ef730a attacker-ns-10.9.0.153
74c7fb3af9b4 local-dns-server-10.9.0.53
7ac4bdffce14 seed-attacker
6b48dfc3afcb user-10.9.0.5
$ docksh 7ac
root@VM:/#
// Note: If a command requires a container ID, you do not need to
// type the entire ID string. Typing the first few characters will
// be sufficient, as long as they are unique among all the
containers.
• Forwarding the attacker32.com zone. A forward zone is added to the local DNS
server, so if anybody queries the attacker32.com domain, the query will be
forwarded to this domain’s nameserver (nameserver is also known as authoritative
server), which is hosted in the attacker container. The zone entry is put inside the
named.conf file.
zone "attacker32.com" {
type forward;
forwarders {
10.9.0.153;
};
};
User Machine: The user machine whose IP is 10.9.0.5 is already configured to use
10.9.0.53 as its local DNS server. This is achieved by changing the resolver configuration
file (/etc/resolv.conf) of the user machine, so the server 10.9.0.53 is added as the first
nameserver entry in the file, i.e., this server will be used as the primary DNS server.
Attacker’s Nameserver: Two zones are hosted on the attacker’s nameserver. One is the
attacker’s legitimate zone attacker32.com, and the other is the faked example.com zone.
The zones are configured in the file /etc/bind/named.conf:
zone "attacker32.com" {
type master;
file "/etc/bind/attacker32.com.zone";
};
zone "example.com" {
type master;
file "/etc/bind/example.com.zone";
};
4. Tasks
4.1 Testing the DNS Setup
We will run a series of commands from the user machine to ensure that the lab setup is correct.
Get the IP address of ns.attacker32.com. Open a new Terminal window. Run the
"dockps" command to find out the ID of the user container, and then use "docksh" to enter
the shell of the user container. Run the following dig command. The user machine will
generate a DNS request for the IP address of ns.attacker32.com and send to the local DNS
server. The local DNS server will forward the request to the attacker’s nameserver, since it is
the authoritative server for attacker32.com zone. Therefore, the answer should come from
the zone file (attacker32.com.zone) that we set up on the attacker’s nameserver. If this is
not what you get, your lab setup has an issue. Please include a screenshot of the testing result
and describe your observation in your lab report.
$ dig ns.attacker32.com
Get the IP address of www.example.com. Two nameservers are now hosting the
example.com domain: one is the domain’s official nameserver, and the other one is the
attacker’s nameserver. We will query these two nameservers and see what response we will
get. Run the following two commands from the shell of the user machine. Include screenshots
of the testing results and describe your observation in your lab report.
// Send the query to our local DNS server, which will send the query
// to example.com’s official nameserver.
$ dig www.example.com
When a user types the name of a website (i.e., a hostname, such as www.example.com) in a
web browser, the user’s computer will send a DNS query to the local DNS server to resolve the
IP address of the hostname. Attackers can sniff the DNS request message, then immediately
create a fake DNS response, and send back to the user machine. If the fake reply arrives earlier
than the real reply, it will be accepted by the user machine. This is called the DNS response
spoofing attack, and it is illustrated in Figure 2.
STEP 1: Download the Python program dns_sniff_spoof.py from Canvas. Open it and
replace the network interface ID (i.e., "iface" of the sniff function) with the one of your
VM. Click on “Save” to save the change. Move it to the volumes folder on the VM (the
volumes folder is inside the Labsetup folder) to replace the existing dns_sniff_spoof.py
in the folder. The dns_sniff_spoof.py program will sniff the packets on the virtual
network for this lab. When it overhears a packet that meets the condition specified in the
"filter" of the sniff function (the last but second line), the program will generate a
spoofed DNS response and send it to the target. The condition is stored in a string f, and it is
"udp and (src host 10.9.0.53 and dst port 53)". So, when the overheard packet
is a UDP packet (all DNS packets are UDP packets), the source IP address is X.X.X.X, and the
destination port number is 53 (port number 53 is reserved for DNS), the
dns_sniff_spoof.py program will generate a spoofed DNS response and send it to the
target with the source IP address. We have intentionally left out the IP of "src host" (the IP
address of the source) in the "filter" (the last but second line). Please find out which
machine should be the target and fill out the IP of "src host".
STEP 2: Before launching this attack, open a new Terminal window and enter the shell of the
local DNS server and run the following command to clean the cache. If the cache has the
answer to the DNS request, the reply from the local DNS server will be faster than the one you
spoofed. Your attack will not be able to succeed.
# rndc flush
STEP 3: Open a new Terminal window and enter the shell of the attacker container (not the
attacker’s nameserver). Run the "ls" command and you will see a folder named volumes.
Enter that folder and run the following command to run the sniff_and_spoof.py program:
$ python3 dns_sniff_spoof.py
STEP 4: Open a new Terminal window and enter the shell of the user machine. Run the
following dig command. It will trigger the user machine to send out a DNS query to the local
DNS server, which will eventually send out a DNS query to the authoritative nameserver of
the example.com domain (if its cache does not contain the answer). If your attack is
successful, you should be able to see your spoofed information in the reply to the dig
command. Please include a screenshot of the result and describe your observation in your lab
report.
$ dig www.example.com
STEP 5: Switch back to the Terminal window of the attacker container where the
sniff_and_spoof.py program is running. Terminate the sniff_and_spoof.py program
with ctrl+c/control+c.
Note: When the authors tested this lab with containers, sometimes (not always) they found
that the sniffing and spoofing inside containers is very slow. The spoofed responses arrive
later than the legitimate one from the Internet, and the attack fails. The authors have not
figured out the cause of this issue yet. If you also encounter this strange situation, here is a
solution. We can intentionally slow down the traffic going to the outside, so the authentic
replies will not come that fast. This can be done using the following tc command on the router
to add some delay to the outgoing network traffic. The router has two interfaces, eth0 and
eth1. Make sure you use the one connected to the external network 10.8.0.0/24.
Open a new Terminal window and enter the shell of the router. Then, run the following
commands: the first command will delay the network traffic by 100ms, and the second
command show the tc entry.
You can keep the tc entry on for this entire lab, because all the tasks will face a similar
situation.
There is a much better way to conduct attacks by targeting the local DNS server. When a local
DNS server receives a query, it first looks for the answer from its own cache; if the answer is
there, the local DNS server will simply reply with the information from its cache. If the answer
is not in the cache, the local DNS server will ask other DNS servers for an answer. When it
gets the answer, it will store the answer in the cache, so next time, there is no need to ask
other DNS servers. Therefore, if attackers can spoof the response from other DNS servers and
send it to the local DNS server, the local DNS server will keep the spoofed response in its
cache for certain period of time. Next time, when a user wants to resolve the same hostname, it
will receive the spoofed response from the cache of the local DNS server. This way, attackers
only need to spoof once, and the impact will last until the cached information expires. This
attack is called DNS cache poisoning, as illustrated in Figure 3.
STEP 2: Before launching this attack, open a new Terminal window and enter the shell of the
local DNS server. Clean the local DNS server’s cache with the following command:
# rndc flush
STEP 3: Open a new Terminal window and enter the shell of the attacker container. Run the
sniff_and_spoof.py program.
STEP 4: Then, open a new Terminal window and enter the shell of the user machine. Run the
dig command. If your attack is successful, you should be able to see your spoofed information
in the reply to the dig command. Please include a screenshot of the reply and describe your
observation in your lab report.
$ dig www.example.com
STEP 5: Let’s also inspect the cache on the local DNS server to see whether it is poisoned or
not. Switch to the Terminal window for the shell of the local DNS server. Run the following
commands to first dump the cache into a file, and then display the content of the cache file.
Include a screenshot of the dumped cache and describe your observation in your lab report.
When you finish the lab, don’t forget to shut down the containers. Open a new Terminal
window and enter the Labsetup folder. run the dcdown command there.
5. Submission
Write a lab report and answer all the lab questions. Submit the report to the regular
submission link on Canvas before the announced deadline.