Files
OneForAll-mirror/oneforall/oneforall.py
T
2019-08-09 16:56:03 +08:00

108 lines
4.4 KiB
Python

#!/usr/bin/python3
# coding=utf-8
"""
OneForAll是一款功能强大的子域收集工具
:copyright: Copyright (c) 2019, Jing Ling. All rights reserved.
:license: GNU General Public License v3.0, see LICENSE for more details.
"""
import asyncio
import fire
import config
import dbexport
from datetime import datetime
from config import logger
from collect import Collect
from aiobrute import AIOBrute
from common import utils, database, resolve, request
banner = """\033[01;33m
___ _ _
___ ___ ___| _|___ ___ ___| | | \033[01;37m{\033[1;31mv0.0.3#dev\033[01;37m}\033[01;32m
| . | | -_| _| . | _| .'| | | \033[01;34m
|___|_|_|___|_| |___|_| |__,|_|_| \033[0m\033[4;37mgit.io/fjHT1\033[0m\n
"""
class OneForAll(object):
"""
OneForAll是一款功能强大的子域收集工具
Version: 0.0.3
Project: https://github.com/shmilylty/OneForAll/
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
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参数和域名名称在项目结果目录生成相应文件
: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)
"""
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):
print(banner)
dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f'[*] Starting OneForAll @ {dt}\n')
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)
# 数据库导出
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('example.com').run()