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
OneForAll/oneforall.py
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
#!/usr/bin/python3
|
2
|
+
# coding=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
OneForAll is a powerful subdomain integration tool
|
6
|
+
|
7
|
+
:copyright: Copyright (c) 2019, Jing Ling. All rights reserved.
|
8
|
+
:license: GNU General Public License v3.0, see LICENSE for more details.
|
9
|
+
"""
|
10
|
+
|
11
|
+
import fire
|
12
|
+
from datetime import datetime
|
13
|
+
|
14
|
+
|
15
|
+
import export
|
16
|
+
from brute import Brute
|
17
|
+
from common import utils, resolve, request
|
18
|
+
from modules.collect import Collect
|
19
|
+
from modules.srv import BruteSRV
|
20
|
+
from modules.finder import Finder
|
21
|
+
from modules.altdns import Altdns
|
22
|
+
from modules.enrich import Enrich
|
23
|
+
from modules import wildcard
|
24
|
+
from config import settings
|
25
|
+
from config.log import logger
|
26
|
+
from takeover import Takeover
|
27
|
+
|
28
|
+
yellow = '\033[01;33m'
|
29
|
+
white = '\033[01;37m'
|
30
|
+
green = '\033[01;32m'
|
31
|
+
blue = '\033[01;34m'
|
32
|
+
red = '\033[1;31m'
|
33
|
+
end = '\033[0m'
|
34
|
+
|
35
|
+
version = 'v0.4.5'
|
36
|
+
message = white + '{' + red + version + ' #dev' + white + '}'
|
37
|
+
|
38
|
+
oneforall_banner = f"""
|
39
|
+
OneForAll is a powerful subdomain integration tool{yellow}
|
40
|
+
___ _ _
|
41
|
+
___ ___ ___| _|___ ___ ___| | | {message}{green}
|
42
|
+
| . | | -_| _| . | _| .'| | | {blue}
|
43
|
+
|___|_|_|___|_| |___|_| |__,|_|_| {white}git.io/fjHT1
|
44
|
+
|
45
|
+
{red}OneForAll is under development, please update before each use!{end}
|
46
|
+
"""
|
47
|
+
|
48
|
+
|
49
|
+
class OneForAll(object):
|
50
|
+
"""
|
51
|
+
OneForAll help summary page
|
52
|
+
|
53
|
+
OneForAll is a powerful subdomain integration tool
|
54
|
+
|
55
|
+
Example:
|
56
|
+
python3 oneforall.py version
|
57
|
+
python3 oneforall.py check
|
58
|
+
python3 oneforall.py --target example.com run
|
59
|
+
python3 oneforall.py --targets ./domains.txt run
|
60
|
+
python3 oneforall.py --target example.com --alive False run
|
61
|
+
python3 oneforall.py --target example.com --brute False run
|
62
|
+
python3 oneforall.py --target example.com --port medium run
|
63
|
+
python3 oneforall.py --target example.com --fmt csv run
|
64
|
+
python3 oneforall.py --target example.com --dns False run
|
65
|
+
python3 oneforall.py --target example.com --req False run
|
66
|
+
python3 oneforall.py --target example.com --takeover False run
|
67
|
+
python3 oneforall.py --target example.com --show True run
|
68
|
+
|
69
|
+
Note:
|
70
|
+
--port small/medium/large See details in ./config/setting.py(default small)
|
71
|
+
--fmt csv/json (result format)
|
72
|
+
--path Result path (default None, automatically generated)
|
73
|
+
|
74
|
+
:param str target: One domain (target or targets must be provided)
|
75
|
+
:param str targets: File path of one domain per line
|
76
|
+
:param bool brute: Use brute module (default True)
|
77
|
+
:param bool dns: Use DNS resolution (default True)
|
78
|
+
:param bool req: HTTP request subdomains (default True)
|
79
|
+
:param str port: The port range to request (default small port is 80,443)
|
80
|
+
:param bool alive: Only export alive subdomains (default False)
|
81
|
+
:param str fmt: Result format (default csv)
|
82
|
+
:param str path: Result path (default None, automatically generated)
|
83
|
+
:param bool takeover: Scan subdomain takeover (default False)
|
84
|
+
"""
|
85
|
+
def __init__(self, target=None, targets=None, brute=None, dns=None, req=None,
|
86
|
+
port=None, alive=None, fmt=None, path=None, takeover=None):
|
87
|
+
self.target = target
|
88
|
+
self.targets = targets
|
89
|
+
self.brute = brute
|
90
|
+
self.dns = dns
|
91
|
+
self.req = req
|
92
|
+
self.port = port
|
93
|
+
self.alive = alive
|
94
|
+
self.fmt = fmt
|
95
|
+
self.path = path
|
96
|
+
self.takeover = takeover
|
97
|
+
self.domain = str() # The domain currently being collected
|
98
|
+
self.domains = set() # All domains that are to be collected
|
99
|
+
self.data = list() # The subdomain results of the current domain
|
100
|
+
self.datas = list() # All subdomain results of the domain
|
101
|
+
self.access_internet = False
|
102
|
+
self.enable_wildcard = False
|
103
|
+
|
104
|
+
def config_param(self):
|
105
|
+
"""
|
106
|
+
Config parameter
|
107
|
+
"""
|
108
|
+
if self.brute is None:
|
109
|
+
self.brute = bool(settings.enable_brute_module)
|
110
|
+
if self.dns is None:
|
111
|
+
self.dns = bool(settings.enable_dns_resolve)
|
112
|
+
if self.req is None:
|
113
|
+
self.req = bool(settings.enable_http_request)
|
114
|
+
if self.takeover is None:
|
115
|
+
self.takeover = bool(settings.enable_takeover_check)
|
116
|
+
if self.port is None:
|
117
|
+
self.port = settings.http_request_port
|
118
|
+
if self.alive is None:
|
119
|
+
self.alive = bool(settings.result_export_alive)
|
120
|
+
if self.fmt is None:
|
121
|
+
self.fmt = settings.result_save_format
|
122
|
+
if self.path is None:
|
123
|
+
self.path = settings.result_save_path
|
124
|
+
|
125
|
+
def check_param(self):
|
126
|
+
"""
|
127
|
+
Check parameter
|
128
|
+
"""
|
129
|
+
if self.target is None and self.targets is None:
|
130
|
+
logger.log('FATAL', 'You must provide either target or targets parameter')
|
131
|
+
exit(1)
|
132
|
+
|
133
|
+
def export_data(self):
|
134
|
+
"""
|
135
|
+
Export data from the database
|
136
|
+
|
137
|
+
:return: exported data
|
138
|
+
:rtype: list
|
139
|
+
"""
|
140
|
+
return export.export_data(self.domain, alive=self.alive, fmt=self.fmt, path=self.path)
|
141
|
+
|
142
|
+
def main(self):
|
143
|
+
"""
|
144
|
+
OneForAll main process
|
145
|
+
|
146
|
+
:return: subdomain results
|
147
|
+
:rtype: list
|
148
|
+
"""
|
149
|
+
utils.init_table(self.domain)
|
150
|
+
|
151
|
+
if not self.access_internet:
|
152
|
+
logger.log('ALERT', 'Because it cannot access the Internet, '
|
153
|
+
'OneForAll will not execute the subdomain collection module!')
|
154
|
+
if self.access_internet:
|
155
|
+
self.enable_wildcard = wildcard.detect_wildcard(self.domain)
|
156
|
+
|
157
|
+
collect = Collect(self.domain)
|
158
|
+
collect.run()
|
159
|
+
|
160
|
+
srv = BruteSRV(self.domain)
|
161
|
+
srv.run()
|
162
|
+
|
163
|
+
if self.brute:
|
164
|
+
# Due to there will be a large number of dns resolution requests,
|
165
|
+
# may cause other network tasks to be error
|
166
|
+
brute = Brute(self.domain, word=True, export=False)
|
167
|
+
brute.enable_wildcard = self.enable_wildcard
|
168
|
+
brute.quite = True
|
169
|
+
brute.run()
|
170
|
+
|
171
|
+
utils.deal_data(self.domain)
|
172
|
+
# Export results without resolve
|
173
|
+
if not self.dns:
|
174
|
+
self.data = self.export_data()
|
175
|
+
self.datas.extend(self.data)
|
176
|
+
return self.data
|
177
|
+
|
178
|
+
self.data = utils.get_data(self.domain)
|
179
|
+
|
180
|
+
# Resolve subdomains
|
181
|
+
utils.clear_data(self.domain)
|
182
|
+
self.data = resolve.run_resolve(self.domain, self.data)
|
183
|
+
# Save resolve results
|
184
|
+
resolve.save_db(self.domain, self.data)
|
185
|
+
|
186
|
+
# Export results without HTTP request
|
187
|
+
if not self.req:
|
188
|
+
self.data = self.export_data()
|
189
|
+
self.datas.extend(self.data)
|
190
|
+
return self.data
|
191
|
+
|
192
|
+
if self.enable_wildcard:
|
193
|
+
# deal wildcard
|
194
|
+
self.data = wildcard.deal_wildcard(self.data)
|
195
|
+
|
196
|
+
# HTTP request
|
197
|
+
utils.clear_data(self.domain)
|
198
|
+
request.run_request(self.domain, self.data, self.port)
|
199
|
+
|
200
|
+
# Finder module
|
201
|
+
if settings.enable_finder_module:
|
202
|
+
finder = Finder()
|
203
|
+
finder.run(self.domain, self.data, self.port)
|
204
|
+
|
205
|
+
# altdns module
|
206
|
+
if settings.enable_altdns_module:
|
207
|
+
altdns = Altdns(self.domain)
|
208
|
+
altdns.run(self.data, self.port)
|
209
|
+
|
210
|
+
# Information enrichment module
|
211
|
+
if settings.enable_enrich_module:
|
212
|
+
enrich = Enrich(self.domain)
|
213
|
+
enrich.run()
|
214
|
+
|
215
|
+
self.data = self.export_data()
|
216
|
+
self.datas.extend(self.data)
|
217
|
+
|
218
|
+
# Scan subdomain takeover
|
219
|
+
if self.takeover:
|
220
|
+
subdomains = utils.get_subdomains(self.data)
|
221
|
+
takeover = Takeover(targets=subdomains)
|
222
|
+
takeover.run()
|
223
|
+
return self.data
|
224
|
+
|
225
|
+
def run(self):
|
226
|
+
"""
|
227
|
+
OneForAll running entrance
|
228
|
+
|
229
|
+
:return: All subdomain results
|
230
|
+
:rtype: list
|
231
|
+
"""
|
232
|
+
print(oneforall_banner)
|
233
|
+
dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
234
|
+
print(f'[*] Starting OneForAll @ {dt}\n')
|
235
|
+
logger.log('DEBUG', 'Python ' + utils.python_version())
|
236
|
+
logger.log('DEBUG', 'OneForAll ' + version)
|
237
|
+
utils.check_dep()
|
238
|
+
self.access_internet = utils.get_net_env()
|
239
|
+
if self.access_internet and settings.enable_check_version:
|
240
|
+
utils.check_version(version)
|
241
|
+
logger.log('INFOR', 'Start running OneForAll')
|
242
|
+
self.config_param()
|
243
|
+
self.check_param()
|
244
|
+
self.domains = utils.get_domains(self.target, self.targets)
|
245
|
+
count = len(self.domains)
|
246
|
+
logger.log('INFOR', f'Got {count} domains')
|
247
|
+
if not count:
|
248
|
+
logger.log('FATAL', 'Failed to obtain domain')
|
249
|
+
exit(1)
|
250
|
+
for domain in self.domains:
|
251
|
+
self.domain = utils.get_main_domain(domain)
|
252
|
+
self.main()
|
253
|
+
if count > 1:
|
254
|
+
utils.export_all(self.alive, self.fmt, self.path, self.datas)
|
255
|
+
logger.log('INFOR', 'Finished OneForAll')
|
256
|
+
|
257
|
+
@staticmethod
|
258
|
+
def version():
|
259
|
+
"""
|
260
|
+
Print version information and exit
|
261
|
+
"""
|
262
|
+
print(oneforall_banner)
|
263
|
+
exit(0)
|
264
|
+
|
265
|
+
@staticmethod
|
266
|
+
def check():
|
267
|
+
"""
|
268
|
+
Check if there is a new version and exit
|
269
|
+
"""
|
270
|
+
utils.check_version(version)
|
271
|
+
exit(0)
|
272
|
+
|
273
|
+
|
274
|
+
if __name__ == '__main__':
|
275
|
+
fire.Fire(OneForAll)
|
OneForAll/takeover.py
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/python3
|
2
|
+
# coding=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
OneForAll subdomain takeover module
|
6
|
+
|
7
|
+
:copyright: Copyright (c) 2019, Jing Ling. All rights reserved.
|
8
|
+
:license: GNU General Public License v3.0, see LICENSE for more details.
|
9
|
+
"""
|
10
|
+
import time
|
11
|
+
import json
|
12
|
+
from threading import Thread
|
13
|
+
from queue import Queue
|
14
|
+
|
15
|
+
import fire
|
16
|
+
from common.tablib.tablib import Dataset
|
17
|
+
from tqdm import tqdm
|
18
|
+
|
19
|
+
from config.log import logger
|
20
|
+
from config import settings
|
21
|
+
from common import utils
|
22
|
+
from common.module import Module
|
23
|
+
|
24
|
+
|
25
|
+
def get_fingerprint():
|
26
|
+
path = settings.data_storage_dir.joinpath('fingerprints.json')
|
27
|
+
with open(path, encoding='utf-8', errors='ignore') as file:
|
28
|
+
fingerprints = json.load(file)
|
29
|
+
return fingerprints
|
30
|
+
|
31
|
+
|
32
|
+
def get_cname(subdomain):
|
33
|
+
resolver = utils.dns_resolver()
|
34
|
+
try:
|
35
|
+
answers = resolver.query(subdomain, 'CNAME')
|
36
|
+
except Exception as e:
|
37
|
+
logger.log('TRACE', e.args)
|
38
|
+
return None
|
39
|
+
for answer in answers:
|
40
|
+
return answer.to_text() # 一个子域只有一个CNAME记录
|
41
|
+
|
42
|
+
|
43
|
+
class Takeover(Module):
|
44
|
+
"""
|
45
|
+
OneForAll subdomain takeover module
|
46
|
+
|
47
|
+
Example:
|
48
|
+
python3 takeover.py --target www.example.com --fmt csv run
|
49
|
+
python3 takeover.py --targets ./subdomains.txt --thread 10 run
|
50
|
+
|
51
|
+
Note:
|
52
|
+
--fmt txt/csv/json (result format)
|
53
|
+
--path Result directory (default directory is ./results)
|
54
|
+
|
55
|
+
:param str target: One domain (target or targets must be provided)
|
56
|
+
:param str targets: File path of one domain per line
|
57
|
+
:param int thread: threads number (default 20)
|
58
|
+
:param str fmt: Result format (default csv)
|
59
|
+
:param str path: Result directory (default None)
|
60
|
+
"""
|
61
|
+
|
62
|
+
def __init__(self, target=None, targets=None, thread=20, path=None, fmt='csv'):
|
63
|
+
Module.__init__(self)
|
64
|
+
self.subdomains = set()
|
65
|
+
self.module = 'Check'
|
66
|
+
self.source = 'Takeover'
|
67
|
+
self.target = target
|
68
|
+
self.targets = targets
|
69
|
+
self.thread = thread
|
70
|
+
self.path = path
|
71
|
+
self.fmt = fmt
|
72
|
+
self.fingerprints = None
|
73
|
+
self.queue = Queue() # subdomain queue
|
74
|
+
self.cnames = list()
|
75
|
+
self.results = Dataset()
|
76
|
+
|
77
|
+
def save(self):
|
78
|
+
logger.log('DEBUG', 'Saving results')
|
79
|
+
if self.fmt == 'txt':
|
80
|
+
data = str(self.results)
|
81
|
+
else:
|
82
|
+
data = self.results.export(self.fmt)
|
83
|
+
utils.save_to_file(self.path, data)
|
84
|
+
|
85
|
+
def compare(self, subdomain, cname, responses):
|
86
|
+
domain_resp = self.get('http://' + subdomain, check=False, ignore=True)
|
87
|
+
cname_resp = self.get('http://' + cname, check=False, ignore=True)
|
88
|
+
if domain_resp is None or cname_resp is None:
|
89
|
+
return
|
90
|
+
|
91
|
+
for resp in responses:
|
92
|
+
if resp in domain_resp.text and resp in cname_resp.text:
|
93
|
+
logger.log('ALERT', f'{subdomain} takeover threat found')
|
94
|
+
self.results.append([subdomain, cname])
|
95
|
+
break
|
96
|
+
|
97
|
+
def worker(self, subdomain):
|
98
|
+
cname = get_cname(subdomain)
|
99
|
+
if cname is None:
|
100
|
+
return
|
101
|
+
main_domain = utils.get_main_domain(cname)
|
102
|
+
for fingerprint in self.fingerprints:
|
103
|
+
cnames = fingerprint.get('cname')
|
104
|
+
if main_domain not in cnames:
|
105
|
+
continue
|
106
|
+
responses = fingerprint.get('response')
|
107
|
+
self.compare(subdomain, cname, responses)
|
108
|
+
|
109
|
+
def check(self):
|
110
|
+
while not self.queue.empty(): # 保证域名队列遍历结束后能退出线程
|
111
|
+
subdomain = self.queue.get() # 从队列中获取域名
|
112
|
+
self.worker(subdomain)
|
113
|
+
self.queue.task_done()
|
114
|
+
|
115
|
+
def progress(self):
|
116
|
+
bar = tqdm()
|
117
|
+
bar.total = len(self.subdomains)
|
118
|
+
bar.desc = 'Check Progress'
|
119
|
+
bar.ncols = 80
|
120
|
+
while True:
|
121
|
+
done = bar.total - self.queue.qsize()
|
122
|
+
bar.n = done
|
123
|
+
bar.update()
|
124
|
+
if done == bar.total: # 完成队列中所有子域的检查退出
|
125
|
+
break
|
126
|
+
|
127
|
+
def run(self):
|
128
|
+
start = time.time()
|
129
|
+
logger.log('INFOR', f'Start running {self.source} module')
|
130
|
+
if isinstance(self.targets, set):
|
131
|
+
self.subdomains = self.targets
|
132
|
+
else:
|
133
|
+
self.subdomains = utils.get_domains(self.target, self.targets)
|
134
|
+
self.fmt = utils.check_format(self.fmt)
|
135
|
+
timestamp = utils.get_timestamp()
|
136
|
+
name = f'takeover_check_result_{timestamp}'
|
137
|
+
self.path = utils.check_path(self.path, name, self.fmt)
|
138
|
+
if self.subdomains:
|
139
|
+
logger.log('INFOR', f'Checking subdomain takeover')
|
140
|
+
self.fingerprints = get_fingerprint()
|
141
|
+
self.results.headers = ['subdomain', 'cname']
|
142
|
+
# 创建待检查的子域队列
|
143
|
+
for domain in self.subdomains:
|
144
|
+
self.queue.put(domain)
|
145
|
+
# 进度线程
|
146
|
+
progress_thread = Thread(target=self.progress, name='ProgressThread',
|
147
|
+
daemon=True)
|
148
|
+
progress_thread.start()
|
149
|
+
# 检查线程
|
150
|
+
for i in range(self.thread):
|
151
|
+
check_thread = Thread(target=self.check, name=f'CheckThread{i}',
|
152
|
+
daemon=True)
|
153
|
+
check_thread.start()
|
154
|
+
|
155
|
+
self.queue.join()
|
156
|
+
self.save()
|
157
|
+
else:
|
158
|
+
logger.log('FATAL', f'Failed to obtain domain')
|
159
|
+
end = time.time()
|
160
|
+
elapse = round(end - start, 1)
|
161
|
+
logger.log('ALERT', f'{self.source} module takes {elapse} seconds, '
|
162
|
+
f'There are {len(self.results)} subdomains exists takeover')
|
163
|
+
logger.log('INFOR', f'Subdomain takeover results: {self.path}')
|
164
|
+
logger.log('INFOR', f'Finished {self.source} module')
|
165
|
+
|
166
|
+
|
167
|
+
if __name__ == '__main__':
|
168
|
+
fire.Fire(Takeover)
|
OneForAll/test.py
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# coding=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Example
|
6
|
+
"""
|
7
|
+
|
8
|
+
from oneforall import OneForAll
|
9
|
+
|
10
|
+
|
11
|
+
def oneforall(domain):
|
12
|
+
test = OneForAll(target=domain)
|
13
|
+
test.dns = True
|
14
|
+
test.brute = True
|
15
|
+
test.req = True
|
16
|
+
test.takeover = True
|
17
|
+
test.run()
|
18
|
+
results = test.datas
|
19
|
+
print(results)
|
20
|
+
|
21
|
+
|
22
|
+
if __name__ == '__main__':
|
23
|
+
oneforall('freebuf.com')
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: oneforall_kjl
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: oneforall打包
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
6
|
+
License: MIT
|
7
|
+
Project-URL: Homepage, https://github.com/yourusername/test1v2
|
8
|
+
Project-URL: Bug Tracker, https://github.com/yourusername/test1v2/issues
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
10
|
+
Classifier: Intended Audience :: Developers
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Classifier: Operating System :: OS Independent
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
17
|
+
Requires-Python: >=3.8
|
18
|
+
Description-Content-Type: text/markdown
|
@@ -0,0 +1,114 @@
|
|
1
|
+
OneForAll/__init__.py,sha256=mwVz3JJzWyFyWQSVuidtHokWO21Am4-pxpTxLF_lgoQ,246
|
2
|
+
OneForAll/brute.py,sha256=zC7r5MhvC8rBwb2N4MxUlmn4g1qzwvlbKaJyYOTWFJ0,21102
|
3
|
+
OneForAll/export.py,sha256=Zm4enI5cBjrkhL6CQsv8n9rZl-jwAdK9Q7KE8h3kiEg,2341
|
4
|
+
OneForAll/oneforall.py,sha256=ptLGxdRz7VR3ZDtaqH2tf0dUT25AKoGsbN1H0QgiuVI,9443
|
5
|
+
OneForAll/takeover.py,sha256=qU7MQxWMyfHwCITot07OpIHJnCuAsDvgae2XPtRRZ2s,5949
|
6
|
+
OneForAll/test.py,sha256=IgSbkrg7BNCxTSDLx8g3JTa834HDI_N_iZb53u4H4FY,376
|
7
|
+
OneForAll/common/check.py,sha256=tHpBJSquyfF4Dzgqad5mmi9pbLAycUDkA3DHXHB2Sjg,1281
|
8
|
+
OneForAll/common/crawl.py,sha256=3wlilmx9EQ77MKnR1YSSDRgo2opSrkhiuy3cmxD9sWQ,158
|
9
|
+
OneForAll/common/database.py,sha256=3c7vaA4Whnyy8kNRFqqocSFiHqCo23jLttInXtZQNjI,10781
|
10
|
+
OneForAll/common/domain.py,sha256=4L2b5Q0ild0vCHtDE26YCPOJVUXomCvWKx4IYA53SdI,1651
|
11
|
+
OneForAll/common/ipasn.py,sha256=M0CTGEXEuNyzjmcxNKBId9lmSzr6-3jxQng4z3a2kjE,1222
|
12
|
+
OneForAll/common/ipreg.py,sha256=y_mxFVbcs2d-e1HjCV5fPp0vm7ZdM-AelPfrNYJ5Fvw,3845
|
13
|
+
OneForAll/common/lookup.py,sha256=ZLzZtxEVPqaz1TXUHyfulaJ9xLnOnHxIj6jFXc6fJsU,721
|
14
|
+
OneForAll/common/module.py,sha256=zYykltzp0FynqGgzmjwNEBr7FFc3zCeIbGi4AsSz30I,13668
|
15
|
+
OneForAll/common/query.py,sha256=cFYJmrGiNsXL_z2Xbge3RNFOOS8MxnT-HUDW04wcEvI,156
|
16
|
+
OneForAll/common/records.py,sha256=UHPP_m8HtvjWtkXpa2ngsEtIKXlnrOco11VtUYlsFeU,11336
|
17
|
+
OneForAll/common/request.py,sha256=oeSjGveQ3xYrXenZ-lWEf5QUZOwKTZ_QHNdDwkSorBg,7482
|
18
|
+
OneForAll/common/resolve.py,sha256=ipv2dmFQ5SMOJDI_XoBOLVgqGU8Aj4A60qbNboBBIaQ,5643
|
19
|
+
OneForAll/common/search.py,sha256=h00spEdsC1FLhMHXHZ2T-1Q492h6wX2yidr_8A6goj0,3039
|
20
|
+
OneForAll/common/similarity.py,sha256=IKjM0rDfi4U68uCYYlg9DC_uRVPnbailK5jnIEWRnM8,5418
|
21
|
+
OneForAll/common/tldextract.py,sha256=hM6wja7Jt0fxHdDNmnT0GyXQKRsVnKNFe6bt3cjumpM,7783
|
22
|
+
OneForAll/common/utils.py,sha256=JCBV2vVaXAAW40P7DgETc5CFIBAeuhKHSanAGfdcpZM,23209
|
23
|
+
OneForAll/common/tablib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
+
OneForAll/common/tablib/format.py,sha256=rO1byJO8DTd4hfBiyip6li93h5nb_Vx6QOmneWgjWHQ,2148
|
25
|
+
OneForAll/common/tablib/tablib.py,sha256=vV9U-b-IQv5v9mxlWfKXQwdnd-NVylz1kowwLy2Lalc,10627
|
26
|
+
OneForAll/config/__init__.py,sha256=E0nMk3gGFn_bwDsFLXJHE4-RYC5ZndoeKI9UJ0rny9o,538
|
27
|
+
OneForAll/config/api.py,sha256=oNJ6O6lc9cMH8huzedWn8Oqmj_-0mHC9vioxD-pFkvI,3106
|
28
|
+
OneForAll/config/default.py,sha256=c6LSquE9Qsj55wpMRESZLk_EzQTrFBz5C1QpNo9L7vU,12593
|
29
|
+
OneForAll/config/log.py,sha256=vs7I_J10FbN-468nPl0FfAb6VkwT_UCMCyzPsHzNNtY,1742
|
30
|
+
OneForAll/config/setting.py,sha256=93Fx4eUByborda3A8qIdP637kd3ltLVpN0ZWJhNE7MQ,6458
|
31
|
+
OneForAll/modules/altdns.py,sha256=eS3egc_kPObozPE43XcKgZMSzRmWeUtExHVPDra0UbA,8335
|
32
|
+
OneForAll/modules/collect.py,sha256=QvxSbPlf_JxZaOwZVOYEQro2ajd_oU2P9CmHtHICe0Q,2426
|
33
|
+
OneForAll/modules/enrich.py,sha256=EFM9ifS4Mwmm5g0LeK4IBYMrggetPkqM326Qre1vKBQ,2102
|
34
|
+
OneForAll/modules/finder.py,sha256=NU9cBBuF5aVHVgKxe9BnEN-UZPKTX86g9s09n8GtKjc,7164
|
35
|
+
OneForAll/modules/iscdn.py,sha256=-2gVj39xmDnmBd7zI45lEYccWBh4VLC2-n_aTb-Z2zw,2447
|
36
|
+
OneForAll/modules/srv.py,sha256=XZLagHoYkKXCfzk7Pkh1EpSm5Z_5lL5czrXvBxqf7c0,2182
|
37
|
+
OneForAll/modules/wildcard.py,sha256=keLHKZbmJOgtt6YhNlDzlVLMxarroEYPSucvBfVtFC4,10442
|
38
|
+
OneForAll/modules/autotake/github.py,sha256=vyoZxCAfY-_R9w9ELS_hLz5Bpe1bP7TDFUY1xiX_0E4,4671
|
39
|
+
OneForAll/modules/certificates/censys_api.py,sha256=4NKLv61I-mEmbnIfDREO_1ehW3zCDwRO3sV_wO-YU1o,2225
|
40
|
+
OneForAll/modules/certificates/certspotter.py,sha256=BxSu_zxJigXtDdCyI7Ec-evic0C0teuylsWPrr6Qvu8,1148
|
41
|
+
OneForAll/modules/certificates/crtsh.py,sha256=naC_c9Jo9oYsSHw3rtOZT8DLuBziy1HNb7nZ8uCeAbE,2420
|
42
|
+
OneForAll/modules/certificates/google.py,sha256=UjhKZYJMzdv68YNFSzSeEd1U2UsgMfd9Pw5Ff2kOV2Y,1210
|
43
|
+
OneForAll/modules/certificates/myssl.py,sha256=PAkF7-gyu1tpzZFvUtlMDJ6raqXweVbog3ShFyleNYQ,1043
|
44
|
+
OneForAll/modules/certificates/racent.py,sha256=8SlcOhRkimNPW0FyRm-7TxES9f-yFOFT9VGMpqSKbm4,1196
|
45
|
+
OneForAll/modules/check/axfr.py,sha256=ez9T8heDNAHmMswhhJi0Nxuq8OV7UuImBZTIDDTWSuY,3214
|
46
|
+
OneForAll/modules/check/cdx.py,sha256=m_PD3_n63tZoW6BsgR9vsXmo5axmQNqQSjNu9KKMdBw,873
|
47
|
+
OneForAll/modules/check/cert.py,sha256=ye_JE8JLsM7EkCxHLFgwd27Woc-s1I_SuHt58JQPEOs,1355
|
48
|
+
OneForAll/modules/check/csp.py,sha256=LJxXCWbK9t-okp7uGmGi8uHy5EHn8QasHBwv4wIZUfU,2715
|
49
|
+
OneForAll/modules/check/nsec.py,sha256=3uWG0EO017SrqTV2L61CLz0_qzL4ma3LFY4ZQvi09lU,1765
|
50
|
+
OneForAll/modules/check/robots.py,sha256=4SXdgEiVxORh26g5PkQv4NV9ymkPZn9Dt20udMB6IYM,877
|
51
|
+
OneForAll/modules/check/sitemap.py,sha256=c7okXcb5_Ykiy-bauTpSERDbeUnnhtYsNoNijRFgdqY,929
|
52
|
+
OneForAll/modules/crawl/archivecrawl.py,sha256=qV9q0TAm8mugXH7zZLvDvgBa5xYHshlwGZwMMoaM3YA,1591
|
53
|
+
OneForAll/modules/crawl/commoncrawl.py,sha256=sRwNqJRLy-CTZJv7JsmnDm_Hy6eL78cySl0hxd9OJaY,1522
|
54
|
+
OneForAll/modules/datasets/anubis.py,sha256=6RXgr-zuuHzAT5lRV8ZlkfNs89VDdHplYrDvaODDZiQ,1027
|
55
|
+
OneForAll/modules/datasets/bevigil.py,sha256=Zfz5DbW2Xj6D_JtiRg0wo219gquFAaDmeq5i_i8qVzU,1233
|
56
|
+
OneForAll/modules/datasets/binaryedge_api.py,sha256=FpxbOk0nLCGH-ViWw0ylPZ6JqTOpEgQrA_b9wQw3B10,1236
|
57
|
+
OneForAll/modules/datasets/cebaidu.py,sha256=zAJSh7jW6xVuF-YheoiZkVZMDuWr6clne9p9FKOq9Y4,1047
|
58
|
+
OneForAll/modules/datasets/chinaz.py,sha256=wIpzsuWDACPmzI3wEYyLobRw1qQ26oKFvsJyPHWNZeo,1016
|
59
|
+
OneForAll/modules/datasets/chinaz_api.py,sha256=BRLC63G1zjbaDEuAMHrL1JyPPu5q3TkONsT3gc555mM,1196
|
60
|
+
OneForAll/modules/datasets/circl_api.py,sha256=Lxf_YivJLWkf5W1gFtEHac-Lvpgcz-CpOkpn6UZjVH8,1224
|
61
|
+
OneForAll/modules/datasets/cloudflare_api.py,sha256=dyKPdt88AKxai8oO-7fDlOSRV-gxKJjqWhwGLZGZzqA,4761
|
62
|
+
OneForAll/modules/datasets/dnsdb_api.py,sha256=R1HEob58r8gqox8f6AwOi4hoNQTEHyHBf7wf11nbWp8,1220
|
63
|
+
OneForAll/modules/datasets/dnsdumpster.py,sha256=x94DHoZSqXQmYoQmBedK886KkIjb5jajqSmt07Ug8Rw,1313
|
64
|
+
OneForAll/modules/datasets/dnsgrep.py,sha256=yrXGCZ7NXlS1iQp-c38klqvROuVrNuzs_svgE1RRTOs,984
|
65
|
+
OneForAll/modules/datasets/fullhunt.py,sha256=z4TyoYSv_Blj1_cnUOrss3P8oqKi_nfK3VRAcLyOgkg,1133
|
66
|
+
OneForAll/modules/datasets/hackertarget.py,sha256=ikJ-cHIMbIBossvHN4rsILJwZwdI7a4lk3BdJHRnJTE,1049
|
67
|
+
OneForAll/modules/datasets/ip138.py,sha256=lCKST6Nc0pboapO6lN4H8JUUEu6QKMugXHydzIFgxBM,1043
|
68
|
+
OneForAll/modules/datasets/ipv4info_api.py,sha256=w2j48j0AW-KMbI3H9zzeAmuWsd9y-FgVb7jtlmcsgLg,2238
|
69
|
+
OneForAll/modules/datasets/netcraft.py,sha256=w5FbT5fznBFWolnqvHToBUmKS2937hxlzRSHrVsIYvE,1882
|
70
|
+
OneForAll/modules/datasets/passivedns_api.py,sha256=0Dfm14_Y9_u7V58tKpD3XIiBUOQNKtRFXTiVgKVyxY8,1328
|
71
|
+
OneForAll/modules/datasets/qianxun.py,sha256=D2J4KWAeF1SUXx7va2umgnw7urmJ8mbZvDTdvezk9t8,1622
|
72
|
+
OneForAll/modules/datasets/rapiddns.py,sha256=htAG7d8Rf4_b1GB4cFvAMa_g2g7LQ18PG0_DC9nFeUw,1023
|
73
|
+
OneForAll/modules/datasets/riddler.py,sha256=-ourJJwWHiRLDRkrQw9RmGDEplKRsu-pu9wT_cL6KB0,1028
|
74
|
+
OneForAll/modules/datasets/robtex.py,sha256=_7YIxrbXpfyWSeI1F6pXWeokeVx8hGUxgtUlM02EGX4,1473
|
75
|
+
OneForAll/modules/datasets/securitytrails_api.py,sha256=6jqngsHr9TpXWz8zLTE6MMuQX1t_jdBQIz3XNu8DNac,1491
|
76
|
+
OneForAll/modules/datasets/sitedossier.py,sha256=SOCEacO3uNGH5hAKOIlBr1UXt5qWZJqlzEBHH0sGz2U,1508
|
77
|
+
OneForAll/modules/datasets/spyse_api.py,sha256=p9VI7GxdLZbue7xjeD57KxKIxCOpBTYvfRVuY_2FWa4,1707
|
78
|
+
OneForAll/modules/datasets/sublist3r.py,sha256=yU93QCNTtA4lDw0JaUMWUjvE5jTnhmyF433RVSJl8xA,1029
|
79
|
+
OneForAll/modules/datasets/urlscan.py,sha256=ZQLjQTPspGv6XL9Pp0-5Z0AMgqX2DiwnoPmXt__q_uA,1027
|
80
|
+
OneForAll/modules/datasets/windvane.py,sha256=B_KLcOxZleaVbngK4g5usjDBjkka_e4Dh0einy8vl7w,2450
|
81
|
+
OneForAll/modules/dnsquery/mx.py,sha256=Ay7nexISHaTtC9YOsj8A_0LJl7NfDva9oAlSABtQLJ4,714
|
82
|
+
OneForAll/modules/dnsquery/ns.py,sha256=ZJ28yux0eU6R2nfluQmnAGJlJhJyCP7G4bAWk8wwzWo,714
|
83
|
+
OneForAll/modules/dnsquery/soa.py,sha256=v58DRQ7d8waTt1u53ReQ5T0UHzARSlDoOF5FB6t6WuY,719
|
84
|
+
OneForAll/modules/dnsquery/spf.py,sha256=nko_mX7-nC0GIjCEl8ZE95fo7VotlzXcDAToEtLvfYE,714
|
85
|
+
OneForAll/modules/dnsquery/txt.py,sha256=l3R-lbpkVrRectsGiY7GUJ-PhtzXdwHNpzGuLVcDUyg,719
|
86
|
+
OneForAll/modules/intelligence/alienvault.py,sha256=FTYpXg89ei_TVjtDxGgMNWt31zKS_F5YGzLCoU_t42M,1193
|
87
|
+
OneForAll/modules/intelligence/riskiq_api.py,sha256=pPjPZLA3ukpXID96AZNPwP7zW_vJqMeeKN55bkapuHE,1605
|
88
|
+
OneForAll/modules/intelligence/threatbook_api.py,sha256=DB9xpoPnsKJW-jxYEdy8w4y89CYJRPi9MXkdTbmuPkg,1249
|
89
|
+
OneForAll/modules/intelligence/threatminer.py,sha256=06ov1S_wk0Aiow01W3XXsOqOreBkPsgjv3mOJ5joCQ8,1061
|
90
|
+
OneForAll/modules/intelligence/virustotal.py,sha256=p94I6tGGeCFjjgQ1-cq_NRPuHbHRVvKOB5L_FUkXZL8,1552
|
91
|
+
OneForAll/modules/intelligence/virustotal_api.py,sha256=tqYBXVtjrdL3tMPTePb2tUkJ4TUZJdpRsndLJQMfua4,1607
|
92
|
+
OneForAll/modules/search/ask.py,sha256=9tarvGrfaDo2N6NnLt67-PMAkE9EQKzmNYGDQssjaAg,2079
|
93
|
+
OneForAll/modules/search/baidu.py,sha256=S4i6gD1H8qbXmIdVcl5qzWwGDcG-jiHQM_lIBSGMT_I,3207
|
94
|
+
OneForAll/modules/search/bing.py,sha256=5l93lDuUdYMMLEfGfd0REJvqsErIQwjaXWSf7CNEwo8,2546
|
95
|
+
OneForAll/modules/search/bing_api.py,sha256=fMEoj1ofUTeZibU7-UnWdHV6kfl6Ahwaka3dmm-iMM0,2544
|
96
|
+
OneForAll/modules/search/fofa_api.py,sha256=-Lpnj6va3f-bjNn8u8twEBD1ivCPMTJx0wjVD6BTpUk,2211
|
97
|
+
OneForAll/modules/search/gitee.py,sha256=SJGIfCBjbJpirmrrzo6Xen3tcQ4d0J5yT_rtE59uwlY,1984
|
98
|
+
OneForAll/modules/search/github_api.py,sha256=bz-CfZBP1q53VmgxfAzDOrCjqC8pQOSlacG2hVsWP_k,2464
|
99
|
+
OneForAll/modules/search/google.py,sha256=Ka7BWHWDj0p5KXiBsreyTwxYE3rWZ4aoIYSh173jz7I,2590
|
100
|
+
OneForAll/modules/search/google_api.py,sha256=_wLOZINuNBnWovjpKMpTbFBgzH6JIRBlg4O0yDtjs84,2436
|
101
|
+
OneForAll/modules/search/hunter_api.py,sha256=xqjL44Ygy7hbWnWyVhyn-_ZJOzV7UNnFrwcKvJNNMcI,2079
|
102
|
+
OneForAll/modules/search/quake_api.py,sha256=oqdJodsElyuPYcWCsXQ64QjIniR4p-6tZ760UfBxXec,2179
|
103
|
+
OneForAll/modules/search/shodan_api.py,sha256=pXvPwM6_5ewFLYa_nDGl-1XQX61AYmSYeelvD6VenjY,1347
|
104
|
+
OneForAll/modules/search/so.py,sha256=rg29rhHPGenVWw81STuh9MEtiwv_vV4u67J8SAjCooU,2256
|
105
|
+
OneForAll/modules/search/sogou.py,sha256=K10sih0g5thfjv-hQ81-iwP2WpWGd4u3wrjHfwpj8Zg,2231
|
106
|
+
OneForAll/modules/search/wzsearch.py,sha256=5k7PTsyLvxcCmi7RDRgXZYvVKVf7vbnj4DFf-hfxAlo,2038
|
107
|
+
OneForAll/modules/search/yahoo.py,sha256=u47TAuGTRHqtFC7nUj34Q-p7YkE3Dx3iFlaEARnCWA4,2664
|
108
|
+
OneForAll/modules/search/yandex.py,sha256=bKfQWUS84mAYsEMXqvsfBAAfFdf-NO2LJ5Qs4HVAZr8,2499
|
109
|
+
OneForAll/modules/search/zoomeye_api.py,sha256=Xp9CrXv38xvdH5o3DRLOtk05tH0Qvcmd6cr1zitKQ7s,2077
|
110
|
+
oneforall_kjl-0.1.1.dist-info/METADATA,sha256=Hi4ySL7t-Mdns9H7cgSFU1wG1fLkxofIKYAC3s77rgI,749
|
111
|
+
oneforall_kjl-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
112
|
+
oneforall_kjl-0.1.1.dist-info/entry_points.txt,sha256=hHS8lS7NtYunLF_NhJk1U7gEaRHWT-rF7WjtsFCgwEw,57
|
113
|
+
oneforall_kjl-0.1.1.dist-info/top_level.txt,sha256=JFOGw97vXO-PwGFnYR3ZFiRx18Z37HU_kI-9oO2f8Fs,10
|
114
|
+
oneforall_kjl-0.1.1.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
OneForAll
|