-
Notifications
You must be signed in to change notification settings - Fork 115
/
Copy pathpassmaker.py
276 lines (239 loc) · 9.37 KB
/
passmaker.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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# !/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'bit4woo'
__github__ = 'https://github.com/bit4woo'
import config
import inspect
import itertools
import datetime
import os
import argparse
import argcomplete
import interactive
import GUI
from argparse import RawTextHelpFormatter
from lib.paras import paras
from lib.common import logger
from lib import common
def parse_args():
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description= \
"Usage: python passmaker.py <OPTIONS> \n")
menu_group = parser.add_argument_group('Menu Options')
menu_group.add_argument('-o', '--output', help="password dict file", default=None)
menu_group.add_argument('-i', '--interactive', help="interactive mode",action='store_true',default=False)
menu_group.add_argument('-g', '--gui', help="GUI mode", action='store_true', default=False)
argcomplete.autocomplete(parser)
args = parser.parse_args()
return args
def getseedname():#获取所有list
result = []
for item in inspect.getmembers(config):
if isinstance(item[1],list):
#print item[0]
result.append(item[0])
#print result
return result
def getseedvalue(name):
for item in inspect.getmembers(config):
if name == item[0] and isinstance(item[1],list):
tmplist = []
for x in item[1]:
x= x.strip("\r")
x = x.strip("\n")
tmplist.append(x)
return tmplist
def config2Paras():
paras.seed_map = {}
for item in getseedname(): # for step one
paras.seed_map[item] = getseedvalue(item)
paras.rule_list = config.rule_list # for step two
paras.keep_in_order = config.keep_in_order
paras.leet = config.leet # for step three
paras.capitalize = config.capitalize
paras.additional_list = config.additional_list # for step 4 list of file
paras.enable_filter = config.enable_filter # for step 5
paras.min_lenth = config.min_lenth
paras.filter_rule = config.filter_rule
paras.kinds_needed = config.kinds_needed # 四者包含其三
class passmaker():
def __init__(self,isinteractive= False,isGUI = True, output_file= None):
self.logger = logger()
self.output_file = output_file
def write_add(self,filename,write_list):
try:
fp = open(filename,"a+") #a = append 追加
if len(fp.readlines()) !=0:
fp.write("\n")
fp.writelines("\n".join(write_list))
fp.close()
return 0
except Exception as e:
self.logger.error(e)
return 1
def passmaker(self): # first step and two ,combine base on the rules.
self.logger.info("making password base on the rule...")
now = datetime.datetime.now()
timestr = now.strftime("-%Y-%m-%d-%H-%M")
if self.output_file:
filename = self.output_file
else:
filename = os.path.join("output","passmaker{0}.txt".format(timestr))
resultlist = []
templist = []
rulelist = []
for item in paras.rule_list: #所有规则
if paras.keep_in_order == False:
x = item.split("+")
y = len(x)
z = itertools.permutations(x, y)#结构是list,
rulelist = list(set(z))#一个规则变成了多个
#print rulelist
else:
rulelist.append(tuple(item.split("+")))
#print rulelist
for item in rulelist: #item 是一个规则,类型是元组
#print item
try:
for seedKey in item: #解析一个规则,i是seed,单个组成部分
if seedKey in paras.seed_map: #seed 是否有在config中定义
seedValue = paras.seed_map[seedKey]
if isinstance(seedValue, str) and os.path.exists(seedValue):
seedValueList = open(seedValue,"r").readlines()
else:
seedValueList = seedValue
if len(resultlist) == 0:
resultlist = seedValueList
else:
for x in resultlist:
for y in seedValueList:
y = y.strip()
templist.append(x+y)
#print resultlist
resultlist = templist
templist = []
else:
raise Exception("No \"{0}\" found, Please check your config!".format(i))
except Exception as e:
print(e)
exit(0)
#begin write file
self.write_add(filename,resultlist)
resultlist = [] #每个规则处理完后要清空这个list
return filename
def filter(self,string): #密码约束规则过滤
#第一重过滤
if len(string) < paras.min_lenth:#先要满足长度要求,提高过滤速度。
return False
hasSpecialchar = False
hasNumber = False
hasUpperletter =False
hasLowerletter =False
kind = 0
if common.hasSpecialchar(string):#特殊字符
hasSpecialchar = True
kind += 1
if common.hasNumber(string):#数字
hasNumber = True
kind += 1
if common.hasUpperletter(string): #大写字母
hasUpperletter = True
kind += 1
if common.hasLowerletter(string): #小写字母
hasLowerletter = True
kind += 1
#第2重过滤,需要满足种类种数
if kind < paras.kinds_needed:
return False
else:
pass
# 第3重过滤,需要满足种类
if paras.filter_rule["Nummber"]:
if not hasNumber:
return False
if paras.filter_rule["Upper_letter"]:
if not hasUpperletter:
return False
if paras.filter_rule["Lower_letter"]:
if not hasLowerletter:
return False
if paras.filter_rule["Special_char"]:
if not hasSpecialchar:
return False
return True
def filter_file(self,filename): # step four
self.logger.info("Doing filter base on the password requirements ...")
tmplist = []
fpr = open(filename, "r") # 写句柄不能用于读
for item in fpr.readlines():
if self.filter(item.strip()):
tmplist.append(item.strip())
tmplist = list(set(tmplist)) #去重
fpw = open(filename, "w")#这里要覆盖写入
fpw.writelines("\n".join(tmplist))
fpw.close()
def caps(self,filename): # step three
self.logger.info("Doing capitalize for all passwords have generated ...")
tmplist = []
fpr = open(filename, "r") # 写句柄不能用于读
# print fpr.readlines()
for item in fpr.readlines():
x = item.strip().capitalize()
if x != item.strip():
tmplist.append(x)
fpr.close()
# print tmplist
self.write_add(filename,tmplist)
#return filename
def leetit(self,filename): #step three
self.logger.info("Doing leet change for all passwords have generated ...")
tmplist = []
fpr = open(filename, "r")
for item in fpr.readlines():
for x in item.strip():
if x in list(paras.leet_rule.keys()):
leeted = item.strip().replace(x,paras.leet_rule[x])
tmplist.append(leeted)
self.write_add(filename,tmplist)
def addpassworddict(self,filename): #step five
self.logger.info("Adding common weak password to result ...")
tmplist = []
for item in paras.additional_list:
if os.path.isfile(item):
fp = open(item,"r")
for it in fp.readlines():
tmplist.append(it.strip("\n").strip("\r"))
self.write_add(filename,tmplist)
def run(self):
if len(paras.seed_map.keys()) >= 2 and len(paras.rule_list) >= 1:
file = self.passmaker()
if paras.capitalize:
self.caps(file)
else:
self.logger.info("CAPS = False. Skip this step ...")
if paras.leet:
self.leetit(file)
else:
self.logger.info("Leet = False. Skip this step ...")
self.addpassworddict(file)
if paras.enable_filter:
self.filter_file(file)
else:
self.logger.info("Filter disabled. Skip this step...")
return file
else:
self.logger.info("Config Not complete ...Please check and run again")
return None
if __name__ == "__main__":
args = parse_args()
if args.interactive:
interactive.interactive().interactive()
filename = passmaker().run()
if filename:
logger().info("Password file: {0}".format(os.path.join(os.getcwd(), filename)))
elif args.gui:
GUI.GUI()
else:
config2Paras()
filename = passmaker().run()
if filename:
logger().info("Password file: {0}".format(os.path.join(os.getcwd(),filename)))