mirror of
https://github.com/shmilylty/OneForAll.git
synced 2026-08-25 20:37:48 +08:00
99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
#!/usr/bin/python3
|
||
# coding=utf-8
|
||
|
||
"""
|
||
OneForAll是一款强大的子域收集神器
|
||
"""
|
||
|
||
import asyncio
|
||
import fire
|
||
import config
|
||
import dbexport
|
||
from config import logger
|
||
from collect import Collect
|
||
from aiobrute import AIOBrute
|
||
from common import utils, database, resolve, request
|
||
|
||
__author__ = 'Jing Ling, Black Star'
|
||
__contact__ = 'admin@hackfun.org'
|
||
__copyright__ = 'Copyright (c) 2019, Jing Ling. All rights reserved.'
|
||
__license__ = 'GNU General Public License v3.0'
|
||
__version__ = '0.0.1'
|
||
|
||
|
||
class OneForAll(object):
|
||
"""
|
||
OneForAll是一款强大的子域收集神器
|
||
|
||
Version: 0.0.1
|
||
Project: https://github.com/shmilylty/OneForAll/
|
||
|
||
:param str target: 单个域名或者每行一个域名的文件路径
|
||
:param bool brute: 是否使用爆破模块(默认禁用)
|
||
:param str port: HTTP请求验证的端口范围(默认medium)
|
||
:param int valid: 导出子域的有效性(默认1)
|
||
:param str format: 导出格式(默认xlsx)
|
||
:param str path: 导出路径(默认None)
|
||
:param bool output: 是否将导出数据输出到终端(默认False)
|
||
|
||
Note:
|
||
参数valid可选值有1,0,None,分别表示导出有效,无效,全部子域
|
||
参数port可选值有'small', 'medium', 'large', 'xlarge',详见config.py配置
|
||
参数format可选格式有'csv','tsv','json','yaml','html','xls','xlsx','dbf','latex','ods'
|
||
参数path为None会根据format参数和域名名称在项目结果目录生成相应文件
|
||
|
||
Example:
|
||
python oneforall.py --target example.com run
|
||
python oneforall.py --target example.com --brute True --port medium valid 1 run
|
||
python oneforall.py --target ./domains.txt --format csv --path= ./result.csv --output True run
|
||
"""
|
||
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()
|
||
self.domain = ''
|
||
self.datas = list()
|
||
self.brute = brute or config.enable_brute_module
|
||
self.valid = valid
|
||
self.path = path
|
||
self.format = format
|
||
self.output = output
|
||
|
||
def run(self):
|
||
logger.log('INFOR', f'开始运行OneForAll')
|
||
self.domains = utils.get_domains(self.target)
|
||
if self.domains:
|
||
for self.domain in self.domains:
|
||
collect = Collect(self.domain, export=False)
|
||
collect.run()
|
||
if self.brute:
|
||
# 由于爆破会有大量dns解析请求 并发常常会导致其他任务中的网络请求超时
|
||
brute = AIOBrute(self.domain)
|
||
brute.run()
|
||
table_name = self.domain.replace('.', '_')
|
||
db_conn = database.connect_db()
|
||
self.datas = database.get_data(db_conn, table_name).as_dict()
|
||
loop = asyncio.get_event_loop()
|
||
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.close()
|
||
database.clear_table(db_conn, table_name)
|
||
database.save_db(db_conn, table_name, self.datas)
|
||
# database.deduplicate_subdomain(db_conn, table_name)
|
||
# database.remove_invalid(db_conn, table_name)
|
||
# 数据库导出
|
||
if not self.path:
|
||
self.path = config.result_save_path.joinpath(f'{self.domain}.{self.format}')
|
||
dbexport.export(table_name, db_conn, self.valid, self.path, self.format, self.output)
|
||
db_conn.close()
|
||
else:
|
||
logger.log('FATAL', f'获取域名失败')
|
||
logger.log('INFOR', f'结束运行OneForAll')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
fire.Fire(OneForAll)
|
||
# OneForAll('owasp.org').run()
|