def calcParentZones(self): inZoneCounter = 0 for i in self.NSrecords: # if 'bio-bak' in i: # print('wait') parent = getparent(i) parentLenght = len(parent.split(".")) if parentLenght > 0: if parent[-1] != ".": parent = parent + "." else: print("CHECK: parent has zero length") isParentTLD = False # if len==2 , then is a TLD if parentLenght == 2: isParentTLD = True self.zoneHasAtLeastOneNSinBailiwick = True inZoneCounter = inZoneCounter + 1 self.zoneItDepends.add(i) elif parentLenght > 2 and parent != self.zone: self.zoneItDepends.add(parent) else: self.zoneHasAtLeastOneNSinBailiwick = True self.zoneItDepends.add(parent) inZoneCounter = inZoneCounter + 1 if inZoneCounter == len(self.NSrecords): self.allNSinBailiwick = True self.extZonesItDepends = self.zoneItDepends if self.zone in self.extZonesItDepends: self.extZonesItDepends.remove(self.zone) return self.extZonesItDepends
def getDepZones(x): # this code gets all the zones a certain zone depends # example, giovane-moura.nl depends on webreus.nl isOK = False results = dict() localNSes = getNS(x) timeOUtButNotFromParent = False if localNSes == "TIMEOUT" or localNSes == "NXDOMAIN": logging.info(f"Domain {x}: NX or bailiwick?") tempP = getparent(x) if tempP[-1] != '.': tempP = tempP + "." parentNS = getNS(tempP) # print(parentNS) timeOUtButNotFromParent = True if parentNS != 'TIMEOUT': for singleNS in parentNS: if isOK == False and singleNS not in results: tempA = getA(singleNS) if tempA != -1: tempNSParent = retrieveNSFromParent(x, tempA) # we only add domains here if they timeout if timeOUtButNotFromParent == True and isinstance( tempNSParent, dict): results[x] = tempNSParent # for key, v in tempNSParent.items(): # if key not in results: # results[key]=v # else: # print('been tghere done that') isOK = True elif tempNSParent == 'SOA': isOK = True # do nothing domain is ok elif tempNSParent == 'NXDOMAIN': isOK = True return 'NXDOMAIN' else: print("Parent does no work,try to get soa") # try get soa parentNS = getSOA(tempP) return 'BROKEN NS' return results elif len(localNSes) > 0: results[x] = localNSes return results
def evalNSSet(cyclic, nsset): ret = False for ns in nsset: parentNS = getparent(ns) if parentNS[-1] != ".": parentNS = parentNS + "." if parentNS in cyclic: ret = True return ret
def figureParentRecords(domain): parentZone = getparent(domain) toBeRet = [] localRes = resolver.Resolver() localRes.timeout = 5 localRes.lifetime = 5 answer = '' try: answer = localRes.resolve(parentZone, 'NS') except Exception as e: logging.error(f"Getting NS for {domain} triggered exception {e}") return 'NXDOMAIN' if answer != '': response = answer.response # print(type(response)) rcode = response.rcode() # parent is valid if rcode == 0: try: localA = response.answer for k in localA: for addr in k.items: tempNS = '' try: tempNS = addr.target toBeRet.append(str(tempNS)) except Exception as e: print(e) # print(type(e)) except: print('no NS') pass elif rcode == 3: print('does not exist') toBeRet.append(-1) return toBeRet
def getParentNSes(k): # get the parent parent = getparent(k) toBeRet = [] try: try: answer = dns.resolver.resolve(parent, 'NS') response = answer.response # print(type(response)) rcode = response.rcode() # parent is valid if rcode == dns.rcode.NOERROR: try: localA = response.answer for k in localA: for addr in k.items: try: tempNS = addr.target toBeRet.append(str(tempNS)) except Exception as e: logging.error(f"{k}: NS from parent has No A - {e}") except Exception as e: logging.error(f'{k}: auth server has no NS, reason {e}') pass elif rcode == dns.rcode.NXDOMAIN: logging.info(f"{parent} NXDOMAIN") toBeRet.append(-1) elif rcode == dns.rcode.SERVFAIL: logging.info(f"{parent} SERVFAIL") except Exception as e: logging.error(f"{k}: NS from parent has failed - {e}") # print(type(e)) return 'ERROR' except Exception as e: logging.error(f"{k}: failed to retrieve NS answers - {e}") return toBeRet
async def probe_ns(nsname): localSoa = await getSOA(nsname) res = None # only analyze nses that have no soa if localSoa == 'ERROR': logging.error(f"{nsname} has error with SOA query") isOK = False timeOUtButNotFromParent = False bailiStatus = False tempTest = getparent(nsname) if tempTest != "" and len(tempTest.split(".")) < 2: logging.info(f"{nsname} is already at the top (tld), skip it") else: parentNS = await getParentNSes(nsname) logging.info(f"the parent domain of {nsname} is {parentNS}") if isinstance(parentNS, list): # check if in bailwikc at least one sp2 = nsname.split(".") baili = '' for ww in range(1, len(sp2) - 1): baili = baili + "." + sp2[ww] if baili[0] == ".": baili = baili[1:] for e in parentNS: logging.info( f"{nsname} has bailiwick {baili} and nameserver {e}") if baili in e: logging.info( f"Result: {nsname} is fine has NS in bailiwick {e}" ) bailiStatus = True break elif parentNS == "ERROR": tempP = getparent(nsname) tempP = getparent(tempP) if len(tempP) > 0: if tempP[-1] != '.': tempP = tempP + "." else: print(f"tempP is {tempP}") parentNS = await getNS(tempP) timeOUtButNotFromParent = True logging.info(f"{nsname} has timed out via normal resolution") if not bailiStatus: for singleNS in parentNS: if not isOK: tempA = await getA(singleNS) if tempA != -1: tempNSParent = await retrieveNSFromParent( nsname, tuple(sorted(tempA))) # we only add domains here if they timeout if timeOUtButNotFromParent and isinstance( tempNSParent, dict): res = tempNSParent logging.info( f"Result: {nsname} has been added") isOK = True elif tempNSParent == 'SOA': isOK = True logging.info( f"Result: {nsname} has SOA (is fine)") # do nothing domain is ok elif tempNSParent == 'NXDOMAIN': isOK = True logging.info(f"Result: {nsname} IS NXDOMAIN") return nsname, res
def findParents(x): results = dict() ''' 1. get soa - see if it resolves 1a. if it works, proceed to 2 1b. if soa does not work, then have to find the real parent recursively utnil get an answer 2. for the nmname is soa list, then ask this mname for all NS records of the parent zone ''' soaRec = getSOA(x) # has soa if len(soaRec) == 0: logging.warning(f"Domain {x} has no soa") parentX = getparent(x) if parentX[-1] != ".": localParent = parentX + "." else: localParent = parentX nsLocalParent = '' try: nsLocalParent = getNS(localParent) except Exception as e: print("failed to get NS from zone at findParents" + str(x)) print(e) print(type(e)) return -1 if nsLocalParent != '': # print("analyze here") for k in nsLocalParent: tempA = getA(k) tempAAAA = getAAAA(k) gotAnswer = False if gotAnswer == False: if len(tempA) > 0: # query it resParent = retrieveNSFromParent(x, tempA) if isinstance(resParent, dict): # then got results gotAnswer = True tempAuth = Authority(x) for k, v in resParent.items(): for singleNS in v: tempAuth.addNS(singleNS) tempAuth.calcParentZones() results[x] = tempAuth.zoneItDepends return results elif isinstance(resParent, str): if resParent == 'NXDOMAIN': return "NXDOMAIN" else: print("FAILED hon here too") print(resParent) return resParent else: return nsLocalParent else: # the domain resolves, the soa record shows the first avail auth server. for k, v in soaRec.items(): parentsK = '' try: parentsK = getNS2(k) except Exception as e: print( "failed to get NS from zone that has soa on findParents " + str(k)) print(e) print(type(e)) if parentsK != '': tempAuth = Authority(x) for singleNS in parentsK: tempAuth.addNS(singleNS) tempAuth.calcParentZones() results[x] = tempAuth.zoneItDepends return results else: print('FOUND SOA< but not NS, could not happen') return -2
def getNSrecordForDomain(parent): # get the parent #has to support servfail toBeRet = [] retDict = dict() localRes = resolver.Resolver() localRes.timeout = 5 localRes.lifetime = 5 answer = '' try: answer = localRes.resolve(parent, 'NS') except Exception as e: print(str(e)) if 'timed out' in str(e): toBeRet.append('TIMEOUT') return toBeRet elif 'does not exist in' in str(e): print('does not exist') toBeRet.append('NXDOMAIN') return toBeRet elif "The DNS response does not contain an answer" in str(e): if 'response' in e.kwargs: authRes = e.kwargs['response'].authority additional = e.kwargs['response'].additional if len(authRes) > 0: rdtype = authRes[0].rdtype toBeRet.append("NO ANSWER, rdtype is " + str(rdtype)) return toBeRet elif len(additional) > 0: rdtype = additional[0].rdtype toBeRet.append("NO ANSWER, rdtype is " + str(rdtype)) return toBeRet else: toBeRet.append("NO ANSWER or additonal or auth") return toBeRet else: try: if e.kwargs['errors'][0][3] == "SERVFAIL": #if it failed, then ask parent zone for its NS parentZONE = getparent(parent) nsparent = getNS(parentZONE) #if nsparent is a list, is because it worked resolvable = False if isinstance(nsparent, list): for singleNS in nsparent: ipv4 = getA(singleNS) #has IPv4, let's query if (isinstance(ipv4, list)): nsFromParent = retrieveNSFromParent( parent, ipv4) if isinstance(nsFromParent, dict): #see if glue is there for k, v in nsFromParent.items(): for nsAtParent in v: gluePresent = hasGlue( nsAtParent, ipv4) if (isinstance(gluePresent, list)): #print("domain has glue") retDict['domain'] = parent retDict['NSSetFromParent'] = v mappings = dict() mappings[ nsAtParent] = gluePresent if 'NSandGlue' not in retDict: tempL = [] tempL.append(mappings) retDict[ 'NSandGlue'] = tempL else: tempL = retDict[ 'NSandGlue'] tempL.append(mappings) retDict[ 'NSandGlue'] = tempL return retDict except Exception as w: #print(str(w)) pass if answer != '': response = answer.response # print(type(response)) rcode = response.rcode() # parent is valid if rcode == 0: try: localA = response.answer for k in localA: for addr in k.items: tempNS = '' try: tempNS = addr.target toBeRet.append(str(tempNS)) except Exception as e: print(e) # print(type(e)) except: print('no NS') pass elif rcode == 3: print('does not exist') toBeRet.append('NXDOMAIN') return toBeRet