def test_ip_v4_to_ipv6_compatible():
    assert IPAddress('192.0.2.15').ipv6(ipv4_compatible=True) == IPAddress('::192.0.2.15')
    assert IPAddress('192.0.2.15').ipv6(ipv4_compatible=True).is_ipv4_compat()
    assert IPAddress('192.0.2.15').ipv6(True) == IPAddress('::192.0.2.15')

    ip = IPNetwork('192.0.2.1/23')
    assert ip.ipv4() == IPNetwork('192.0.2.1/23')
    assert ip.ipv6() == IPNetwork('::ffff:192.0.2.1/119')
    assert ip.ipv6(ipv4_compatible=True) == IPNetwork('::192.0.2.1/119')
def test_ip_v4_to_ipv6_compatible():
    assert IPAddress('192.0.2.15').ipv6(
        ipv4_compatible=True) == IPAddress('::192.0.2.15')
    assert IPAddress('192.0.2.15').ipv6(ipv4_compatible=True).is_ipv4_compat()
    assert IPAddress('192.0.2.15').ipv6(True) == IPAddress('::192.0.2.15')

    ip = IPNetwork('192.0.2.1/23')
    assert ip.ipv4() == IPNetwork('192.0.2.1/23')
    assert ip.ipv6() == IPNetwork('::ffff:192.0.2.1/119')
    assert ip.ipv6(ipv4_compatible=True) == IPNetwork('::192.0.2.1/119')
def operate_on_ip_network(ipnet):
    net_attributes = []
    net = IPNetwork(ipnet)

    net_attributes.append("Network IP Address is " + str(net.network) +
                          " and Network Mask is " + str(net.netmask))

    net_attributes.append("The Broadcast is " + str(net.broadcast))

    net_attributes.append("IP Version is " + str(net.version))
    net_attributes.append("Information known about this network is " +
                          str(net.info))

    net_attributes.append("The IPv6 representation is " + str(net.ipv6()))

    net_attributes.append("The Network size is " + str(net.size))

    net_attributes.append(
        "Generating a list of ip addresses inside the subnet")

    for ip in net:
        net_attributes.append("\t" + str(ip))

    return "\n".join(net_attributes)
