Beispiel #1
0
def requests_sniffer(source_mac_address):

    # region Set network filter
    network_filters = {'Ethernet': {'source': source_mac_address}}
    # endregion

    # region Start sniffer
    sniff = Sniff_raw()
    sniff.start(
        protocols=['ARP', 'IP', 'IPv6', 'ICMPv6', 'UDP', 'DNS', 'DHCP'],
        prn=requests_sniffer_prn,
        filters=network_filters)
Beispiel #2
0
def dhcp_request_sniffer():

    # region Set network filter
    network_filters = {'Ethernet': {'source': target_mac_address}}
    # endregion

    # region Start sniffer
    sniff = Sniff_raw()

    global raw_socket
    raw_socket = socket(AF_PACKET, SOCK_RAW)
    raw_socket.bind((listen_network_interface, 0))

    sniff.start(protocols=['IP', 'IPv6', 'ICMPv6', 'ARP', 'UDP', 'DNS', 'DHCP', 'DHCPv6'],
                prn=dhcp_request_sniffer_prn, filters=network_filters)
Beispiel #3
0
    def _sniff_packets(
            self,
            destination_mac_address,  # type: str
            destination_ipv4_address,  # type: str
            destination_ipv6_address,  # type: str
            source_port=53  # type: int
    ):
        # type: (...) -> None
        """
        Sniff DNS answers
        :param destination_mac_address: Destination MAC address in DNS answer (most likely this is MAC address on your network interface)
        :param destination_ipv4_address: Destination IPv4 address in DNS answer (most likely this is IPv4 address on your network interface)
        :param destination_ipv6_address: Destination IPv6 address in DNS answer (most likely this is IPv6 address on your network interface)
        :param source_port: Source UDP port in DNS answer (default: 53 - default port for DNS servers)
        :return: None
        """

        network_filters = {
            'Ethernet': {
                'destination': destination_mac_address
            },
            'IP': {
                'destination-ip': destination_ipv4_address
            },
            'IPv6': {
                'destination-ip': destination_ipv6_address
            },
            'UDP': {
                'source-port': source_port
            }
        }

        sniff = Sniff_raw()

        sniff.start(protocols=['Ethernet', 'IP', 'IPv6', 'UDP', 'DNS'],
                    prn=self._parse_packet,
                    filters=network_filters)
