mirror of
https://github.com/shmilylty/OneForAll.git
synced 2026-08-26 04:47:48 +08:00
pep8
This commit is contained in:
@@ -224,7 +224,8 @@ class AIOBrute(Module):
|
||||
self.enable_wildcard, self.wildcard_ips, self.wildcard_ttl = detect_wildcard(domain)
|
||||
tasks = self.gen_tasks(domain)
|
||||
logger.log('INFOR', f'正在爆破{domain}的域名')
|
||||
for task in tqdm.tqdm(tasks, desc='Progress', smoothing=1.0, ncols=True):
|
||||
for task in tqdm.tqdm(tasks, desc='Progress',
|
||||
smoothing=1.0, ncols=True):
|
||||
async with aiomultiprocess.Pool(processes=self.processes,
|
||||
initializer=init_worker,
|
||||
childconcurrency=self.coroutine)\
|
||||
|
||||
+12
-5
@@ -31,13 +31,17 @@ class Collect(object):
|
||||
:return: None
|
||||
"""
|
||||
if config.enable_all_module:
|
||||
# modules = ['brute', 'certificates', 'crawl', 'datasets', 'intelligence', 'search']
|
||||
modules = ['certificates', 'check', 'datasets', 'dnsquery', 'intelligence', 'search'] # crawl模块还有点问题
|
||||
# modules = ['brute', 'certificates', 'crawl',
|
||||
# 'datasets', 'intelligence', 'search']
|
||||
# crawl模块还有点问题
|
||||
modules = ['certificates', 'check', 'datasets',
|
||||
'dnsquery', 'intelligence', 'search']
|
||||
# modules = ['intelligence'] # crawl模块还有点问题
|
||||
for module in modules:
|
||||
module_path = config.oneforall_module_path.joinpath(module)
|
||||
for path in module_path.rglob('*.py'):
|
||||
import_module = ('modules.' + module, path.stem) # 需要导入的类
|
||||
# 需要导入的类
|
||||
import_module = ('modules.' + module, path.stem)
|
||||
self.modules.append(import_module)
|
||||
else:
|
||||
self.modules = config.enable_partial_module
|
||||
@@ -62,7 +66,9 @@ class Collect(object):
|
||||
threads = []
|
||||
# 创建多个子域收集线程
|
||||
for collect_func in self.collect_func:
|
||||
thread = threading.Thread(target=collect_func, args=(self.domain,), daemon=True)
|
||||
thread = threading.Thread(target=collect_func,
|
||||
args=(self.domain,),
|
||||
daemon=True)
|
||||
threads.append(thread)
|
||||
# 启动所有线程
|
||||
for thread in threads:
|
||||
@@ -81,7 +87,8 @@ class Collect(object):
|
||||
# 数据库导出
|
||||
if self.export:
|
||||
if not self.path:
|
||||
self.path = config.result_save_path.joinpath(f'{self.domain}.{self.format}')
|
||||
name = f'{self.domain}.{self.format}'
|
||||
self.path = config.result_save_path.joinpath(name)
|
||||
dbexport.export(table_name, path=self.path, format=self.format)
|
||||
end = time.time()
|
||||
self.elapsed = round(end - start, 1)
|
||||
|
||||
+31
-23
@@ -18,7 +18,9 @@ result_save_path = oneforall_relpath.joinpath('results') # 结果保存目录
|
||||
save_module_result = True # 保存模块中各脚本结果 默认保存
|
||||
enable_all_module = True # 启用所有模块 默认启用
|
||||
enable_partial_module = [] # 启用部分模块 必须禁用enable_all_module才能生效
|
||||
# enable_partial_module = [('modules.search', 'ask'),('modules.search', 'baidu')] # 只使用ask和baidu搜索引擎收集子域
|
||||
# 只使用ask和baidu搜索引擎收集子域
|
||||
# enable_partial_module = [('modules.search', 'ask')
|
||||
# ('modules.search', 'baidu')]
|
||||
|
||||
|
||||
# 爆破模块设置
|
||||
@@ -29,8 +31,10 @@ brute_processes_num = os.cpu_count()
|
||||
brute_coroutine_num = 128 # 爆破时每个进程下的协程数(不宜大于1000)
|
||||
# 爆破所使用的字典路径 默认data/subdomains.txt
|
||||
brute_wordlist_path = 'data/subdomains.txt'
|
||||
brute_task_segment = 500 # 参数segment的设置受CPU性能,网络带宽,运营商限制等问题影响,默认设置500个子域为一任务组,
|
||||
# 当你觉得你的环境不受以上因素影响,当前爆破速度较慢,那么强烈建议根据字典大小调整大小:十万字典建议设置为5000,百万字典设置为50000
|
||||
brute_task_segment = 500
|
||||
# 参数segment的设置受CPU性能,网络带宽,运营商限制等问题影响,默认设置500个子域为一任务组,
|
||||
# 当你觉得你的环境不受以上因素影响,当前爆破速度较慢,那么强烈建议根据字典大小调整大小:
|
||||
# 十万字典建议设置为5000,百万字典设置为50000
|
||||
enable_recursive_brute = False # 是否使用递归爆破(默认禁用)
|
||||
brute_recursive_depth = 2 # 递归爆破深度(默认2层)
|
||||
# 爆破下一层子域所使用的字典路径 默认data/next_subdomains.txt
|
||||
@@ -42,10 +46,14 @@ ips_appear_maximum = 10 # 同一IP集合出现次数超过10认为是泛解析
|
||||
# 代理设置
|
||||
enable_proxy = False # 是否使用代理 全局开关
|
||||
proxy_all_module = False # 代理所有模块
|
||||
proxy_partial_module = ['GoogleQuery', 'AskSearch', 'DuckDuckGoSearch', 'GoogleAPISearch', 'GoogleSearch',
|
||||
'YahooSearch', 'YandexSearch', 'CrossDomainXml', 'ContentSecurityPolicy'] # 代理自定义的模块
|
||||
proxy_pool = [{'http': 'http://127.0.0.1:1080', 'https': 'https://127.0.0.1:1080'}] # 代理池
|
||||
# proxy_pool = [{'http': 'socks5://127.0.0.1:10808', 'https': 'socks5://127.0.0.1:10808'}] # 代理池
|
||||
proxy_partial_module = ['GoogleQuery', 'AskSearch', 'DuckDuckGoSearch',
|
||||
'GoogleAPISearch', 'GoogleSearch', 'YahooSearch',
|
||||
'YandexSearch', 'CrossDomainXml',
|
||||
'ContentSecurityPolicy'] # 代理自定义的模块
|
||||
proxy_pool = [{'http': 'http://127.0.0.1:1080',
|
||||
'https': 'https://127.0.0.1:1080'}] # 代理池
|
||||
# proxy_pool = [{'http': 'socks5://127.0.0.1:10808',
|
||||
# 'https': 'socks5://127.0.0.1:10808'}] # 代理池
|
||||
|
||||
|
||||
# 网络请求设置
|
||||
@@ -84,14 +92,17 @@ xlarge_ports = {80, 81, 300, 443, 591, 593, 832, 981, 1010, 1311, 2082,
|
||||
8500, 8834, 8880, 8888, 8983, 9000, 9043, 9060, 9080, 9090,
|
||||
9091, 9200, 9443, 9800, 9981, 12443, 16080, 18091, 18092,
|
||||
20720, 28017}
|
||||
ports = {'small': small_ports, 'medium': medium_ports, 'large': large_ports, 'xlarge': xlarge_ports}
|
||||
ports = {'small': small_ports, 'medium': medium_ports,
|
||||
'large': large_ports, 'xlarge': xlarge_ports}
|
||||
verify_ssl = False
|
||||
get_proxy = None # aiohttp 支持 HTTP/HTTPS形式的代理 proxy="http://user:pass@some.proxy.com"
|
||||
# aiohttp 支持 HTTP/HTTPS形式的代理
|
||||
get_proxy = None # proxy="http://user:pass@some.proxy.com"
|
||||
get_timeout = 10 # http请求探测总超时时间 None或者0则表示不检测超时
|
||||
get_redirects = True # 允许请求跳转
|
||||
fake_header = True # 使用伪造请求头
|
||||
limit_open_conn = 100 # 限制同一时间打开的连接数(默认100),0表示不限制
|
||||
limit_per_host = 0 # 限制同一时间在同一个端点((host, port, is_ssl) 3者都一样的情况)打开的连接数(默认0表示不限制)
|
||||
# 限制同一时间在同一个端点((host, port, is_ssl) 3者都一样的情况)打开的连接数
|
||||
limit_per_host = 0 # 默认0表示不限制
|
||||
|
||||
|
||||
# 模块API配置
|
||||
@@ -106,7 +117,8 @@ binaryedge_api = ''
|
||||
# Binaryedge可以免费注册获取API:http://api.chinaz.com/ApiDetails/Alexa
|
||||
chinaz_api = ''
|
||||
|
||||
# Bing可以免费注册获取API:https://azure.microsoft.com/zh-cn/services/cognitive-services/bing-web-search-api/#web-json
|
||||
# Bing可以免费注册获取API:https://azure.microsoft.com/zh-cn/services/
|
||||
# cognitive-services/bing-web-search-api/#web-json
|
||||
bing_api_id = ''
|
||||
bing_api_key = ''
|
||||
|
||||
@@ -117,7 +129,8 @@ securitytrails_api = ''
|
||||
fofa_api_email = '' # fofa用户邮箱
|
||||
fofa_api_key = '' # fofa用户key
|
||||
|
||||
# Google可以免费注册获取API: https://developers.google.com/custom-search/v1/overview
|
||||
# Google可以免费注册获取API:
|
||||
# https://developers.google.com/custom-search/v1/overview
|
||||
# 免费的API只能查询前100条结果
|
||||
google_api_key = '' # Google API搜索key
|
||||
google_api_cx = '' # Google API搜索cx
|
||||
@@ -153,8 +166,10 @@ dnsdb_api_key = ''
|
||||
# 免费的API有效期只有2天,到期之后可以再次生成,每天可以查询50次。
|
||||
ipv4info_api_key = ''
|
||||
|
||||
subdomains_common = {'i', 'w', 'm', 'en', 'us', 'zh', 'w3', 'app', 'bbs', 'web', 'www', 'job', 'docs', 'news', 'blog',
|
||||
'data', 'help', 'live', 'mall', 'blogs', 'files', 'forum', 'store', 'mobile'}
|
||||
subdomains_common = {'i', 'w', 'm', 'en', 'us', 'zh', 'w3', 'app', 'bbs',
|
||||
'web', 'www', 'job', 'docs', 'news', 'blog', 'data',
|
||||
'help', 'live', 'mall', 'blogs', 'files', 'forum',
|
||||
'store', 'mobile'}
|
||||
|
||||
# 日志配置
|
||||
stdout_fmt = '<cyan>{time:HH:mm:ss,SSS}</cyan> ' \
|
||||
@@ -178,12 +193,5 @@ logger.level(name='ERROR', no=40, color='<red><bold>', icon='❌️')
|
||||
logger.level(name='FATAL', no=50, color='<RED><bold>', icon='☠️')
|
||||
|
||||
logger.add(sys.stdout, level='INFOR', format=stdout_fmt, enqueue=True)
|
||||
logger.add(log_path, level='TRACE', format=logfile_fmt, enqueue=True, encoding='utf-8')
|
||||
|
||||
# 调试模式
|
||||
# import urllib3
|
||||
# urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
# request_proxy = [{'http': 'http://127.0.0.1:8080', 'https': 'https://127.0.0.1:8080'}]
|
||||
# request_verify = False
|
||||
# enable_all_module = False # 启用所有模块 默认启用
|
||||
# enable_partial_module = [('modules.certificates', 'censys_api')] # 启用部分模块 必须禁用enable_all_module才能生效
|
||||
logger.add(log_path, level='TRACE', format=logfile_fmt, enqueue=True,
|
||||
encoding='utf-8')
|
||||
|
||||
@@ -22,15 +22,19 @@ class CertDBAPI(Query):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'domain': self.domain, 'api_token': self.token, 'page': page_num}
|
||||
params = {'domain': self.domain,
|
||||
'api_token': self.token,
|
||||
'page': page_num}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
resp_json = resp.json()
|
||||
subdomains_find = utils.match_subdomain(self.domain, str(resp_json))
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
json = resp.json()
|
||||
subdomains_find = utils.match_subdomain(self.domain, str(json))
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
page_num += 1
|
||||
if resp_json.get('count') < 30: # 默认每次查询最多返回30条 当前条数小于30条说明已经查完
|
||||
# 默认每次查询最多返回30条 当前条数小于30条说明已经查完
|
||||
if json.get('count') < 30:
|
||||
break
|
||||
|
||||
def run(self):
|
||||
|
||||
@@ -18,12 +18,14 @@ class CertSpotter(Query):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'domain': self.domain, 'include_subdomains': 'true', 'expand': 'dns_names'}
|
||||
params = {'domain': self.domain, 'include_subdomains': 'true',
|
||||
'expand': 'dns_names'}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = utils.match_subdomain(self.domain, str(resp.json()))
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -49,5 +51,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -18,7 +18,8 @@ class Entrust(Query):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'fields': 'subjectDN', 'domain': self.domain, 'includeExpired': 'true'}
|
||||
params = {'fields': 'subjectDN', 'domain': self.domain,
|
||||
'includeExpired': 'true'}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
|
||||
@@ -9,7 +9,8 @@ class Google(Query):
|
||||
self.domain = self.register(domain)
|
||||
self.module = 'Certificate'
|
||||
self.source = 'GoogleQuery'
|
||||
self.addr = 'https://transparencyreport.google.com/transparencyreport/api/v3/httpsreport/ct/certsearch'
|
||||
self.addr = 'https://transparencyreport.google.com/' \
|
||||
'transparencyreport/api/v3/httpsreport/ct/certsearch'
|
||||
|
||||
def query(self):
|
||||
"""
|
||||
@@ -18,12 +19,14 @@ class Google(Query):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'include_expired': 'true', 'include_subdomains': 'true', 'domain': self.domain}
|
||||
params = {'include_expired': 'true', 'include_subdomains': 'true',
|
||||
'domain': self.domain}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = utils.match_subdomain(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
|
||||
@@ -23,8 +23,10 @@ class CheckCDX(Module):
|
||||
检查crossdomain.xml收集子域名
|
||||
:return:
|
||||
"""
|
||||
urls = [f'http://{self.domain}/crossdomain.xml', f'https://{self.domain}/crossdomain.xml',
|
||||
f'http://www.{self.domain}/crossdomain.xml', f'https://www.{self.domain}/crossdomain.xml']
|
||||
urls = [f'http://{self.domain}/crossdomain.xml',
|
||||
f'https://{self.domain}/crossdomain.xml',
|
||||
f'http://www.{self.domain}/crossdomain.xml',
|
||||
f'https://www.{self.domain}/crossdomain.xml']
|
||||
response = None
|
||||
for url in urls:
|
||||
self.header = self.get_header()
|
||||
@@ -41,12 +43,12 @@ class CheckCDX(Module):
|
||||
类执行入口
|
||||
"""
|
||||
self.begin()
|
||||
logger.log('DEBUG', f'开始执行{self.source}检查{self.domain}域的crossdomain.xml')
|
||||
logger.log('DEBUG', f'开始执行{self.source}检查{self.domain}域的跨域策略')
|
||||
self.check()
|
||||
self.save_json()
|
||||
self.gen_result()
|
||||
self.save_db()
|
||||
logger.log('DEBUG', f'结束执行{self.source}检查{self.domain}域的crossdomain.xml')
|
||||
logger.log('DEBUG', f'结束执行{self.source}检查{self.domain}域的跨域策略')
|
||||
self.finish()
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ class ArchiveCrawl(Crawl):
|
||||
if resp.data.get('status') not in ['301', '302']:
|
||||
url = resp.data.get('url')
|
||||
subdomains_find = self.match(self.register(domain), url + resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -53,10 +54,7 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
"""
|
||||
crawl = ArchiveCrawl(domain)
|
||||
crawl.run()
|
||||
logger.log('INFOR', f'{crawl.source}模块耗时{crawl.elapsed}秒发现{crawl.domain}的子域{len(crawl.subdomains)}个')
|
||||
logger.log('DEBUG', f'{crawl.source}模块发现{crawl.domain}的子域 {crawl.subdomains}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -28,7 +28,8 @@ class CommonCrawl(Crawl):
|
||||
for resp in tqdm(cdx.iter(url, limit=limit), total=limit):
|
||||
if resp.data.get('status') not in ['301', '302']:
|
||||
subdomains_find = self.match(self.register(domain), resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -54,10 +55,7 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
"""
|
||||
crawl = CommonCrawl(domain)
|
||||
crawl.run()
|
||||
logger.log('INFOR', f'{crawl.source}模块耗时{crawl.elapsed}秒发现{crawl.domain}的子域{len(crawl.subdomains)}个')
|
||||
logger.log('DEBUG', f'{crawl.source}模块发现{crawl.domain}的子域 {crawl.subdomains}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -52,5 +52,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -22,7 +22,8 @@ class BufferOver(Query):
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -41,12 +42,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = BufferOver(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -48,5 +48,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -24,7 +24,8 @@ class ChinazAPI(Query):
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, str(resp.json()))
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -51,5 +52,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -24,7 +24,8 @@ class CirclAPI(Query):
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, str(resp.json()))
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -51,5 +52,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -28,16 +28,19 @@ class DNSdb(Query):
|
||||
soup = BeautifulSoup(resp.text, features='lxml')
|
||||
index_urls = set(map(lambda x: self.addr + self.domain + x.text, soup.find_all('a')))
|
||||
for url in index_urls:
|
||||
self.delay = random.randint(2, 5) # 休眠绕过CloudFlare的DDoS保护
|
||||
# 休眠绕过CloudFlare的DDoS保护
|
||||
self.delay = random.randint(2, 5)
|
||||
time.sleep(self.delay)
|
||||
resp = self.get(url)
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
else:
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
|
||||
@@ -27,7 +27,8 @@ class DNSdbAPI(Query):
|
||||
return
|
||||
if resp.status_code == 200:
|
||||
subdomains_find = utils.match_subdomain(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -55,5 +56,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -4,10 +4,6 @@ from common.query import Query
|
||||
|
||||
|
||||
class DNSdumpster(Query):
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain):
|
||||
Query.__init__(self)
|
||||
self.domain = self.register(domain)
|
||||
@@ -33,7 +29,8 @@ class DNSdumpster(Query):
|
||||
return
|
||||
subdomains_find = utils.match_subdomain(self.domain, resp.text)
|
||||
if subdomains_find:
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -52,7 +49,6 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = DNSdumpster(domain)
|
||||
query.run()
|
||||
|
||||
@@ -23,7 +23,8 @@ class HackerTarget(Query):
|
||||
if resp.status_code == 200:
|
||||
subdomains_find = utils.match_subdomain(self.domain, resp.text)
|
||||
if subdomains_find:
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -42,12 +43,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = HackerTarget(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -19,7 +19,8 @@ class IPv4InfoAPI(Query):
|
||||
while True:
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'type': 'SUBDOMAINS', 'key': self.api, 'value': self.domain, 'page': page}
|
||||
params = {'type': 'SUBDOMAINS', 'key': self.api,
|
||||
'value': self.domain, 'page': page}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
@@ -29,9 +30,12 @@ class IPv4InfoAPI(Query):
|
||||
subdomains_find = self.match(self.domain, str(resp_json))
|
||||
if not subdomains_find:
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
subdomains = resp_json.get('Subdomains') # 不直接使用subdomains是因为可能里面会出现不符合标准的子域名
|
||||
if len(subdomains) < 300: # ipv4info子域查询接口每次最多返回300个 用来判断是否还有下一页
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
# 不直接使用subdomains是因为可能里面会出现不符合标准的子域名
|
||||
subdomains = resp_json.get('Subdomains')
|
||||
# ipv4info子域查询接口每次最多返回300个 用来判断是否还有下一页
|
||||
if len(subdomains) < 300:
|
||||
break
|
||||
page += 1
|
||||
if page >= 50: # ipv4info子域查询接口最多允许查询50页
|
||||
@@ -54,12 +58,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = IPv4InfoAPI(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -27,7 +27,8 @@ class NetCraft(Query):
|
||||
return None
|
||||
self.cookie = self.get(self.init).cookies
|
||||
cookie_value = self.cookie['netcraft_js_verification_challenge']
|
||||
verify_taken = hashlib.sha1(parse.unquote(cookie_value).encode('utf-8')).hexdigest()
|
||||
cookie_encode = parse.unquote(cookie_value).encode('utf-8')
|
||||
verify_taken = hashlib.sha1(cookie_encode).hexdigest()
|
||||
self.cookie['netcraft_js_verification_response'] = verify_taken
|
||||
|
||||
def query(self):
|
||||
@@ -48,7 +49,8 @@ class NetCraft(Query):
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
if 'Next page' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
break
|
||||
last = re.search(r'&last=.*' + self.domain, resp.text).group(0)
|
||||
@@ -71,12 +73,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = NetCraft(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -18,7 +18,8 @@ class PTRArchive(Query):
|
||||
"""
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
self.cookie = {'pa_id': str(random.randint(0, 1000000000))} # 绕过主页前端JS验证
|
||||
# 绕过主页前端JS验证
|
||||
self.cookie = {'pa_id': str(random.randint(0, 1000000000))}
|
||||
params = {'label': self.domain, 'date': 'ALL'}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
@@ -26,7 +27,8 @@ class PTRArchive(Query):
|
||||
if resp.status_code == 200:
|
||||
subdomains_find = utils.match_subdomain(self.domain, resp.text)
|
||||
if subdomains_find:
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -51,5 +53,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -22,7 +22,8 @@ class Riddler(Query):
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -47,5 +48,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -34,7 +34,8 @@ class Robtex(Query):
|
||||
return
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
if subdomains_find:
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
|
||||
@@ -25,10 +25,11 @@ class SecurityTrailsAPI(Query):
|
||||
resp = self.get(url, params)
|
||||
if not resp:
|
||||
return
|
||||
subdomains_prefix = resp.json()['subdomains']
|
||||
subdomains_find = [f'{prefix}.{self.domain}' for prefix in subdomains_prefix]
|
||||
prefixs = resp.json()['subdomains']
|
||||
subdomains_find = [f'{prefix}.{self.domain}' for prefix in prefixs]
|
||||
if subdomains_find:
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -49,12 +50,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = SecurityTrailsAPI(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -29,8 +29,10 @@ class SiteDossier(Query):
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
if 'Show next 100 items' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
# 搜索页面没有出现下一页时停止搜索
|
||||
if 'Show next 100 items' not in resp.text:
|
||||
break
|
||||
self.page_num += self.per_page_num
|
||||
|
||||
@@ -57,5 +59,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -46,12 +46,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = RiskIQ(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -18,12 +18,14 @@ class ThreatMiner(Query):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'e': 'subdomains_container', 'q': self.domain, 't': 0, 'rt': 10}
|
||||
params = {'e': 'subdomains_container',
|
||||
'q': self.domain, 't': 0, 'rt': 10}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
subdomains_find = self.match(self.domain, resp.text)
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -48,5 +50,4 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -65,12 +65,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = VirusTotal(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -44,12 +44,10 @@ def do(domain): # 统一入口名字 方便多线程调用
|
||||
类统一调用入口
|
||||
|
||||
:param str domain: 域名
|
||||
|
||||
"""
|
||||
query = VirusTotalAPI(domain)
|
||||
query.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
do('example.com')
|
||||
|
||||
@@ -34,7 +34,8 @@ class Ask(Search):
|
||||
if not subdomain_find:
|
||||
break
|
||||
if not full_search:
|
||||
if subdomain_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomain_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomain_find)
|
||||
self.page_num += 1
|
||||
@@ -53,9 +54,12 @@ class Ask(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
self.save_json()
|
||||
self.gen_result()
|
||||
|
||||
@@ -22,7 +22,8 @@ class Baidu(Search):
|
||||
"""
|
||||
bs = BeautifulSoup(html, features='lxml')
|
||||
subdomains_all = set()
|
||||
for find_res in bs.find_all('a', {'class': 'c-showurl'}): # 获取搜索结果中所有的跳转URL地址
|
||||
# 获取搜索结果中所有的跳转URL地址
|
||||
for find_res in bs.find_all('a', {'class': 'c-showurl'}):
|
||||
url = find_res.get('href')
|
||||
subdomain = self.match_location(domain, url)
|
||||
subdomains_all = subdomains_all.union(subdomain)
|
||||
@@ -42,22 +43,27 @@ class Baidu(Search):
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
query = 'site:' + domain + filtered_subdomain
|
||||
params = {'wd': query, 'pn': self.page_num, 'rn': self.per_page_num}
|
||||
params = {'wd': query, 'pn': self.page_num,
|
||||
'rn': self.per_page_num}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
if len(domain) > 12: # 解决百度搜索结果中域名过长会显示不全的问题
|
||||
subdomains_find = self.redirect_match(domain, resp.text) # 获取百度跳转URL响应头的Location字段获取直链
|
||||
# 获取百度跳转URL响应头的Location字段获取直链
|
||||
subdomains_find = self.redirect_match(domain, resp.text)
|
||||
else:
|
||||
subdomains_find = self.match(domain, resp.text)
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
if not full_search:
|
||||
if subdomains_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomains_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
self.page_num += self.per_page_num
|
||||
if '&pn={next_pn}&'.format(next_pn=self.page_num) not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
# 搜索页面没有出现下一页时停止搜索
|
||||
if '&pn={next_pn}&'.format(next_pn=self.page_num) not in resp.text:
|
||||
break
|
||||
if self.page_num >= self.limit_num: # 搜索条数限制
|
||||
break
|
||||
@@ -76,9 +82,12 @@ class Baidu(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -31,7 +31,8 @@ class Bing(Search):
|
||||
time.sleep(self.delay)
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
query = 'site:' + domain + filtered_subdomain
|
||||
params = {'q': query, 'first': self.page_num, 'count': self.per_page_num}
|
||||
params = {'q': query, 'first': self.page_num,
|
||||
'count': self.per_page_num}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
@@ -39,10 +40,13 @@ class Bing(Search):
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
if not full_search:
|
||||
if subdomains_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomains_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
if '<div class="sw_next>' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
# 搜索页面没有出现下一页时停止搜索
|
||||
if '<div class="sw_next>' not in resp.text:
|
||||
break
|
||||
self.page_num += self.per_page_num
|
||||
if self.page_num >= self.limit_num: # 搜索条数限制
|
||||
@@ -53,7 +57,6 @@ class Bing(Search):
|
||||
类执行入口
|
||||
"""
|
||||
self.begin()
|
||||
|
||||
self.search(self.domain, full_search=True)
|
||||
|
||||
# 排除同一子域搜索结果过多的子域以发现新的子域
|
||||
@@ -62,15 +65,17 @@ class Bing(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
self.gen_result()
|
||||
self.save_db()
|
||||
|
||||
self.finish()
|
||||
|
||||
|
||||
|
||||
@@ -39,9 +39,11 @@ class BingAPI(Search):
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
if not full_search:
|
||||
if subdomains_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomains_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
self.page_num += self.per_page_num
|
||||
if self.page_num >= self.limit_num: # 搜索条数限制
|
||||
break
|
||||
@@ -61,9 +63,12 @@ class BingAPI(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -34,7 +34,8 @@ class DuckDuckGO(Search):
|
||||
if not subdomain_find:
|
||||
break
|
||||
if not full_search:
|
||||
if subdomain_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomain_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomain_find)
|
||||
try:
|
||||
@@ -43,7 +44,8 @@ class DuckDuckGO(Search):
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
break
|
||||
data.update({'s': s, 'nextParams': '', 'o': 'json', 'dc': dc, 'api': '/d.js'})
|
||||
data.update({'s': s, 'nextParams': '', 'o': 'json',
|
||||
'dc': dc, 'api': '/d.js'})
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@@ -59,9 +61,12 @@ class DuckDuckGO(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -27,7 +27,8 @@ class Exalead(Search):
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
query = 'site:' + domain + filtered_subdomain
|
||||
params = {'q': query, 'elements_per_page': '30', "start_index": self.page_num}
|
||||
params = {'q': query, 'elements_per_page': '30',
|
||||
"start_index": self.page_num}
|
||||
resp = self.get(url=self.addr, params=params)
|
||||
if not resp:
|
||||
return
|
||||
@@ -59,15 +60,17 @@ class Exalead(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
self.gen_result()
|
||||
self.save_db()
|
||||
|
||||
self.finish()
|
||||
|
||||
|
||||
|
||||
@@ -22,12 +22,13 @@ class FoFa(Search):
|
||||
发送搜索请求并做子域匹配
|
||||
"""
|
||||
self.page_num = 1
|
||||
query_base64 = base64.b64encode(f'domain={self.domain}'.encode('utf-8'))
|
||||
query_data = base64.b64encode(f'domain={self.domain}'.encode('utf-8'))
|
||||
while True:
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
query = {'email': self.email, 'key': self.key, 'qbase64': query_base64, 'page': self.page_num}
|
||||
query = {'email': self.email, 'key': self.key,
|
||||
'qbase64': query_data, 'page': self.page_num}
|
||||
resp = self.get(self.addr, query)
|
||||
if not resp:
|
||||
return
|
||||
@@ -39,7 +40,6 @@ class FoFa(Search):
|
||||
"""
|
||||
类执行入口
|
||||
"""
|
||||
|
||||
if not self.check(self.email, self.key):
|
||||
return
|
||||
self.begin()
|
||||
|
||||
@@ -67,9 +67,12 @@ class Google(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -29,7 +29,8 @@ class GoogleAPI(Search):
|
||||
time.sleep(self.delay)
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
params = {'key': self.key, 'cx': self.cx, 'q': word, 'fields': 'items/link',
|
||||
params = {'key': self.key, 'cx': self.cx,
|
||||
'q': word, 'fields': 'items/link',
|
||||
'start': self.page_num, 'num': self.per_page_num}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
@@ -60,9 +61,12 @@ class GoogleAPI(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -20,7 +20,8 @@ class ShodanAPI(Search):
|
||||
query = 'hostname:.' + self.domain
|
||||
page = 1
|
||||
while True:
|
||||
params = {'key': self.key, 'page': page, 'query': query, 'minify': True, 'facets': {'hostnames'}}
|
||||
params = {'key': self.key, 'page': page, 'query': query,
|
||||
'minify': True, 'facets': {'hostnames'}}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
|
||||
@@ -35,13 +35,16 @@ class So(Search):
|
||||
if not subdomain_find:
|
||||
break
|
||||
if not full_search:
|
||||
if subdomain_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomain_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomain_find)
|
||||
page_num += 1
|
||||
if '<a id="snext"' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
# 搜索页面没有出现下一页时停止搜索
|
||||
if '<a id="snext"' not in resp.text:
|
||||
break
|
||||
if self.page_num * self.per_page_num >= self.limit_num: # 搜索条数限制
|
||||
# 搜索条数限制
|
||||
if self.page_num * self.per_page_num >= self.limit_num:
|
||||
break
|
||||
|
||||
def run(self):
|
||||
@@ -49,7 +52,6 @@ class So(Search):
|
||||
类执行入口
|
||||
"""
|
||||
self.begin()
|
||||
|
||||
self.search(self.domain, full_search=True)
|
||||
|
||||
# 排除同一子域搜索结果过多的子域以发现新的子域
|
||||
@@ -58,9 +60,12 @@ class So(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -23,7 +23,8 @@ class Sogou(Search):
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
word = 'site:' + domain + filtered_subdomain
|
||||
payload = {'query': word, 'page': self.page_num, "num": self.per_page_num}
|
||||
payload = {'query': word, 'page': self.page_num,
|
||||
"num": self.per_page_num}
|
||||
resp = self.get(self.addr, payload)
|
||||
if not resp:
|
||||
return
|
||||
@@ -31,13 +32,16 @@ class Sogou(Search):
|
||||
if not subdomain_find:
|
||||
break
|
||||
if not full_search:
|
||||
if subdomain_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomain_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomain_find)
|
||||
self.page_num += 1
|
||||
if '<a id="sogou_next"' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
# 搜索页面没有出现下一页时停止搜索
|
||||
if '<a id="sogou_next"' not in resp.text:
|
||||
break
|
||||
if self.page_num * self.per_page_num >= self.limit_num: # 搜索条数限制
|
||||
# 搜索条数限制
|
||||
if self.page_num * self.per_page_num >= self.limit_num:
|
||||
break
|
||||
|
||||
def run(self):
|
||||
@@ -54,9 +58,12 @@ class Sogou(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -40,9 +40,11 @@ class Yahoo(Search):
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
if not full_search:
|
||||
if subdomains_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomains_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
if '>Next</a>' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
break
|
||||
self.page_num += self.per_page_num
|
||||
@@ -63,9 +65,12 @@ class Yahoo(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -31,7 +31,8 @@ class Yandex(Search):
|
||||
self.header = self.get_header()
|
||||
self.proxy = self.get_proxy(self.source)
|
||||
query = 'site:' + domain + filtered_subdomain
|
||||
params = {'text': query, 'p': self.page_num, 'numdoc': self.per_page_num}
|
||||
params = {'text': query, 'p': self.page_num,
|
||||
'numdoc': self.per_page_num}
|
||||
resp = self.get(self.addr, params)
|
||||
if not resp:
|
||||
return
|
||||
@@ -39,9 +40,11 @@ class Yandex(Search):
|
||||
if not subdomains_find: # 搜索没有发现子域名则停止搜索
|
||||
break
|
||||
if not full_search:
|
||||
if subdomains_find.issubset(self.subdomains): # 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
# 搜索中发现搜索出的结果有完全重复的结果就停止搜索
|
||||
if subdomains_find.issubset(self.subdomains):
|
||||
break
|
||||
self.subdomains = self.subdomains.union(subdomains_find) # 合并搜索子域名搜索结果
|
||||
# 合并搜索子域名搜索结果
|
||||
self.subdomains = self.subdomains.union(subdomains_find)
|
||||
if '>next</a>' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
||||
break
|
||||
self.page_num += 1
|
||||
@@ -62,9 +65,12 @@ class Yandex(Search):
|
||||
|
||||
# 递归搜索下一层的子域
|
||||
if self.recursive_search:
|
||||
for layer_num in range(1, self.recursive_times): # 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
# 从1开始是之前已经做过1层子域搜索了,当前实际递归层数是layer+1
|
||||
for layer_num in range(1, self.recursive_times):
|
||||
for subdomain in self.subdomains:
|
||||
if subdomain.count('.') - self.domain.count('.') == layer_num: # 进行下一层子域搜索的限制条件
|
||||
# 进行下一层子域搜索的限制条件
|
||||
count = subdomain.count('.') - self.domain.count('.')
|
||||
if count == layer_num:
|
||||
self.search(subdomain)
|
||||
|
||||
self.save_json()
|
||||
|
||||
@@ -53,7 +53,8 @@ class OneForAll(object):
|
||||
:param str path: 导出路径(默认None)
|
||||
:param bool output: 是否将导出数据输出到终端(默认False)
|
||||
"""
|
||||
def __init__(self, target, brute=False, port='medium', valid=1, path=None, format='xlsx', output=False):
|
||||
def __init__(self, target, brute=False, port='medium', valid=1, path=None,
|
||||
format='xlsx', output=False):
|
||||
self.target = target
|
||||
self.port = port
|
||||
self.domains = set()
|
||||
@@ -86,7 +87,8 @@ class OneForAll(object):
|
||||
asyncio.set_event_loop(loop)
|
||||
self.datas = loop.run_until_complete(resolve.bulk_query_a(self.datas))
|
||||
self.datas = loop.run_until_complete(request.bulk_get_request(self.datas, self.port))
|
||||
loop.run_until_complete(asyncio.sleep(0.25)) # 在关闭事件循环前加入一小段延迟让底层连接得到关闭的缓冲时间
|
||||
# 在关闭事件循环前加入一小段延迟让底层连接得到关闭的缓冲时间
|
||||
loop.run_until_complete(asyncio.sleep(0.25))
|
||||
loop.close()
|
||||
database.clear_table(db_conn, table_name)
|
||||
database.save_db(db_conn, table_name, self.datas)
|
||||
|
||||
Reference in New Issue
Block a user