Пример #1
0
 def create_server(self):
     self._server = UDPServer(self.listen_responses, None, socket=self._soc)
     self._server_coro = self._server.run()
Пример #2
0
class MDNSClient():
    def __init__(self, timeout=5):
        self._mcast_addr = ('224.0.0.251', 5353)
        self.timeout = timeout
        self._query_TID = os.urandom(2)
        self._soc = None
        self._server_coro = None
        self._query_packet = None
        self._loop = asyncio.get_event_loop()
        self.result = {}

    def setup_socket(self):
        mcast_addr = ipaddress.ip_address(self._mcast_addr[0])
        self._soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                  socket.IPPROTO_UDP)
        self._soc.setblocking(
            False)  #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!!
        self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
        self._soc.bind(self._mcast_addr)
        mreq = struct.pack("=4sl", mcast_addr.packed, socket.INADDR_ANY)
        self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

    def create_server(self):
        self._server = UDPServer(self.listen_responses, None, socket=self._soc)
        self._server_coro = self._server.run()

    def send_queries(self, query_names):
        qstns = []
        for qry in query_names:
            qstns.append(DNSQuestion.construct(qry, DNSType.PTR, DNSClass.IN))

        self._query_packet = DNSPacket.construct(TID=self._query_TID,
                                                 response=DNSResponse.REQUEST,
                                                 questions=qstns)

        self._soc.sendto(self._query_packet.toBytes(), self._mcast_addr)

    @asyncio.coroutine
    def stop_loop(self):
        yield from asyncio.sleep(self.timeout)
        self._loop.stop()
        return

    def run(self, query_names):
        self.setup_socket()
        self.create_server()
        self.send_queries(query_names)

        self._loop.create_task(self.stop_loop())
        try:
            self._loop.run_until_complete(self._server_coro)
        except RuntimeError as e:
            if str(e) == 'Event loop stopped before Future completed.':
                pass
            else:
                raise (e)
        except Exception as e:
            traceback.print_exc()
            print(e)

        return self.result

    def listen_responses(self, reader, writer):
        msg = DNSPacket.from_buffer(reader.buff)
        if msg.QR == DNSResponse.RESPONSE:
            for ans in msg.Answers:
                if ans.domainname.name[0] == '_':
                    #walking the tree...
                    print('Walk the tree: %s' % ans.domainname.name)
                    qst = DNSQuestion.construct(ans.domainname.name,
                                                DNSType.PTR, DNSClass.IN)
                    qry = DNSPacket.construct(TID=os.urandom(2),
                                              response=DNSResponse.REQUEST,
                                              questions=[qst])
                    self._soc.sendto(qry.toBytes(), self._mcast_addr)

                #else:
                #        print(ans.domainname)

            name = None
            for ans in msg.Additionals:
                if ans.TYPE == DNSType.A or ans.TYPE == DNSType.AAAA:
                    if ans.NAME.name not in self.result:
                        self.result[ans.NAME.name] = {}
                    self.result[ans.NAME.name][ans.ipaddress] = []
                    name = ans.NAME.name

            for ans in msg.Additionals:
                if ans.TYPE == DNSType.SRV:
                    for ip in self.result[name]:
                        self.result[name][ip].append(ans.Port)
