subdomainCol - 子域名收集接口工具
subdomainCol - 子域名收集接口工具
前情提要
- 自己想要个纯粹的子域名收集接口小工具,Just Wrapper。
- 目前没发现单独的泛解析处理工具,或许会有人需要。
- 之前没有做过比较完整的python项目,练手For Fun。
- 代码质量垃圾警告
TL;DR
1 | __ __ _ ______ __ |
功能:
使用方式:
- 对单个域名
meituan.com
进行子域名收集1
$ python3 ./subdomainCol/subdomaincol.py --target "meituan.com" run
- 对
~/Downloads/meituan.txt
文件内的域名进行子域名收集1
2
3
4
5
6
7$ cat ~/Downloads/meituan.txt
meituan.com
meituan.net
dianping.com
neixin.cn
$ python3 ./subdomainCol/subdomaincol.py --targets ~/Downloads/meituan.txt run - 对子域名集合
~/Downloads/subfinder_xxxx.txt
进行泛解析过滤1
$ python3 ./subdomainCol/subdomaincol.py --mode filter --targets ~/Downloads/subfinder_xxxx.txt run
配置文件:
- SubdomainCol配置文件位置固定于
SubdomainCol/config/config.yaml
,根据需求进行修改。 - 被调用的subfinder配置文件固定于
SubdomainCol/bin/subfinder/config.yaml
,根据需求进行修改。
原理
- 如何安装轮子A
纯粹的调用了别的子域名工具:subfinder、ksubdomian。
后面可能还会装别家的轮子。 - 如何组装轮子B
找寻后发现oneforall的泛解析是实现的比较完善的,但是估计因为一些考虑没有做独立接口。
于是把oneforall的泛解析实现给单独抽成了个泛解析过滤模块。
泛解析
subfinder
看readme的时候发现有泛解析处理参数-nW
,代码中实现位于InitWildcards
函数,原理比较简单粗暴:随机生成一个字符串拼接在域名前面,如果nslookup
不存在解析到的ip即不存在泛解析。
ksubdomain
原理是把结果集中的ip数量进行统计,即某个ip在结果中出现了多少次。再根据此数据进行一个权重计算,类似一种比例划分把,由此过滤掉一些可能有泛解析嫌疑的ip,且由此过滤域名结果集。
oneforall
oneforall.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 以一定的格式获取从target/targets参数传入的域名
self.domains = utils.get_domains(self.target, self.targets)
...
# 处理域名后转到main函数
for domain in self.domains:
self.domain = utils.get_main_domain(domain)
self.main()
...
# 判断主域名是否存在泛解析
self.enable_wildcard = wildcard.detect_wildcard(self.domain)
...
# 处理泛解析
if self.enable_wildcard:
# deal wildcard
self.data = wildcard.deal_wildcard(self.data)wildcard.py
该模块有3个主要逻辑处理入口:detect_wildcard/collect_wildcard_record/deal_wildcard1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 通过随机请求主域名的3个子域名并进行相似度判断,以判定该主域名是否存在泛解析现象
def detect_wildcard(domain):
is_enable = to_detect_wildcard(domain)
if is_enable:
logger.log('ALERT', f'The domain {domain} enables wildcard')
else:
logger.log('ALERT', f'The domain {domain} disables wildcard')
return is_enable
...
# collect_wildcard_record用于获取wildcard_ips, wildcard_ttl;这两个参数最终会作为wildcard.is_valid_subdomain(ip, ip_num, cname, cname_num, ttl, wc_ttl, wc_ips)的wc_ttl, wc_ips参数。最终是用于判断domain的子域名到底是不是泛解析。并且这个函数也会被deal_wildcard调用。
def collect_wildcard_record(domain, authoritative_ns):
...
# 通过各种方式(只看懂了黑名单部分的代码)过滤掉子域名合集里的泛解析子域名
def deal_wildcard(data):
new_data = list()
appear_times = stat_times(data)
for info in data:
subdomain = info.get('subdomain')
isvalid, reason = check_valid_subdomain(appear_times, info)
logger.log('DEBUG', f'{subdomain} is {isvalid} subdomain reason because {reason}')
if isvalid:
new_data.append(info)
return new_data
subdomainCol-泛解析实现逻辑
- 输入子域名 - domains
1
2
3
4xxx1.xxx2.xxx3.xxx4
yyy1.yyy2.yyy3
zzz1.zzz2.zzz3.zzz4
... get_upper_domains(domains)
获取上一级域名集合并去重 - upper_domains1
2
3
4xxx2.xxx3.xxx4
yyy2.yyy3
zzz2.zzz3.zzz4
...get_upper_domain_infos(upper_domains)
获取upper_domains所需的三个信息:
(1)enable_wc - 通过detect_wildcard()
函数判断该域名是否开启泛解析
如果开启泛解析则调用collect_wildcard_record()
函数获取信息(2)(3),反之不需要。
(2)wc_ips - 泛解析IP列表
(3)wc_ttl - 泛解析TTL整型值- 遍历step1输入的子域名 - domains
(1)如果其上一级域名upper_domain
没有开启泛解析则直接认为是有效子域名
(2)反之加入域名列uncertain_subdomains
继续判断 get_uncertain_subdomain_infos(uncertain_subdomains)
获取域名的以下信息
ttl/cnames/ips/max_ip_num/max_cname_num- 遍历
uncertain_subdomain_infos
,对每个uncertain_subdomain
进行is_valid_subdomain()
判断 is_valid_subdomain()
(1)通过cname黑名单和ip黑名单过滤子域名
(2)check_by_compare提取有效ip
(3)通过cname和ip出现次数过滤子域名
环境依赖
- 安装所调用工具subfinder、ksubdomain的配置。
- 替换以下两个二进制文件为对应平台版本
1
2SubdomainCol/bin/ksubdomain/ksubdomain
SubdomainCol/bin/subfinder/subfinder
推荐
Linux-CentOS - 已测试可运行,丢服务器上很自由。
不推荐
macOS - 已测试可运行,但ksubdomain耗资源,不想吹风扇/心疼电脑的不推荐。
Win - 未测试,同理因为耗资源不推荐。不过推测安装依赖+替换bin下的工具程序为win版本即可。
TODO
subdomainCol
- xray高级版的子域名功能集成
主要是自己没有,有的话就加上。不过自己写也很快。 - 更多可控参数
比如被调用的subfinder和ksubdomain的运行参数控制,输出文件位置控制等等。但纠结部分的必要性。 - 暂时想不到,欢迎提需求
但作为一个纯粹的子域名收集工具还需要别的吗🤔好像也没有。
相关
- 主/被动子域名字典收集
被动 - chrome插件?burp插件?
主动 - 每次对收集结果进行处理的小脚本?
还没有搜集过这块的已经实现的轮子或者其他相关信息,若有希望大佬评论区推荐一下。 - 扫title和判断指纹的调用脚本
未完待续
这段时间再做一些完善和测试再把项目放到github上。