Example #1
0
def detect_wildcard(domain):
    """
    探测域名是否使用泛解析

    :param str domain: 域名
    :return: 如果没有使用泛解析返回False 反之返回泛解析的IP集合和ttl整型值
    """
    logger.log('INFOR', f'正在探测{domain}是否使用泛解析')
    token = secrets.token_hex(4)
    random_subdomain = f'{token}.{domain}'
    try:
        resolver = resolve.dns_resolver()
        answers = resolver.query(random_subdomain, 'A')
    # 如果查询随机域名A记录出错 说明不存在随机子域的A记录 即没有开启泛解析
    except Exception as e:
        logger.log('DEBUG', e)
        logger.log('INFOR', f'{domain}没有使用泛解析')
        return False, None, None
    ttl = answers.ttl
    name = answers.name
    ips = {item.address for item in answers}
    logger.log('ALERT', f'{domain}使用了泛解析')
    logger.log('ALERT', f'{random_subdomain} 解析到域名: {name} '
               f'IP: {ips} TTL: {ttl}')
    return True, ips, ttl
Example #2
0
 def check(self):
     """
     正则匹配响应头中的内容安全策略字段以发现子域名
     """
     resolver = resolve.dns_resolver()
     try:
         answers = resolver.query(self.domain, "NS")
     except Exception as e:
         logger.log('ERROR', e)
         return
     self.nsservers = [str(answer) for answer in answers]
     if not len(self.nsservers):
         logger.log('ALERT', f'没有找到{self.domain}的NS域名服务器记录')
         return
     for nsserver in self.nsservers:
         logger.log('DEBUG', f'正在尝试对{self.domain}的域名服务器{nsserver}进行域传送')
         try:
             xfr = dns.query.xfr(nsserver, self.domain)
             zone = dns.zone.from_xfr(xfr)
         except Exception as e:
             logger.log('DEBUG', str(e))
             logger.log('DEBUG', f'对{self.domain}的域名服务器{nsserver}进行域传送失败')
             continue
         else:
             names = zone.nodes.keys()
             for name in names:
                 subdomain = utils.match_subdomain(self.domain, str(name) + '.' + self.domain)
                 self.subdomains = self.subdomains.union(subdomain)
                 record = zone[name].to_text(name)
                 self.results.append(record)
         if self.results:
             logger.log('DEBUG', f'发现{self.domain}在{nsserver}上的域传送记录')
             logger.log('DEBUG', '\n'.join(self.results))
             self.results = []
Example #3
0
def collect_wildcard_record(domain, authoritative_ns):
    logger.log('INFOR', f'正在收集{domain}的泛解析记录')
    if not authoritative_ns:
        return list(), int()
    resolver = resolve.dns_resolver()
    resolver.nameservers = authoritative_ns
    resolver.rotate = True
    resolver.cache = None
    ips = set()
    ips_stat = dict()
    while True:
        token = secrets.token_hex(4)
        random_subdomain = f'{token}.{domain}'
        ip, ttl = get_wildcard_record(random_subdomain, resolver)
        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'收集到{domain}的泛解析记录\n{ips}\n{ttl}')
    return ips, ttl
Example #4
0
def get_cname(subdomain):
    resolver = resolve.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记录
Example #5
0
def query_domain_ns(domain):
    resolver = resolve.dns_resolver()
    try:
        answer = resolver.query(domain, 'NS')
    except Exception as e:
        logger.log('ERROR', e.args)
        logger.log('ERROR', f'查询{domain}的NS记录出错')
        return list()
    ns = [item.to_text() for item in answer]
    logger.log('INFOR', f'{domain}的权威DNS名称服务器 {ns}')
    return ns
Example #6
0
 def check(self):
     """
     正则匹配响应头中的内容安全策略字段以发现子域名
     """
     resolver = resolve.dns_resolver()
     try:
         answers = resolver.query(self.domain, "NS")
     except Exception as e:
         logger.log('ERROR', e)
         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)
Example #7
0
def query_domain_ns_a(ns_list):
    if not isinstance(ns_list, list):
        return list()
    ns_ip_list = []
    resolver = resolve.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
Example #8
0
def dns_query(qname, qtype):
    """
    查询域名DNS记录

    :param str qname: 待查域名
    :param str qtype: 查询类型
    :return: 查询结果
    """
    logger.log('TRACE', f'尝试查询{qname}的{qtype}记录')
    resolver = resolve.dns_resolver()
    try:
        answer = resolver.query(qname, qtype)
    except Exception as e:
        logger.log('TRACE', e.args)
        logger.log('TRACE', f'查询{qname}的{qtype}记录失败')
        return None
    else:
        logger.log('TRACE', f'查询{qname}的{qtype}记录成功')
        return answer
Example #9
0
def get_wildcard_record(domain, authoritative_ns):
    if not authoritative_ns:
        return list(), int()
    resolver = resolve.dns_resolver()
    resolver.nameservers = authoritative_ns
    token = secrets.token_hex(4)
    random_subdomain = f'{token}.{domain}'
    logger.log('INFOR', f'查询{random_subdomain}在权威DNS名称服务器的泛解析记录')
    try:
        answer = resolver.query(random_subdomain, 'A')
    except Exception as e:
        logger.log('ERROR', e.args)
        logger.log('ERROR', f'查询{random_subdomain}在权威DNS名称服务器泛解析记录出错')
        return None, None
    name = answer.name
    ips = {item.address for item in answer}
    ttl = answer.ttl
    logger.log(
        'INFOR', f'{random_subdomain} 在权威DNS上解析到域名: {name} '
        f'IP: {ips} TTL: {ttl}')
    return ips, ttl
Example #10
0
def do_query_a(domain):
    resolver = resolve.dns_resolver()
    try:
        answer = resolver.query(domain, 'A')
    # 如果查询随机域名A记录时抛出Timeout异常则重新探测
    except Timeout as e:
        logger.log('ALERT', f'探测超时重新探测中')
        logger.log('DEBUG', e.args)
        raise TryAgain
    # 如果查询随机域名A记录时抛出NXDOMAIN,YXDOMAIN,NoAnswer,NoNameservers异常
    # 则说明不存在随机子域的A记录 即没有开启泛解析
    except Exception as e:
        logger.log('DEBUG', e.args)
        logger.log('INFOR', f'{domain}没有使用泛解析')
        return False
    if isinstance(answer, Answer):
        ttl = answer.ttl
        name = answer.name
        ips = {item.address for item in answer}
        logger.log('ALERT', f'{domain}使用了泛解析')
        logger.log('ALERT', f'{domain} 解析到域名: {name} ' f'IP: {ips} TTL: {ttl}')
        return True
Example #11
0
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 = resolve.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('FATAL', f'探测{domain}是否使用泛解析失败')
        exit(1)
    else:
        return wildcard
Example #12
0
 def __init__(self, domain):
     Module.__init__(self)
     self.domain = self.register(domain)
     self.module = 'dnsquery'
     self.source = "BruteSRV"
     self.resolver = resolve.dns_resolver()
Example #13
0
 def __init__(self, names_que, answers_que):
     threading.Thread.__init__(self)
     self.names_que = names_que
     self.answers_que = answers_que
     self.resolver = resolve.dns_resolver()