Sending DHCP Discover using python scapy

匿名 (未验证) 提交于 2019-12-03 02:49:01

问题:

I am new to python and learning some network programming, I wish to send an DHCP Packet through my tap interface to my DHCP server and expecting some response from it. I tried with several packet building techniques such a structs and ctypes and ended up with using scapy. Here I am able to send DHCP Packet but unable to get any response from the DHCP server(Analyzed using wireshark and tcpdump)..My packet looked like same as original DHCP packet but failed to get response. Here is my code

import socket from scapy.all import *  def main():   if len(sys.argv)<3:    print " fewer arguments."    sys.exit(1)  else:    tap_interface = sys.argv[1]    src_mac_address = sys.argv[2]   ethernet = Ether(dst='ff:ff:ff:ff:ff:ff',src=src_mac_address,type=0x800)  ip = IP(src ='0.0.0.0',dst='255.255.255.255')  udp =UDP (sport=68,dport=67)  fam,hw = get_if_raw_hwaddr(tap_interface)  bootp = BOOTP(chaddr = hw, ciaddr = '0.0.0.0',xid =  0x01020304,flags= 1)  dhcp = DHCP(options=[("message-type","discover"),"end"])  packet = ethernet / ip / udp / bootp / dhcp   fd = open('/dev/net/tun','r+')  TUNSETIFF = 0x400454ca  IFF_TAP = 0x0002  IFF_NO_PI = 0x1000  mode = IFF_TAP | IFF_NO_PI  ifr = struct.pack('16sH', tap_interface, IFF_TAP | IFF_NO_PI)  fcntl.ioctl(fd,TUNSETIFF,ifr)    while True:     sendp(packet, iface = tap_interface)     time.sleep(10)    if __name__ == '__main__':      main() 

Is there any other ways of achieving this? If so please do mention them as well. Thanks in Advance.

回答1:

Solved ! I had the same problem,

The problem I think was on the srp() function, it can't receive packets on port 68, but I've created a new function with a new thread that sniffs BOOTP messages and displays the packet fields. you can simulate it :

sniff(iface=myiface, filter="port 68 and port 67")

then send the packet using srp() or sendp() func :)

NOTE: I have used multithreading mechanism cause my program sends messages and sniffs if a rogue DHCP Server is on the network



回答2:

I am not sure if this would qualify as an answer, but we use scapy to simulate DHCP server/client exchange, and the following does the job for us:

discover = Ether(dst='ff:ff:ff:ff:ff:ff', src=cliMAC, type=0x0800) / IP(src='0.0.0.0', dst='255.255.255.255') / UDP(dport=67,sport=68) / BOOTP(op=1, chaddr=cliMACchaddr) / DHCP(options=[('message-type','discover'), ('end')]) 

The main difference between my code and yours seem to be how the BOOTP header is defined. Maybe you could try my packet definition and see if it works?



回答3:

Here is an example that I did that gets a dhcp address and assigns it to an ip interface:

My rough POC, while creating code for my project:

 #!/usr/bin/python      from scapy.all import Ether,IP,UDP,DHCP,BOOTP,get_if_raw_hwaddr,get_if_hwaddr,conf,sniff,sendp     from pyroute2 import IPDB     from Queue import Empty     from multiprocessing import Process, Queue, Manager     from wpa_supplicant.core import WpaSupplicantDriver     from twisted.internet.selectreactor import SelectReactor     import threading     import time     import errno     import sys     import types     import netifaces     import dbus     import json      import re      class PythonDHCPScanner:          def change_ip(self,ipObject,netInterface):             ipdb = IPDB()             ips= ipdb.interfaces[self.get_interface(netInterface)]             ipAddrs = ips.ipaddr.ipv4[0]             ips.del_ip(ipAddrs['address'],ipAddrs['prefixlen'])             ips.add_ip(ipObject['ipAddr'],24)             ipdb.commit()             ipdb.routes.add(dst="default",gateway=ipObject['router'])             ipdb.commit()           def queue_get_all(self):             items = []             maxItems = 50             for numOfItemsRetrieved in range(0, maxItems):                try:                    items.append(self.q.get_nowait())                except Empty, e:                    break             return items          def __init__(self):             self.net_iface = netifaces.interfaces()          def dhcp_print(self,pkt):             self.q.put(str(pkt))          def get_interface(self,number):             return str(self.net_iface[number].decode())          def get_interfaces(self):             return self.net_iface          def get_dhcp_object(self,interfaceNumber):             self.q = Manager().Queue()             c = Process(target=self.callSniffer,args=(interfaceNumber,)).start()             time.sleep(0.1)             p = Process(target=self.callPacket(interfaceNumber)).start()             time.sleep(5)             if c is not None:                 c.join()             dhcp = {}             for strPkt in self.queue_get_all():                 try:                     pkt = Ether(strPkt)                     pkt.show()                     if pkt[Ether].dst == get_if_hwaddr(self.get_interface(interfaceNumber)):                         if pkt[DHCP]:                             if pkt.getlayer(DHCP).fields['options'][0][1] == 2:                                  if pkt[IP]:                                      dhcp['ipAddr'] = pkt[IP].dst                                  for option in pkt.getlayer(DHCP).fields['options']:                                      if option == 'end':                                         break                                      dhcp[option[0]] = option[1]                                  print dhcp['router']                                  print dhcp['subnet_mask']                                  break                 except:                         continue             return dhcp          def callSniffer(self,interfaceNumber):             inter = self.get_interface(interfaceNumber)             conf.iface = inter             print inter             sniff(iface=inter,filter="udp",prn=self.dhcp_print, timeout=10)          def callPacket(self,interfaceNumber):             inter = self.get_interface(interfaceNumber)              print inter             fam,hw = get_if_raw_hwaddr(inter)             macaddress= get_if_hwaddr(inter)             conf.iface = inter             ethernet = Ether(dst="ff:ff:ff:ff:ff:ff",src=macaddress,type=0x800)             ip = IP(src="0.0.0.0",dst="255.255.255.255")             udp = UDP(sport=68,dport=67)             bootp = BOOTP(chaddr =hw,xid=0x10000000)             dhcp = DHCP(options=[("message-type","discover"),("end")])             packet=ethernet/ip/udp/bootp/dhcp             sendp(packet,iface=inter)      # get dhcp object      dave  = PythonDHCPScanner()     dhcpObject = dave.get_dhcp_object(3)   # Pick interface number 3 on my box      time.sleep(1)     for dhcpKey in dhcpObject.keys():         print str(dhcpKey) + ":" + str(dhcpObject[dhcpKey])     time.sleep(1)     dave.change_ip(dhcpObject,3) 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!