From d82443388542f56512890d508a870fcb29fa8f08 Mon Sep 17 00:00:00 2001 From: JrDw0 <37445725+JrDw0@users.noreply.github.com> Date: Sat, 9 May 2020 17:54:03 +0800 Subject: [PATCH 1/4] Update takeover.py --- takeover.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/takeover.py b/takeover.py index 1af4b89..356d88d 100644 --- a/takeover.py +++ b/takeover.py @@ -2,7 +2,7 @@ # coding=utf-8 """ -OneForAll子域接管模块 +OneForAll subdomain takeover module :copyright: Copyright (c) 2019, Jing Ling. All rights reserved. :license: GNU General Public License v3.0, see LICENSE for more details. @@ -47,22 +47,22 @@ def get_maindomain(subdomain): class Takeover(Module): """ - OneForAll多线程子域接管风险检查模块 + OneForAll subdomain takeover module Example: python3 takeover.py --target www.example.com --format csv run python3 takeover.py --target ./subdomains.txt --thread 10 run Note: - 参数format可选格式有'txt', 'rst', 'csv', 'tsv', 'json', 'yaml', 'html', - 'jira', 'xls', 'xlsx', 'dbf', 'latex', 'ods' - 参数path默认None使用OneForAll结果目录生成路径 + --format rst/csv/tsv/json/yaml/html/jira/xls/xlsx/dbf/latex/ods (result format) + --path Result directory (default directory is ./results) - :param any target: 单个子域或者每行一个子域的文件路径(必需参数) - :param int thread: 线程数(默认100) - :param str format: 导出格式(默认csv) - :param str path: 导出路径(默认None) + :param any target: One domain or File path of one domain per line (required) + :param int thread: threads number (default 100) + :param str format: Result format (default csv) + :param str path: Result directory (default None) """ + def __init__(self, target, thread=100, path=None, format='csv'): Module.__init__(self) self.subdomains = set() @@ -78,7 +78,7 @@ class Takeover(Module): self.results = Dataset() def save(self): - logger.log('DEBUG', '正在保存检查结果') + logger.log('DEBUG', 'Saving Results...') if self.format == 'txt': data = str(self.results) else: @@ -93,7 +93,7 @@ class Takeover(Module): for resp in responses: if resp in domain_resp.text and resp in cname_resp.text: - logger.log('ALERT', f'{subdomain}存在子域接管风险') + logger.log('ALERT', f'{subdomain}Subdomain takeover threat found') self.results.append([subdomain, cname]) break @@ -131,14 +131,14 @@ class Takeover(Module): def run(self): start = time.time() - logger.log('INFOR', f'开始执行{self.source}模块') + logger.log('INFOR', f'Start runing {self.source} module') self.subdomains = utils.get_domains(self.target) self.format = utils.check_format(self.format, len(self.subdomains)) timestamp = utils.get_timestamp() name = f'takeover_check_result_{timestamp}' self.path = utils.check_path(self.path, name, self.format) if self.subdomains: - logger.log('INFOR', f'正在检查子域接管风险') + logger.log('INFOR', f'Checking subdomain takeover...') self.fingerprints = get_fingerprint() self.results.headers = ['subdomain', 'cname'] # 创建待检查的子域队列 @@ -155,13 +155,13 @@ class Takeover(Module): self.subdomainq.join() self.save() else: - logger.log('FATAL', f'获取域名失败') + logger.log('FATAL', f'Failed to obtain domain') end = time.time() elapse = round(end - start, 1) - logger.log('INFOR', f'{self.source}模块耗时{elapse}秒' - f'发现{len(self.results)}个子域存在接管风险') - logger.log('INFOR', f'子域接管风险检查结果 {self.path}') - logger.log('INFOR', f'结束执行{self.source}模块') + logger.log('INFOR', f'{self.source} module spends {elapse} seconds' + f'There are {len(self.results)} subdomains exit takeover') + logger.log('INFOR', f'Subdomain takeover results: {self.path}') + logger.log('INFOR', f'Finished {self.source} module') if __name__ == '__main__': From 9710d2bf8d237154fb19b630e694271e3c34c412 Mon Sep 17 00:00:00 2001 From: JrDw0 <37445725+JrDw0@users.noreply.github.com> Date: Sat, 9 May 2020 17:54:41 +0800 Subject: [PATCH 2/4] Update test.py --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index afdf024..1b62fc9 100644 --- a/test.py +++ b/test.py @@ -2,7 +2,7 @@ # coding=utf-8 """ -示例 +Example """ from oneforall import OneForAll From 88e825a123641775f67f4a95cced24aa29cdc1eb Mon Sep 17 00:00:00 2001 From: JrDw0 <37445725+JrDw0@users.noreply.github.com> Date: Mon, 11 May 2020 09:59:30 +0800 Subject: [PATCH 3/4] Update brute.py --- brute.py | 201 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 101 insertions(+), 100 deletions(-) diff --git a/brute.py b/brute.py index d665082..b8e32e4 100644 --- a/brute.py +++ b/brute.py @@ -2,7 +2,7 @@ # coding=utf-8 """ -OneForAll子域爆破模块 +OneForAll subdomain brute module :copyright: Copyright (c) 2019, Jing Ling. All rights reserved. :license: GNU General Public License v3.0, see LICENSE for more details. @@ -30,43 +30,43 @@ from config.log import logger def do_query_a(domain, resolver): try: answer = resolver.query(domain, 'A') - # 如果查询随机域名A记录时抛出Timeout异常则重新探测 + # If resolve random subdomain raise timeout error, try again except Timeout as e: - logger.log('ALERT', f'探测超时重新探测中') + logger.log('ALERT', f'DNS resolve timeout, retrying...') logger.log('DEBUG', e.args) raise tenacity.TryAgain - # 如果查询随机域名A记录时抛出NXDOMAIN异常 - # 则说明不存在随机子域的A记录 即没有开启泛解析 + # If resolve random subdomain raise NXDOMAIN error + # It means that there is no A record of random subdomain and not use wildcard dns record except (NXDOMAIN, YXDOMAIN, NoAnswer, NoNameservers) as e: logger.log('DEBUG', e.args) - logger.log('INFOR', f'{domain}没有使用泛解析') + logger.log('INFOR', f'{domain} seems not use wildcard dns record') return False except Exception as e: - logger.log('ALERT', f'探测{domain}是否使用泛解析出错') + logger.log('ALERT', f'Detect {domain} wildcard dns record error') logger.log('FATAL', e.args) exit(1) else: if answer.rrset is None: - logger.log('ALERT', f'结果无记录重新探测中') + logger.log('ALERT', f'DNS resolve dont have result, retrying...') raise tenacity.TryAgain 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}') + logger.log('ALERT', f'{domain} use wildcard dns record') + logger.log('ALERT', f'{domain} resolve to: {name} ' + f'IP: {ips} TTL: {ttl}') return True def detect_wildcard(domain, authoritative_ns): """ - 探测域名是否使用泛解析 + Detect use wildcard dns record or not - :param str domain: 域名 - :param list authoritative_ns: 权威DNS - :return: 是否使用泛解析 + :param str domain: domain + :param list authoritative_ns: authoritative name server + :return bool use wildcard dns record or not """ - logger.log('INFOR', f'正在探测{domain}是否使用泛解析') + logger.log('INFOR', f'Detecting {domain} use wildcard dns record or not') token = secrets.token_hex(4) random_subdomain = f'{token}.{domain}' resolver = utils.dns_resolver() @@ -77,7 +77,7 @@ def detect_wildcard(domain, authoritative_ns): wildcard = do_query_a(random_subdomain, resolver) except Exception as e: logger.log('DEBUG', e.args) - logger.log('ALERT', f'多次探测出错暂且认为{domain}没有使用泛解析') + logger.log('ALERT', f'Multiple detection errors, so temporarily {domain} does not use wildcard dns record') return False else: return wildcard @@ -85,17 +85,17 @@ def detect_wildcard(domain, authoritative_ns): def gen_fuzz_subdomains(expression, rule): """ - 生成基于fuzz模式的爆破子域 + Generate subdomains based on fuzz mode - :param str expression: 子域域名生成表达式 - :param str rule: 生成子域所需的正则规则 - :return: 用于爆破的子域 + :param str expression: generate subdomains's expression + :param str rule: regexp rule + :return list subdomains: list of subdomains """ subdomains = list() fuzz_count = exrex.count(rule) if fuzz_count > 10000000: - logger.log('ALERT', f'请注意该规则生成的字典太大:{fuzz_count} > 10000000') - logger.log('DEBUG', f'fuzz模式下生成的字典大小:{fuzz_count}') + logger.log('ALERT', f'The dictionary generated by this rule is so large:{fuzz_count} > 10000000') + logger.log('DEBUG', f'Dictionary size based on fuzz mode: {fuzz_count}') for fuzz_string in exrex.generate(rule): fuzz_string = fuzz_string.lower() if not fuzz_string.isalnum(): @@ -103,17 +103,17 @@ def gen_fuzz_subdomains(expression, rule): fuzz_domain = expression.replace('*', fuzz_string) subdomains.append(fuzz_domain) random_domain = random.choice(subdomains) - logger.log('ALERT', f'请注意检查基于fuzz模式生成的{random_domain}是否正确') + logger.log('ALERT', f'Please check whether {random_domain} is correct or not') return subdomains def gen_word_subdomains(expression, path): """ - 生成基于word模式的爆破子域 + Generate subdomains based on word mode - :param str expression: 子域域名生成表达式 - :param str path: 字典路径 - :return: 用于爆破的子域 + :param str expression: generate subdomains's expression + :param str path: path of wordlist + :return list subdomains: list of subdomains """ subdomains = list() with open(path, encoding='utf-8', errors='ignore') as fd: @@ -126,13 +126,13 @@ def gen_word_subdomains(expression, path): subdomain = expression.replace('*', word) subdomains.append(subdomain) random_domain = random.choice(subdomains) - logger.log('DEBUG', f'fuzz模式下生成的字典大小:{len(subdomains)}') - logger.log('ALERT', f'请注意检查基于word模式生成的{random_domain}是否正确') + logger.log('DEBUG', f'Dictionary based on word mode size: {len(subdomains)}') + logger.log('ALERT', f'Please check whether {random_domain} is correct or not') return subdomains def query_domain_ns_a(ns_list): - logger.log('INFOR', f'正在查询权威DNS名称服务器{ns_list}的A记录') + logger.log('INFOR', f'Querying authoritative name server {ns_list} A record') if not isinstance(ns_list, list): return list() ns_ip_list = [] @@ -142,62 +142,62 @@ def query_domain_ns_a(ns_list): answer = resolver.query(ns, 'A') except Exception as e: logger.log('ERROR', e.args) - logger.log('ERROR', f'查询权威DNS名称服务器{ns}的A记录出错') + logger.log('ERROR', f'Query authoritative name server {ns} A record error') continue if answer: for item in answer: ns_ip_list.append(item.address) - logger.log('INFOR', f'权威DNS名称服务器对应A记录 {ns_ip_list}') + logger.log('INFOR', f'Authoritative name server A record: {ns_ip_list}') return ns_ip_list def query_domain_ns(domain): - logger.log('INFOR', f'正在查询{domain}的NS记录') + logger.log('INFOR', f'Querying NS records of {domain}') domain = utils.get_maindomain(domain) resolver = utils.dns_resolver() try: answer = resolver.query(domain, 'NS') except Exception as e: logger.log('ERROR', e.args) - logger.log('ERROR', f'查询{domain}的NS记录出错') + logger.log('ERROR', f'Querying NS records of {domain} error') return list() ns = [item.to_text() for item in answer] - logger.log('INFOR', f'{domain}的权威DNS名称服务器 {ns}') + logger.log('INFOR', f'{domain}\'s authoritative name server: {ns}') return ns @tenacity.retry(stop=tenacity.stop_after_attempt(2)) def get_wildcard_record(domain, resolver): - logger.log('INFOR', f'查询{domain}在权威DNS名称服务器的泛解析记录') + logger.log('INFOR', f'Query {domain} \'s wildcard dns record in authoritative name server') try: answer = resolver.query(domain, 'A') # 如果查询随机域名A记录时抛出Timeout异常则重新查询 except Timeout as e: - logger.log('ALERT', f'查询超时重新查询中') + logger.log('ALERT', f'Query timeout, retrying') logger.log('DEBUG', e.args) raise tenacity.TryAgain except (NXDOMAIN, YXDOMAIN, NoAnswer, NoNameservers) as e: logger.log('DEBUG', e.args) - logger.log('INFOR', f'{domain}在权威DNS名称服务器上没有A记录') + logger.log('INFOR', f'{domain} dont have A record on authoritative name server') return None, None except Exception as e: logger.log('ERROR', e.args) - logger.log('ERROR', f'查询{domain}在权威DNS名称服务器泛解析记录出错') + logger.log('ERROR', f'Query {domain} wildcard dns record in authoritative name server error') exit(1) else: if answer.rrset is None: - logger.log('DEBUG', f'查询结果无记录') + logger.log('DEBUG', f'No record of query results') return None, None name = answer.name ip = {item.address for item in answer} ttl = answer.ttl - logger.log('INFOR', f'{domain} 在权威DNS上解析到域名: {name} ' - f'IP: {ip} TTL: {ttl}') + logger.log('INFOR', f'{domain} results on authoritative name server: {name} ' + f'IP: {ip} TTL: {ttl}') return ip, ttl def collect_wildcard_record(domain, authoritative_ns): - logger.log('INFOR', f'正在收集{domain}的泛解析记录') + logger.log('INFOR', f'Collecting wildcard dns record for {domain}') if not authoritative_ns: return list(), int() resolver = utils.dns_resolver() @@ -214,7 +214,7 @@ def collect_wildcard_record(domain, authoritative_ns): ip, ttl = get_wildcard_record(random_subdomain, resolver) except Exception as e: logger.log('DEBUG', e.args) - logger.log('ALERT', f'多次查询出错将尝试查询新的随机子域') + logger.log('ALERT', f'Multiple query errors, try to query a new random subdomain') continue if ip is None: continue @@ -231,7 +231,7 @@ def collect_wildcard_record(domain, authoritative_ns): # 大部分的IP地址出现次数大于2次停止收集泛解析IP记录 if len(addrs) / len(ips) >= 0.8: break - logger.log('DEBUG', f'收集到{domain}的泛解析记录\n{ips}\n{ttl}') + logger.log('DEBUG', f'Collected the wildcard dns record of {domain}\n{ips}\n{ttl}') return ips, ttl @@ -251,17 +251,17 @@ def check_dict(): if not setting.enable_check_dict: return sec = setting.check_time - logger.log('ALERT', f'你有{sec}秒时间检查爆破配置是否正确') - logger.log('ALERT', f'退出爆破请使用`Ctrl+C`') + logger.log('ALERT', f'You have {sec} seconds to check whether the configuration is correct or not') + logger.log('ALERT', f'If you want to exit, please use `Ctrl + C`') try: time.sleep(sec) except KeyboardInterrupt: - logger.log('INFOR', '爆破配置有误退出爆破') + logger.log('INFOR', 'Due to configuration incorrect, exited') exit(0) def gen_records(items, records, subdomains, ip_times, wc_ips, wc_ttl): - qname = items.get('name')[:-1] # 去出最右边的`.`点号 + qname = items.get('name')[:-1] # 去除最右边的`.`点号 reason = items.get('status') resolver = items.get('resolver') data = items.get('data') @@ -276,9 +276,9 @@ def gen_records(items, records, subdomains, ip_times, wc_ips, wc_ttl): have_a_record = False for answer in answers: if answer.get('type') != 'A': - logger.log('TRACE', f'查询{qname}返回的应答没有A记录\n{answer}') + logger.log('TRACE', f'The query result of {qname} has no A record\n{answer}') continue - logger.log('TRACE', f'查询{qname}返回的应答具有A记录\n{answer}') + logger.log('TRACE', f'The query result of {qname} no A record\n{answer}') have_a_record = True ttl = answer.get('ttl') ttls.append(ttl) @@ -289,10 +289,10 @@ def gen_records(items, records, subdomains, ip_times, wc_ips, wc_ttl): num = ip_times.get(ip) times.append(num) isvalid, reason = is_valid_subdomain(ip, ttl, num, wc_ips, wc_ttl) - logger.log('TRACE', f'{ip}是否有效:{isvalid} 原因:{reason}') + logger.log('TRACE', f'{ip} effective: {isvalid} reason: {reason}') is_valid_flags.append(isvalid) if not have_a_record: - logger.log('TRACE', f'查询{qname}返回的所有应答都中没有A记录{answers}') + logger.log('TRACE', f'All query result of {qname} no A record{answers}') # 为了优化内存 只添加有A记录且通过判断的子域到记录中 if have_a_record and all(is_valid_flags): record['resolve'] = 1 @@ -309,10 +309,10 @@ def gen_records(items, records, subdomains, ip_times, wc_ips, wc_ttl): def stat_ip_times(result_paths): - logger.log('INFOR', f'正在统计IP次数') + logger.log('INFOR', f'Counting IP...') times = dict() for result_path in result_paths: - logger.log('DEBUG', f'正在读取{result_path}') + logger.log('DEBUG', f'Reading {result_path}') with open(result_path) as fd: for line in fd: line = line.strip() @@ -320,7 +320,7 @@ def stat_ip_times(result_paths): items = json.loads(line) except Exception as e: logger.log('ERROR', e.args) - logger.log('ERROR', f'解析{result_path}行{line}出错跳过解析该行') + logger.log('ERROR', f'Error parsing {result_path} line {line} Skip this line') continue status = items.get('status') if status != 'NOERROR': @@ -339,11 +339,11 @@ def stat_ip_times(result_paths): def deal_output(output_paths, ip_times, wildcard_ips, wildcard_ttl): - logger.log('INFOR', f'正在处理解析结果') + logger.log('INFOR', f'Processing results...') records = dict() # 用来记录所有域名解析数据 subdomains = list() # 用来保存所有通过有效性检查的子域 for output_path in output_paths: - logger.log('DEBUG', f'正在处理{output_path}') + logger.log('DEBUG', f'Processing {output_path}') with open(output_path) as fd: for line in fd: line = line.strip() @@ -351,16 +351,16 @@ def deal_output(output_paths, ip_times, wildcard_ips, wildcard_ttl): items = json.loads(line) except Exception as e: logger.log('ERROR', e.args) - logger.log('ERROR', f'解析行{line}出错跳过解析该行') + logger.log('ERROR', f'Error parsing {line} Skip this line') continue - qname = items.get('name')[:-1] # 去出最右边的`.`点号 + qname = items.get('name')[:-1] # 去除最右边的`.`点号 status = items.get('status') if status != 'NOERROR': - logger.log('TRACE', f'处理{line}时发现{qname}查询结果状态{status}') + logger.log('TRACE', f'Found {qname}\'s result {status} while processing {line}') continue data = items.get('data') if 'answers' not in data: - logger.log('TRACE', f'处理{line}时发现{qname}返回的结果无应答') + logger.log('TRACE', f'Processing {line}, {qname} no response') continue records, subdomains = gen_records(items, records, subdomains, ip_times, wildcard_ips, @@ -370,15 +370,15 @@ def deal_output(output_paths, ip_times, wildcard_ips, wildcard_ttl): def check_by_compare(ip, ttl, wc_ips, wc_ttl): """ - 通过与泛解析返回的IP集合和返回的TTL值进行对比判断发现的子域是否是泛解析子域 + Use TTL comparison to detect wildcard dns record - :param set ip: 子域A记录查询出的IP - :param int ttl: 子域A记录查询出的TTL - :param set wc_ips: 泛解析的IP集合 - :param int wc_ttl: 泛解析的TTL - :return: 判断结果 + :param set ip: A record IP address set + :param int ttl: A record TTL value + :param set wc_ips: wildcard dns record IP address set + :param int wc_ttl: wildcard dns record TTL value + :return bool: result """ - # 参考:http://sh3ll.me/archives/201704041222.txt + # Reference:http://sh3ll.me/archives/201704041222.txt if ip not in wc_ips: return False # 子域IP不在泛解析IP集合则不是泛解析 if ttl != wc_ttl and ttl % 60 == 0 and wc_ttl % 60 == 0: @@ -388,10 +388,10 @@ def check_by_compare(ip, ttl, wc_ips, wc_ttl): def check_ip_times(times): """ - 根据ip出现次数判断是否为泛解析 + Use IP address times to determine wildcard or not - :param times: 子域IP出现次数 - :return: 判断结果 + :param times: IP address times + :return bool: result """ if times > setting.ip_appear_maximum: return True @@ -413,7 +413,7 @@ def is_valid_subdomain(ip, ttl, times, wc_ips, wc_ttl): def save_brute_dict(dict_path, dict_set): dict_data = '\n'.join(dict_set) if not utils.save_data(dict_path, dict_data): - logger.log('FATAL', '保存生成的字典出错') + logger.log('FATAL', 'Saving dictionary error') exit(1) @@ -438,26 +438,27 @@ class Brute(Module): brute.py --target d.com --fuzz True --place m.*.d.com --rule '[a-z]' run Note: - 参数alive可选值True,False分别表示导出存活,全部子域结果 - 参数format可选格式有'txt', 'rst', 'csv', 'tsv', 'json', 'yaml', 'html', - 'jira', 'xls', 'xlsx', 'dbf', 'latex', 'ods' - 参数path默认None使用OneForAll结果目录自动生成路径 + --alive True/False Only export alive subdomains or not (default False) + --format rst/csv/tsv/json/yaml/html/jira/xls/xlsx/dbf/latex/ods (result format) + --path Result directory (default directory is ./results) + + + :param str target: One domain or File path of one domain per line (required) + :param int process: Number of processes (default 1) + :param int concurrent: Number of concurrent (default 10000) + :param bool word: Use word mode generate dictionary (default False) + :param str wordlist: Dictionary path used in word mode (default use ./config/setting.py) + :param bool recursive: Use recursion (default False) + :param int depth: Recursive depth (default 2) + :param str nextlist: Dictionary file path used by recursive (default use ./config/setting.py) + :param bool fuzz: Use fuzz mode generate dictionary (default False) + :param bool alive: Only export alive subdomains (default False) + :param str place: Designated fuzz position (required if use fuzz mode) + :param str rule: Specify the regexp rules used in fuzz mode (required if use fuzz mode) + :param bool export: Export the results (default True) + :param str format: Result format (default csv) + :param str path: Result directory (default None) - :param str target: 单个域名或者每行一个域名的文件路径 - :param int process: 爆破进程数(默认1) - :param int concurrent: 并发爆破数量(默认10000) - :param bool word: 是否使用word模式进行爆破(默认False) - :param str wordlist: word模式爆破使用的字典路径(默认使用setting.py配置) - :param bool recursive: 是否使用递归进行爆破(默认False) - :param int depth: 递归爆破的深度(默认2) - :param str nextlist: 递归爆破所使用的字典路径(默认使用setting.py配置) - :param bool fuzz: 是否使用fuzz模式进行爆破(默认False) - :param str place: 指定爆破位置(开启fuzz模式时必需指定此参数) - :param str rule: 指定fuzz模式爆破使用的正则规则(开启fuzz模式时必需指定此参数) - :param bool export: 是否导出爆破结果(默认True) - :param bool alive: 只导出存活的子域结果(默认True) - :param str format: 结果导出格式(默认csv) - :param str path: 结果导出路径(默认None) """ def __init__(self, target, process=None, concurrent=None, word=False, @@ -596,16 +597,16 @@ class Brute(Module): delete_file(dict_path, output_paths) end = time.time() self.elapse = round(end - start, 1) - logger.log('INFOR', f'{self.source}模块耗时{self.elapse}秒' - f'发现{domain}的子域{len(self.subdomains)}个') - logger.log('DEBUG', f'{self.source}模块发现{domain}的子域:\n' - f'{self.subdomains}') + logger.log('INFOR', f'{self.source} module 耗时{self.elapse}秒' + f'发现{domain}的子域{len(self.subdomains)}个') + logger.log('DEBUG', f'{self.source} module 发现{domain}的子域:\n' + f'{self.subdomains}') self.gen_result(brute=dict_len, valid=len(self.subdomains)) self.save_db() return self.subdomains def run(self): - logger.log('INFOR', f'开始执行{self.source}模块') + logger.log('INFOR', f'Start runing {self.source} module') if self.check_env: utils.check_env() self.domains = utils.get_domains(self.target) @@ -623,7 +624,7 @@ class Brute(Module): for layer_num in range(1, self.recursive_depth): # 之前已经做过1层子域爆破 当前实际递归层数是layer+1 logger.log('INFOR', f'开始递归爆破{self.domain}的' - f'第{layer_num + 1}层子域') + f'第{layer_num + 1}层子域') for subdomain in all_subdomains: self.place = '*.' + subdomain # 进行下一层子域爆破的限制条件 @@ -632,7 +633,7 @@ class Brute(Module): valid_subdomains = self.main(subdomain) all_subdomains.extend(valid_subdomains) - logger.log('INFOR', f'结束执行{self.source}模块爆破域名{self.domain}') + logger.log('INFOR', f'结束执行{self.source} module 爆破域名{self.domain}') if not self.path: name = f'{self.domain}_brute_result.{self.format}' self.path = setting.result_save_dir.joinpath(name) From c12d70b56a5c06cc003f2f0e0aa6b6550fc052a3 Mon Sep 17 00:00:00 2001 From: JrDw0 <37445725+JrDw0@users.noreply.github.com> Date: Mon, 11 May 2020 10:27:00 +0800 Subject: [PATCH 4/4] Update brute.py --- brute.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/brute.py b/brute.py index b8e32e4..3c2e919 100644 --- a/brute.py +++ b/brute.py @@ -94,7 +94,7 @@ def gen_fuzz_subdomains(expression, rule): subdomains = list() fuzz_count = exrex.count(rule) if fuzz_count > 10000000: - logger.log('ALERT', f'The dictionary generated by this rule is so large:{fuzz_count} > 10000000') + logger.log('ALERT', f'The dictionary generated by this rule is too large:{fuzz_count} > 10000000') logger.log('DEBUG', f'Dictionary size based on fuzz mode: {fuzz_count}') for fuzz_string in exrex.generate(rule): fuzz_string = fuzz_string.lower() @@ -493,7 +493,7 @@ class Brute(Module): self.check_env = True def gen_brute_dict(self, domain): - logger.log('INFOR', f'正在为{domain}生成爆破字典') + logger.log('INFOR', f'Generating dictionary for {domain}') dict_set = set() # 如果domain不是self.subdomain 而是self.domain的子域则生成递归爆破字典 if self.place is None: @@ -512,41 +512,41 @@ class Brute(Module): # logger.log('INFOR', f'正在去重爆破字典') # dict_set = utils.uniq_dict_list(dict_set) count = len(dict_set) - logger.log('INFOR', f'生成的爆破字典大小为{count}') + logger.log('INFOR', f'Dictionary size: {count}') if count > 10000000: - logger.log('ALERT', f'注意生成的爆破字典太大:{count} > 10000000') + logger.log('ALERT', f'The dictionary generated is too large:{count} > 10000000') return dict_set def check_brute_params(self): if not (self.word or self.fuzz): - logger.log('FATAL', f'请至少指定一种爆破模式') + logger.log('FATAL', f'Please specify at least one brute mode') exit(1) if len(self.domains) > 1: self.bulk = True if self.fuzz: if self.place is None or self.rule is None: - logger.log('FATAL', f'没有指定fuzz位置或规则') + logger.log('FATAL', f'No fuzz position or rules specified') exit(1) if self.bulk: - logger.log('FATAL', f'批量爆破的场景下不能使用fuzz模式') + logger.log('FATAL', f'Cannot use fuzz mode in the bulk brute') exit(1) if self.recursive_brute: - logger.log('FATAL', f'使用fuzz模式下不能使用递归爆破') + logger.log('FATAL', f'Cannot use recursive brute in fuzz mode') exit(1) fuzz_count = self.place.count('*') if fuzz_count < 1: - logger.log('FATAL', f'没有指定fuzz位置') + logger.log('FATAL', f'No fuzz position specified') exit(1) if fuzz_count > 1: - logger.log('FATAL', f'只能指定1个fuzz位置') + logger.log('FATAL', f'Only one fuzz position can be specified') exit(1) if self.domain not in self.place: - logger.log('FATAL', f'指定fuzz的域名有误') + logger.log('FATAL', f'Incorrect domain for fuzz') exit(1) def main(self, domain): start = time.time() - logger.log('INFOR', f'正在爆破域名{domain}') + logger.log('INFOR', f'Blasting {domain} ...') massdns_dir = setting.third_party_dir.joinpath('massdns') result_dir = setting.result_save_dir temp_dir = result_dir.joinpath('temp') @@ -597,9 +597,9 @@ class Brute(Module): delete_file(dict_path, output_paths) end = time.time() self.elapse = round(end - start, 1) - logger.log('INFOR', f'{self.source} module 耗时{self.elapse}秒' - f'发现{domain}的子域{len(self.subdomains)}个') - logger.log('DEBUG', f'{self.source} module 发现{domain}的子域:\n' + logger.log('INFOR', f'{self.source} module spends {self.elapse} seconds' + f'Found {len(self.subdomains)} subdomains of {domain}') + logger.log('DEBUG', f'{self.source} module found subdomains of {domain}:\n' f'{self.subdomains}') self.gen_result(brute=dict_len, valid=len(self.subdomains)) self.save_db() @@ -614,7 +614,7 @@ class Brute(Module): for self.domain in self.domains: self.check_brute_params() if self.recursive_brute: - logger.log('INFOR', f'开始递归爆破{self.domain}的第1层子域') + logger.log('INFOR', f'Start recursively brute the first layer subdomain of {self.domain}') valid_subdomains = self.main(self.domain) all_subdomains.extend(valid_subdomains) @@ -623,8 +623,8 @@ class Brute(Module): if self.recursive_brute: for layer_num in range(1, self.recursive_depth): # 之前已经做过1层子域爆破 当前实际递归层数是layer+1 - logger.log('INFOR', f'开始递归爆破{self.domain}的' - f'第{layer_num + 1}层子域') + logger.log('INFOR', f'Start recursively brute' + f'the {layer_num + 1} layer subdomain of {self.domain}') for subdomain in all_subdomains: self.place = '*.' + subdomain # 进行下一层子域爆破的限制条件 @@ -633,7 +633,7 @@ class Brute(Module): valid_subdomains = self.main(subdomain) all_subdomains.extend(valid_subdomains) - logger.log('INFOR', f'结束执行{self.source} module 爆破域名{self.domain}') + logger.log('INFOR', f'Finished {self.source} module\'s brute {self.domain}') if not self.path: name = f'{self.domain}_brute_result.{self.format}' self.path = setting.result_save_dir.joinpath(name)