├── README.md
├── capitalize_letters.py
├── combinator2.py
├── combinator3.py
├── combinator4.py
├── complexity_sorter.py
├── date_rule.py
├── example_md5_hashes.txt
├── get_pot_passwords.py
├── hash_generator.py
├── idiom_getter.py
├── leet_gen.py
├── leet_rule_generator.py
├── mask_finder.py
├── md5_hashgen.py
├── phrase_cleaner.py
├── phrase_combiner.py
├── positional_character_frequency.py
├── pot.py
├── quote_parser_001.py
├── quote_parser_002.py
├── quote_parser_003.py
├── remove_duplicates.py
├── seclist_password_combiner.py
├── wordlist_cleaner.py
└── wordlist_searcher.py
/README.md:
--------------------------------------------------------------------------------
1 | # Password Scripts
2 |
3 | ### mask_finder.py
4 | > Analyzes a password list to find frequency of password character masks.
5 |
6 | ### positional_character_frequency.py
7 | > Analyzes a password list to find frequency of characters per position.
8 |
9 | ### seclist_password_combiner.py
10 | > Combines, sorts, and uniques the passwords contained in files located at https://github.com/danielmiessler/SecLists.
11 |
12 | ### get_pot_passwords.py
13 | > Extracts the plain passwords from a hashcat or jtr pot file.
14 |
15 | ### md5_hashgen.py
16 | > Reads a plain password file, MD5s each password, and writes the hashes to a new file.
17 |
18 | ### remove_duplicates.py
19 | > Reads a file, removes duplicates, writes to a new file
20 |
21 | ### wordlist_cleaner.py
22 | > Reads a file, converts to lowercase, strips everything but lowercase letters, writes to new file.
23 |
24 | ### leet_gen.py
25 | > Reads a string or file, and creates a ridiculous amount of permutations using leet subsitutions. This will produce a LOT of output per word.
26 |
27 | ### capitalize_letters.py
28 | > Reads a file and capitalizes letters specified by index. If no index provided, will capitalize the first letter.
29 |
30 | ### wordlist_searcher.py
31 | > Searches a dictionary to see if a word exists. You can search for a single word, multiple words, or a words in a file.
32 |
33 | ### pot.py
34 | > Combines get_pot_passwords.py with wordlist_cleaner.py.
35 |
36 | ### combinator2.py
37 | > Combines two dictionaries. Can also title-case each word.
38 |
39 | ### combinator3.py
40 | > Combines three dictionaries. Can also title-case each word.
41 |
42 | ### combinator4.py
43 | > Combines four dictionaries. Can also title-case each word.
44 |
--------------------------------------------------------------------------------
/capitalize_letters.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20180924'
5 | __version__ = '0.01'
6 | __description__ = """Convert all words to lowercase and capitalizes letters at
7 | specified indexes. Can write output to a new file."""
8 |
9 | import argparse
10 | import os
11 |
12 | def main():
13 | print('[*] Reading file: {}...'.format(filename))
14 | with open(filename, encoding="utf8", errors='ignore') as fh:
15 | words = fh.read().splitlines()
16 | print('[*] Processing {} words...'.format(len(words)))
17 | print('[*] Changing all words to lowercase...')
18 | words = [word.lower() for word in words]
19 | if args.all:
20 | print('[*] Capitalizing all letters...')
21 | capitalized_words = [word.upper() for word in words]
22 | elif args.index:
23 | print('[*] Capitalizing letters at specified indexes...')
24 | capitalized_words = []
25 | for word in words:
26 | if not word: continue
27 | list_word = list(word)
28 | for pos in args.index:
29 | try:
30 | list_word[pos] = list_word[pos].capitalize()
31 | except IndexError as e:
32 | continue
33 | capitalized_words.append(''.join(list_word))
34 | else:
35 | print('[*] Capitalizing first letter of each word...')
36 | capitalized_words = [word.title() for word in words]
37 | if args.outfile:
38 | print('[*] Writing to {}...'.format(args.outfile))
39 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
40 | for word in capitalized_words:
41 | fh.write(word + '\n')
42 | else:
43 | for word in capitalized_words:
44 | print(word)
45 |
46 | if __name__ == '__main__':
47 | parser = argparse.ArgumentParser()
48 | parser.add_argument("-f", "--filename",
49 | help="Specify a file containing words.")
50 | parser.add_argument("-o", "--outfile",
51 | help="Writes the output to a specified file.")
52 | parser.add_argument("-a", "--all",
53 | action="store_true",
54 | help="Capitalizes all letters.")
55 | parser.add_argument("-i", "--index",
56 | nargs='*',
57 | type=int,
58 | help="Specify one or more integers to be used as positions (zero index) to capitalize a letter or letters.")
59 | args = parser.parse_args()
60 | if not args.filename:
61 | parser.print_help()
62 | print("\n[-] Please specify an input file containing words (-f).\n")
63 | exit()
64 | else:
65 | filename = args.filename
66 | if not os.path.exists(filename):
67 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(filename))
68 | exit()
69 | main()
70 |
--------------------------------------------------------------------------------
/combinator2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __author__ = "Jake Miller (@LaconicWolf)"
4 | __date__ = "20181216"
5 | __version__ = "0.01"
6 | __description__ = """Combines two wordlists."""
7 |
8 | import os
9 | import argparse
10 |
11 | def combine_words(wordlists):
12 | combined_words = []
13 | d1 = wordlists[0]
14 | d2 = wordlists[1]
15 | for h in range(len(d1)):
16 | w1 = d1[h].title() if args.title_case else d1[h]
17 | for i in range(len(d2)):
18 | w2 = d2[i].title() if args.title_case else d2[i]
19 | combined_words.append(w1 + w2)
20 | return combined_words
21 |
22 | def main():
23 | combined_words = combine_words(wordlists)
24 | if args.outfile:
25 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
26 | for word in combined_words:
27 | fh.write(word + '\n')
28 | else:
29 | for word in combined_words:
30 | print(word)
31 |
32 | if __name__ == '__main__':
33 | parser = argparse.ArgumentParser()
34 | parser.add_argument("-d", "--dictionaries",
35 | nargs="*",
36 | help="Specify a file or files containing words.")
37 | parser.add_argument("-o", "--outfile",
38 | help="Writes the output to a specified file.")
39 | parser.add_argument("-t", "--title_case",
40 | action="store_true",
41 | help="Capitalizes the first letter and lowercases the remaining letters of a word.")
42 | args = parser.parse_args()
43 | if not args.dictionaries:
44 | parser.print_help()
45 | print("\n[-] Please specify 2 dictionaries (-d dict1.txt dict2.txt).\n")
46 | exit()
47 | if len(args.dictionaries) != 2:
48 | parser.print_help()
49 | print("\n[-] You must specify 2 dictionaries (-d dict1.txt dict2.txt). No more, no less.\n")
50 | exit()
51 | wordlists = []
52 | for file in args.dictionaries:
53 | if not os.path.exists(file):
54 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(file))
55 | exit()
56 | with open(file, encoding="utf8", errors='ignore') as fh:
57 | words = fh.read().splitlines()
58 | wordlists.append(words)
59 | main()
--------------------------------------------------------------------------------
/combinator3.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __author__ = "Jake Miller (@LaconicWolf)"
4 | __date__ = "20181216"
5 | __version__ = "0.01"
6 | __description__ = """Combines three wordlists."""
7 |
8 | import os
9 | import argparse
10 |
11 | def combine_words(wordlists):
12 | combined_words = []
13 | d1 = wordlists[0]
14 | d2 = wordlists[1]
15 | d3 = wordlists[2]
16 | for h in range(len(d1)):
17 | w1 = d1[h].title() if args.title_case else d1[h]
18 | for i in range(len(d2)):
19 | w2 = d2[i].title() if args.title_case else d2[i]
20 | for j in range(len(d3)):
21 | w3 = d3[j].title() if args.title_case else d3[j]
22 | combined_words.append(w1 + w2 + w3)
23 | return combined_words
24 |
25 | def main():
26 | combined_words = combine_words(wordlists)
27 | if args.outfile:
28 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
29 | for word in combined_words:
30 | fh.write(word + '\n')
31 | else:
32 | for word in combined_words:
33 | print(word)
34 |
35 | if __name__ == '__main__':
36 | parser = argparse.ArgumentParser()
37 | parser.add_argument("-d", "--dictionaries",
38 | nargs="*",
39 | help="Specify a file or files containing words.")
40 | parser.add_argument("-o", "--outfile",
41 | help="Writes the output to a specified file.")
42 | parser.add_argument("-t", "--title_case",
43 | action="store_true",
44 | help="Capitalizes the first letter and lowercases the remaining letters of a word.")
45 | args = parser.parse_args()
46 | if not args.dictionaries:
47 | parser.print_help()
48 | print("\n[-] Please specify 3 dictionaries (-d dict1.txt dict2.txt dict3.txt).\n")
49 | exit()
50 | if len(args.dictionaries) != 3:
51 | parser.print_help()
52 | print("\n[-] You must specify 3 dictionaries (-d dict1.txt dict2.txt dict3.txt). No more, no less.\n")
53 | exit()
54 | wordlists = []
55 | for file in args.dictionaries:
56 | if not os.path.exists(file):
57 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(file))
58 | exit()
59 | with open(file, encoding="utf8", errors='ignore') as fh:
60 | words = fh.read().splitlines()
61 | wordlists.append(words)
62 | main()
--------------------------------------------------------------------------------
/combinator4.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __author__ = "Jake Miller (@LaconicWolf)"
4 | __date__ = "20181216"
5 | __version__ = "0.01"
6 | __description__ = """Combines four wordlists."""
7 |
8 | import os
9 | import argparse
10 |
11 | def combine_words(wordlists):
12 | combined_words = []
13 | d1 = wordlists[0]
14 | d2 = wordlists[1]
15 | d3 = wordlists[2]
16 | d4 = wordlists[3]
17 | for h in range(len(d1)):
18 | w1 = d1[h].title() if args.title_case else d1[h]
19 | for i in range(len(d2)):
20 | w2 = d2[i].title() if args.title_case else d2[i]
21 | for j in range(len(d3)):
22 | w3 = d3[j].title() if args.title_case else d3[j]
23 | for k in range(len(d4)):
24 | w4 = d4[k].title() if args.title_case else d4[k]
25 | combined_words.append(w1 + w2 + w3 + w4)
26 | return combined_words
27 |
28 | def main():
29 | combined_words = combine_words(wordlists)
30 | if args.outfile:
31 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
32 | for word in combined_words:
33 | fh.write(word + '\n')
34 | else:
35 | for word in combined_words:
36 | print(word)
37 |
38 | if __name__ == '__main__':
39 | parser = argparse.ArgumentParser()
40 | parser.add_argument("-d", "--dictionaries",
41 | nargs="*",
42 | help="Specify a file or files containing words.")
43 | parser.add_argument("-o", "--outfile",
44 | help="Writes the output to a specified file.")
45 | parser.add_argument("-t", "--title_case",
46 | action="store_true",
47 | help="Capitalizes the first letter and lowercases the remaining letters of a word.")
48 | args = parser.parse_args()
49 | if not args.dictionaries:
50 | parser.print_help()
51 | print("\n[-] Please specify 4 dictionaries (-d dict1.txt dict2.txt dict3.txt dict4.txt).\n")
52 | exit()
53 | if len(args.dictionaries) != 4:
54 | parser.print_help()
55 | print("\n[-] You must specify 4 dictionaries (-d dict1.txt dict2.txt dict3.txt dict4.txt). No more, no less.\n")
56 | exit()
57 | wordlists = []
58 | for file in args.dictionaries:
59 | if not os.path.exists(file):
60 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(file))
61 | exit()
62 | with open(file, encoding="utf8", errors='ignore') as fh:
63 | words = fh.read().splitlines()
64 | wordlists.append(words)
65 | main()
--------------------------------------------------------------------------------
/complexity_sorter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190401'
5 | __version__ = '0.01'
6 | __description__ = """Reads a file containing plain text words, accepts user input
7 | specifying the number of charsets present, and prints to new file words that meet
8 | the charset requirement."""
9 |
10 | import argparse
11 | import string
12 | import os
13 |
14 | def get_complexity(word):
15 | """Analyzes a word and returns a tuple containing the
16 | word, along with a complexity number of the number of
17 | charsets present."""
18 | complexity = 0
19 | lowercase = False
20 | uppercase = False
21 | special = False
22 | digits = False
23 |
24 | string.punctuation += ' '
25 |
26 | for char in string.ascii_lowercase:
27 | if char in word:
28 | lowercase = True
29 |
30 | for char in string.ascii_uppercase:
31 | if char in word:
32 | uppercase = True
33 |
34 | for char in string.punctuation:
35 | if char in word:
36 | special = True
37 |
38 | for char in string.digits:
39 | if char in word:
40 | digits = True
41 | if lowercase:
42 | complexity += 1
43 | if uppercase:
44 | complexity += 1
45 | if special:
46 | complexity += 1
47 | if digits:
48 | complexity += 1
49 | return (word,complexity)
50 |
51 |
52 | def main():
53 | sorted_words = []
54 | print('[*] Reading file: {}...',format(filename))
55 | with open(filename) as fh:
56 | words = fh.read().splitlines()
57 | print('[*] Getting word complexity...')
58 | word_tuple = [get_complexity(word) for word in words]
59 | for item in word_tuple:
60 | word = item[0]
61 | complexity = item[1]
62 | if complexity in [int(number) for number in args.complexity]:
63 | sorted_words.append(word)
64 | print('[+] Writing words to {}...'.format(outfile))
65 | with open(outfile, 'w') as fh:
66 | for word in sorted_words:
67 | fh.write(word + '\n')
68 | print('[+] Complete!')
69 |
70 | if __name__ == '__main__':
71 | parser = argparse.ArgumentParser()
72 | parser.add_argument("-f", "--filename",
73 | help="Specify a file containing plain text passwords.")
74 | parser.add_argument("-o", "--outfile",
75 | help="Writes the output to a file, masks.txt, in the current directory.")
76 | parser.add_argument("-c", "--complexity",
77 | nargs='*',
78 | default=['1','2','3','4'],
79 | choices=['1','2','3','4'],
80 | help="Specify the the number of charsets the must be present.")
81 | parser.add_argument("-i", "--include_less_complex",
82 | help="Specify a file containing plain text passwords.")
83 | args = parser.parse_args()
84 |
85 | if not args.filename:
86 | parser.print_help()
87 | print("\n[-] Please specify a file containing plaintext passwords.\n")
88 | exit()
89 | filename = args.filename
90 | if not os.path.exists(filename):
91 | parser.print_help()
92 | print("\n[-] The file {}, does not exist or you lack permissions to open it. Please try again.\n".format(filename))
93 | exit()
94 |
95 | outfile = args.outfile if args.outfile else "complexity_sorter_outfile.txt"
96 | main()
--------------------------------------------------------------------------------
/date_rule.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190316'
5 | __version__ = '0.01'
6 | __description__ = """Creates a rule file that will append digits that may
7 | map to dates in popular formats that may be appended to files. You can also
8 | append or prepend characters or words, capitalize the first character of the
9 | words, and double the word. Dates are currently MDY, but can be DMY or YMD"""
10 |
11 | import argparse
12 | import time
13 | try:
14 | import pandas as pd
15 | except ImportError:
16 | print("This script requires Pandas. Try 'pip install pandas', or 'python -m pip install pandas', or do an Internet search for installation instructions.")
17 | exit()
18 |
19 | def create_2_digit_year():
20 | """Returns a list of strings from 00-99."""
21 | string_year_range = []
22 | for i in range(0, 100):
23 | i = str(i)
24 | if len(i) < 2:
25 | i = '0' + i
26 | string_year_range.append(i)
27 | return string_year_range
28 |
29 | def create_month_day(start_year, end_year):
30 | """Returns a list of from 0101-1231."""
31 | month_day_list = []
32 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
33 | for time in times:
34 | month_day_list.append(''.join(str(time).split(' ')[0].split('-')[1:]))
35 | return list(set(month_day_list))
36 |
37 | def create_month_day_2_dig_year(start_year, end_year):
38 | """Returns a list of from 010100-123199."""
39 | month_day_year = []
40 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
41 | for time in times:
42 | year = str(time).split('-')[0][-2:]
43 | month_day = ''.join(str(time).split(' ')[0].split('-')[1:])
44 | month_day_year.append(month_day + year)
45 | return list(set(month_day_year))
46 |
47 | def create_month_day_4_dig_year(start_year, end_year):
48 | """Returns a list of from 01011900-12312099."""
49 | month_day_year = []
50 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
51 | for time in times:
52 | year = ''.join(str(time).split('-')[0])
53 | month_day = ''.join(str(time).split(' ')[0].split('-')[1:])
54 | month_day_year.append(month_day + year)
55 | return list(set(month_day_year))
56 |
57 | def create_day_month(start_year, end_year):
58 | """Returns a list of from 0101-3112."""
59 | day_month_list = []
60 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
61 | for time in times:
62 | day = str(time).split(' ')[0].split('-')[2]
63 | month = str(time).split(' ')[0].split('-')[1]
64 | day_month_list.append(day + month)
65 | return list(set(day_month_list))
66 |
67 | def create_day_month_2_dig_year(start_year, end_year):
68 | """Returns a list of from 010100-311299."""
69 | day_month_year = []
70 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
71 | for time in times:
72 | day = str(time).split(' ')[0].split('-')[2]
73 | month = str(time).split(' ')[0].split('-')[1]
74 | year = str(time).split('-')[0][-2:]
75 | day_month_year.append(day + month + year)
76 | return list(set(day_month_year))
77 |
78 | def create_day_month_4_dig_year(start_year, end_year):
79 | """Returns a list of from 01011900-31122099."""
80 | day_month_year = []
81 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
82 | for time in times:
83 | day = str(time).split(' ')[0].split('-')[2]
84 | month = str(time).split(' ')[0].split('-')[1]
85 | year = str(time).split('-')[0]
86 | day_month_year.append(day + month + year)
87 | return list(set(day_month_year))
88 |
89 | def create_2_dig_year_month_day(start_year, end_year):
90 | """Returns a list of from 000101-991231."""
91 | year_month_day = []
92 | times = pd.date_range('01-01-2000', '12-31-2099')
93 | for time in times:
94 | year = str(time).split('-')[0][-2:]
95 | month_day = ''.join(str(time).split(' ')[0].split('-')[1:])
96 | year_month_day.append(year + month_day)
97 | return list(set(year_month_day))
98 |
99 | def create_4_dig_year_month_day(start_year, end_year):
100 | """Returns a list of from 19000101-20991231."""
101 | year_month_day = []
102 | times = pd.date_range('01-01-{}'.format(start_year), '12-31-{}'.format(end_year))
103 | for time in times:
104 | year_month_day.append(str(time).split(' ')[0].replace('-', ''))
105 | return list(set(year_month_day))
106 |
107 | def main():
108 | print("[*] Generating dates...")
109 |
110 | # 00-99
111 | two_dig_year = create_2_digit_year()
112 |
113 | # 0101-1231
114 | month_day = create_month_day(start_year, end_year)
115 |
116 | # 010100-123199
117 | month_day_2_dig_year = create_month_day_2_dig_year(start_year, end_year)
118 |
119 | # 01011900-12312099
120 | month_day_4_dig_year = create_month_day_4_dig_year(start_year, end_year)
121 |
122 | # 0101-3112
123 | day_month = create_day_month(start_year, end_year)
124 |
125 | # 010100-311299
126 | day_month_2_dig_year = create_day_month_2_dig_year(start_year, end_year)
127 |
128 | # 01011900-31122099
129 | day_month_4_dig_year = create_day_month_4_dig_year(start_year, end_year)
130 |
131 | # 000101-991231
132 | two_dig_year_month_day = create_2_dig_year_month_day(start_year, end_year)
133 |
134 | # 19000101-20991231
135 | four_dig_year_month_day = create_4_dig_year_month_day(start_year, end_year)
136 |
137 | all_dates = two_dig_year
138 | if date_time_format == 'MDY':
139 | all_dates += month_day
140 | all_dates += month_day_2_dig_year
141 | all_dates += month_day_4_dig_year
142 |
143 | if date_time_format == 'YMD':
144 | all_dates += month_day
145 | all_dates += two_dig_year_month_day
146 | all_dates += four_dig_year_month_day
147 |
148 | if date_time_format == 'DMY':
149 | all_dates += month_day
150 | all_dates += two_dig_year_month_day
151 | all_dates += four_dig_year_month_day
152 |
153 | # Write to rule file
154 | print("[*] Writing rules...")
155 | with open(filename, 'w') as fh:
156 | for date in all_dates:
157 | # Dates only
158 | fh.write('${}\n'.format('$'.join(list(date))))
159 |
160 | if args.title:
161 | # Capitalizes first letter then dates
162 | fh.write('c${}\n'.format('$'.join(list(date))))
163 |
164 | if args.title and args.double:
165 | # Capitalizes first letter, doubles, then dates
166 | fh.write('cd${}\n'.format('$'.join(list(date))))
167 |
168 | # Doubles, dates, then capitalizes first letter
169 | fh.write('d${}c\n'.format('$'.join(list(date))))
170 |
171 | if appensions:
172 | for item in appensions:
173 | # Writes dates with items
174 | fh.write('${}${}\n'.format('$'.join(list(date)), '$'.join(list(item))))
175 |
176 | if args.title:
177 | # Capitalizes, dates, and writes with items
178 | fh.write('c${}${}\n'.format('$'.join(list(date)), '$'.join(list(item))))
179 |
180 | if args.double:
181 | # Capitalizes first letter, doubles, then dates with items
182 | fh.write('cd${}${}\n'.format('$'.join(list(date)), '$'.join(list(item))))
183 |
184 | if args.title and args.double:
185 | # Capitalizes first letter, then doubles, dates and items
186 | fh.write('cd${}${}\n'.format('$'.join(list(date)), '$'.join(list(item))))
187 |
188 | # Doubles, dates and items, then capitalizes first letter
189 | fh.write('d${}${}c\n'.format('$'.join(list(date)), '$'.join(list(item))))
190 |
191 | if prepensions:
192 | for item in appensions:
193 | # Writes items with dates
194 | fh.write('^{}${}\n'.format('^'.join(list(item)[::-1]), '$'.join(list(date)) ))
195 |
196 | if args.title:
197 | # Capitalizes, dates, and writes with items
198 | fh.write('c^{}${}\n'.format('^'.join(list(item)[::-1]), '$'.join(list(date)) ))
199 |
200 | if args.double:
201 | # Capitalizes first letter, doubles, then dates with items
202 | fh.write('cd^{}${}\n'.format('^'.join(list(item)[::-1]), '$'.join(list(date)) ))
203 |
204 | if args.title and args.double:
205 | # Capitalizes first letter, then doubles, dates and items
206 | fh.write('cd^{}${}\n'.format('^'.join(list(item)[::-1]), '$'.join(list(date)) ))
207 |
208 | # Doubles, dates and items, then capitalizes first letter
209 | fh.write('d^{}${}c\n'.format('^'.join(list(item)[::-1]), '$'.join(list(date)) ))
210 |
211 | print("[+] Complete! Rule file written to {}".format(filename))
212 |
213 | if __name__ == '__main__':
214 | parser = argparse.ArgumentParser()
215 | parser.add_argument("-f", "--format",
216 | nargs='?',
217 | const='MDY',
218 | default='MDY',
219 | choices=['DMY', 'MDY', 'YMD'],
220 | help="Choose date/time format. Default MDY")
221 | parser.add_argument("-d", "--double",
222 | help="Double word before appending date",
223 | action="store_true")
224 | parser.add_argument("-t", "--title",
225 | help="title case word",
226 | action="store_true")
227 | parser.add_argument("-a", "--append",
228 | nargs="*",
229 | help="Specify characters or words to add to end of dates, separated by spaces. (-a ! !! !!! !@#$")
230 | parser.add_argument("-p", "--prepend",
231 | nargs="*",
232 | help="Specify characters or words to add to the beginning of the word, separated by spaces. (-p ! !! !!! !@#$")
233 | parser.add_argument("-s", "--start_year",
234 | help="Specify 4 digit year as a starting date range. Default is 1970.")
235 | parser.add_argument("-e", "--end_year",
236 | help="Specify 4 digit year as a starting date range. Default is current year + 1.")
237 | parser.add_argument("-o", "--filename",
238 | help="Specify a filename to write to. Default is date_rule.rule")
239 | args = parser.parse_args()
240 | if args.start_year:
241 | if not args.start_year.isdigit() or len(args.start_year) != 4:
242 | print('[-] Start year must be a 4 digit year (-s 2005). Default is 1970')
243 | exit()
244 | start_year = args.start_year if args.start_year else '1970'
245 | if args.end_year:
246 | if not args.end_year.isdigit() or len(args.end_year) != 4:
247 | print('[-] End year must be a 4 digit year (-e 2019). Default is current year + 1')
248 | exit()
249 |
250 | date_time_format = args.format
251 | end_year = args.end_year if args.end_year else str(time.localtime().tm_year + 1)
252 | appensions = args.append if args.append else None
253 | prepensions = args.prepend if args.prepend else None
254 | filename = args.filename if args.filename else 'date_rule.rule'
255 |
256 | main()
257 |
--------------------------------------------------------------------------------
/example_md5_hashes.txt:
--------------------------------------------------------------------------------
1 | 699cb5b6b8a56b9cd25cef37d199d4ac
2 | 260263760ece559fe365589d6c11eba9
3 | 2637051b051cfc5ade8a9a85f28a25cf
4 | fa45ce2768b3bcacf084cfcb08991e8b
5 | 37fe46e1fd7ce80760835d5ae7868bfc
6 | 70b7f532c9452004bf6a475b64a009c3
7 | b85bfe1a3e7b5e200dc806f221019d28
8 | 828113e6a780593648b5ca2c34da42da
9 | 8ba013fd99cdc64ee07d6b1dc98eb73f
10 | 6df8751a6a45bc56c4c834faac7925ee
11 | e309bdf1de5640f114fddfe5eac9ccf8
12 | 3f334b240048a0f6fc9546765d331922
13 | 178f2d3fbe316aa8a50417b17cb0a305
14 | 8c8539414e9a3cbde319212a99e7fb55
15 | 722c5acd147dccf514e9f8d43c4f1bf5
16 | 358df8ac69d9280117cbeaf7c93311d5
17 | 934cb4ea55342ef59e0a6f353fe75f22
18 | ec3a0498fda303aaa660ed775f13241e
19 | 4f3c3fc1575af79c32fcb2f096bda18f
20 | 0c8fda55b15fec3cdbe7a4ef96e93e68
21 | 14839d5c2c0465919e1c88e96ea7fcf9
22 | 08925418198cc8c94fadd5cc375355b1
23 | 083611c2b56aa90a7492471853c99446
24 | 4c3089589918649c8044a08a02d709ac
25 | 85eaccc021a9390c7d4965d6f3ce84bd
26 | 97435782796621bb14ede6f6bd04a940
27 | 74a32f9daf45084b0ea955ed06dd9c41
28 | cd17666830b55097a331e1e23175ba13
29 | 752aa8693aebd2d1c62f792c27959617
30 | c4d8676f8918542fb96b1ba34488a7e6
31 | 9fa6a7b1a11abed8c26125604db90727
32 | 3d461a885ea7115e1caf632c4dec4b96
33 | 85746df6be17313d0ff067a1b489dc43
34 | 3ecd86e03725554d6fc8138971c40d3f
35 | d9faa0dd65085891c66eb394b5a0dcb9
36 | e285a588711dd510afa6f416408b9edf
37 | 142853074e899f704f66624b7957caa1
38 | 2ea53aa3f3f3e64bf2e80c44eaf9c86d
39 | f59017ec3fad4abba289f856d640adf3
40 | 67ef6e0f615dd378572e42833dc2e3f2
41 | a4f2dcf6a952d8e5c0c1347eedc12024
42 | fa89a344f345a6c910ad3e158093ce1d
43 | 09ad2dc99adca85d7c7c746afe40cee5
44 | 55c72bf24748405d4129d994a6db2ae4
45 | 354a6305e24b52d1bacac1be01f36a26
46 | ad9d55297954e63f65451949b86d7d63
47 | cab43e4a2055f220c4685022fc44ef94
48 | 13ee3fa82956feb92ba06d9ab74811d6
49 | 0280abda9613ab7d99c5d7a6c5ca0ecf
50 | 24665528da7a9add56fe66c8414e3c8a
51 |
--------------------------------------------------------------------------------
/get_pot_passwords.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180921'
6 | __version__ = '0.01'
7 | __description__ = """Extracts the plain passwords from a hashcat or jtr pot file."""
8 |
9 |
10 | import argparse
11 |
12 |
13 | def decode_hashcat_hexstring(hexstring):
14 | """Parses a hex encoded password string ($HEX[476f6f646669676874343a37])
15 | and returns the decodes the hex.
16 | """
17 | index_1 = hexstring.index("[")+1
18 | index_2 = len(hexstring)-1
19 | hexdata = hexstring[index_1:index_2]
20 | return bytes.fromhex(hexdata).decode()
21 |
22 |
23 | def decode_hashcat_hex(data):
24 | """Calls the decoded_hashcat_hexstring on an encoded hex represented password
25 | ($HEX[476f6f646669676874343a37]). Occasionally the string will be encoded
26 | multiple times, so a loop is used until the $HEX prefix no longer remains.
27 | Returns the decodes the hexstring.
28 | """
29 | while data.startswith('$HEX['):
30 | data = decode_hashcat_hexstring(data)
31 | return data
32 |
33 |
34 | def main():
35 |
36 | # Reads in the potfile
37 | with open(potfile) as fh:
38 | lines = fh.read().splitlines()
39 | try:
40 | # Both JTR and Hashcat potfiles are colon delimited. In JTR pot files,
41 | # a colon in the password will mess up the split, so it must be split
42 | # from the first colon until the end of line.
43 | pt_passwords = [line.split(':')[1:] for line in lines]
44 | fixed_passwords = []
45 | for line in pt_passwords:
46 | if len(line) > 1:
47 | fixed_passwords.append(':'.join(line))
48 | else:
49 | fixed_passwords.append(''.join(line))
50 | except IndexError as e:
51 | print('Error detected:')
52 | print(e)
53 | passwords = []
54 | for password in fixed_passwords:
55 |
56 | # Hashcat will encode passwords containing colons or non-ascii characters.
57 | # This will decode those passwords if they are there.
58 | if password.startswith('$HEX['):
59 | passwords.append(decode_hashcat_hex(password))
60 | else:
61 | passwords.append(password)
62 |
63 | # Output to file or print to terminal
64 | if args.outfile:
65 | with open(args.outfile, 'w') as fh:
66 | for password in passwords:
67 | fh.write(password + '\n')
68 | else:
69 | for password in passwords:
70 | print(password)
71 |
72 |
73 | if __name__ == '__main__':
74 | parser = argparse.ArgumentParser()
75 | parser.add_argument('-f', '--filename')
76 | parser.add_argument('-o', '--outfile')
77 | args = parser.parse_args()
78 | if not args.filename:
79 | parser.print_help()
80 | print("\n[-] Please specify the filename of the potfile\n")
81 | exit()
82 | else:
83 | potfile = args.filename
84 | main()
85 |
--------------------------------------------------------------------------------
/hash_generator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20190102'
6 | __version__ = '0.01'
7 | __description__ = """Reads a plain text file and hashes each line. The hashes are written
8 | to a new file. The purpose of this tool is to generate sample hashes for testing password
9 | cracking."""
10 |
11 |
12 | import hashlib
13 | import argparse
14 | import os
15 |
16 | def md5_hash(string_value):
17 | """Returns a md5 hash of the supplied string."""
18 | return hashlib.md5(string_value.encode()).hexdigest()
19 |
20 | def ntlm_hash(string_value):
21 | """Returns an ntlm hash of the supplied string."""
22 | return hashlib.new('md4', string_value.encode('utf-16le')).hexdigest()
23 |
24 | def main():
25 | with open(filename, encoding="utf8", errors='ignore') as fh:
26 | words = fh.read().splitlines()
27 | if algo == 'md5':
28 | hashes = [md5_hash(word) for word in words]
29 | elif algo == 'ntlm':
30 | hashes = [ntlm_hash(word) for word in words]
31 | else:
32 | hashes = ''
33 | with open(outfile, 'w', encoding="utf8", errors='ignore') as fh:
34 | for digest in hashes:
35 | print(digest)
36 | fh.write(digest + '\n')
37 |
38 | if __name__ == '__main__':
39 | parser = argparse.ArgumentParser()
40 | parser.add_argument("-f", "--filename",
41 | help="Specify a file containing words.")
42 | parser.add_argument("-o", "--outfile",
43 | help="Writes the output to a specified file.")
44 | parser.add_argument("-a", "--algorithm",
45 | choices=('md5', 'ntlm'),
46 | help="Selects an algorithm to generate hashes.")
47 | args = parser.parse_args()
48 | if not args.filename:
49 | parser.print_help()
50 | print("\n[-] Please specify an input file containing words (-f).\n")
51 | exit()
52 | else:
53 | filename = args.filename
54 | if not os.path.exists(filename):
55 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(filename))
56 | exit()
57 | if not args.algorithm:
58 | parser.print_help()
59 | print("\n[-] Please specify an algorithm (-a ntlm).\n")
60 | exit()
61 | else:
62 | algo = args.algorithm
63 | if args.outfile:
64 | outfile = args.outfile
65 | else:
66 | outfile = 'hashed_values.txt'
67 | main()
--------------------------------------------------------------------------------
/idiom_getter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20181227'
5 | __version__ = '0.01'
6 | __description__ = """Retrieves all idioms listed at https://www.theidioms.com
7 | and writes to a file"""
8 |
9 | import re
10 | import requests
11 |
12 | idioms = []
13 | for num in range(1, 132):
14 | url = "https://www.theidioms.com/list/page/{}".format(num)
15 | contents = requests.get(url).text
16 | idioms += re.findall(
17 | r'
(.*?)',
18 | contents
19 | )
20 |
21 | with open('idioms.txt', 'w') as fh:
22 | for idiom in idioms:
23 | if '’' in idiom:
24 | idiom = idiom.replace('’', "'")
25 | print(idiom.lower())
26 | fh.write(idiom.lower() + '\n')
27 |
28 | print('[*] File written to idioms.txt!')
--------------------------------------------------------------------------------
/leet_gen.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf). Credit @aswsec for the idea and the leet_dict'
5 | __date__ = '20180924'
6 | __version__ = '0.01'
7 | __description__ = """Generates leet words"""
8 |
9 |
10 | import argparse
11 | import os
12 |
13 |
14 | leet_dict = {
15 | 'a': ['a','A','/-\\', '/\\', '4', '@'],
16 | 'b': ['b','B','|3', '8', '|o'],
17 | 'c': ['c','C','(', '<', 'K', 'S'],
18 | 'd': ['d','D','|)', 'o|', '|>', '<|'],
19 | 'e': ['e','E','3'],
20 | 'f': ['f','F','|=', 'ph'],
21 | 'g': ['g','G','(', '9', '6'],
22 | 'h': ['h','H','|-|', ']-[','}-{', '(-)', ')-(', '#'],
23 | 'i': ['i','I','l', '1', '|', '!', ']['],
24 | 'j': ['j','J','_|'],
25 | 'k': ['k','K','|<', '/<', '\\<', '|{'],
26 | 'l': ['l','L','|_', '|', '1'],
27 | 'm': ['m','M','|\\/|', '/\\/\\', '|\'|\'|', '(\\/)', '/|\\', '/v\\'],
28 | 'n': ['n','N','|\\|', '/\\/', '|\\|', '/|/'],
29 | 'o': ['o','O','0', '()', '[]', '{}'],
30 | 'p': ['p','P','|2', '|D'],
31 | 'q': ['q','Q','(,)', 'kw'],
32 | 'r': ['r','R','|2', '|Z', '|?'],
33 | 's': ['s','S','5', '$'],
34 | 't': ['t','T','+', '\'][\'', '7'],
35 | 'u': ['u','U','|_|'],
36 | 'v': ['v','V','|/', '\\|', '\\/', '/'],
37 | 'w': ['w','W','\\/\\/', '\\|\\|', '|/|/', '\\|/', '\\^/', '//'],
38 | 'x': ['x','X','><', '}{'],
39 | 'y': ['y','Y','`/', '\'/', 'j'],
40 | 'z': ['z','Z','2', '(\\)']
41 | }
42 |
43 |
44 | def permute(dict_word):
45 | """Looks up each letter of a word to its leet equivalent and
46 | returns a list of words permutated with the leet values.
47 | Adapted from: https://github.com/madglory/permute_wordlist/blob/master/permuteWordlist.py
48 | """
49 | if len(dict_word) > 0:
50 | current_letter = dict_word[0]
51 | rest_of_word = dict_word[1:]
52 | if current_letter in leet_dict:
53 | substitutions = leet_dict[current_letter] + [current_letter]
54 | else:
55 | substitutions = [current_letter]
56 | if len(rest_of_word) > 0:
57 | perms = [s + p for s in substitutions for p in permute(rest_of_word)]
58 | else:
59 | perms = substitutions
60 | return perms
61 |
62 |
63 | def main():
64 | """Generates all possible combination or leet letters for
65 | a given word or wordlist.
66 | """
67 | global words
68 | words = [word.lower() for word in words]
69 |
70 | for word in words:
71 | permuted = permute(word)
72 | unique_list=set(permuted)
73 | if args.outfile:
74 | print("[*] Writing to {}...".format(args.outfile))
75 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
76 | for item in unique_list:
77 | fh.write(item + '\n')
78 | else:
79 | for item in unique_list:
80 | print(item)
81 |
82 |
83 | if __name__ == '__main__':
84 | parser = argparse.ArgumentParser()
85 | parser.add_argument("-f", "--file",
86 | help="Specify a file containing words.")
87 | parser.add_argument("-w", "--word",
88 | help="Specify a single word.")
89 | parser.add_argument("-o", "--outfile",
90 | help="Writes the output to a specified file.")
91 | args = parser.parse_args()
92 |
93 | if not args.word and not args.file:
94 | parser.print_help()
95 | print("\n[-] Please specify a word (-w) or an input file containing words (-f).\n")
96 | exit()
97 |
98 | if args.word and args.file:
99 | parser.print_help()
100 | print("\n[-] Please specify a word (-w) or an input file containing words (-f). Not both\n")
101 | exit()
102 |
103 | if args.file:
104 | file = args.file
105 | if not os.path.exists(file):
106 | print("\n[-] The file cannot be found or you do not have permission to open the file. Please check the path and try again\n")
107 | exit()
108 | with open(file, encoding="utf8", errors='ignore') as fh:
109 | words = fh.read().splitlines()
110 |
111 | if args.word:
112 | words = [args.word]
113 | main()
114 |
--------------------------------------------------------------------------------
/leet_rule_generator.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf). Inspired by work from Adam Willard (@aswsec)'
4 | __date__ = '20190323'
5 | __version__ = '0.01'
6 | __description__ = """Generates leet word rules"""
7 |
8 | import argparse
9 | import itertools
10 |
11 | small_leet_dict = {
12 | 'a': ['4', '@'],
13 | 'b': ['8', '6'],
14 | 'c': ['(', '<', '{', 'k'],
15 | 'e': ['3'],
16 | 'g': ['9', '6'],
17 | 'h': ['#'],
18 | 'i': ['l','1','|','!'],
19 | 'l': ['|','1'],
20 | 'o': ['0'],
21 | 'q': ['9'],
22 | 's': ['5','$'],
23 | 't': ['+','7'],
24 | 'x': ['%'],
25 | 'z': ['2']
26 | }
27 |
28 | # Uppercase letters omitted due to memory error when
29 | # creating the combined list of dictionaries.
30 | large_leet_dict = {
31 | 'a': ['a', '4', '@'],
32 | 'b': ['b', '8', '6'],
33 | 'c': ['c', '(', '<', '{'],
34 | 'd': ['d'],
35 | 'e': ['e','3'],
36 | 'f': ['f'],
37 | 'g': ['g', '9', '6'],
38 | 'h': ['h','#'],
39 | 'i': ['i','l','1','|','!'],
40 | 'j': ['j'],
41 | 'k': ['k'],
42 | 'l': ['l','|','1'],
43 | 'm': ['m'],
44 | 'n': ['n'],
45 | 'o': ['o','0'],
46 | 'p': ['p'],
47 | 'q': ['q','9'],
48 | 'r': ['r'],
49 | 's': ['s','5','$'],
50 | 't': ['t','+','7'],
51 | 'u': ['u'],
52 | 'v': ['v'],
53 | 'w': ['w'],
54 | 'x': ['x','%'],
55 | 'z': ['2']
56 | }
57 |
58 |
59 | def main():
60 | """Permutates a dictionary to write hashcat rules."""
61 | if args.size == 'large':
62 | leet_mappings = large_leet_dict
63 | else:
64 | leet_mappings = small_leet_dict
65 | print('[*] Generating rules...')
66 |
67 | # https://codereview.stackexchange.com/questions/171173/list-all-possible-permutations-from-a-python-dictionary-of-lists
68 | keys, values = zip(*leet_mappings.items())
69 | leet_dict_list = [dict(zip(keys, v)) for v in itertools.product(*values)]
70 |
71 | all_lines = []
72 | for leet_dict in leet_dict_list:
73 | subruleline = []
74 | for key in leet_dict:
75 | subruleline.append('s{}{}'.format(key,leet_dict.get(key)))
76 | all_lines.append(subruleline)
77 |
78 | print('[*] Writing rules...')
79 |
80 | with open(outfilename, 'w') as fh:
81 | for line in all_lines:
82 | fh.write('{}\n'.format(' '.join(line)))
83 |
84 | if args.title:
85 | fh.write('l {} c\n'.format(' '.join(line)))
86 |
87 | if args.double and not args.title:
88 | fh.write('d {}\n'.format(' '.join(line)))
89 |
90 | if args.double and args.title:
91 | fh.write('d {} c\n'.format(' '.join(line)))
92 | fh.write('c d {}\n'.format(' '.join(line)))
93 |
94 | if appensions:
95 | for item in appensions:
96 | fh.write('{}${}\n'.format(' '.join(line), '$'.join(list(item))))
97 |
98 | if args.title:
99 | fh.write('l {} ${} c\n'.format(' '.join(line), '$'.join(list(item))))
100 |
101 | if args.double and not args.title:
102 | fh.write('{} ${} d\n'.format(' '.join(line), '$'.join(list(item))))
103 |
104 | if args.double and args.title:
105 | fh.write('l d {} ${} c\n'.format(' '.join(line), '$'.join(list(item))))
106 | fh.write('l c d {} ${}\n'.format(' '.join(line), '$'.join(list(item))))
107 |
108 | if prepensions:
109 | for item in prepensions:
110 | fh.write('^{}{}\n'.format('^'.join(list(item)[::-1]), ' '.join(line)))
111 |
112 | if args.title:
113 | fh.write('l ^{} {} c\n'.format('^'.join(list(item)[::-1]), ' '.join(line)))
114 |
115 | if args.double and not args.title:
116 | fh.write('^{} {} d\n'.format('^'.join(list(item)[::-1]), ' '.join(line)))
117 |
118 | if args.double and args.title:
119 | fh.write('l d ^{} {} c\n'.format('^'.join(list(item)[::-1]), ' '.join(line)))
120 | fh.write('l c d ^{} {}\n'.format('^'.join(list(item)[::-1]), ' '.join(line)))
121 |
122 | print('[+] Complete! Rules written to {}'.format(outfilename))
123 |
124 | if __name__ == '__main__':
125 | parser = argparse.ArgumentParser()
126 | parser.add_argument("-o", "--outfile",
127 | help="Output file name")
128 | parser.add_argument("-s", "--size",
129 | nargs='?',
130 | choices=["small", "large"],
131 | const="small",
132 | default="small",
133 | help="'small' uses a dictionary of only leet mappings. 'large' uses the lowercase character, and the leet mappings, which results in a MUCH larger rule file. ")
134 | parser.add_argument("-d", "--double",
135 | action="store_true",
136 | help="Double word and leet")
137 | parser.add_argument("-t", "--title",
138 | action="store_true",
139 | help="title case word")
140 | parser.add_argument("-a", "--append",
141 | nargs="*",
142 | help="Specify characters or words to add to end of the word, separated by spaces. (-a ! !! !!! !@#$")
143 | parser.add_argument("-p", "--prepend",
144 | nargs="*",
145 | help="Specify characters or words to add to the beginning of the word, separated by spaces. (-p ! !! !!! !@#$")
146 | args = parser.parse_args()
147 |
148 | appensions = args.append if args.append else None
149 | prepensions = args.prepend if args.prepend else None
150 | outfilename = args.outfile if args.outfile else "5UP3R_1337.rule"
151 |
152 | main()
153 |
--------------------------------------------------------------------------------
/mask_finder.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180914'
6 | __version__ = '0.02'
7 | __description__ = """Reads in a plain-text password lists to find the frequency
8 | of password character masks. Will display all character masks found"""
9 |
10 |
11 | import argparse
12 | import string
13 | import os
14 | from collections import Counter
15 |
16 |
17 | def generate_char_mask(word):
18 | """Analyzes the characters of a word and generates a mask per character.
19 | Returns the mask of a word as a string."""
20 | mask = ''
21 | for char in word:
22 | try:
23 | if char in string.uppercase:
24 | mask += '?u'
25 | elif char in string.lowercase:
26 | mask += '?l'
27 | elif char in string.digits:
28 | mask += '?d'
29 | elif char in string.punctuation or char == ' ':
30 | mask += '?s'
31 | else:
32 | if args.verbose:
33 | print('Encountered an non-standard character: {}. It will appear in a mask as ?X '.format(char))
34 | mask += '?X'
35 | except AttributeError:
36 | if char in string.ascii_uppercase:
37 | mask += '?u'
38 | elif char in string.ascii_lowercase:
39 | mask += '?l'
40 | elif char in string.digits:
41 | mask += '?d'
42 | elif char in string.punctuation or char == ' ':
43 | mask += '?s'
44 | else:
45 | if args.verbose:
46 | print('Encountered an non-standard character: {}. It will appear in a mask as ?X '.format(char))
47 | mask += '?X'
48 | return mask
49 |
50 |
51 | def sort_char_masks(mask_list):
52 | """Returns a listed tuple of a character masks, where the mask is the first ([0]) element
53 | and the number of times the mask occurs is the second element ([1]). For example:
54 | [('?l?l?l?l?l', 4)]
55 | """
56 | mask_dict = dict(Counter(mask_list))
57 | sorted_counted_mask = [(k, mask_dict[k]) for k in sorted(mask_dict, key=mask_dict.get, reverse=True)]
58 | return sorted_counted_mask
59 |
60 |
61 | def arrange_words_by_length(list_of_words):
62 | """Takes a list of words and returns a list of multiple lists
63 | arranged by the word length.
64 | """
65 | list_of_words.sort(key=len)
66 | return list_of_words
67 |
68 |
69 | def sort_dict_by_key_len(dict_obj):
70 | """Takes a dictionary and returns a list of tuples sorted by the length of
71 | the dictionary's keys.
72 | """
73 | return [(k, dict_obj[k]) for k in sorted(dict_obj, key=len)]
74 |
75 |
76 | def sort_tuple_list_by_two_elements(tuple_list):
77 | """sorts a list of tuples that contain two values, first by the first value,
78 | then by the second value. The -x[1] sorts in reverse.
79 | #https://stackoverflow.com/questions/14466068/sort-a-list-of-tuples-by-second-value-reverse-true-and-then-by-key-reverse-fal
80 | """
81 | return sorted(tuple_list, key=lambda x: (len(x[0]), -x[1]))
82 |
83 |
84 | def main():
85 | """Reads in a plain-text password lists to find the frequency
86 | of password character masks. Will display all character masks found.
87 | """
88 | # Initialize variable to hold a list of all sorted mask dictionaries for a file
89 | file_mask_list = []
90 | for filename in args.filename:
91 | print("[*] Processing {}".format(filename))
92 | # Read the file into memory.
93 | words = open(filename, encoding="utf8", errors='ignore').read().splitlines()
94 |
95 | # Initialize a list per file to store lists of words sorted by length.
96 | file_word_list = []
97 | sorted_word_list = []
98 |
99 | # Generate the masks for each word and sort them by count.
100 | masks = [generate_char_mask(word) for word in words]
101 | sorted_masks = sort_char_masks(masks)
102 |
103 | # Add masks to he list for all files
104 | file_mask_list.append(sorted_masks)
105 |
106 | # Converts tuples to a dictionary to combine values of the same mask
107 | # across the different input files
108 | file_mask_list = [dict(l) for l in file_mask_list]
109 |
110 | # Gets all the unique masks from the input files
111 | mask_keys = []
112 | for mask_dictionary in file_mask_list:
113 | dict_keys = list(mask_dictionary.keys())
114 | for k in dict_keys:
115 | mask_keys.append(k)
116 | mask_keys = list(set(mask_keys))
117 |
118 | # Adds the number of occurences of mask from each input file
119 | # by combining dictionary values of the same key
120 | results = {}
121 | for k in mask_keys:
122 | sums = []
123 | for item in file_mask_list:
124 | if item.get(k):
125 | sums.append(item.get(k))
126 | results[k] = sum(sums)
127 |
128 | # Sorts the result by mask length, converting it to a list of tuples
129 | sorted_results = sort_dict_by_key_len(results)
130 |
131 | # Sorts the tuples first by length, then by value
132 | sorted_results = sort_tuple_list_by_two_elements(sorted_results)
133 |
134 | # Output to terminal and file.
135 | if args.outfile:
136 |
137 | # Opens the outfile.
138 | with open(args.outfile, 'a') as outfile:
139 |
140 | # Records the files processed.
141 | outfile.write('Processed files:\n')
142 | for f in args.filename:
143 | outfile.write(f + '\n')
144 |
145 | # Stores the starting word length to control printing word length.
146 | # Length is divided by 2 because the masks are measured, so they
147 | # include ? before each character.
148 | word_length = int(len(sorted_results[0][0]) / 2)
149 |
150 | print("\n[+] Mask for {} letter words".format(word_length))
151 | outfile.write("\n[+] Mask for {} letter words\n".format(word_length))
152 |
153 | # Iterates through the results, checking the mask length to control
154 | # the printed output
155 | for k, v in sorted_results:
156 | new_word_length = int(len(k) / 2)
157 | if new_word_length != word_length:
158 | print("\n[+] Mask for {} letter words".format(new_word_length))
159 | outfile.write("\n[+] Mask for {} letter words\n".format(new_word_length))
160 | word_length = new_word_length
161 | if args.charset:
162 | if all(char in k for char in args.charset.lower()):
163 | print("{} : {}".format(k, v))
164 | outfile.write("{} : {}\n".format(k, v))
165 | else:
166 | print("{} : {}".format(k, v))
167 | outfile.write("{} : {}\n".format(k, v))
168 | else:
169 | word_length = int(len(sorted_results[0][0]) / 2)
170 | print("\n[+] Mask for {} letter words".format(word_length))
171 | for k, v in sorted_results:
172 | new_word_length = int(len(k) / 2)
173 | if new_word_length != word_length:
174 | print("\n[+] Mask for {} letter words".format(new_word_length))
175 | word_length = new_word_length
176 | if args.charset:
177 | if all(char in k for char in args.charset.lower()):
178 | print("{} : {}".format(k, v))
179 | else:
180 | print("{} : {}".format(k, v))
181 |
182 |
183 | if __name__ == '__main__':
184 | parser = argparse.ArgumentParser()
185 | parser.add_argument("-v", "--verbose",
186 | action='store_true',
187 | help="Increase output verbosity.")
188 | parser.add_argument("-f", "--filename",
189 | nargs='*',
190 | help="Specify a file containing plain text passwords.")
191 | parser.add_argument("-o", "--outfile",
192 | help="Writes the output to a file, masks.txt, in the current directory.")
193 | parser.add_argument("-c", "--charset",
194 | help="Specify the charset that must be present in mask for. Example -c ?d?u?l")
195 | args = parser.parse_args()
196 |
197 | if not args.filename:
198 | parser.print_help()
199 | print("\n[-] Please specify one or more password files to analyze. For multiple input files, separate with a space.\n")
200 | exit()
201 | for filename in args.filename:
202 | if not os.path.exists(filename):
203 | parser.print_help()
204 | print("\n[-] The file {}, does not exist or you lack permissions to open it. Please try again.\n".format(filename))
205 | exit()
206 |
207 | main()
--------------------------------------------------------------------------------
/md5_hashgen.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180921'
6 | __version__ = '0.01'
7 | __description__ = """Reads a plain text file and hashes each line. The hashes are written
8 | to a new file. The purpose of this tool is to generate sample hashes for testing password
9 | cracking."""
10 |
11 |
12 | import hashlib
13 | import sys
14 |
15 | def md5(string):
16 | """Returns a md5 hash of the supplied parameter"""
17 | return hashlib.md5(string.encode()).hexdigest()
18 |
19 | def main():
20 | hashes = [md5(word) for word in words]
21 | with open(outfile, 'w', encoding="utf8", errors='ignore') as fh:
22 | for hash in hashes:
23 | print(hash)
24 | fh.write(hash + '\n')
25 |
26 | if __name__ == '__main__':
27 | if len(sys.argv) != 3:
28 | print("\n[*] Usage: python3 {} \n".format(sys.argv[0]))
29 | exit()
30 | filename = sys.argv[1]
31 | outfile = sys.argv[2]
32 | with open(filename, encoding="utf8", errors='ignore') as fh:
33 | words = fh.read().splitlines()
34 | main()
--------------------------------------------------------------------------------
/phrase_cleaner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190102'
5 | __version__ = '0.01'
6 | __description__ = """Combines files containing phrases. Converts lines to lowercase and removes punctuation except spaces."""
7 |
8 | import argparse
9 | import os
10 | import string
11 |
12 | def main():
13 | all_lines = []
14 | for filename in files:
15 | print('[*] Reading file: {}...'.format(filename))
16 | with open(filename, encoding="utf8", errors='ignore') as fh:
17 | lines = fh.read().splitlines()
18 | print('[*] Processing {} lines...'.format(len(lines)))
19 | for line in lines:
20 | line = line.lower()
21 |
22 | # Remove punctuation except spaces
23 | # https://stackoverflow.com/questions/34293875/how-to-remove-punctuation-marks-from-a-string-in-python-3-x-using-translate
24 | translator = str.maketrans('', '', string.punctuation)
25 | line = line.translate(translator)
26 |
27 | all_lines.append(line)
28 |
29 | if args.outfile:
30 | print('[*] Writing to {}...'.format(args.outfile))
31 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
32 | for line in all_lines:
33 | fh.write(line + '\n')
34 | else:
35 | for line in all_lines:
36 | print(line)
37 |
38 | if __name__ == '__main__':
39 | parser = argparse.ArgumentParser()
40 | parser.add_argument("-f", "--filename",
41 | nargs='*',
42 | help="Specify a file containing phrases.")
43 | parser.add_argument("-o", "--outfile",
44 | help="Writes the output to a specified file.")
45 | args = parser.parse_args()
46 | if not args.filename:
47 | parser.print_help()
48 | print("\n[-] Please specify an input file containing words (-f).\n")
49 | exit()
50 | else:
51 | files = args.filename
52 | for filename in files:
53 | if not os.path.exists(filename):
54 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(filename))
55 | exit()
56 | main()
--------------------------------------------------------------------------------
/phrase_combiner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190102'
5 | __version__ = '0.01'
6 | __description__ = """Combines files containing phrases. Can capitalize, manipulate the phrases, etc."""
7 |
8 | import argparse
9 | import os
10 |
11 | def main():
12 | all_lines = []
13 | for filename in files:
14 | print('[*] Reading file: {}...'.format(filename))
15 | with open(filename, encoding="utf8", errors='ignore') as fh:
16 | lines = fh.read().splitlines()
17 | print('[*] Processing {} lines...'.format(len(lines)))
18 | for line in lines:
19 | line = line.strip('.')
20 | line = line.strip(',')
21 | line = line.strip('\'')
22 | words = line.split(' ')
23 | base_words = [word.lower() for word in words]
24 |
25 | all_lines.append(''.join(base_words))
26 | all_lines.append(' '.join(base_words))
27 | all_lines.append('-'.join(base_words))
28 | all_lines.append('_'.join(base_words))
29 |
30 | words = [word.title() for word in base_words]
31 | all_lines.append(''.join(words))
32 | all_lines.append(' '.join(words))
33 | all_lines.append('-'.join(words))
34 | all_lines.append('_'.join(words))
35 |
36 | words = [word for word in base_words]
37 | all_lines.append(''.join(words).title())
38 | all_lines.append(' '.join(words).title())
39 | all_lines.append('-'.join(words).title())
40 | all_lines.append('_'.join(words).title())
41 |
42 | if args.outfile:
43 | print('[*] Writing to {}...'.format(args.outfile))
44 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
45 | for line in all_lines:
46 | fh.write(line + '\n')
47 | else:
48 | for line in all_lines:
49 | print(line)
50 |
51 | if __name__ == '__main__':
52 | parser = argparse.ArgumentParser()
53 | parser.add_argument("-f", "--filename",
54 | nargs='*',
55 | help="Specify a file containing phrases.")
56 | parser.add_argument("-o", "--outfile",
57 | help="Writes the output to a specified file.")
58 | args = parser.parse_args()
59 | if not args.filename:
60 | parser.print_help()
61 | print("\n[-] Please specify an input file containing words (-f).\n")
62 | exit()
63 | else:
64 | files = args.filename
65 | for filename in files:
66 | if not os.path.exists(filename):
67 | print("\n[-] The file {} cannot be found or you do not have permission to open the file. Please check the path and try again\n".format(filename))
68 | exit()
69 | main()
--------------------------------------------------------------------------------
/positional_character_frequency.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180914'
6 | __version__ = '0.02'
7 | __description__ = """Analyzes a password list to find frequency of characters per position."""
8 |
9 |
10 | import argparse
11 | import os
12 | import string
13 | import itertools
14 |
15 |
16 | def get_freq(word):
17 | """docstring
18 | #https://stackoverflow.com/questions/43693018/python-position-frequency-dictionary-of-letters-in-words
19 | """
20 | l = len(word) - word.count(None)
21 | return {n: word.count(n)/l for n in charset}
22 |
23 |
24 | def arrange_words_by_length(list_of_words):
25 | """Takes a list of words and returns a list arranged by the word length."""
26 | list_of_words.sort(key=len)
27 | return list_of_words
28 |
29 |
30 | def sort_frequency_list(frequency_dict):
31 | """Returns a listed tuple of a frequencies, sorted by the key that occurs
32 | most.
33 | """
34 | sorted_frequencies = [(k, frequency_dict[k]) for k in sorted(frequency_dict, key=frequency_dict.get, reverse=True)]
35 | return sorted_frequencies
36 |
37 | def group_words_by_length(word_list):
38 | d={}
39 | for word in word_list:
40 | d.setdefault(len(word), []).append(word)
41 | return [d[n] for n in sorted(d)]
42 |
43 |
44 | def main():
45 | for filename in args.filename:
46 | wordlist = open(filename, encoding="utf8", errors='ignore').read().splitlines()
47 | grouped_words = group_words_by_length(wordlist)
48 | for words in grouped_words:
49 | print("\n[*] {} letter words - Total words: {}\n".format(len(words[0]), len(words)))
50 | frequency_list = [get_freq(word) for word in itertools.zip_longest(*words)]
51 | pos_counter = 1
52 | for item in frequency_list:
53 | sorted_freq = sort_frequency_list(item)
54 | print('[*] Character position {}'.format(pos_counter))
55 | for k, v in sorted_freq:
56 | if v:
57 | print(k,v)
58 | pos_counter += 1
59 |
60 |
61 | if __name__ == '__main__':
62 | parser = argparse.ArgumentParser()
63 | parser.add_argument("-v", "--verbose",
64 | action='store_true',
65 | help="Increase output verbosity.")
66 | parser.add_argument("-f", "--filename",
67 | nargs='*',
68 | help="Specify a file containing plain text passwords.")
69 | parser.add_argument("-o", "--outfile",
70 | help="Writes the output to a specified file in the current directory.")
71 | args = parser.parse_args()
72 |
73 | if not args.filename:
74 | parser.print_help()
75 | print("\n[-] Please specify one or more password files to analyze. For multiple input files, separate with a space.\n")
76 | exit()
77 | for filename in args.filename:
78 | if not os.path.exists(filename):
79 | parser.print_help()
80 | print("\n[-] The file {}, does not exist or you lack permissions to open it. Please try again.\n".format(filename))
81 | exit()
82 | charset = string.ascii_letters + string.digits + string.punctuation + ' '
83 | main()
--------------------------------------------------------------------------------
/pot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)...Written for Adam'
4 | __date__ = '20180921'
5 | __version__ = '0.01'
6 | __description__ = """Extracts the plain passwords from a hashcat or jtr pot file. Cleans them if specified."""
7 |
8 | import argparse
9 | import re
10 |
11 | def clean_words(words):
12 | """Passes a wordlist through a series of functions to generate
13 | a rule file.
14 | """
15 | print("[*] Processing {} words.".format(len(words)))
16 | print("[*] Changing all words to lowercase...")
17 | words = [word.lower() for word in words]
18 | print("[*] Removing numbers and special characters...")
19 | words = [re.sub(r'[^a-z]+', '', word) for word in words]
20 | print("[*] Removing duplicate words...")
21 | words = list(set(words))
22 | return words
23 |
24 | def decode_hashcat_hexstring(hexstring):
25 | """Parses a hex encoded password string ($HEX[476f6f646669676874343a37])
26 | and returns the decodes the hex.
27 | """
28 | index_1 = hexstring.index("[")+1
29 | index_2 = len(hexstring)-1
30 | hexdata = hexstring[index_1:index_2]
31 | return bytes.fromhex(hexdata).decode()
32 |
33 | def decode_hashcat_hex(data):
34 | """Calls the decoded_hashcat_hexstring on an encoded hex represented password
35 | ($HEX[476f6f646669676874343a37]). Occasionally the string will be encoded
36 | multiple times, so a loop is used until the $HEX prefix no longer remains.
37 | Returns the decodes the hexstring.
38 | """
39 | while data.startswith('$HEX['):
40 | data = decode_hashcat_hexstring(data)
41 | return data
42 |
43 | def main():
44 |
45 | # Reads in the potfile
46 | with open(potfile) as fh:
47 | lines = fh.read().splitlines()
48 | try:
49 | # Both JTR and Hashcat potfiles are colon delimited. In JTR pot files,
50 | # a colon in the password will mess up the split, so it must be split
51 | # from the first colon until the end of line.
52 | pt_passwords = [line.split(':')[1:] for line in lines]
53 | fixed_passwords = []
54 | for line in pt_passwords:
55 | if len(line) > 1:
56 | fixed_passwords.append(':'.join(line))
57 | else:
58 | fixed_passwords.append(''.join(line))
59 | except IndexError as e:
60 | print('Error detected:')
61 | print(e)
62 | passwords = []
63 | for password in fixed_passwords:
64 |
65 | # Hashcat will encode passwords containing colons or non-ascii characters.
66 | # This will decode those passwords if they are there.
67 | if password.startswith('$HEX['):
68 | passwords.append(decode_hashcat_hex(password))
69 | else:
70 | passwords.append(password)
71 |
72 | if args.clean:
73 | passwords = clean_words(passwords)
74 |
75 | # Output to file or print to terminal
76 | if args.outfile:
77 | with open(args.outfile, 'w') as fh:
78 | for password in passwords:
79 | fh.write(password + '\n')
80 | else:
81 | for password in passwords:
82 | print(password)
83 |
84 | if __name__ == '__main__':
85 | parser = argparse.ArgumentParser()
86 | parser.add_argument('-f', '--filename')
87 | parser.add_argument('-o', '--outfile')
88 | parser.add_argument('-c', '--clean',
89 | action="store_true")
90 | args = parser.parse_args()
91 | if not args.filename:
92 | parser.print_help()
93 | print("\n[-] Please specify the filename of the potfile\n")
94 | exit()
95 | else:
96 | potfile = args.filename
97 | main()
--------------------------------------------------------------------------------
/quote_parser_001.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190102'
5 | __version__ = '0.01'
6 | __description__ = """Retrieves data listed at https://gist.githubusercontent.com/signed0/d70780518341e1396e11/raw/2a7f4af8d181a714f9d49105ed57fafb3f450960/quotes.json,
7 | parses, and writes to a file."""
8 |
9 | import requests
10 | import ast
11 |
12 | url = "https://gist.githubusercontent.com/signed0/d70780518341e1396e11/raw/2a7f4af8d181a714f9d49105ed57fafb3f450960/quotes.json"
13 | contents = requests.get(url).text.split('\n')
14 |
15 | lines = []
16 | for line in contents:
17 | try:
18 | line = ast.literal_eval(line)
19 | except SyntaxError:
20 | input(line)
21 | continue
22 | lines.append(line[0])
23 |
24 | with open('short_quotes.txt', 'a') as fh:
25 | s_lines = [l for l in lines if len(l) < 33]
26 | for line in s_lines:
27 | print(line.lower())
28 | fh.write(line.lower() + '\n')
29 |
30 | print('[*] File written to short_quotes.txt!')
31 |
32 | with open('medium_quotes.txt', 'a') as fh:
33 | m_lines = [l for l in lines if len(l) > 32 and len(l) < 128]
34 | for line in m_lines:
35 | print(line.lower())
36 | fh.write(line.lower() + '\n')
37 |
38 | print('[*] File written to medium_quotes.txt!')
39 |
40 | with open('long_quotes.txt', 'a') as fh:
41 | l_lines = [l for l in lines if len(l) < 127]
42 | for line in l_lines:
43 | print(line.lower())
44 | fh.write(line.lower() + '\n')
45 |
46 | print('[*] File written to long_quotes.txt!')
--------------------------------------------------------------------------------
/quote_parser_002.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190102'
5 | __version__ = '0.01'
6 | __description__ = """Retrieves words listed at https://raw.githubusercontent.com/alvations/Quotables/master/author-quote.txt,
7 | parses, and writes to three files."""
8 |
9 | import requests
10 |
11 | url = "https://raw.githubusercontent.com/alvations/Quotables/master/author-quote.txt"
12 | contents = requests.get(url).text.split('\n')
13 |
14 | lines = []
15 | for line in contents:
16 | try:
17 | lines.append(line.split('\t')[1])
18 | except IndexError:
19 | continue
20 |
21 |
22 | with open('short_quotes.txt', 'a') as fh:
23 | s_lines = [l for l in lines if len(l) < 33]
24 | for line in s_lines:
25 | print(line.lower())
26 | fh.write(line.lower() + '\n')
27 |
28 | print('[*] File written to short_quotes.txt!')
29 |
30 | with open('medium_quotes.txt', 'a') as fh:
31 | m_lines = [l for l in lines if len(l) > 32 and len(l) < 128]
32 | for line in m_lines:
33 | print(line.lower())
34 | fh.write(line.lower() + '\n')
35 |
36 | print('[*] File written to medium_quotes.txt!')
37 |
38 | with open('long_quotes.txt', 'a') as fh:
39 | l_lines = [l for l in lines if len(l) < 127]
40 | for line in l_lines:
41 | print(line.lower())
42 | fh.write(line.lower() + '\n')
43 |
44 | print('[*] File written to long_quotes.txt!')
45 |
--------------------------------------------------------------------------------
/quote_parser_003.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | __author__ = 'Jake Miller (@LaconicWolf)'
4 | __date__ = '20190102'
5 | __version__ = '0.01'
6 | __description__ = """Retrieves words listed at https://www.phrases.org.uk/meanings/phrases-and-sayings-list.html,
7 | parses, and writes to a file."""
8 |
9 | import requests
10 | import re
11 |
12 | url = "https://www.phrases.org.uk/meanings/phrases-and-sayings-list.html"
13 | contents = requests.get(url).text
14 |
15 | lines = re.findall(r'(.*?)
', contents)
16 |
17 | with open('phrases_and_sayings.txt', 'w') as fh:
18 | for line in lines:
19 | print(line.lower())
20 | fh.write(line.lower() + '\n')
21 |
22 | print('[*] File written to phrases_and_sayings.txt!')
--------------------------------------------------------------------------------
/remove_duplicates.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180921'
6 | __version__ = '0.01'
7 | __description__ = """Reads a file, removes duplicate lines, and writes to a new file."""
8 |
9 |
10 | import argparse
11 |
12 |
13 | def main():
14 | print('[*] Reading file: {}'.format(filename))
15 | with open(filename, encoding="utf8", errors='ignore') as fh:
16 | lines = fh.read().splitlines()
17 | print("[*] Processing {} words.".format(len(lines)))
18 | print('[*] Removing duplicate words...')
19 | unique_lines = list(set(lines))
20 | if args.outfile:
21 | print('[*] Writing to file: {}'.format(args.outfile))
22 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
23 | for line in unique_lines:
24 | fh.write(line + '\n')
25 | else:
26 | for line in unique_lines:
27 | print(line)
28 |
29 | if __name__ == '__main__':
30 | parser = argparse.ArgumentParser()
31 | parser.add_argument('-f', '--filename')
32 | parser.add_argument('-o', '--outfile')
33 | args = parser.parse_args()
34 | if not args.filename:
35 | parser.print_help()
36 | print("\n[-] Please specify the filename of the wordlist.\n")
37 | exit()
38 | else:
39 | filename = args.filename
40 | main()
--------------------------------------------------------------------------------
/seclist_password_combiner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180921'
6 | __version__ = '0.01'
7 | __description__ = """Combines, sorts, and uniques the passwords contained in files located at
8 | https://github.com/danielmiessler/SecLists."""
9 |
10 |
11 | import argparse
12 | import os
13 |
14 |
15 | def main():
16 | combined = []
17 | for root, dirnames, filenames in os.walk(root_dir):
18 | for filename in filenames:
19 | filepath = os.path.join(root, filename)
20 | if filepath.endswith('.txt') or filepath.endswith('.csv'):
21 | print("[*] Processing file: {}".format(filepath))
22 | with open(filepath, encoding="utf8", errors='ignore') as fh:
23 | contents = fh.read().splitlines()
24 |
25 | # This dir includes files containing username and password combos
26 | # delimited usually by a colon, but some are csv files.
27 | if os.sep + "Default-Credentials" in filepath:
28 | if filepath.endswith('csv'):
29 |
30 | # Annoying to parse so I'm not doing it.
31 | if 'scada-pass.csv' in filepath:
32 | pass
33 | # This one is easier to parse.
34 | if 'default-passwords.csv' in filepath:
35 | passwords = [line.split(',')[2] for line in contents if line.split(',')[2] != ""]
36 | else:
37 | try:
38 | passwords = [line.split(':')[1] for line in contents]
39 | except IndexError:
40 | passwords = contents
41 | combined += passwords
42 | else:
43 | combined += contents
44 | print("[*] Sorting list and removing duplicates words...")
45 | combined.sort()
46 | unique_combined = list(set(combined))
47 |
48 | if args.outfile:
49 | print("[*] Writing to {}...".format(args.outfile))
50 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
51 | for word in unique_combined:
52 | fh.write(word + '\n')
53 | else:
54 | for word in unique_combined:
55 | print(word)
56 |
57 | if __name__ == '__main__':
58 | parser = argparse.ArgumentParser()
59 | parser.add_argument("-d", "--directory",
60 | nargs='?',
61 | const='.',
62 | help="Specify the directory. You'll want to run this in the Passwords folder.")
63 | parser.add_argument("-o", "--outfile",
64 | help="Writes the output to a specified file.")
65 | args = parser.parse_args()
66 |
67 | if args.directory:
68 | root_dir = args.directory
69 | else:
70 | root_dir = '.'
71 | main()
--------------------------------------------------------------------------------
/wordlist_cleaner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180924'
6 | __version__ = '0.01'
7 | __description__ = """Removes case, digits, and special characters for a wordlist
8 | and uniques it."""
9 |
10 | import argparse
11 | import re
12 | import os
13 |
14 |
15 | def main():
16 | """Passes a wordlist through a series of functions to generate
17 | a rule file.
18 | """
19 | global words
20 | print("[*] Processing {} words.".format(len(words)))
21 | print("[*] Changing all words to lowercase...")
22 | words = [word.lower() for word in words]
23 | print("[*] Removing numbers and special characters...")
24 | words = [re.sub(r'[^a-z]+', '', word) for word in words]
25 | print("[*] Removing duplicate words...")
26 | words = list(set(words))
27 | print("[*] Printing cleaned words to {}".format(outfile))
28 | with open(outfile, 'w') as fh:
29 | for word in words:
30 | fh.write(word + '\n')
31 |
32 |
33 | if __name__ == '__main__':
34 | parser = argparse.ArgumentParser()
35 | parser.add_argument("-f", "--file",
36 | help="Specify a file containing words.")
37 | parser.add_argument("-o", '--outfile',
38 | help="Writes the words to a specified outfile name")
39 | args = parser.parse_args()
40 |
41 | if not args.file and not args.outfile:
42 | parser.print_help()
43 | print("\n[-] Please specify an input file containing words (-f) and the name of an output file to write to (-o out.txt).\n")
44 | exit()
45 | else:
46 | file = args.file
47 | outfile = args.outfile
48 | if not os.path.exists(file):
49 | print("\n[-] The file cannot be found or you do not have permission to open the file. Please check the path and try again\n")
50 | exit()
51 | print('[*] Reading file: {}'.format(file))
52 | with open(file, encoding="utf8", errors='ignore') as fh:
53 | words = fh.read().splitlines()
54 |
55 | main()
--------------------------------------------------------------------------------
/wordlist_searcher.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | __author__ = 'Jake Miller (@LaconicWolf)'
5 | __date__ = '20180921'
6 | __version__ = '0.01'
7 | __description__ = """Searches for specified words in a dictionary."""
8 |
9 |
10 | import argparse
11 | import os
12 |
13 |
14 | def main():
15 | global words
16 | dict_words = {}
17 | print('[*] Reading dictionary file: {}'.format(filename))
18 | dict_file = open(filename, encoding="utf8", errors='ignore')
19 | for line in dict_file.read().split('\n'):
20 | dict_words[line] = True
21 | dict_file.close()
22 | print('[*] Searching...')
23 | words = [word for word in words]
24 | unique_words = []
25 | for word in words:
26 | if not dict_words.get(word):
27 | unique_words.append(word)
28 | if unique_words:
29 | if args.outfile:
30 | print("[*] Writing words that do not appear in {} to {}...".format(filename, args.outfile))
31 | with open(args.outfile, 'w', encoding="utf8", errors='ignore') as fh:
32 | for word in unique_words:
33 | fh.write(word + '\n')
34 | else:
35 | for word in unique_words:
36 | print("[*] {} does not appear in {}".format(word, filename))
37 | else:
38 | print("[*] All words from {} appeared in {}".format(args.wordlist, filename))
39 |
40 |
41 | if __name__ == '__main__':
42 | parser = argparse.ArgumentParser()
43 | parser.add_argument('-d', '--dictionary',
44 | help="Specify the dictionary you would like to search in.")
45 | parser.add_argument('-w', '--word',
46 | nargs="*",
47 | help="Specify the word or words you'd like to search for.")
48 | parser.add_argument('-wl', '--wordlist',
49 | help="Specify the filename containing the list of words you'd like to search for.")
50 | parser.add_argument("-o", "--outfile",
51 | help="Writes the output to a specified file.")
52 | args = parser.parse_args()
53 | if not args.dictionary:
54 | parser.print_help()
55 | print("\n[-] Please specify the filename of the dictionary you would like to search in.\n")
56 | exit()
57 | else:
58 | filename = args.dictionary
59 | if not args.word and not args.wordlist:
60 | parser.print_help()
61 | print("\n[-] Please specify a word you would like to search for (-w) or specify a filename containing a list of words you'd like to search for (-wl).\n")
62 | exit()
63 | if args.word and args.wordlist:
64 | parser.print_help()
65 | print("\n[-] Please specify a word (-w) or specify a filename containing a list of words (-wl). Not both.\n")
66 | exit()
67 | if args.word:
68 | words = args.word
69 | if args.wordlist:
70 | if not os.path.exists(args.wordlist):
71 | print("\n[-] The file cannot be found or you do not have permission to open the file. Please check the path and try again\n")
72 | exit()
73 | with open(args.wordlist, encoding="utf8", errors='ignore') as fh:
74 | words = fh.read().splitlines()
75 | main()
76 |
--------------------------------------------------------------------------------