Пример #3
0
class MDNSClient():
    def __init__(self, timeout=5):
        self._mcast_addr = ('224.0.0.251', 5353)
        self.timeout = timeout
        self._query_names = {}
        self._soc = None
        self._server_coro = None
        self._query_packet = None
        self._loop = asyncio.get_event_loop()
        self.result = {}

    def setup_socket(self):
        mcast_addr = ipaddress.ip_address(self._mcast_addr[0])
        self._soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                  socket.IPPROTO_UDP)
        self._soc.setblocking(
            False)  #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!!
        self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
        self._soc.bind(self._mcast_addr)
        mreq = struct.pack("=4sl", mcast_addr.packed, socket.INADDR_ANY)
        self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

    def create_server(self):
        self._server = UDPServer(self.listen_responses, None, socket=self._soc)
        self._server_coro = self._server.run()

    def send_queries(self, query_names):
        qstns = []
        for qry in query_names:
            for dtype in [DNSType.A, DNSType.AAAA]:
                if qry.find('.local') == -1:
                    qry += '.local'
                qstns.append(DNSQuestion.construct(qry, dtype, DNSClass.IN))

                tid = os.urandom(2)
                if qry not in self._query_names:  #apparently there are no transaction IDs in mdns...
                    self._query_names[qry] = 1
                self._query_packet = DNSPacket.construct(
                    TID=tid, response=DNSResponse.REQUEST, questions=qstns)

                self._soc.sendto(self._query_packet.to_bytes(),
                                 self._mcast_addr)

    @asyncio.coroutine
    def stop_loop(self):
        yield from asyncio.sleep(self.timeout)
        self._loop.stop()
        return

    def run(self, query_names):
        self.setup_socket()
        self.create_server()
        self.send_queries(query_names)

        self._loop.create_task(self.stop_loop())
        try:
            self._loop.run_until_complete(self._server_coro)
        except RuntimeError as e:
            if str(e) == 'Event loop stopped before Future completed.':
                pass
            else:
                raise (e)
        except Exception as e:
            traceback.print_exc()
            print(e)

        return self.result

    def listen_responses(self, reader, writer):
        msg = DNSPacket.from_buffer(reader.buff)
        if msg.QR == DNSResponse.RESPONSE:
            for ans in msg.Answers:
                if ans.TYPE == DNSType.A or ans.TYPE == DNSType.AAAA:
                    if ans.NAME.name in self._query_names:
                        if ans.NAME.name not in self.result:
                            self.result[ans.NAME.name] = []
                        self.result[ans.NAME.name].append(ans.ipaddress)
Пример #4
0
class DHCPClient():
	def __init__(self):
		self._query_TID = os.urandom(4)
		self._soc = None
		self._server_coro = None
		self._loop    = asyncio.get_event_loop()
		self.result = {}

	def setup_socket(self):
		self._soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
		self._soc.setblocking(False)#SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!!
		self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
		self._soc.bind(('', 68))


	def create_server(self):
		self._server = UDPServer(self.listen_responses, None, sock = self._soc)
		self._server_coro = self._server.run()

	def send_discover(self, options_extra = None):
		options = [DHCPOptDHCPMESSAGETYPE.construct(DHCPOptMessageType.DHCPDISCOVER)]
		if options_extra is not None:
			options += options_extra
		options.append(DHCPOptEND.construct())
		dhcpquery = DHCPMessage.construct(self._query_TID, DHCPOpcode.BOOTREQUEST, options)
		self._soc.sendto(dhcpquery.to_bytes(), ('255.255.255.255', 67))

	@asyncio.coroutine
	def stop_loop(self):
		yield from asyncio.sleep(1)
		self._loop.stop()
		return

	def run(self, options = None):
		self.setup_socket()
		self.create_server()
		self.send_discover(options)

		self._loop.create_task(self.stop_loop())
		try:
			self._loop.run_until_complete(self._server_coro)
		except RuntimeError as e:
			if str(e) == 'Event loop stopped before Future completed.':
				pass
			else:
				raise(e)
		except Exception as e:
			traceback.print_exc()
			print(e)
		
	def listen_responses(self, reader, writer):
		msg = DHCPMessage.from_buffer(reader.buff)
		if msg.xid == self._query_TID:
			for option in msg.options:
				if option.code == 53 and option.msgtype == DHCPOptMessageType.DHCPOFFER:
					print('Got offer! IP address offered: %s' % (str(msg.yiaddr)))
					print(repr(msg))
					self._loop.create_task(self.send_request(msg))

				if option.code == 53 and option.msgtype == DHCPOptMessageType.DHCPACK:
					print('Got ACK!: %s' % (str(msg.yiaddr)))
					print(repr(msg))
					#self._loop.create_task(self.send_request(msg))

		else:
			#not a message for us
			pass

	@asyncio.coroutine
	def send_request(self, offer, request_options_extra = None):
		options = [DHCPOptDHCPMESSAGETYPE.construct(DHCPOptMessageType.DHCPREQUEST)]
		options.append(DHCPOptREQUESTEDIPADDRESS.construct(offer.yiaddr))
		options.append(DHCPOptSERVERIDENTIFIER.construct(offer.siaddr))
		options.append(DHCPOptPARAMETERREQUEST.construct(list(range(2,61))))
		if request_options_extra is not None:
			options += request_options_extra
		options.append(DHCPOptEND.construct())
		dhcprequest = DHCPMessage.construct(self._query_TID, DHCPOpcode.BOOTREQUEST, options, yiaddr=offer.yiaddr, siaddr=offer.siaddr)
		self._soc.sendto(dhcprequest.to_bytes(), ('255.255.255.255', 67))
