forked from funkandwagnalls/pythonpentest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
username_generator.py
200 lines (177 loc) · 8.64 KB
/
username_generator.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
#!/usr/bin/env python
'''
Author: Christopher S. Duffy
Date: March 2015
Name: username_generator.py
Purpose: To generate a username list from the US Census Top 1000 surnames and other lists
Copyright (c) 2015, Christopher Duffy All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: * Redistributions
of source code must retain the above copyright notice, this list of conditions and
the following disclaimer. * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. * Neither the
name of the nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL CHRISTOPHER DUFFY BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
import sys
from collections import namedtuple
import string
import argparse
import os
try:
import xlrd
except:
sys.exit("[!] Please install the xlrd library: pip install xlrd")
def unique_list(list_sort, verbose):
noted = []
if verbose > 0:
print("[*] Removing duplicates while maintaining order")
[noted.append(item) for item in list_sort if not noted.count(item)] # List comprehension
return noted
def census_parser(filename, verbose):
# Create the named tuple
CensusTuple = namedtuple('Census', 'name, rank, count, prop100k, cum_prop100k, pctwhite, pctblack, pctapi, pctaian, pct2prace, pcthispanic')
# Define the location of the file and worksheet till arguments are developed
worksheet_name = "top1000"
#Define work book and work sheet variables
workbook = xlrd.open_workbook(filename)
spreadsheet = workbook.sheet_by_name(worksheet_name)
total_rows = spreadsheet.nrows - 1
current_row = -1
# Define holder for details
username_dict = {}
surname_dict = {}
alphabet = list(string.ascii_lowercase)
while current_row < total_rows:
row = spreadsheet.row(current_row)
current_row += 1
entry = CensusTuple(*tuple(row)) #Passing the values of the row as a tuple into the namedtuple
surname_dict[entry.rank] = entry
cellname = entry.name
cellrank = entry.rank
for letter in alphabet:
if "." not in str(cellrank.value):
if verbose > 1:
print("[-] Eliminating table headers")
break
username = letter + str(cellname.value.lower())
rank = str(cellrank.value)
username_dict[username] = rank
username_list = sorted(username_dict, key=lambda key: username_dict[key])
return(surname_dict, username_dict, username_list)
def username_file_parser(prepend_file, append_file, verbose):
if prepend_file:
put_where = "begin"
filename = prepend_file
elif append_file:
put_where = "end"
filename = append_file
else:
sys.exit("[!] There was an error in processing the supplemental username list!")
with open(filename) as file:
lines = [line.rstrip('\n') for line in file]
if verbose > 1:
if "end" in put_where:
print("[*] Appending %d entries to the username list") % (len(lines))
else:
print("[*] Prepending %d entries to the username list") % (len(lines))
return(lines, put_where)
def combine_usernames(supplemental_list, put_where, username_list, verbose):
if "begin" in put_where:
username_list[:0] = supplemental_list #Prepend with a slice
if "end" in put_where:
username_list.extend(supplemental_list)
username_list = unique_list(username_list, verbose)
return(username_list)
def write_username_file(username_list, filename, domain, verbose):
open(filename, 'w').close() #Delete contents of file name
if domain:
domain_filename = filename + "_" + domain
email_list = []
open(domain_filename, 'w').close()
if verbose > 1:
print("[*] Writing to %s") % (filename)
with open(filename, 'w') as file:
file.write('\n'.join(username_list))
if domain:
if verbose > 1:
print("[*] Writing domain supported list to %s") % (domain_filename)
for line in username_list:
email_address = line + "@" + domain
email_list.append(email_address)
with open(domain_filename, 'w') as file:
file.write('\n'.join(email_list))
return
if __name__ == '__main__':
# If script is executed at the CLI
usage = '''usage: %(prog)s [-c census.xlsx] [-f output_filename] [-a append_filename] [-p prepend_filename] [-d domain_name] -q -v -vv -vvv'''
parser = argparse.ArgumentParser(usage=usage)
parser.add_argument("-c", "--census", type=str, help="The census file that will be used to create usernames, this can be retrieved like so:\n wget http://www2.census.gov/topics/genealogy/2000surnames/Top1000.xls", action="store", dest="census_file")
parser.add_argument("-f", "--filename", type=str, help="Filename for output the usernames", action="store", dest="filename")
parser.add_argument("-a","--append", type=str, action="store", help="A username list to append to the list generated from the census", dest="append_file")
parser.add_argument("-p","--prepend", type=str, action="store", help="A username list to prepend to the list generated from the census", dest="prepend_file")
parser.add_argument("-d","--domain", type=str, action="store", help="The domain to append to usernames", dest="domain_name")
parser.add_argument("-v", action="count", dest="verbose", default=1, help="Verbosity level, defaults to one, this outputs each command and result")
parser.add_argument("-q", action="store_const", dest="verbose", const=0, help="Sets the results to be quiet")
parser.add_argument('--version', action='version', version='%(prog)s 0.42b')
args = parser.parse_args()
# Set Constructors
census_file = args.census_file # Census
filename = args.filename # Filename for outputs
verbose = args.verbose # Verbosity level
append_file = args.append_file # Filename for the appending usernames to the output file
prepend_file = args.prepend_file # Filename to prepend to the usernames to the output file
domain_name = args.domain_name # The name of the domain to be appended to the username list
dir = os.getcwd() # Get current working directory
# Argument Validator
if len(sys.argv)==1:
parser.print_help()
sys.exit(1)
if append_file and prepend_file:
sys.exit("[!] Please select either prepend or append for a file not both")
if not filename:
if os.name != "nt":
filename = dir + "/census_username_list"
else:
filename = dir + "\\census_username_list"
else:
if filename:
if "\\" or "/" in filename:
if verbose > 1:
print("[*] Using filename: %s") % (filename)
else:
if os.name != "nt":
filename = dir + "/" + filename
else:
filename = dir + "\\" + filename
if verbose > 1:
print("[*] Using filename: %s") % (filename)
# Define working variables
sur_dict = {}
user_dict = {}
user_list = []
sup_username = []
target = []
combined_users = []
# Process census file
if not census_file:
sys.exit("[!] You did not provide a census file!")
else:
sur_dict, user_dict, user_list = census_parser(census_file, verbose)
# Process supplemental username file
if append_file or prepend_file:
sup_username, target = username_file_parser(prepend_file, append_file, verbose)
combined_users = combine_usernames(sup_username, target, user_list, verbose)
else:
combined_users = user_list
write_username_file(combined_users, filename, domain_name, verbose)