def collect_wildcard_record(domain, authoritative_ns): logger.log('INFOR', f'Collecting wildcard dns record for {domain}') if not authoritative_ns: return list(), int() resolver = utils.dns_resolver() resolver.nameservers = authoritative_ns # 使用权威名称服务器 resolver.rotate = True # 随机使用NS resolver.cache = None # 不使用DNS缓存 ips = set() ttl = int() ttls_check = list() ips_stat = dict() ips_check = list() while True: token = secrets.token_hex(4) random_subdomain = f'{token}.{domain}' try: ip, ttl = get_wildcard_record(random_subdomain, resolver) except Exception as e: logger.log('DEBUG', e.args) logger.log( 'ALERT', f'Multiple query errors,' f'try to query a new random subdomain') continue # 每5次查询检查结果列表 如果都没结果则结束查询 ips_check.append(ip) ttls_check.append(ttl) if len(ips_check) == 5: if not any(ips_check): logger.log( 'ALERT', 'The query ends because there are ' 'no results for 5 consecutive queries.') break ips_check = list() if len(ttls_check) == 5 and len(set(ttls_check)) == 5: logger.log( 'ALERT', 'The query ends because there are ' '5 different TTL results for 5 consecutive queries.') ips, ttl = set(), int() break if ip is None: continue ips.update(ip) # 统计每个泛解析IP出现次数 for addr in ip: count = ips_stat.setdefault(addr, 0) ips_stat[addr] = count + 1 # 筛选出出现次数2次以上的IP地址 addrs = list() for addr, times in ips_stat.items(): if times >= 2: addrs.append(addr) # 大部分的IP地址出现次数大于2次停止收集泛解析IP记录 if len(addrs) / len(ips) >= 0.8: break logger.log('DEBUG', f'Collected the wildcard dns record of {domain}\n{ips}\n{ttl}') return ips, ttl
def get_cname(subdomain): resolver = utils.dns_resolver() try: answers = resolver.query(subdomain, 'CNAME') except Exception as e: logger.log('TRACE', e.args) return None for answer in answers: return answer.to_text() # 一个子域只有一个CNAME记录
def all_resolve_success(subdomains): """ 判断是否所有子域都解析成功 :param subdomains: 子域列表 """ resolver = utils.dns_resolver() resolver.cache = None # 不使用DNS缓存 status = set() for subdomain in subdomains: status.add(query_a_record(subdomain, resolver)) return all(status)
def query_domain_ns(domain): logger.log('INFOR', f'Querying NS records of {domain}') domain = utils.get_main_domain(domain) resolver = utils.dns_resolver() try: answer = resolver.query(domain, 'NS') except Exception as e: logger.log('ERROR', e.args) logger.log('ERROR', f'Querying NS records of {domain} error') return list() ns = [item.to_text() for item in answer] logger.log('INFOR', f'{domain}\'s authoritative name server is {ns}') return ns
def check(self): """ check """ resolver = utils.dns_resolver() try: answers = resolver.query(self.domain, "NS") except Exception as e: logger.log('ERROR', e.args) return nsservers = [str(answer) for answer in answers] if not len(nsservers): logger.log('ALERT', f'No name server record found for {self.domain}') return for nsserver in nsservers: self.axfr(nsserver)
def query_domain_ns_a(ns_list): logger.log( 'INFOR', f'Querying A record from authoritative name server: {ns_list} ') if not isinstance(ns_list, list): return list() ns_ip_list = [] resolver = utils.dns_resolver() for ns in ns_list: try: answer = resolver.query(ns, 'A') except Exception as e: logger.log('ERROR', e.args) logger.log('ERROR', f'Query authoritative name server {ns} A record error') continue if answer: for item in answer: ns_ip_list.append(item.address) logger.log('INFOR', f'Authoritative name server A record result: {ns_ip_list}') return ns_ip_list