Beispiel #4
0
class DnsServer:

    # region Set variables
    base = None
    sniff = None
    dns = None

    rawSocket = None

    network_interface = None
    port = 0
    your_mac_address = None
    your_ip_address = None
    your_ipv6_addresses = None

    target_ip_address = None
    target_ipv6_address = None

    fake_answers = False
    fake_domains = []
    fake_addresses = {}
    no_such_names = []

    DNS_QUERY_TYPES = []
    A_DNS_QUERY = 0
    AAAA_DNS_QUERY = 0

    success_domains = []

    # endregion

    # region Init
    def __init__(self):
        self.base = Base()
        self.sniff = Sniff_raw()
        self.dns = DNS_raw()

        self.rawSocket = socket(AF_PACKET, SOCK_RAW)

        self.port = 53
        self.A_DNS_QUERY = 1
        self.AAAA_DNS_QUERY = 28

    # endregion

    # region Get first IPv4 or IPv6 address of domain
    @staticmethod
    def _get_domain_address(query_name, query_type=1):

        # Set proto
        if query_type == 28:
            proto = AF_INET6
        else:
            proto = AF_INET

        try:
            # Get list of addresses
            addresses = getaddrinfo(query_name, None, proto)

            # Return first address from list
            return [addresses[0][4][0]]

        except gaierror:

            # Could not resolve name
            return None

    # endregion

    # region DNS reply function
    def _reply(self, request):

        # region This request is DNS query
        if 'DNS' in request.keys():

            for request_query in request['DNS']['queries']:

                # region Get DNS query type
                query_type = request_query['type']
                # endregion

                # region Type of DNS query type: A or AAAA
                if query_type in self.DNS_QUERY_TYPES:

                    try:

                        # region Local variables
                        query_class = request_query['class']
                        answer = []
                        addresses = None
                        # endregion

                        # region Create query list
                        if request_query['name'].endswith("."):
                            query_name = request_query['name'][:-1]
                        else:
                            query_name = request_query['name']

                        query = [{
                            "type": query_type,
                            "class": query_class,
                            "name": query_name
                        }]
                        # endregion

                        # region Script arguments condition check

                        # region Variable fake_answers is True
                        if self.fake_answers:
                            addresses = self.fake_addresses[query_type]
                        # endregion

                        # region Variable fake_answers is False
                        else:

                            # region Fake domains list is set
                            if len(self.fake_domains) > 0:

                                # region Fake domains list is set and DNS query name in fake domains list
                                if query_name in self.fake_domains:

                                    # region A DNS query
                                    if query_type == self.A_DNS_QUERY:

                                        # Fake IPv4 is set
                                        if self.A_DNS_QUERY in self.fake_addresses.keys(
                                        ):
                                            if len(self.fake_addresses[
                                                    self.A_DNS_QUERY]) > 0:
                                                addresses = self.fake_addresses[
                                                    self.A_DNS_QUERY]

                                        # Fake IPv4 is NOT set
                                        else:
                                            addresses = self._get_domain_address(
                                                query_name, query_type)

                                    # endregion

                                    # region AAAA DNS query
                                    if query_type == self.AAAA_DNS_QUERY:

                                        # Fake IPv6 is set
                                        if self.AAAA_DNS_QUERY in self.fake_addresses.keys(
                                        ):
                                            if len(self.fake_addresses[
                                                    self.AAAA_DNS_QUERY]) > 0:
                                                addresses = self.fake_addresses[
                                                    self.AAAA_DNS_QUERY]

                                        # Fake IPv6 is NOT set
                                        else:
                                            addresses = self._get_domain_address(
                                                query_name, query_type)

                                    # endregion

                                # endregion

                                # region Fake domains list is set and DNS query name NOT in fake domains list
                                else:
                                    addresses = self._get_domain_address(
                                        query_name, query_type)
                                # endregion

                            # endregion

                            # region Fake domains list is NOT set
                            else:

                                # region A DNS query
                                if query_type == self.A_DNS_QUERY:

                                    # Fake IPv4 is set
                                    if self.A_DNS_QUERY in self.fake_addresses.keys(
                                    ):
                                        if len(self.fake_addresses[
                                                self.A_DNS_QUERY]) > 0:
                                            addresses = self.fake_addresses[
                                                self.A_DNS_QUERY]

                                    # Fake IPv4 is NOT set
                                    else:
                                        addresses = self._get_domain_address(
                                            query_name, query_type)

                                # endregion

                                # region AAAA DNS query
                                if query_type == self.AAAA_DNS_QUERY:

                                    # Fake IPv6 is set
                                    if self.AAAA_DNS_QUERY in self.fake_addresses.keys(
                                    ):
                                        if len(self.fake_addresses[
                                                self.AAAA_DNS_QUERY]) > 0:
                                            addresses = self.fake_addresses[
                                                self.AAAA_DNS_QUERY]

                                    # Fake IPv6 is NOT set
                                    else:
                                        addresses = self._get_domain_address(
                                            query_name, query_type)

                                # endregion

                            # endregion

                        # endregion

                        # endregion

                        # region Query name in no_such_names list
                        if query_name in self.no_such_names:
                            addresses = ['no such name']
                        # endregion

                        # region Answer addresses is set

                        if addresses is not None:

                            # region Create answer list
                            dns_answer_flags = 0x8580

                            for address in addresses:
                                if address == 'no such name':
                                    dns_answer_flags = 0x8183
                                    answer = []
                                    break
                                else:
                                    answer.append({
                                        "name": query_name,
                                        "type": query_type,
                                        "class": query_class,
                                        "ttl": 0xffff,
                                        "address": address
                                    })

                            # endregion

                            # region Make dns answer packet
                            if 'IP' in request.keys():
                                dns_answer_packet = self.dns.make_response_packet(
                                    src_mac=request['Ethernet']['destination'],
                                    dst_mac=request['Ethernet']['source'],
                                    src_ip=request['IP']['destination-ip'],
                                    dst_ip=request['IP']['source-ip'],
                                    src_port=53,
                                    dst_port=request['UDP']['source-port'],
                                    tid=request['DNS']['transaction-id'],
                                    flags=dns_answer_flags,
                                    queries=query,
                                    answers_address=answer)

                            elif 'IPv6' in request.keys():
                                dns_answer_packet = self.dns.make_response_packet(
                                    src_mac=request['Ethernet']['destination'],
                                    dst_mac=request['Ethernet']['source'],
                                    src_ip=request['IPv6']['destination-ip'],
                                    dst_ip=request['IPv6']['source-ip'],
                                    src_port=53,
                                    dst_port=request['UDP']['source-port'],
                                    tid=request['DNS']['transaction-id'],
                                    flags=dns_answer_flags,
                                    queries=query,
                                    answers_address=answer)

                            else:
                                dns_answer_packet = None
                            # endregion

                            # region Send DNS answer packet
                            if dns_answer_packet is not None:
                                self.rawSocket.send(dns_answer_packet)
                            # endregion

                            # region Print info message
                            if 'IP' in request.keys():
                                if query_type == 1:
                                    if query_name in self.success_domains:
                                        self.base.print_success(
                                            "DNS query from: ",
                                            request['IP']['source-ip'], " to ",
                                            request['IP']['destination-ip'],
                                            " type: ", "A", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                    else:
                                        self.base.print_info(
                                            "DNS query from: ",
                                            request['IP']['source-ip'], " to ",
                                            request['IP']['destination-ip'],
                                            " type: ", "A", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                if query_type == 28:
                                    if query_name in self.success_domains:
                                        self.base.print_success(
                                            "DNS query from: ",
                                            request['IP']['source-ip'], " to ",
                                            request['IP']['destination-ip'],
                                            " type: ", "AAAA", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                    else:
                                        self.base.print_info(
                                            "DNS query from: ",
                                            request['IP']['source-ip'], " to ",
                                            request['IP']['destination-ip'],
                                            " type: ", "AAAA", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))

                            if 'IPv6' in request.keys():
                                if query_type == 1:
                                    if query_name in self.success_domains:
                                        self.base.print_success(
                                            "DNS query from: ",
                                            request['IPv6']['source-ip'],
                                            " to ",
                                            request['IPv6']['destination-ip'],
                                            " type: ", "A", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                    else:
                                        self.base.print_info(
                                            "DNS query from: ",
                                            request['IPv6']['source-ip'],
                                            " to ",
                                            request['IPv6']['destination-ip'],
                                            " type: ", "A", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                if query_type == 28:
                                    if query_name in self.success_domains:
                                        self.base.print_success(
                                            "DNS query from: ",
                                            request['IPv6']['source-ip'],
                                            " to ",
                                            request['IPv6']['destination-ip'],
                                            " type: ", "AAAA", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                                    else:
                                        self.base.print_info(
                                            "DNS query from: ",
                                            request['IPv6']['source-ip'],
                                            " to ",
                                            request['IPv6']['destination-ip'],
                                            " type: ", "AAAA", " domain: ",
                                            query_name, " answer: ",
                                            (", ".join(addresses)))
                            # endregion

                        # endregion

                    except:
                        pass
                # endregion

        # endregion

    # endregion

    # region Start server
    def listen(self,
               listen_network_interface,
               listen_port=53,
               target_mac_address=None,
               target_ip_address=None,
               target_ipv6_address=None,
               fake_answers=False,
               fake_ip_addresses=[],
               fake_ipv6_addresses=[],
               fake_domains=[],
               no_such_names=[],
               listen_ipv6=False,
               disable_ipv4=False,
               disable_ipv6=False,
               success_domains=[]):

        # region Set success domains
        self.success_domains = success_domains
        # endregion

        # region Set fake answers
        self.fake_answers = fake_answers
        # endregion

        # region Set DNS_QUERY_TYPES
        if listen_ipv6:
            if disable_ipv4:
                self.DNS_QUERY_TYPES = [28]
            else:
                if disable_ipv6:
                    self.DNS_QUERY_TYPES = [1]
                else:
                    self.DNS_QUERY_TYPES = [1, 28]
        else:
            self.DNS_QUERY_TYPES = [1]
        # endregion

        # region Set listen network interface
        self.network_interface = listen_network_interface
        # endregion

        # region Set listen UDP port
        if listen_port != 53:
            if 0 < listen_port < 65535:
                self.port = listen_port
            else:
                self.base.print_error("Bad value in `listen_port`: ",
                                      str(listen_port),
                                      "; listen UDP port must be in range: ",
                                      "1 - 65534")
                exit(1)
        # endregion

        # region Get your MAC, IP and IPv6 addresses
        self.your_mac_address = self.base.get_netiface_mac_address(
            self.network_interface)
        if self.your_mac_address is None:
            self.base.print_error("Network interface: ",
                                  self.network_interface,
                                  " do not have MAC address!")
            exit(1)

        self.your_ip_address = self.base.get_netiface_ip_address(
            self.network_interface)
        if self.your_ip_address is None:
            self.base.print_error("Network interface: ",
                                  self.network_interface,
                                  " do not have IP address!")
            exit(1)

        if listen_ipv6:
            self.your_ipv6_addresses = self.base.get_netiface_ipv6_link_address(
                self.network_interface)
            if len(self.your_ipv6_addresses) == 0:
                self.base.print_error("Network interface: ",
                                      self.network_interface,
                                      " do not have IPv6 link local address!")
                exit(1)
            else:
                self.fake_addresses[self.AAAA_DNS_QUERY] = [
                    self.your_ipv6_addresses
                ]
        else:
            self.fake_addresses[self.AAAA_DNS_QUERY] = None
        # endregion

        # region Bind raw socket
        self.rawSocket.bind((self.network_interface, 0))
        # endregion

        # region Set fake addresses
        if len(fake_ip_addresses) > 0:
            self.fake_addresses[self.A_DNS_QUERY] = fake_ip_addresses
        else:
            if not disable_ipv4:
                self.fake_addresses[self.A_DNS_QUERY] = [self.your_ip_address]

        if len(fake_ipv6_addresses) > 0:
            self.fake_addresses[self.AAAA_DNS_QUERY] = fake_ipv6_addresses
            if disable_ipv4:
                self.DNS_QUERY_TYPES = [self.AAAA_DNS_QUERY]
            else:
                self.DNS_QUERY_TYPES = [self.A_DNS_QUERY, self.AAAA_DNS_QUERY]
        else:
            if self.fake_answers:
                if listen_ipv6:
                    self.fake_addresses[self.AAAA_DNS_QUERY] = [
                        self.your_ipv6_addresses
                    ]
        # endregion

        # region Set fake domains and "no such names" lists
        self.fake_domains = fake_domains
        self.no_such_names = no_such_names
        # endregion

        # region Check target IPv4 address
        if target_ip_address is not None:
            if not self.base.ip_address_validation(target_ip_address):
                self.base.print_error("Bad target IPv4 address: ",
                                      target_ip_address)
                exit(1)
            else:
                self.target_ip_address = target_ip_address
        # endregion

        # region Check target IPv6 address
        if target_ipv6_address is not None:
            if not self.base.ipv6_address_validation(target_ipv6_address):
                self.base.print_error("Bad target IPv6 address: ",
                                      target_ipv6_address)
                exit(1)
            else:
                self.target_ipv6_address = target_ipv6_address
        # endregion

        # region Sniffing DNS requests

        # region Set network filter
        network_filters = {}

        if target_mac_address is not None:
            network_filters['Ethernet'] = {'source': target_mac_address}
        else:
            network_filters['Ethernet'] = {'not-source': self.your_mac_address}

        if self.target_ip_address is not None:
            network_filters['IP'] = {'source-ip': self.target_ip_address}

        if self.target_ipv6_address is not None:
            network_filters['IPv6'] = {'source-ip': self.target_ipv6_address}

        network_filters['IP'] = {'not-source-ip': '127.0.0.1'}
        network_filters['UDP'] = {'destination-port': self.port}
        # endregion

        # region Clear fake_answers list
        if not self.fake_answers:
            if len(fake_ipv6_addresses) == 0:
                del self.fake_addresses[self.AAAA_DNS_QUERY]
            if len(fake_ip_addresses) == 0:
                del self.fake_addresses[self.A_DNS_QUERY]
        # endregion

        # region Start sniffer
        if listen_ipv6:
            if disable_ipv4:
                self.sniff.start(protocols=['IPv6', 'UDP', 'DNS'],
                                 prn=self._reply,
                                 filters=network_filters)
            else:
                self.sniff.start(protocols=['IP', 'IPv6', 'UDP', 'DNS'],
                                 prn=self._reply,
                                 filters=network_filters)
        else:
            self.sniff.start(protocols=['IP', 'UDP', 'DNS'],
                             prn=self._reply,
                             filters=network_filters)
Beispiel #5
0
    #     if 'IPv6' in request.keys():
    #         Base.print_info("MDNS packet from: ",
    #                         request['IPv6']['source-ip'] + " (" + request['Ethernet']['source'] + ")")

    if 'DHCP' in request.keys():
        Base.print_info("DHCP packet from: ", request['Ethernet']['source'])

    if 'DHCPv6' in request.keys():
        Base.print_info("DHCPv6 packet from: ",
                        request['IPv6']['source-ip'] + " (" + request['Ethernet']['source'] + ")")

    print(dumps(request, indent=4))

# endregion


# region Main function
if __name__ == "__main__":

    # region Print info message
    Base.print_info("Available protocols: ", "Ethernet ARP IP IPv6 ICMPv6 UDP DNS MDNS DHCP DHCPv6")
    Base.print_info("Start test sniffing ...")
    # endregion

    # region Start sniffer
    sniff = Sniff_raw()
    sniff.start(protocols=['ARP', 'IP', 'IPv6', 'ICMPv6', 'UDP', 'DNS', 'DHCP', 'DHCPv6'], prn=print_packet)
    # endregion

# endregion
Beispiel #6
0
            # region Start DHCP sender in other thread
            tm = ThreadManager(2)
            tm.add_task(send_dhcp_discover)
            # endregion

            # region Set network filter
            network_filters = {}
            network_filters['IP'] = {'destination-ip': your_ip_address}
            network_filters['UDP'] = {'source-port': 67}
            network_filters['UDP'] = {'destination-port': 67}
            # endregion

            # region Start sniffer
            sniff = Sniff_raw()
            sniff.start(protocols=['IP', 'UDP', 'DHCP'],
                        prn=send_dhcp_request,
                        filters=network_filters)
            # endregion

    except KeyboardInterrupt:
        # region Start network
        system('service network-manager start')
        system('service networking start 2>/dev/null')
        system('service network start 2>/dev/null')
        # endregion

        Base.print_info("Exit ...")
        exit(3)

# endregion