Beispiel #4
0
    def run(self):
        """
        This is the mainloop of the process manager.

        It will go over the ip address given and preform an initial host discovery, after that it will run deeper
        level scans of the network starting with the hosts found in the first scan. It will then move onto the remaining
        hosts.
        :return: True/False/None based on if the process failed to complete
        """

        _exit = self.exit
        _is_empty = False
        _jobs = []

        _uncommon_ports = sorted(set(range(65535)) - KNPORTS.as_nums())
        _uncommon_ports = ["{}-{}".format(*i) if i[0] != str(i[1]) else i[0] for i in KNPORTS.group(_uncommon_ports)]

        try:
            self.database.open_db()
            self.__load_options()

            def job(item, opt_override=""):
                if type(item) is list:
                    ipv4 = NProcess(options=self.options if not opt_override else opt_override)
                    ipv6 = NProcess(options="{} {}".format("-6", self.options if not opt_override else opt_override))
                    ipv4.targets.pop()  # removes the default target list
                    ipv6.targets.pop()
                    for h_ip in item:
                        if h_ip.ipv4():
                            ipv4.targets.append(str(h_ip.ipv4()))
                        else:
                            ipv6.targets.append(str(h_ip.ipv6()))
                    if ipv4.targets:
                        _jobs.append(ipv4)
                        _jobs[-1].run_background()
                    if ipv6.targets:
                        _jobs.append(ipv6)
                        _jobs[-1].run_background()
                else:
                    if item.ipv4():
                        _jobs.append(
                            NProcess(str(item.ipv4()), options=self.options if not opt_override else opt_override))
                    else:
                        _jobs.append(NProcess(str(item.ipv6()), options="{} {}".
                                              format("-6", self.options if not opt_override else opt_override)))
                    _jobs[-1].run_background()

            def process_jobs():
                for ind, proc in enumerate(_jobs):
                    if proc.has_terminated():
                        if proc.rc != 0:
                            print("nmap scan failed: {0}".format(proc.stderr))
                        if __DEBUG__: self.to_file(proc.stdout)
                        try:
                            parsed = NmapParser.parse(proc.stdout)
                            if __DEBUG__: print(parsed.summary)
                            for host in parsed.hosts:
                                print("Saving {} to database.".format(host.address))
                                self.database.add_ip_scan(ipaddr=host.address, port_data=host.get_open_ports(),
                                                          e_time=parsed.elapsed, command=proc.command,
                                                          raw_data=host.get_dict(), _raw=proc.stdout)
                        except NmapParserException as e:
                            print("Exception raised while parsing scan: {0}".format(e.msg))
                        self.database.commit()
                        del _jobs[ind]
                        break

            # preform 1st level scan
            if __DEBUG__: print("Initial Scan")
            init_discovery = set()
            while self._init_host_scan:
                try:
                    _ip = IPNetwork(self._init_host_scan.pop())
                    self._scanned_hosts.append(_ip.ipv4() if _ip.ipv4 else _ip.ipv6)
                    if _ip.ipv4():
                        _h = NProcess(list("%s" % i for i in _ip.ipv4()), options="-sn")
                    else:
                        _h = NProcess(list("%s" % i for i in _ip.ipv6()), options="-sn -6")
                    _h.sudo_run()
                    _p = NmapParser.parse(_h.stdout)
                    for _host in _p.hosts:
                        if _host.is_up():
                            init_discovery.add(_host.ipv4 if _host.ipv4 else _host.ipv6)
                        else:
                            self._add_host("med", _host.ipv4 if _host.ipv4 else _host.ipv6, 32)
                except NmapParserException:
                    pass

            # preform 2nd level scan, will only be preformed on init hosts found
            if __DEBUG__: print("Secondary Scans")
            _knports = ",".join(
                ["{}-{}".format(*i) if i[0] != i[1] else str(i[0]) for i in KNPORTS.group(list(KNPORTS.as_nums()))])
            for _ip in init_discovery:
                for opt in self.__scan_options:
                    job(IPAddress(_ip), opt_override="{} -p {} {}".format(opt, _knports, self.options))

            # all code beyond this point will take a very long time to execute
            if __DEBUG__: print("Primary Scans")
            if __DEBUG__: print(self.hosts_to_scan)
            while 1:

                if _exit.kill:
                    for _index, _j in enumerate(_jobs):
                        _jobs[_index].stop()
                    return False

                if len(_jobs) < self.max_workers and not _is_empty:
                    ip_group = []
                    while len(ip_group) < self.__max_host_scan and not _is_empty:
                        try:
                            # job(self.hosts_to_scan['high'].pop())
                            ip_group.append(self.hosts_to_scan['high'].pop())
                        except KeyError as e1:
                            try:
                                # job(self.hosts_to_scan['med'].pop())
                                ip_group.append(self.hosts_to_scan['med'].pop())
                            except KeyError as e2:
                                try:
                                    # job(self.hosts_to_scan['low'].pop())
                                    ip_group.append(self.hosts_to_scan['low'].pop())
                                except KeyError as e3:
                                    _is_empty = True
                    for opt in self.__scan_options:
                        job(ip_group, opt_override="{} -p {} {}".format(opt, _knports, self.options))

                process_jobs()
                if len(_jobs) == 0:
                    break

        except Exception as error:
            print("Failed: {}\t {}\n Cleaning up processes".format(Exception, error))
            traceback.print_tb(error.__traceback__)
            for _index, _j in enumerate(_jobs):
                try:
                    _jobs[_index].stop()
                except Exception as err:
                    print("Failed to stop {}\t{}".format(Exception, err))
                    print("Killing all nmap process!")
                    system('killall -9 nmap')
                    system('killall -9 python')
                    system('killall -9 python3')
                    print("Killall command for nmap process sent")
                finally:
                    print("Job Failed with kill signal.")
            return False
        # Time to run the uncommon ports, this will take a HUGE amount of time
        print("Final Scan\nThis Scan will take a very long time\n")
        _jobs = []
        while self._scanned_hosts:
            __ip = self._scanned_hosts.pop()
            for opt in self.__scan_options:
                job(__ip, opt_override="{} -p {} {}".
                    format(opt, ",".join(_uncommon_ports), self.options))
        while 1:
            if _exit.kill:
                try:
                    for _index, _j in enumerate(_jobs):
                        _jobs[_index].stop()
                except PermissionError:
                    return False
                finally:
                    print("Job Failed with kill signal.")
                return False

            process_jobs()

            if len(_jobs) == 0:
                break

        self.database.close_db()
