├── LICENSE ├── README.md └── wordlistgen.py /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, frizb 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WordListGen 2 | Super Simple Python Word List Generator for Password Cracking (Hashcat)! 3 | 4 | I know what your are thinking. Why create another word list generator? Well, I needed something very simple I could modify on the fly to get the exact character generators for the task at hand. This script is fully functional in its own right, but intended to be modified during CTF's or pen testing engagements easily *on the fly*. 5 | 6 | ## Python help documentation: 7 | ``` 8 | > wordlistgen.py -h 9 | WordListGen: 0.2 Updated: June 2, 2019 10 | usage: wordlistgen.py [-h] [-all] [-lower] [-upper] [-leet] [-swap] [-ntlm] 11 | [-baseword] [-capitalize] [-orig] [-min MIN] [-max MAX] 12 | [-inputfolder file] [-input file] [-output file] 13 | 14 | WordListGen - Very Simple Word List Morpher - Creates a list of unique 15 | words for fuzzing / brute forcing 16 | 17 | optional arguments: 18 | -h, --help show this help message and exit 19 | -all Runs all word list morphers 20 | -lower Lowercase each word on the input list 21 | -upper Uppercase each word on the input list 22 | -leet Leetspeak each word on the input list 23 | -swap Swap the case of the word list 24 | -ntlm Parse an NTLM Hash dump list for plaintext words to use 25 | in a wordlist 26 | -baseword Base words only (Post-process) Strips any numbers or 27 | symbols from the generated word list 28 | -capitalize Capitalize the first letter of the word list 29 | -orig Include the original word from the word list 30 | -min MIN Minimum word size (default: 4) 31 | -max MAX Maximum word size (default: 32) 32 | -inputfolder file Specify a folder of wordlists to crawl, process and 33 | combine 34 | -input file Input wordlist (default: wordlist.txt) 35 | -output file Output wordlist (default: wordlistout.txt) 36 | ``` 37 | 38 | ## Example use and output 39 | ``` 40 | > wordlistgen.py -all 41 | WordListGen: 0.2 Updated: June 2, 2019 42 | DONE! 43 | Wordlist input: wordlist.txt 44 | Wordlist output: wordlistout.txt 45 | ``` 46 | -------------------------------------------------------------------------------- /wordlistgen.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import re 3 | import os 4 | from string import maketrans 5 | input_lines = [] 6 | new_word_list = [] 7 | post_processed_word_list = [] 8 | 9 | leet_trans = ["aeiotsbzAEIOTSBZ","4310758243107582","altsALTS","@!+$@!+$"] 10 | 11 | print('\033[0;32m'+"WordListGen: " + '0.2' + " Updated: " + 'June 2, 2019'+'\033[0;39m') 12 | parser = argparse.ArgumentParser(description='\033[0;31m'+'WordListGen - Very Simple Word List Morpher - Creates a list of unique words for fuzzing / brute forcing'+'\033[0;39m') 13 | parser.add_argument("-all", action='store_true', help='Runs all word list morphers') 14 | parser.add_argument("-lower", action='store_true', help='Lowercase each word on the input list') 15 | parser.add_argument("-upper", action='store_true', help='Uppercase each word on the input list') 16 | parser.add_argument("-leet", action='store_true', help='Leetspeak each word on the input list') 17 | parser.add_argument("-swap", action='store_true', help='Swap the case of the word list') 18 | parser.add_argument("-ntlm", action='store_true', help='Parse an NTLM Hash dump list for plaintext words to use in a wordlist') 19 | parser.add_argument("-baseword", action='store_true', help='Base words only (Post-process) Strips any numbers or symbols from the generated word list') 20 | parser.add_argument("-capitalize", action='store_true', help='Capitalize the first letter of the word list') 21 | parser.add_argument("-orig", action='store_true', help='Include the original word from the word list') 22 | parser.add_argument("-min", type=int, default="4", help='Minimum word size (default: %(default)s)') 23 | parser.add_argument("-max", type=int, default="32", help='Maximum word size (default: %(default)s)') 24 | parser.add_argument("-inputfolder", metavar='file', type=str, help='Specify a folder of wordlists to crawl, process and combine') 25 | parser.add_argument("-input", metavar='file', type=str, default="wordlist.txt", help='Input wordlist (default: %(default)s)') 26 | parser.add_argument("-output", metavar='file', type=str, default="wordlistout.txt", help='Output wordlist (default: %(default)s)') 27 | 28 | args = parser.parse_args() 29 | 30 | if args.inputfolder is not None: 31 | print "Importing all files in folder: " + args.inputfolder 32 | files = [] 33 | # r=root, d=directories, f = files 34 | for r, d, f in os.walk(args.inputfolder): 35 | for file in f: 36 | #if '.txt' in file: 37 | files.append(os.path.join(r, file)) 38 | for f in files: 39 | print("\t"+f) 40 | with open(f, "r") as filein: 41 | input_lines += filein.readlines() 42 | 43 | else: 44 | with open(args.input, "r") as filein: 45 | input_lines = filein.readlines() 46 | 47 | for line in input_lines: 48 | if ( len(line) < args.min or len(line) > args.max ): continue 49 | if (args.lower or args.all): new_word_list.append(line.lower()) 50 | if (args.upper or args.all): new_word_list.append(line.upper()) 51 | if (args.leet or args.all): new_word_list.append(line.translate(maketrans(leet_trans[0], leet_trans[1]))) 52 | if (args.leet or args.all): new_word_list.append(line.translate(maketrans(leet_trans[2], leet_trans[3]))) 53 | if (args.leet or args.all): new_word_list.append(line.translate(maketrans(leet_trans[2], leet_trans[3])).translate(maketrans(leet_trans[0], leet_trans[1]))) 54 | if (args.swap or args.all): new_word_list.append(line.swapcase()) 55 | if (args.ntlm or args.all): 56 | results = re.findall(r"\\([\w\.\_\-]{2-32})\$*\:", line) 57 | if len(results)>0: new_word_list.append(results[0]) # Username with domain prefix 58 | results = re.findall(r"([\w\.\_\-]{2-32})\$*\:", line) 59 | if len(results) > 0: new_word_list.append(results[0]) # Match username no domain prefix 60 | results = re.findall(r"([\w\.\_\-]{2-32})\\", line) 61 | if len(results) > 0: new_word_list.append(results[0]) # Domain name 62 | if (args.capitalize or args.all): new_word_list.append(line.title()) 63 | if (args.orig or args.all): new_word_list.append(line) 64 | 65 | # Post processing for base word 66 | if args.baseword: 67 | for line in new_word_list: 68 | line = re.sub(r'^[^a-zA-Z ]+', "", line) # remove prefix non-letter chars 69 | line = re.sub(r'[^a-zA-Z ]+$', "", line) # remove postfix non-letter chars 70 | #results = re.findall(r"([A-Za-z\s]{4,})", line) 71 | #if len(results) > 0: post_processed_word_list.append(results[0]) 72 | post_processed_word_list.append(line + "\n") # we lose the newline after we remove non-word chars :P 73 | new_word_list = post_processed_word_list 74 | 75 | with open(args.output,"w") as fileout: 76 | fileout.writelines(sorted(list(set(new_word_list)))) 77 | print '\033[0;34m'+"DONE!\n "+'\033[0;33m'+"Wordlist input:\t"+'\033[0;39m'+args.input+"\n"+'\033[0;33m'+" Wordlist output:\t"+'\033[0;39m'+args.output+"\n" 78 | --------------------------------------------------------------------------------