Search code examples
pythonpicklenmapport-scanning

Unable to print additional detail (tag_name & region) while subtracting 2 sets()


I have 2 pickel files which hold the IPaddress along with the ports , aws_tags and region information assocaiated with them. This is basically a port scanner which has a method which prints when a new IP addresss is found. This is done by subtracting the NEW_pickel_scan with OLD_pickel_scan as follows :

self.prev_hosts = set()
self.curr_hosts = set()

def new_hosts(self)  
    result_new_hosts =  self.curr_hosts - self.prev_hosts

this works fine and prints the new IP added in the pickel report.

Now i need to add the associated tag and region of that IP address too. I have the needed data already at a mapping :

 mapping = {i[0]:[i[1],i[2]] for i in data}

i[0] is IP , i[1] is Tag and i[2] is the region

so i am trying to print the tag using this mapping.

Just for example i have another method which prints when a illegle port is found

def dump_raw(self,mapping):
    nmap_report =  self.report
    for host in nmap_report.hosts:
            #print
            if len(host.hostnames):
                tmp_host = host.hostnames.pop()
            else:
                tmp_host = host.address
            print("Nmap scan report for {0} ({1})".format(tmp_host,host.address))
            print("Host is {0}.".format(host.status))

            #val = config.get('ports', 'scan_range')
            #val_known = config.get('ports','known')

            #safe_port = range(*map(int, val.split(',')))
            #known_ports = map(int, val_known.split(','))

            print("  PORT     STATE         SERVICE")

            for serv in host.services:
                if serv.state == "open":
                 ## print ('Illegal Port open :'+str(serv.port) +'/'+str(serv.protocol)+' '+str(serv.service)+', on host=> '+str(host))
                  print ('Illegal Port open :'+str(serv.port) +'/'+str(serv.protocol)+' '+str(serv.service)+', on host=> '+str(host) + ' Tag =' + (mapping[host.address.strip()][0]) + ' Region =' + str(mapping[host.address.strip()][1]))

This is how i used mapping , can someone help me for the new_hosts() ?

I tried :

def new_hosts(self,mapping):
        """Return a list of new hosts added in latest scan"""
        result_new_hosts =  self.curr_hosts - self.prev_hosts
        print mapping[result_new_hosts]

it says : TypeError: unhashable type: 'set'

also if i do something like :

def new_hosts(self,mapping):
        """Return a list of new hosts added in latest scan"""
        result_new_hosts =  self.curr_hosts - self.prev_hosts
        print mapping[result_new_hosts]
        nmap_report = self.report
        for host in nmap_report.hosts:
            for serv in host.services:
                print result_new_hosts,mapping[result_new_hosts.address.strip()[0]],mapping[result_new_hosts.address.strip()[1]]
            return (result_new_hosts,mapping[result_new_hosts.address.strip()[0]],mapping[result_new_hosts.address.strip()[1]])

This prints:

AttributeError: 'set' object has no attribute 'address'

Solution

  •  result_new_hosts =  self.curr_hosts - self.prev_hosts
     print mapping[result_new_hosts]
    

    result_new_hosts is a set, and as the error says, sets are unhashable therefore can't be stored or looked up in a dictionary.

    Instead, you should search each individual element in the set:

    result_new_hosts =  self.curr_hosts - self.prev_hosts
    for result in result_new_hosts:    
        print mapping[result]
    

    UPDATE In case you want to return a list of tuples that contain (ip, (tag, region)):

    def new_hosts(self, mapping):
        result_new_hosts =  self.curr_hosts - self.prev_hosts
        return [(result, mapping[result]) for result in result_new_hosts]