{"id":16421782,"url":"https://github.com/peppelinux/pydhcpstarvator","last_synced_at":"2026-03-10T08:33:40.953Z","repository":{"id":143289862,"uuid":"133684099","full_name":"peppelinux/pyDHCPStarvator","owner":"peppelinux","description":"DHCP starvation with Python Scapy ","archived":false,"fork":false,"pushed_at":"2020-07-01T10:03:50.000Z","size":105,"stargazers_count":21,"open_issues_count":1,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-04T13:44:34.185Z","etag":null,"topics":["attack","dhcp","exhaustion","network","packet-crafting","pentesting","pydhcpstarvator","python","python3","scapy","security","starvation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peppelinux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-16T15:07:32.000Z","updated_at":"2024-01-27T11:10:11.000Z","dependencies_parsed_at":"2023-05-11T02:15:30.980Z","dependency_job_id":null,"html_url":"https://github.com/peppelinux/pyDHCPStarvator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/peppelinux/pyDHCPStarvator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2FpyDHCPStarvator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2FpyDHCPStarvator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2FpyDHCPStarvator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2FpyDHCPStarvator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peppelinux","download_url":"https://codeload.github.com/peppelinux/pyDHCPStarvator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2FpyDHCPStarvator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30328251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attack","dhcp","exhaustion","network","packet-crafting","pentesting","pydhcpstarvator","python","python3","scapy","security","starvation"],"created_at":"2024-10-11T07:34:47.729Z","updated_at":"2026-03-10T08:33:40.931Z","avatar_url":"https://github.com/peppelinux.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyDHCPStarvator\n\nThis is a Python program that can run out an entire DHCP pool.\npyDHCPStarvator was not created for doing network attacks but like a way to exaust a DHCP Rogue pool when security-port and dhcp-snoop features are not available in your wired or wireless network equipments.\n\n### Requirements\n````\napt install python3-dev python3-pip\npip3 install scapy\npip3 install netaddr\n````\nIt was migrated from python2 to python3, if you need a runnable python2 version you can use the branch named **python2**.\n\n### Usage\n````\nusage: starvit.py [-h] -i I -net NET [-start N] [-end N] [-rep N]\n                  [-server_id SERVER_ID] [-random_hostnames]\n                  [-dst_mac DST_MAC] [-timeout TIMEOUT] [-debug]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -i I                  local network interface\n  -net NET              /24 subnet, example: -subnet 192.168.27.0/24\n  -start N              start ip to request\n  -end N                how many request will be done\n  -rep N                repetition, sometime packet get lost. Default: 3\n                        requests per ip\n  -server_id SERVER_ID  DHCP server id, example: 192.168.27.254\n  -random_hostnames     random client hostnames, othrewise client's hostname\n                        will be: ?\n  -dst_mac DST_MAC      Destination DHCP MAC address, default:\n                        ff:ff:ff:ff:ff:ff\n  -timeout TIMEOUT      seconds to wait between a request and another. example\n                        -timeout 0.2\n  -debug                print packets\n````\n\n##### usage examples\n````\n# starvation on entire network class\nsudo python3 starvit.py -i eth2  -net 192.168.0.0/16  -dst_mac 08:00:27:7c:f9:41 -t 0.05\n\n# starvation on selected ip range\nsudo python3 starvit.py -i eth2  -net 192.168.1.0/24 -start 92 -end 100 -dst_mac 08:00:27:7c:f9:41\n\n# just add a server_id as a specific target\nsudo python3 starvit.py -net 192.168.1.0/24 -start 10 -end 253 -server_id 192.168.27.254\n\n# specify server by its MAC address and print packets to stdout\nsudo python3 starvit.py -net 192.168.1.0/24 -start 80 -end 100 -dst_mac 08:00:27:7C:F9:41 -debug\n\n\n````\n\n#### example stdout with -debug option\n````\nRequesting: 192.168.1.98\n\u003cEther  dst=08:00:27:7C:F9:41 src=7b:7b:d1:5a:6b:62 type=IPv4 |\u003cIP  frag=0 proto=udp src=0.0.0.0 dst=255.255.255.255 |\u003cUDP  sport=bootpc dport=bootps |\u003cBOOTP  chaddr=\u003cRandMAC\u003e options='c\\x82Sc' |\u003cDHCP  options=[message-type='request' requested_addr=192.168.1.98 end] |\u003e\u003e\u003e\u003e\u003e\n.\nSent 1 packets.\n````\n\n#### -server_id and -dst_mac\nThese options focus the attack on a specified endpoint, the DHCP server, by ip or mac address.\n\nIf you using a wrong server_id value all the DHCP servers in the l2 broadcast will get something similar in their logs and will not release any ip from their pool.\n````\nWed May 16 17:31:35 2018 daemon.info dnsmasq-dhcp[31796]: DHCPNAK(br-lan) 192.168.27.135 30:63:3a:33:38:3a wrong server-ID\n````\n\n### Request an IP release\nUsefull if you want to force a DHCP server to remove a DHCP lease and then make a client to request an ip again\n````\npython3 release_ip.py -src_mac 66:36:3a:37:31:3a -src_ip 192.168.1.93 -dst_mac 08:00:27:7C:F9:41 -dst_ip 192.168.1.1 -debug 1\n\n````\n\n### Send a DHCP discover and listen for event\nA listener could also be executed to run a function callback for every packet sniffed.\nFor example we could send a gratuitous DHCP DISCOVER and listen for DHCP OFFER from rogue DHCP servers.\n\n````\n# DHCP DISCOVER\npython3 dhcp_discover.py -i eth2\n\n# DHCP event listener\npython3 listener.py -i eth2 [-debug]\n\nStart DHCP listener on interface 'eth2' with filter 'port 68 and port 67'\nDHCP OFFER from: 10.21.0.254 [d4:ca:6d:e6:6a:d7]\nDHCP OFFER from: 192.168.1.1 [08:00:27:7c:f9:41]\nDHCP OFFER from: 192.168.1.1 [08:00:27:7c:f9:41]\n````\n\nlistener.py can also be runned in starvation attack mode (subprocess).\nIf a DHCP-OFFER has been sniffed it will automatically starvate that DHCP.\nIt can also whitelists one or more DHCP and attack only the ROGUE DHCP.\n\n\nIn this example 10.21.0.254 is whitelisted, attack will only run \nagainst 192.168.1.1.\n````\npython3 listener.py -i eth2 -starvation-attack -starvation-exclude d4:ca:6d:e6:6a:d7\n\nStart DHCP listener on interface 'eth2' with filter 'port 68 and port 67'\nDHCP OFFER from: 10.21.0.254 [d4:ca:6d:e6:6a:d7]\nDHCP OFFER from: 192.168.1.1 [08:00:27:7c:f9:41]\nstarting starvation on 08:00:27:7c:f9:41, 192.168.1.1/24\n** python3 starvit.py -i eth2 -net 192.168.1.1/24 -dst_mac 08:00:27:7c:f9:41\nDHCP OFFER from: 192.168.1.1 [08:00:27:7c:f9:41]\nstarting starvation on 08:00:27:7c:f9:41, 192.168.1.1/24\n** python3 starvit.py -i eth2 -net 192.168.1.1/24 -dst_mac 08:00:27:7c:f9:41\n````\n\nTo solicitate DHCP-OFFER we craft DHCP-REQUEST packets\n````\npython2 dhcp_discover.py -i eth2\n\n#or\nnmap --script broadcast-dhcp-discover -e eth0\n````\n\n\n### Results\n![example](images/example.png)\nAn OpenWRT DHCP server used as victim.\nSome fake client requests was forged with \"-random_hostnames\" option, some other not.\n\n![discover](images/discover2.png)\nServer side effects of DHCP Discovery, dhcp_discover.py will always use a fake mac address to run its inspections.\n\n### Hints\n````\n# tcpdump activity sniffing\ntcpdump -i $ifname -n 'port 67 and port 68'\n\n# dhcp discover\nnmap --script broadcast-dhcp-discover -e eth0\n````\n````\n# dhcp leases flush\n# openwrt\necho \"\" \u003e  /tmp/dhcp.leases\n\n# debian\necho \"\" \u003e  /var/lib/dhcp3/dhcp.leases\n\n````\n### Attack mitigations\nAs previosly described a DHCP starvation is commonly prevented with:\n\n- port-security, it permits to lock a network switch's physical port to a restricted number of mac addresses. A dhcp starvation cannot spoof mac addresses in this configuration.\n- dnc-snoop, a network switch will reject DHCP packets on port 67 and 68 coming from unauthoritative DHCP servers. This commonly prevents rogue DHCP activities.\n\nIf any of these are not available remember that GNU/Linux as router is a good solution. This example could be used with iptables:\n````\n# 67 server, 68 client\nIPTABLES -I OUTPUT -i $LAN_IFACE -p udp --sport 67 -m mac ! --mac-source $YOUR_DHCP_MAC -j DROP\n````\nAnother homemade solution would be to arping every dhcp request src and, if any response come back, remove that DHCP lease from DHCP server (see previous chapter). A FOR loop on every dhcp.leases file's row could execute an arping to check the real existence of a client, if it will be negative: that row should be removed and the dhcp lease released.\n\n### License\n\nDHCPStarvator is made by Giuseppe De Marco and it's released under the GPL 3 license.\n\n### Todo\n\n- configurable MAC randomization (I found Scapy's RandMAC too much recognizable!);\n- please open issues/ticket and suggest!\n\n### Resources\n\n- http://scapy.readthedocs.io/en/latest/#sniffing\n- https://phaethon.github.io/scapy/api/\n- https://blog.jasonantman.com/2010/04/dhcp-debugging-and-handy-tcpdump-filters/\n- https://www.whitewinterwolf.com/posts/2017/10/30/dhcp-exploitation-guide/\n- https://github.com/foreni-packages/dhcpig\n- https://github.com/skids/ebtables-dhcpsnooping\n\n### Special thanks\nTo [Daniele Albrizio](https://github.com/speedj) for given a name to an idea ;)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeppelinux%2Fpydhcpstarvator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeppelinux%2Fpydhcpstarvator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeppelinux%2Fpydhcpstarvator/lists"}