oneforall-kjl 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- OneForAll/__init__.py +15 -0
- OneForAll/brute.py +503 -0
- OneForAll/common/check.py +41 -0
- OneForAll/common/crawl.py +10 -0
- OneForAll/common/database.py +277 -0
- OneForAll/common/domain.py +63 -0
- OneForAll/common/ipasn.py +42 -0
- OneForAll/common/ipreg.py +139 -0
- OneForAll/common/lookup.py +28 -0
- OneForAll/common/module.py +369 -0
- OneForAll/common/query.py +9 -0
- OneForAll/common/records.py +363 -0
- OneForAll/common/request.py +264 -0
- OneForAll/common/resolve.py +173 -0
- OneForAll/common/search.py +78 -0
- OneForAll/common/similarity.py +138 -0
- OneForAll/common/tablib/__init__.py +0 -0
- OneForAll/common/tablib/format.py +89 -0
- OneForAll/common/tablib/tablib.py +360 -0
- OneForAll/common/tldextract.py +240 -0
- OneForAll/common/utils.py +789 -0
- OneForAll/config/__init__.py +17 -0
- OneForAll/config/api.py +94 -0
- OneForAll/config/default.py +255 -0
- OneForAll/config/log.py +38 -0
- OneForAll/config/setting.py +108 -0
- OneForAll/export.py +72 -0
- OneForAll/modules/altdns.py +216 -0
- OneForAll/modules/autotake/github.py +105 -0
- OneForAll/modules/certificates/censys_api.py +73 -0
- OneForAll/modules/certificates/certspotter.py +48 -0
- OneForAll/modules/certificates/crtsh.py +84 -0
- OneForAll/modules/certificates/google.py +48 -0
- OneForAll/modules/certificates/myssl.py +46 -0
- OneForAll/modules/certificates/racent.py +49 -0
- OneForAll/modules/check/axfr.py +97 -0
- OneForAll/modules/check/cdx.py +44 -0
- OneForAll/modules/check/cert.py +58 -0
- OneForAll/modules/check/csp.py +94 -0
- OneForAll/modules/check/nsec.py +58 -0
- OneForAll/modules/check/robots.py +44 -0
- OneForAll/modules/check/sitemap.py +44 -0
- OneForAll/modules/collect.py +70 -0
- OneForAll/modules/crawl/archivecrawl.py +59 -0
- OneForAll/modules/crawl/commoncrawl.py +59 -0
- OneForAll/modules/datasets/anubis.py +45 -0
- OneForAll/modules/datasets/bevigil.py +50 -0
- OneForAll/modules/datasets/binaryedge_api.py +50 -0
- OneForAll/modules/datasets/cebaidu.py +45 -0
- OneForAll/modules/datasets/chinaz.py +45 -0
- OneForAll/modules/datasets/chinaz_api.py +49 -0
- OneForAll/modules/datasets/circl_api.py +49 -0
- OneForAll/modules/datasets/cloudflare_api.py +130 -0
- OneForAll/modules/datasets/dnsdb_api.py +51 -0
- OneForAll/modules/datasets/dnsdumpster.py +52 -0
- OneForAll/modules/datasets/dnsgrep.py +44 -0
- OneForAll/modules/datasets/fullhunt.py +48 -0
- OneForAll/modules/datasets/hackertarget.py +45 -0
- OneForAll/modules/datasets/ip138.py +45 -0
- OneForAll/modules/datasets/ipv4info_api.py +73 -0
- OneForAll/modules/datasets/netcraft.py +66 -0
- OneForAll/modules/datasets/passivedns_api.py +51 -0
- OneForAll/modules/datasets/qianxun.py +61 -0
- OneForAll/modules/datasets/rapiddns.py +45 -0
- OneForAll/modules/datasets/riddler.py +45 -0
- OneForAll/modules/datasets/robtex.py +58 -0
- OneForAll/modules/datasets/securitytrails_api.py +56 -0
- OneForAll/modules/datasets/sitedossier.py +57 -0
- OneForAll/modules/datasets/spyse_api.py +62 -0
- OneForAll/modules/datasets/sublist3r.py +45 -0
- OneForAll/modules/datasets/urlscan.py +45 -0
- OneForAll/modules/datasets/windvane.py +92 -0
- OneForAll/modules/dnsquery/mx.py +35 -0
- OneForAll/modules/dnsquery/ns.py +35 -0
- OneForAll/modules/dnsquery/soa.py +35 -0
- OneForAll/modules/dnsquery/spf.py +35 -0
- OneForAll/modules/dnsquery/txt.py +35 -0
- OneForAll/modules/enrich.py +72 -0
- OneForAll/modules/finder.py +206 -0
- OneForAll/modules/intelligence/alienvault.py +50 -0
- OneForAll/modules/intelligence/riskiq_api.py +58 -0
- OneForAll/modules/intelligence/threatbook_api.py +50 -0
- OneForAll/modules/intelligence/threatminer.py +45 -0
- OneForAll/modules/intelligence/virustotal.py +60 -0
- OneForAll/modules/intelligence/virustotal_api.py +59 -0
- OneForAll/modules/iscdn.py +86 -0
- OneForAll/modules/search/ask.py +69 -0
- OneForAll/modules/search/baidu.py +96 -0
- OneForAll/modules/search/bing.py +79 -0
- OneForAll/modules/search/bing_api.py +78 -0
- OneForAll/modules/search/fofa_api.py +74 -0
- OneForAll/modules/search/gitee.py +71 -0
- OneForAll/modules/search/github_api.py +86 -0
- OneForAll/modules/search/google.py +83 -0
- OneForAll/modules/search/google_api.py +77 -0
- OneForAll/modules/search/hunter_api.py +72 -0
- OneForAll/modules/search/quake_api.py +72 -0
- OneForAll/modules/search/shodan_api.py +53 -0
- OneForAll/modules/search/so.py +75 -0
- OneForAll/modules/search/sogou.py +72 -0
- OneForAll/modules/search/wzsearch.py +68 -0
- OneForAll/modules/search/yahoo.py +81 -0
- OneForAll/modules/search/yandex.py +80 -0
- OneForAll/modules/search/zoomeye_api.py +73 -0
- OneForAll/modules/srv.py +75 -0
- OneForAll/modules/wildcard.py +319 -0
- OneForAll/oneforall.py +275 -0
- OneForAll/takeover.py +168 -0
- OneForAll/test.py +23 -0
- oneforall_kjl-0.1.1.dist-info/METADATA +18 -0
- oneforall_kjl-0.1.1.dist-info/RECORD +114 -0
- oneforall_kjl-0.1.1.dist-info/WHEEL +5 -0
- oneforall_kjl-0.1.1.dist-info/entry_points.txt +2 -0
- oneforall_kjl-0.1.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
from common.query import Query
|
2
|
+
|
3
|
+
|
4
|
+
class IP138(Query):
|
5
|
+
def __init__(self, domain):
|
6
|
+
Query.__init__(self)
|
7
|
+
self.domain = domain
|
8
|
+
self.module = 'Dataset'
|
9
|
+
self.source = 'IP138Query'
|
10
|
+
self.addr = 'https://site.ip138.com/{domain}/domain.htm'
|
11
|
+
|
12
|
+
def query(self):
|
13
|
+
"""
|
14
|
+
向接口查询子域并做子域匹配
|
15
|
+
"""
|
16
|
+
self.header = self.get_header()
|
17
|
+
self.proxy = self.get_proxy(self.source)
|
18
|
+
self.addr = self.addr.format(domain=self.domain)
|
19
|
+
resp = self.get(self.addr)
|
20
|
+
self.subdomains = self.collect_subdomains(resp)
|
21
|
+
|
22
|
+
def run(self):
|
23
|
+
"""
|
24
|
+
类执行入口
|
25
|
+
"""
|
26
|
+
self.begin()
|
27
|
+
self.query()
|
28
|
+
self.finish()
|
29
|
+
self.save_json()
|
30
|
+
self.gen_result()
|
31
|
+
self.save_db()
|
32
|
+
|
33
|
+
|
34
|
+
def run(domain):
|
35
|
+
"""
|
36
|
+
类统一调用入口
|
37
|
+
|
38
|
+
:param str domain: 域名
|
39
|
+
"""
|
40
|
+
query = IP138(domain)
|
41
|
+
query.run()
|
42
|
+
|
43
|
+
|
44
|
+
if __name__ == '__main__':
|
45
|
+
run('example.com')
|
@@ -0,0 +1,73 @@
|
|
1
|
+
from config import settings
|
2
|
+
from common.query import Query
|
3
|
+
from config.log import logger
|
4
|
+
|
5
|
+
|
6
|
+
class IPv4InfoAPI(Query):
|
7
|
+
def __init__(self, domain):
|
8
|
+
Query.__init__(self)
|
9
|
+
self.domain = domain
|
10
|
+
self.module = 'Dataset'
|
11
|
+
self.source = 'IPv4InfoAPIQuery'
|
12
|
+
self.addr = ' http://ipv4info.com/api_v1/'
|
13
|
+
self.api = settings.ipv4info_api_key
|
14
|
+
|
15
|
+
def query(self):
|
16
|
+
"""
|
17
|
+
向接口查询子域并做子域匹配
|
18
|
+
"""
|
19
|
+
page = 0
|
20
|
+
while True:
|
21
|
+
self.header = self.get_header()
|
22
|
+
self.proxy = self.get_proxy(self.source)
|
23
|
+
params = {'type': 'SUBDOMAINS', 'key': self.api,
|
24
|
+
'value': self.domain, 'page': page}
|
25
|
+
resp = self.get(self.addr, params)
|
26
|
+
if not resp:
|
27
|
+
return
|
28
|
+
if resp.status_code != 200:
|
29
|
+
break # 请求不正常通常网络是有问题,不再继续请求下去
|
30
|
+
try:
|
31
|
+
json = resp.json()
|
32
|
+
except Exception as e:
|
33
|
+
logger.log('DEBUG', e.args)
|
34
|
+
break
|
35
|
+
subdomains = self.match_subdomains(str(json))
|
36
|
+
if not subdomains:
|
37
|
+
break
|
38
|
+
self.subdomains.update(subdomains)
|
39
|
+
# 不直接使用subdomains是因为可能里面会出现不符合标准的子域名
|
40
|
+
subdomains = json.get('Subdomains')
|
41
|
+
if subdomains and len(subdomains) < 300:
|
42
|
+
# ipv4info子域查询接口每次最多返回300个 用来判断是否还有下一页
|
43
|
+
break
|
44
|
+
page += 1
|
45
|
+
if page >= 50: # ipv4info子域查询接口最多允许查询50页
|
46
|
+
break
|
47
|
+
|
48
|
+
def run(self):
|
49
|
+
"""
|
50
|
+
类执行入口
|
51
|
+
"""
|
52
|
+
if not self.have_api(self.api):
|
53
|
+
return
|
54
|
+
self.begin()
|
55
|
+
self.query()
|
56
|
+
self.finish()
|
57
|
+
self.save_json()
|
58
|
+
self.gen_result()
|
59
|
+
self.save_db()
|
60
|
+
|
61
|
+
|
62
|
+
def run(domain):
|
63
|
+
"""
|
64
|
+
类统一调用入口
|
65
|
+
|
66
|
+
:param str domain: 域名
|
67
|
+
"""
|
68
|
+
query = IPv4InfoAPI(domain)
|
69
|
+
query.run()
|
70
|
+
|
71
|
+
|
72
|
+
if __name__ == '__main__':
|
73
|
+
run('example.com')
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import hashlib
|
2
|
+
import re
|
3
|
+
import time
|
4
|
+
from urllib import parse
|
5
|
+
|
6
|
+
from common.query import Query
|
7
|
+
|
8
|
+
|
9
|
+
class NetCraft(Query):
|
10
|
+
def __init__(self, domain):
|
11
|
+
Query.__init__(self)
|
12
|
+
self.domain = domain
|
13
|
+
self.module = 'Dataset'
|
14
|
+
self.source = 'NetCraftQuery'
|
15
|
+
self.addr = 'https://searchdns.netcraft.com/?restriction=site+contains&position=limited'
|
16
|
+
self.page_num = 1
|
17
|
+
self.per_page_num = 20
|
18
|
+
|
19
|
+
def query(self):
|
20
|
+
"""
|
21
|
+
向接口查询子域并做子域匹配
|
22
|
+
"""
|
23
|
+
self.header = self.get_header() # NetCraft会检查User-Agent
|
24
|
+
self.proxy = self.get_proxy(self.source)
|
25
|
+
last = ''
|
26
|
+
while True:
|
27
|
+
time.sleep(self.delay)
|
28
|
+
self.proxy = self.get_proxy(self.source)
|
29
|
+
params = {'host': '*.' + self.domain,
|
30
|
+
'from': self.page_num}
|
31
|
+
resp = self.get(self.addr + last, params)
|
32
|
+
subdomains = self.match_subdomains(resp)
|
33
|
+
if not subdomains: # 搜索没有发现子域名则停止搜索
|
34
|
+
break
|
35
|
+
self.subdomains.update(subdomains)
|
36
|
+
if 'Next Page' not in resp.text: # 搜索页面没有出现下一页时停止搜索
|
37
|
+
break
|
38
|
+
last = re.search(r'&last=.*' + self.domain, resp.text).group(0)
|
39
|
+
self.page_num += self.per_page_num
|
40
|
+
if self.page_num > 500:
|
41
|
+
break
|
42
|
+
|
43
|
+
def run(self):
|
44
|
+
"""
|
45
|
+
类执行入口
|
46
|
+
"""
|
47
|
+
self.begin()
|
48
|
+
self.query()
|
49
|
+
self.finish()
|
50
|
+
self.save_json()
|
51
|
+
self.gen_result()
|
52
|
+
self.save_db()
|
53
|
+
|
54
|
+
|
55
|
+
def run(domain):
|
56
|
+
"""
|
57
|
+
类统一调用入口
|
58
|
+
|
59
|
+
:param str domain: 域名
|
60
|
+
"""
|
61
|
+
query = NetCraft(domain)
|
62
|
+
query.run()
|
63
|
+
|
64
|
+
|
65
|
+
if __name__ == '__main__':
|
66
|
+
run('example.com')
|
@@ -0,0 +1,51 @@
|
|
1
|
+
from config import settings
|
2
|
+
from common.query import Query
|
3
|
+
|
4
|
+
|
5
|
+
class PassiveDnsAPI(Query):
|
6
|
+
def __init__(self, domain):
|
7
|
+
Query.__init__(self)
|
8
|
+
self.domain = domain
|
9
|
+
self.module = 'Dataset'
|
10
|
+
self.source = 'PassiveDnsQuery'
|
11
|
+
self.addr = settings.passivedns_api_addr or 'http://api.passivedns.cn'
|
12
|
+
self.token = settings.passivedns_api_token
|
13
|
+
|
14
|
+
def query(self):
|
15
|
+
"""
|
16
|
+
向接口查询子域并做子域匹配
|
17
|
+
"""
|
18
|
+
self.header = self.get_header()
|
19
|
+
self.header.update({'X-AuthToken': self.token})
|
20
|
+
self.proxy = self.get_proxy(self.source)
|
21
|
+
url = self.addr + '/flint/rrset/*.' + self.domain
|
22
|
+
resp = self.get(url)
|
23
|
+
self.subdomains = self.collect_subdomains(resp)
|
24
|
+
|
25
|
+
def run(self):
|
26
|
+
"""
|
27
|
+
类执行入口
|
28
|
+
"""
|
29
|
+
if 'api.passivedns.cn' in self.addr:
|
30
|
+
if not self.have_api(self.token):
|
31
|
+
return
|
32
|
+
self.begin()
|
33
|
+
self.query()
|
34
|
+
self.finish()
|
35
|
+
self.save_json()
|
36
|
+
self.gen_result()
|
37
|
+
self.save_db()
|
38
|
+
|
39
|
+
|
40
|
+
def run(domain):
|
41
|
+
"""
|
42
|
+
类统一调用入口
|
43
|
+
|
44
|
+
:param str domain: 域名
|
45
|
+
"""
|
46
|
+
query = PassiveDnsAPI(domain)
|
47
|
+
query.run()
|
48
|
+
|
49
|
+
|
50
|
+
if __name__ == '__main__':
|
51
|
+
run('example.com')
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from common.query import Query
|
2
|
+
|
3
|
+
|
4
|
+
class QianXun(Query):
|
5
|
+
def __init__(self, domain):
|
6
|
+
Query.__init__(self)
|
7
|
+
self.domain = domain
|
8
|
+
self.module = 'Query'
|
9
|
+
self.source = 'QianXunQuery'
|
10
|
+
|
11
|
+
def query(self):
|
12
|
+
"""
|
13
|
+
向接口查询子域并做子域匹配
|
14
|
+
"""
|
15
|
+
self.header = self.get_header()
|
16
|
+
self.proxy = self.get_proxy(self.source)
|
17
|
+
|
18
|
+
num = 1
|
19
|
+
while True:
|
20
|
+
data = {'ecmsfrom': '',
|
21
|
+
'show': '',
|
22
|
+
'num': '',
|
23
|
+
'classid': '0',
|
24
|
+
'keywords': self.domain}
|
25
|
+
url = f'https://www.dnsscan.cn/dns.html?' \
|
26
|
+
f'keywords={self.domain}&page={num}'
|
27
|
+
resp = self.post(url, data)
|
28
|
+
subdomains = self.match_subdomains(resp)
|
29
|
+
if not subdomains: # 没有发现子域名则停止查询
|
30
|
+
break
|
31
|
+
self.subdomains.update(subdomains)
|
32
|
+
if '<div id="page" class="pagelist">' not in resp.text:
|
33
|
+
break
|
34
|
+
if '<li class="disabled"><span>»</span></li>' in resp.text:
|
35
|
+
break
|
36
|
+
num += 1
|
37
|
+
|
38
|
+
def run(self):
|
39
|
+
"""
|
40
|
+
类执行入口
|
41
|
+
"""
|
42
|
+
self.begin()
|
43
|
+
self.query()
|
44
|
+
self.finish()
|
45
|
+
self.save_json()
|
46
|
+
self.gen_result()
|
47
|
+
self.save_db()
|
48
|
+
|
49
|
+
|
50
|
+
def run(domain):
|
51
|
+
"""
|
52
|
+
类统一调用入口
|
53
|
+
|
54
|
+
:param str domain: 域名
|
55
|
+
"""
|
56
|
+
query = QianXun(domain)
|
57
|
+
query.run()
|
58
|
+
|
59
|
+
|
60
|
+
if __name__ == '__main__':
|
61
|
+
run('example.com')
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from common.query import Query
|
2
|
+
|
3
|
+
|
4
|
+
class RapidDNS(Query):
|
5
|
+
def __init__(self, domain):
|
6
|
+
Query.__init__(self)
|
7
|
+
self.domain = domain
|
8
|
+
self.module = 'Dataset'
|
9
|
+
self.source = 'RapidDNSQuery'
|
10
|
+
|
11
|
+
def query(self):
|
12
|
+
"""
|
13
|
+
向接口查询子域并做子域匹配
|
14
|
+
"""
|
15
|
+
self.header = self.get_header()
|
16
|
+
self.proxy = self.get_proxy(self.source)
|
17
|
+
url = f'http://rapiddns.io/subdomain/{self.domain}'
|
18
|
+
params = {'full': '1'}
|
19
|
+
resp = self.get(url, params)
|
20
|
+
self.subdomains = self.collect_subdomains(resp)
|
21
|
+
|
22
|
+
def run(self):
|
23
|
+
"""
|
24
|
+
类执行入口
|
25
|
+
"""
|
26
|
+
self.begin()
|
27
|
+
self.query()
|
28
|
+
self.finish()
|
29
|
+
self.save_json()
|
30
|
+
self.gen_result()
|
31
|
+
self.save_db()
|
32
|
+
|
33
|
+
|
34
|
+
def run(domain):
|
35
|
+
"""
|
36
|
+
类统一调用入口
|
37
|
+
|
38
|
+
:param str domain: 域名
|
39
|
+
"""
|
40
|
+
query = RapidDNS(domain)
|
41
|
+
query.run()
|
42
|
+
|
43
|
+
|
44
|
+
if __name__ == '__main__':
|
45
|
+
run('example.com')
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from common.query import Query
|
2
|
+
|
3
|
+
|
4
|
+
class Riddler(Query):
|
5
|
+
def __init__(self, domain):
|
6
|
+
Query.__init__(self)
|
7
|
+
self.domain = domain
|
8
|
+
self.module = 'Dataset'
|
9
|
+
self.source = 'RiddlerQuery'
|
10
|
+
self.addr = 'https://riddler.io/search'
|
11
|
+
|
12
|
+
def query(self):
|
13
|
+
"""
|
14
|
+
向接口查询子域并做子域匹配
|
15
|
+
"""
|
16
|
+
self.header = self.get_header()
|
17
|
+
self.proxy = self.get_proxy(self.source)
|
18
|
+
params = {'q': 'pld:' + self.domain}
|
19
|
+
resp = self.get(self.addr, params)
|
20
|
+
self.subdomains = self.collect_subdomains(resp)
|
21
|
+
|
22
|
+
def run(self):
|
23
|
+
"""
|
24
|
+
类执行入口
|
25
|
+
"""
|
26
|
+
self.begin()
|
27
|
+
self.query()
|
28
|
+
self.finish()
|
29
|
+
self.save_json()
|
30
|
+
self.gen_result()
|
31
|
+
self.save_db()
|
32
|
+
|
33
|
+
|
34
|
+
def run(domain):
|
35
|
+
"""
|
36
|
+
类统一调用入口
|
37
|
+
|
38
|
+
:param str domain: 域名
|
39
|
+
"""
|
40
|
+
query = Riddler(domain)
|
41
|
+
query.run()
|
42
|
+
|
43
|
+
|
44
|
+
if __name__ == '__main__':
|
45
|
+
run('example.com')
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import json
|
2
|
+
import time
|
3
|
+
|
4
|
+
from common.query import Query
|
5
|
+
|
6
|
+
|
7
|
+
class Robtex(Query):
|
8
|
+
def __init__(self, domain):
|
9
|
+
Query.__init__(self)
|
10
|
+
self.domain = domain
|
11
|
+
self.module = 'Dataset'
|
12
|
+
self.source = "RobtexQuery"
|
13
|
+
|
14
|
+
def query(self):
|
15
|
+
"""
|
16
|
+
向接口查询子域并做子域匹配
|
17
|
+
"""
|
18
|
+
self.header = self.get_header()
|
19
|
+
self.proxy = self.get_proxy(self.source)
|
20
|
+
base_addr = 'https://freeapi.robtex.com/pdns'
|
21
|
+
url = f'{base_addr}/forward/{self.domain}'
|
22
|
+
resp = self.get(url)
|
23
|
+
if not resp:
|
24
|
+
return
|
25
|
+
text_list = resp.text.splitlines()
|
26
|
+
for item in text_list:
|
27
|
+
record = json.loads(item)
|
28
|
+
if record.get('rrtype') in ['A', 'AAAA']:
|
29
|
+
time.sleep(self.delay) # Robtex有查询频率限制
|
30
|
+
ip = record.get('rrdata')
|
31
|
+
url = f'{base_addr}/reverse/{ip}'
|
32
|
+
resp = self.get(url)
|
33
|
+
self.subdomains = self.collect_subdomains(resp)
|
34
|
+
|
35
|
+
def run(self):
|
36
|
+
"""
|
37
|
+
类执行入口
|
38
|
+
"""
|
39
|
+
self.begin()
|
40
|
+
self.query()
|
41
|
+
self.finish()
|
42
|
+
self.save_json()
|
43
|
+
self.gen_result()
|
44
|
+
self.save_db()
|
45
|
+
|
46
|
+
|
47
|
+
def run(domain):
|
48
|
+
"""
|
49
|
+
类统一调用入口
|
50
|
+
|
51
|
+
:param str domain: 域名
|
52
|
+
"""
|
53
|
+
query = Robtex(domain)
|
54
|
+
query.run()
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == '__main__':
|
58
|
+
run('google.com')
|
@@ -0,0 +1,56 @@
|
|
1
|
+
from config import settings
|
2
|
+
from common.query import Query
|
3
|
+
|
4
|
+
|
5
|
+
class SecurityTrailsAPI(Query):
|
6
|
+
def __init__(self, domain):
|
7
|
+
Query.__init__(self)
|
8
|
+
self.domain = domain
|
9
|
+
self.module = 'Dataset'
|
10
|
+
self.source = 'SecurityTrailsAPIQuery'
|
11
|
+
self.addr = 'https://api.securitytrails.com/v1/domain/'
|
12
|
+
self.api = settings.securitytrails_api
|
13
|
+
self.delay = 2 # SecurityTrails查询时延至少2秒
|
14
|
+
|
15
|
+
def query(self):
|
16
|
+
"""
|
17
|
+
向接口查询子域并做子域匹配
|
18
|
+
"""
|
19
|
+
self.header = self.get_header()
|
20
|
+
self.proxy = self.get_proxy(self.source)
|
21
|
+
params = {'apikey': self.api}
|
22
|
+
url = f'{self.addr}{self.domain}/subdomains'
|
23
|
+
resp = self.get(url, params)
|
24
|
+
if not resp:
|
25
|
+
return
|
26
|
+
prefixs = resp.json()['subdomains']
|
27
|
+
subdomains = [f'{prefix}.{self.domain}' for prefix in prefixs]
|
28
|
+
if subdomains:
|
29
|
+
self.subdomains.update(subdomains)
|
30
|
+
|
31
|
+
def run(self):
|
32
|
+
"""
|
33
|
+
类执行入口
|
34
|
+
"""
|
35
|
+
if not self.have_api(self.api):
|
36
|
+
return
|
37
|
+
self.begin()
|
38
|
+
self.query()
|
39
|
+
self.finish()
|
40
|
+
self.save_json()
|
41
|
+
self.gen_result()
|
42
|
+
self.save_db()
|
43
|
+
|
44
|
+
|
45
|
+
def run(domain):
|
46
|
+
"""
|
47
|
+
类统一调用入口
|
48
|
+
|
49
|
+
:param str domain: 域名
|
50
|
+
"""
|
51
|
+
query = SecurityTrailsAPI(domain)
|
52
|
+
query.run()
|
53
|
+
|
54
|
+
|
55
|
+
if __name__ == '__main__':
|
56
|
+
run('example.com')
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
from common.query import Query
|
3
|
+
|
4
|
+
|
5
|
+
class SiteDossier(Query):
|
6
|
+
def __init__(self, domain):
|
7
|
+
Query.__init__(self)
|
8
|
+
self.domain = domain
|
9
|
+
self.module = 'Dataset'
|
10
|
+
self.source = 'SiteDossierQuery'
|
11
|
+
self.addr = 'http://www.sitedossier.com/parentdomain/'
|
12
|
+
self.delay = 2
|
13
|
+
self.page_num = 1
|
14
|
+
self.per_page_num = 100
|
15
|
+
|
16
|
+
def query(self):
|
17
|
+
"""
|
18
|
+
向接口查询子域并做子域匹配
|
19
|
+
"""
|
20
|
+
while True:
|
21
|
+
self.header = self.get_header()
|
22
|
+
self.proxy = self.get_proxy(self.source)
|
23
|
+
url = f'{self.addr}{self.domain}/{self.page_num}'
|
24
|
+
resp = self.get(url)
|
25
|
+
subdomains = self.match_subdomains(resp)
|
26
|
+
if not subdomains: # 没有发现子域名则停止查询
|
27
|
+
break
|
28
|
+
self.subdomains.update(subdomains)
|
29
|
+
# 搜索页面没有出现下一页时停止搜索
|
30
|
+
if 'Show next 100 items' not in resp.text:
|
31
|
+
break
|
32
|
+
self.page_num += self.per_page_num
|
33
|
+
|
34
|
+
def run(self):
|
35
|
+
"""
|
36
|
+
类执行入口
|
37
|
+
"""
|
38
|
+
self.begin()
|
39
|
+
self.query()
|
40
|
+
self.finish()
|
41
|
+
self.save_json()
|
42
|
+
self.gen_result()
|
43
|
+
self.save_db()
|
44
|
+
|
45
|
+
|
46
|
+
def run(domain):
|
47
|
+
"""
|
48
|
+
类统一调用入口
|
49
|
+
|
50
|
+
:param str domain: 域名
|
51
|
+
"""
|
52
|
+
query = SiteDossier(domain)
|
53
|
+
query.run()
|
54
|
+
|
55
|
+
|
56
|
+
if __name__ == '__main__':
|
57
|
+
run('example.com')
|
@@ -0,0 +1,62 @@
|
|
1
|
+
from config import settings
|
2
|
+
from common.query import Query
|
3
|
+
|
4
|
+
|
5
|
+
class SpyseAPI(Query):
|
6
|
+
def __init__(self, domain):
|
7
|
+
Query.__init__(self)
|
8
|
+
self.domain = domain
|
9
|
+
self.module = 'Dataset'
|
10
|
+
self.source = 'SpyseAPIQuery'
|
11
|
+
self.token = settings.spyse_api_token
|
12
|
+
|
13
|
+
def query(self):
|
14
|
+
"""
|
15
|
+
向接口查询子域并做子域匹配
|
16
|
+
"""
|
17
|
+
limit = 100
|
18
|
+
offset = 0
|
19
|
+
while True:
|
20
|
+
self.header = self.get_header()
|
21
|
+
self.header.update({'Authorization': 'Bearer ' + self.token})
|
22
|
+
self.proxy = self.get_proxy(self.source)
|
23
|
+
addr = 'https://api.spyse.com/v3/data/domain/subdomain'
|
24
|
+
params = {'domain': self.domain, 'offset': offset, 'limit': limit}
|
25
|
+
resp = self.get(addr, params)
|
26
|
+
if not resp:
|
27
|
+
return
|
28
|
+
json = resp.json()
|
29
|
+
subdomains = self.match_subdomains(str(json))
|
30
|
+
if not subdomains: # 没有发现子域名则停止查询
|
31
|
+
break
|
32
|
+
self.subdomains.update(subdomains)
|
33
|
+
offset += limit
|
34
|
+
if len(json.get('data').get('items')) < limit:
|
35
|
+
break
|
36
|
+
|
37
|
+
def run(self):
|
38
|
+
"""
|
39
|
+
类执行入口
|
40
|
+
"""
|
41
|
+
if not self.have_api(self.token):
|
42
|
+
return
|
43
|
+
self.begin()
|
44
|
+
self.query()
|
45
|
+
self.finish()
|
46
|
+
self.save_json()
|
47
|
+
self.gen_result()
|
48
|
+
self.save_db()
|
49
|
+
|
50
|
+
|
51
|
+
def run(domain):
|
52
|
+
"""
|
53
|
+
类统一调用入口
|
54
|
+
|
55
|
+
:param str domain: 域名
|
56
|
+
"""
|
57
|
+
query = SpyseAPI(domain)
|
58
|
+
query.run()
|
59
|
+
|
60
|
+
|
61
|
+
if __name__ == '__main__':
|
62
|
+
run('example.com')
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from common.query import Query
|
2
|
+
|
3
|
+
|
4
|
+
class Sublist3r(Query):
|
5
|
+
def __init__(self, domain):
|
6
|
+
Query.__init__(self)
|
7
|
+
self.domain = domain
|
8
|
+
self.module = 'Dataset'
|
9
|
+
self.source = 'Sublist3rQuery'
|
10
|
+
|
11
|
+
def query(self):
|
12
|
+
"""
|
13
|
+
向接口查询子域并做子域匹配
|
14
|
+
"""
|
15
|
+
self.header = self.get_header()
|
16
|
+
self.proxy = self.get_proxy(self.source)
|
17
|
+
addr = 'https://api.sublist3r.com/search.php'
|
18
|
+
param = {'domain': self.domain}
|
19
|
+
resp = self.get(addr, param)
|
20
|
+
self.subdomains = self.collect_subdomains(resp)
|
21
|
+
|
22
|
+
def run(self):
|
23
|
+
"""
|
24
|
+
类执行入口
|
25
|
+
"""
|
26
|
+
self.begin()
|
27
|
+
self.query()
|
28
|
+
self.finish()
|
29
|
+
self.save_json()
|
30
|
+
self.gen_result()
|
31
|
+
self.save_db()
|
32
|
+
|
33
|
+
|
34
|
+
def run(domain):
|
35
|
+
"""
|
36
|
+
类统一调用入口
|
37
|
+
|
38
|
+
:param str domain: 域名
|
39
|
+
"""
|
40
|
+
query = Sublist3r(domain)
|
41
|
+
query.run()
|
42
|
+
|
43
|
+
|
44
|
+
if __name__ == '__main__':
|
45
|
+
run('example.com')
|