This commit is contained in:
Jing Ling
2020-04-23 10:41:26 +08:00
parent 8d03f29503
commit 13e14c4f76
3 changed files with 39 additions and 15 deletions
+34 -12
View File
@@ -19,7 +19,7 @@ import exrex
import fire import fire
import tenacity import tenacity
from dns.exception import Timeout from dns.exception import Timeout
from dns.resolver import Answer from dns.resolver import Answer, NXDOMAIN, YXDOMAIN, NoAnswer, NoNameservers
import config import config
import dbexport import dbexport
@@ -29,8 +29,7 @@ from config import logger
@tenacity.retry(reraise=True, stop=tenacity.stop_after_attempt(3)) @tenacity.retry(reraise=True, stop=tenacity.stop_after_attempt(3))
def do_query_a(domain): def do_query_a(domain, resolver):
resolver = resolve.dns_resolver()
try: try:
answer = resolver.query(domain, 'A', raise_on_no_answer=False) answer = resolver.query(domain, 'A', raise_on_no_answer=False)
# 如果查询随机域名A记录时抛出Timeout异常则重新探测 # 如果查询随机域名A记录时抛出Timeout异常则重新探测
@@ -38,12 +37,16 @@ def do_query_a(domain):
logger.log('ALERT', f'探测超时重新探测中') logger.log('ALERT', f'探测超时重新探测中')
logger.log('DEBUG', e.args) logger.log('DEBUG', e.args)
raise tenacity.TryAgain raise tenacity.TryAgain
# 如果查询随机域名A记录时抛出NXDOMAIN,YXDOMAIN,NoAnswer,NoNameservers异常 # 如果查询随机域名A记录时抛出NXDOMAIN,NoNameservers异常
# 则说明不存在随机子域的A记录 即没有开启泛解析 # 则说明不存在随机子域的A记录 即没有开启泛解析
except Exception as e: except (NXDOMAIN, NoNameservers) as e:
logger.log('DEBUG', e.args) logger.log('DEBUG', e.args)
logger.log('INFOR', f'{domain}没有使用泛解析') logger.log('INFOR', f'{domain}没有使用泛解析')
return False return False
except Exception as e:
logger.log('ALERT', f'探测出错重新探测中')
logger.log('DEBUG', e.args)
raise tenacity.TryAgain
if isinstance(answer, Answer): if isinstance(answer, Answer):
ttl = answer.ttl ttl = answer.ttl
name = answer.name name = answer.name
@@ -54,7 +57,7 @@ def do_query_a(domain):
return True return True
def detect_wildcard(domain): def detect_wildcard(domain, authoritative_ns):
""" """
探测域名是否使用泛解析 探测域名是否使用泛解析
@@ -64,8 +67,11 @@ def detect_wildcard(domain):
logger.log('INFOR', f'正在探测{domain}是否使用泛解析') logger.log('INFOR', f'正在探测{domain}是否使用泛解析')
token = secrets.token_hex(4) token = secrets.token_hex(4)
random_subdomain = f'{token}.{domain}' random_subdomain = f'{token}.{domain}'
resolver = resolve.dns_resolver()
resolver.nameservers = authoritative_ns
resolver.rotate = True
try: try:
wildcard = do_query_a(random_subdomain) wildcard = do_query_a(random_subdomain, resolver)
except Exception as e: except Exception as e:
logger.log('DEBUG', e.args) logger.log('DEBUG', e.args)
logger.log('FATAL', f'探测{domain}是否使用泛解析失败') logger.log('FATAL', f'探测{domain}是否使用泛解析失败')
@@ -151,6 +157,7 @@ def query_domain_ns_a(ns_list):
def query_domain_ns(domain): def query_domain_ns(domain):
domain = utils.get_maindomain(domain)
resolver = resolve.dns_resolver() resolver = resolve.dns_resolver()
try: try:
answer = resolver.query(domain, 'NS') answer = resolver.query(domain, 'NS')
@@ -167,10 +174,20 @@ def get_wildcard_record(domain, resolver):
logger.log('INFOR', f'查询{domain}在权威DNS名称服务器的泛解析记录') logger.log('INFOR', f'查询{domain}在权威DNS名称服务器的泛解析记录')
try: try:
answer = resolver.query(domain, 'A') answer = resolver.query(domain, 'A')
# 如果查询随机域名A记录时抛出Timeout异常则重新查询
except Timeout as e:
logger.log('ALERT', f'查询超时重新查询中')
logger.log('DEBUG', e.args)
raise tenacity.TryAgain
# 如果查询随机域名A记录时抛出NXDOMAIN, YXDOMAIN, NoAnswer, NoNameservers异常
except (NXDOMAIN, YXDOMAIN, NoAnswer, NoNameservers) as e:
logger.log('DEBUG', e.args)
logger.log('INFOR', f'{domain}没有使用泛解析')
return None, None
except Exception as e: except Exception as e:
logger.log('ERROR', e.args) logger.log('ERROR', e.args)
logger.log('ERROR', f'查询{domain}在权威DNS名称服务器泛解析记录出错') logger.log('ERROR', f'查询{domain}在权威DNS名称服务器泛解析记录出错')
return None, None return e, None
else: else:
name = answer.name name = answer.name
ip = {item.address for item in answer} ip = {item.address for item in answer}
@@ -186,6 +203,7 @@ def collect_wildcard_record(domain, authoritative_ns):
return list(), int() return list(), int()
resolver = resolve.dns_resolver() resolver = resolve.dns_resolver()
resolver.nameservers = authoritative_ns resolver.nameservers = authoritative_ns
resolver.rotate = True
ips = set() ips = set()
ips_stat = dict() ips_stat = dict()
while True: while True:
@@ -193,6 +211,8 @@ def collect_wildcard_record(domain, authoritative_ns):
random_subdomain = f'{token}.{domain}' random_subdomain = f'{token}.{domain}'
ip, ttl = get_wildcard_record(random_subdomain, resolver) ip, ttl = get_wildcard_record(random_subdomain, resolver)
if ip is None: if ip is None:
continue
if isinstance(ip, Exception):
break break
ips = ips.union(ip) ips = ips.union(ip)
# 统计每个泛解析IP出现次数 # 统计每个泛解析IP出现次数
@@ -207,6 +227,7 @@ def collect_wildcard_record(domain, authoritative_ns):
# 大部分的IP地址出现次数大于2次停止收集泛解析IP记录 # 大部分的IP地址出现次数大于2次停止收集泛解析IP记录
if len(addrs) / len(ips) >= 0.8: if len(addrs) / len(ips) >= 0.8:
break break
logger.log('DEBUG', f'收集到{domain}的泛解析记录\n{ips}\n{ttl}')
return ips, ttl return ips, ttl
@@ -562,15 +583,16 @@ class Brute(Module):
utils.check_dir(temp_dir) utils.check_dir(temp_dir)
massdns_path = get_massdns_path(massdns_dir) massdns_path = get_massdns_path(massdns_dir)
timestring = utils.get_timestring() timestring = utils.get_timestring()
self.enable_wildcard = detect_wildcard(domain) ns_list = query_domain_ns(self.domain)
ns_ip_list = query_domain_ns_a(ns_list)
self.enable_wildcard = detect_wildcard(domain, ns_ip_list)
wildcard_ips = list() # 泛解析IP列表 wildcard_ips = list() # 泛解析IP列表
wildcard_ttl = int() # 泛解析TTL整型值 wildcard_ttl = int() # 泛解析TTL整型值
ns_ip_list = list() # DNS权威名称服务器对应A记录列表 ns_ip_list = list() # DNS权威名称服务器对应A记录列表
if self.enable_wildcard: if self.enable_wildcard:
ns_list = query_domain_ns(self.domain) wildcard_ips, wildcard_ttl = collect_wildcard_record(domain,
ns_ip_list = query_domain_ns_a(ns_list) ns_ip_list)
wildcard_ips, wildcard_ttl = collect_wildcard_record(domain, ns_ip_list)
ns_path = get_nameservers_path(self.enable_wildcard, ns_ip_list) ns_path = get_nameservers_path(self.enable_wildcard, ns_ip_list)
dict_set = self.gen_brute_dict(domain) dict_set = self.gen_brute_dict(domain)
+4
View File
@@ -481,3 +481,7 @@ def check_env():
if version < '3.8': if version < '3.8':
logger.log('FATAL', 'OneForAll在Windows系统运行时需要Python 3.8以上版本') logger.log('FATAL', 'OneForAll在Windows系统运行时需要Python 3.8以上版本')
exit(1) exit(1)
def get_maindomain(domain):
return Domain(domain).registered()
+1 -3
View File
@@ -103,13 +103,11 @@ search_recursive_times = 2 # 递归搜索层数
# DNS解析设置 # DNS解析设置
resolve_coroutine_num = 64 resolve_coroutine_num = 64
resolver_nameservers = [ resolver_nameservers = [
'119.29.29.29', # DNSPod
'180.76.76.76', # Baidu DNS
'223.5.5.5', # AliDNS '223.5.5.5', # AliDNS
'119.29.29.29', # DNSPod
'114.114.114.114', # 114DNS '114.114.114.114', # 114DNS
'8.8.8.8', # Google DNS '8.8.8.8', # Google DNS
'1.1.1.1' # CloudFlare DNS '1.1.1.1' # CloudFlare DNS
'208.67.222.222' # OpenDNS
] # 指定查询的DNS域名服务器 ] # 指定查询的DNS域名服务器
resolver_timeout = 5.0 # 解析超时时间 resolver_timeout = 5.0 # 解析超时时间
resolver_lifetime = 60.0 # 解析存活时间 resolver_lifetime = 60.0 # 解析存活时间