Пример #5
0
class LLMNRClient():
    def __init__(self, ipversion=4, ifname='eth0', timeout=1):
        self._mcast_ip4 = ipaddress.ip_address('224.0.0.252')
        self._mcast_ip6 = ipaddress.ip_address('FF02:0:0:0:0:0:1:3')

        self._timeout = timeout
        self._ipversion = ipversion
        self._ifname = ifname
        self._query_TIDs = []
        self._soc = None
        self._server_coro = None
        self._query_packet = None
        self._loop = asyncio.get_event_loop()
        self.result = {}

    def setup_socket(self):
        if self._ipversion == 4:
            self._mcast_addr = (str(self._mcast_ip4), 5355)
            self._soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                      socket.IPPROTO_UDP)
            self._soc.setblocking(
                False)  #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!!
            self._soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL,
                                 255)
            self._soc.bind(('', 5355))
            mreq = struct.pack("=4sl", self._mcast_ip4.packed,
                               socket.INADDR_ANY)
            self._soc.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
                                 mreq)

        else:
            interface_index = socket.if_nametoindex(self._ifname)
            self._soc = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM,
                                      socket.IPPROTO_UDP)
            self._soc.bind(('::', 5355, 0, interface_index))
            self._soc.setsockopt(
                socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP,
                struct.pack('16sI', self._mcast_ip6.packed, interface_index))
            self._soc.setblocking(
                False)  #SUPER IMPORTANT TO SET THIS FOR ASYNCIO!!!!
            self._mcast_addr = (str(self._mcast_ip6), 5355, 0, interface_index)

    def create_server(self):
        self._server = UDPServer(self.listen_responses, None, socket=self._soc)
        self._server_coro = self._server.run()

    def send_queries(self, query_names):
        qstns = []
        for qry in query_names:
            self.result[qry] = []
            tid = os.urandom(2)
            self._query_TIDs.append(tid)
            qstns.append(DNSQuestion.construct(qry, DNSType.A, DNSClass.IN))
            self._query_packet = LLMNRPacket.construct(
                TID=tid, response=LLMNRResponse.REQUEST, questions=qstns)

            self._soc.sendto(self._query_packet.to_bytes(), self._mcast_addr)

    @asyncio.coroutine
    def stop_loop(self):
        yield from asyncio.sleep(self._timeout)
        self._loop.stop()
        return

    def run(self, query_names):
        self.setup_socket()
        self.create_server()
        self.send_queries(query_names)

        self._loop.create_task(self.stop_loop())
        try:
            self._loop.run_until_complete(self._server_coro)
        except RuntimeError as e:
            if str(e) == 'Event loop stopped before Future completed.':
                pass
            else:
                raise (e)
        except Exception as e:
            traceback.print_exc()
            print(e)

        self.print_result()

    def print_result(self):
        print('NAME\tIP\t\tRESPONSE_FROM')
        for qry in self.result:
            for res in self.result[qry]:
                for src in res:
                    print('%s\t%s\t%s' % (qry, res[src], src))

    def listen_responses(self, reader, writer):
        msg = LLMNRPacket.from_buffer(reader.buff)
        if msg.QR == LLMNRResponse.RESPONSE:
            if msg.TransactionID in self._query_TIDs:
                for ans in msg.Answers:
                    if ans.TYPE == DNSType.A or ans.TYPE == DNSType.AAAA:
                        self.result[ans.NAME.name].append(
                            {writer._addr[0]: str(ans.ipaddress)})
            else:
                print('[!] Got response with unknown TID!')