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 check(self): """ 正则匹配响应头中的内容安全策略字段以发现子域名 """ 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'没有找到{self.domain}的NS域名服务器记录') return for nsserver in nsservers: self.axfr(nsserver)
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() 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) 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 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 query_domain_ns_a(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'查询权威DNS名称服务器{ns}的A记录出错') continue if answer: for item in answer: ns_ip_list.append(item.address) logger.log('INFOR', f'权威DNS名称服务器对应A记录 {ns_ip_list}') return ns_ip_list
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
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 resolver.cache = None ips = set() ttl = int() ips_stat = dict() 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 if ip is None: continue ips = ips.union(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 detect_wildcard(domain, authoritative_ns): """ 探测域名是否使用泛解析 :param str domain: 域名 :param list authoritative_ns: 权威DNS :return: 是否使用泛解析 """ logger.log('INFOR', f'正在探测{domain}是否使用泛解析') token = secrets.token_hex(4) random_subdomain = f'{token}.{domain}' resolver = utils.dns_resolver() resolver.nameservers = authoritative_ns resolver.rotate = True resolver.cache = None try: wildcard = do_query_a(random_subdomain, resolver) except Timeout as e: logger.log('DEBUG', e.args) logger.log('ALERT', f'多次探测超时暂且认为{domain}没有使用泛解析') return False else: return wildcard
def detect_wildcard(domain, authoritative_ns): """ Detect use wildcard dns record or not :param str domain: domain :param list authoritative_ns: authoritative name server :return bool use wildcard dns record or not """ logger.log('INFOR', f'Detecting {domain} use wildcard dns record or not') token = secrets.token_hex(4) random_subdomain = f'{token}.{domain}' resolver = utils.dns_resolver() resolver.nameservers = authoritative_ns resolver.rotate = True resolver.cache = None try: wildcard = do_query_a(random_subdomain, resolver) except Exception as e: logger.log('DEBUG', e.args) logger.log('ALERT', f'Multiple detection errors, so temporarily {domain} does not use wildcard dns record') return False else: return wildcard