-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdictionary-grepper.py
97 lines (70 loc) · 3.2 KB
/
dictionary-grepper.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
#!/usr/bin/python
import argparse, subprocess
import sys
import os.path
# Create a series of grep pipes to cut down a large dictionary of passwords to just ones relevant to a password policy
pipes = []
parser = argparse.ArgumentParser(description="Grep out a dictionary file")
parser.add_argument("-l", "--len", help="Minimum length of passwords")
parser.add_argument("-m", "--maxlen", help="Maximum length of passwords")
parser.add_argument("-e", "--excludelist", help="Exclude items from the specified word list")
parser.add_argument("-u", "--upper", action="store_true", help="Must contain an uppercase character")
parser.add_argument("-L", "--lower", action="store_true", help="Must contain a lowercase character")
parser.add_argument("-a", "--letter", action="store_true", help="Must contain an upper or lower case letter")
parser.add_argument("-n", "--numbers", action="store_true", help="Must contain a number")
parser.add_argument("-s", "--special", action="store_true", help="Must contain at least one special (non-alphanumeric) character")
parser.add_argument("-N", "--specnum", action="store_true", help="Must contain at least one special character or number")
parser.add_argument("-S", "--specupnum", action="store_true", help="Must contain at least one special character, uppercase character or number")
parser.add_argument("-f", "--firstupper", action="store_true", help="First character is uppercase")
parser.add_argument("-r", "--norepeat", action="store_true", help="No repeating characters")
parser.add_argument("-w", "--windows", action="store_true", help="Same as '-l 8 -u -L -N' to approximately match Windows minimum password complexity requirements: 8 chars, at least 3 of upper, lower, number, special, unicode")
parser.add_argument("dictionary", help="Input dictionary file")
args = parser.parse_args()
if not args.dictionary:
parser.print_usage()
sys.exit(2)
if not os.path.isfile( args.dictionary ):
print(( "Not found: " + args.dictionary ))
sys.exit(2)
# Work out grep pipes
pipes.append( ('cat', args.dictionary) )
if args.windows:
if not args.len:
args.len = 8
args.upper = True
args.lower = True
args.specnum = True
if args.len:
pipes.append( ['grep', r"^.\{{{0},\}}$".format(int(args.len))] )
if args.maxlen:
pipes.append( ['grep', r'^.{,'+str(int(args.maxlen))+'}$' ] )
if args.excludelist:
pipes.append( [ 'grep', '-x', '-v', '-F', '-f', args.excludelist ] )
if args.upper:
pipes.append( ['grep', '[A-Z]'] )
if args.lower:
pipes.append( ['grep', '[a-z]' ] )
if args.letter:
pipes.append( ['grep', '[A-Za-z]' ] )
if args.numbers:
pipes.append( ['grep', '[0-9]' ] )
if args.special:
pipes.append( ['grep', '[^a-zA-Z0-9]' ] )
if args.specnum:
pipes.append( ['grep', r'\([^a-zA-Z0-9]\|[0-9]\)' ])
if args.specupnum:
pipes.append( ['grep', r'\([^a-zA-Z0-9]\|[0-9]\|[A-Z]\)' ])
if args.firstupper:
pipes.append( ['grep', '^[A-Z]' ])
if args.norepeat:
pipes.append( ['grep', '-v', r'\(.\)\1' ])
procs = []
for p in pipes:
# Any stdout available?
if len( procs ) > 0:
out = procs[-1].stdout
else:
out = None
procs.append( subprocess.Popen(p, stdout=subprocess.PIPE, stdin=out, universal_newlines=False) )
out,err = procs[-1].communicate()
print(out.decode('utf8'))