Beispiel #5
0
def get_ipcalc_network(query, netmask=""):
    """
    IP calculator tool: supports IPv6 and IPv4 networks. For list of values see below.

    IP list is optional since it will return many IPs for some subnets,
    if you need to show ip list you will have to append ``?iplist`` to your get request.

    **PLEASE NOTE:** iplist will print only 65536 addresses which is /16 in IPv4 subnetting or /112 in IPv6 subnetting.
    If you try to get more you will get an error.

    :param query: IP address or hostname
    :param netmask: (Optional) If you want the whole range of hosts

    **Example:**

        When getting single host

        $ GET ``/api/ipcalc/199.16.156.102/30``

        ::


            {
              "results": {
                "broadcast": "199.16.156.103",
                "cidr": "199.16.156.100/30",
                "first_host": "199.16.156.101",
                "hostmask": "0.0.0.3",
                "ip_bits": "11000111.00010000.10011100.01100110",
                "ip_version": 4,
                "is_linklocal": false,
                "is_loopback": false,
                "is_multicast": false,
                "is_private": false,
                "is_public": true,
                "is_reserved": false,
                "is_unicast": true,
                "last_host": "199.16.156.102",
                "netmask": "255.255.255.252",
                "netmask_bits": "11111111.11111111.11111111.11111100",
                "network": "199.16.156.100",
                "network_bits": "11000111.00010000.10011100.01100100",
                "num_addresses": 4,
                "prefixlen": 30,
                "supernet": [
                  "0.0.0.0/0",
                  "128.0.0.0/1",
                  "192.0.0.0/2",
                  "192.0.0.0/3",
                  "192.0.0.0/4",
                  "192.0.0.0/5",
                  "196.0.0.0/6",
                  "198.0.0.0/7",
                  "199.0.0.0/8",
                  "199.0.0.0/9",
                  "199.0.0.0/10",
                  "199.0.0.0/11",
                  "199.16.0.0/12",
                  "199.16.0.0/13",
                  "199.16.0.0/14",
                  "199.16.0.0/15",
                  "199.16.0.0/16",
                  "199.16.128.0/17",
                  "199.16.128.0/18",
                  "199.16.128.0/19",
                  "199.16.144.0/20",
                  "199.16.152.0/21",
                  "199.16.156.0/22",
                  "199.16.156.0/23",
                  "199.16.156.0/24",
                  "199.16.156.0/25",
                  "199.16.156.64/26",
                  "199.16.156.96/27",
                  "199.16.156.96/28",
                  "199.16.156.96/29"
                ],
                "to_ipv6": "::ffff:199.16.156.102/126"
              },
              "status": "ok"
            }

    """

    if netmask is not "":
        ip = query + '/' + netmask
    else:
        ip = query

    try:
        net = IPNetwork(ip)
    except AddrFormatError:
        abort(400)

    results = dict()
    results['broadcast'] = str(net.broadcast)
    results['network'] = str(net.network)
    results['netmask'] = str(net.netmask)
    results['cidr'] = str(net.cidr)
    results['num_addresses'] = net.size
    results['hostmask'] = str(net.hostmask)
    results['is_loopback'] = net.is_loopback()
    results['is_unicast'] = net.is_unicast()
    results['is_multicast'] = net.is_multicast()
    results['is_private'] = net.is_private()
    results['is_reserved'] = net.is_reserved()
    results['is_linklocal'] = net.is_link_local()
    results['is_public'] = net.is_unicast() and not net.is_private()
    results['prefixlen'] = net.prefixlen
    results['ip_version'] = net.version
    results['ip_bits'] = net.ip.bits()
    results['network_bits'] = net.network.bits()
    results['netmask_bits'] = net.netmask.bits()
    results['supernet'] = [str(supernet) for supernet in net.supernet()]

    if net.version == 4:
        results['to_ipv6'] = str(net.ipv6())

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

        if net.broadcast is not None:
            results['first_host'] = str(net.network + 1)
            results['last_host'] = str(net.broadcast - 1)
        else:
            results['first_host'] = str(net.ip)
            results['last_host'] = str(net.ip)

    elif net.version == 6:
        try:
            results['to_ipv4'] = str(net.ipv4())
        except AddrConversionError:
            results['to_ipv4'] = None

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

    return jsonify({'status': "ok",
                    'results': results})
Beispiel #6
0
 def _coerce_net(self, net: netaddr.IPNetwork) -> netaddr.IPNetwork:
     if self._root.net.version == 4:
         return net.ipv4()
     return net.ipv6()
Beispiel #7
0
    def geoip(cls, ip, *args, **kwargs):
        logger = logging.getLogger(__name__)
        logger.debug("Geolocating %s..." % ip)
        geo = {}

        # Get ASN info
        try:
            # should return: (15169, '8.8.8.0/24'), the origin AS, and the BGP prefix it matches
            asn, bgp = asn_db.lookup(ip)
            network = IPNetwork(bgp)

            # Get normalized BGP prefix
            geo['bgp'] = str(network)

            # Upscale to ipv6 and get first and last address
            network = network.ipv6()
            geo['v6_bgp_beg'] = str(
                IPAddress(network.first).format(dialect=ipv6_verbose))
            geo['v6_bgp_end'] = str(
                IPAddress(network.last).format(dialect=ipv6_verbose))

        except Exception as e:
            logger.error(e)

        # Get ISP info
        try:
            response = mm_isp_db.asn(ip)
        except Exception as e:
            logger.error(e)
            response = None

        if response:
            try:
                geo['asn'] = response.autonomous_system_number
            except:
                pass
            try:
                geo['org'] = response.autonomous_system_organization
            except:
                pass

        # Get City info
        try:
            response = mm_city_db.city(ip)
        except Exception as e:
            logger.error(e)
            response = None

        if response:
            try:
                geo['iso'] = response.country.iso_code
            except:
                pass

            try:
                loc = response.subdivisions.most_specific.iso_code
                assert loc
            except:
                loc = '??'
            try:
                geo['iso_local'] = '%s-%s' % (response.country.iso_code, loc)
            except:
                pass

            try:
                geo['lat'] = response.location.latitude
                geo['lon'] = response.location.longitude
            except:
                pass

        return geo