forked from shmilylty/OneForAll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaltdns.py
216 lines (187 loc) · 7.93 KB
/
altdns.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""
Reference: https://github.com/ProjectAnte/dnsgen
"""
import re
import time
import itertools
from config import settings
from modules import wildcard
from common import utils
from common import resolve
from common import request
from common.domain import Domain
from common.module import Module
from config.log import logger
def split_domain(domain):
"""
Split domain base on subdomain levels
Root+TLD is taken as one part, regardless of its levels
"""
# test.1.foo.example.com -> [test, 1, foo, example.com]
# test.2.foo.example.com.cn -> [test, 2, foo, example.com.cn]
# test.example.co.uk -> [test, example.co.uk]
ext = Domain(domain).extract()
subname = ext.subdomain
parts = ext.subdomain.split('.') + [ext.registered_domain]
return subname, parts
class Altdns(Module):
def __init__(self, domain):
Module.__init__(self)
self.module = 'Altdns'
self.source = 'Altdns'
self.start = time.time()
self.domain = domain
self.words = set()
self.now_subdomains = set()
self.new_subdomains = set()
self.wordlen = 6 # Min length of custom words extracted from domains
self.num_count = 3
def get_words(self):
path = settings.data_storage_dir.joinpath('altdns_wordlist.txt')
with open(path) as fd:
for line in fd:
word = line.lower().strip()
if word:
self.words.add(word)
def extract_words(self):
"""
Extend the dictionary based on target's domain naming conventions
"""
for subdomain in self.now_subdomains:
_, parts = split_domain(subdomain)
tokens = set(itertools.chain(*[word.lower().split('-') for word in parts]))
tokens = tokens.union({word.lower() for word in parts})
for token in tokens:
if len(token) >= self.wordlen:
self.words.add(token)
def increase_num(self, subname):
"""
If number is found in existing subdomain,
increase this number without any other alteration.
"""
# test.1.foo.example.com -> test.2.foo.example.com, test.3.foo.example.com, ...
# test1.example.com -> test2.example.com, test3.example.com, ...
# test01.example.com -> test02.example.com, test03.example.com, ...
count = 0
digits = re.findall(r'\d{1,3}', subname)
for d in digits:
for m in range(self.num_count):
replacement = str(int(d) + 1 + m).zfill(len(d))
tmp_domain = subname.replace(d, replacement)
new_domain = f'{tmp_domain}.{self.domain}'
self.new_subdomains.add(new_domain)
count += 1
logger.log('DEBUG', f'The increase_num generated {count} subdomains')
def decrease_num(self, subname):
"""
If number is found in existing subdomain,
decrease this number without any other alteration.
"""
# test.4.foo.example.com -> test.3.foo.example.com, test.2.foo.example.com, ...
# test4.example.com -> test3.example.com, test2.example.com, ...
# test04.example.com -> test03.example.com, test02.example.com, ...
count = 0
digits = re.findall(r'\d{1,3}', subname)
for d in digits:
for m in range(self.num_count):
new_digit = (int(d) - 1 - m)
if new_digit < 0:
break
replacement = str(new_digit).zfill(len(d))
tmp_domain = subname.replace(d, replacement)
new_domain = f'{tmp_domain}.{self.domain}'
self.new_subdomains.add(new_domain)
count += 1
logger.log('DEBUG', f'The decrease_num generated {count} subdomains')
def insert_word(self, parts):
"""
Create new subdomain levels by inserting the words between existing levels
"""
# test.1.foo.example.com -> WORD.test.1.foo.example.com,
# test.WORD.1.foo.example.com,
# test.1.WORD.foo.example.com,
# test.1.foo.WORD.example.com,
# ...
count = 0
for word in self.words:
for index in range(len(parts)):
tmp_parts = parts.copy()
tmp_parts.insert(index, word)
new_domain = '.'.join(tmp_parts)
self.new_subdomains.add(new_domain)
count += 1
logger.log('DEBUG', f'The insert_word generated {count} subdomains')
def add_word(self, subnames):
"""
On every subdomain level, prepend existing content with WORD-`,
append existing content with `-WORD`
"""
count = 0
for word in self.words:
for index, name in enumerate(subnames):
# Prepend with `-`
# test.1.foo.example.com -> WORD-test.1.foo.example.com
tmp_subnames = subnames.copy()
tmp_subnames[index] = f'{word}-{name}'
new_subname = '.'.join(tmp_subnames + [self.domain])
self.new_subdomains.add(new_subname)
# Prepend with `-`
# test.1.foo.example.com -> test-WORD.1.foo.example.com
tmp_subnames = subnames.copy()
tmp_subnames[index] = f'{name}-{word}'
new_subname = '.'.join(tmp_subnames + [self.domain])
self.new_subdomains.add(new_subname)
count += 1
logger.log('DEBUG', f'The add_word generated {count} subdomains')
def replace_word(self, subname):
"""
If word longer than 3 is found in existing subdomain,
replace it with other words from the dictionary
"""
# WORD1.1.foo.example.com -> WORD2.1.foo.example.com,
# WORD3.1.foo.example.com,
# WORD4.1.foo.example.com,
# ..
count = 0
for word in self.words:
if word not in subname:
continue
for word_alt in self.words:
if word == word_alt:
continue
new_subname = subname.replace(word, word_alt)
new_subdomain = f'{new_subname}.{self.domain}'
self.new_subdomains.add(new_subdomain)
count += 1
logger.log('DEBUG', f'The replace_word generated {count} subdomains')
def gen_new_subdomains(self):
for subdomain in self.now_subdomains:
subname, parts = split_domain(subdomain)
subnames = subname.split('.')
if settings.altdns_increase_num:
self.increase_num(subname)
if settings.altdns_decrease_num:
self.decrease_num(subname)
if settings.altdns_replace_word:
self.replace_word(subname)
if settings.altdns_insert_word:
self.insert_word(parts)
if settings.altdns_add_word:
self.add_word(subnames)
count = len(self.new_subdomains)
logger.log('DEBUG', f'The altdns module generated {count} subdomains')
def run(self, data, port):
logger.log('INFOR', f'Start altdns module')
self.now_subdomains = utils.get_subdomains(data)
self.get_words()
self.extract_words()
self.gen_new_subdomains()
self.subdomains = self.new_subdomains - self.now_subdomains
count = len(self.subdomains)
logger.log('INFOR', f'The altdns module generated {count} new subdomains')
self.end = time.time()
self.elapse = round(self.end - self.start, 1)
self.gen_result()
resolved_data = resolve.run_resolve(self.domain, self.results)
valid_data = wildcard.deal_wildcard(resolved_data) # 强制开启泛解析处理
request.run_request(self.domain, valid_data, port)