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)
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()
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})
def _coerce_net(self, net: netaddr.IPNetwork) -> netaddr.IPNetwork: if self._root.net.version == 4: return net.ipv4() return net.ipv6()
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