Custom Wordlist Generator from The Undergrid
WordSmith is a powerful and customizable Python-based wordlist generator built for offensive security professionals. It allows you to forge smart, targeted dictionaries using keywords, leetspeak, number ranges, and more ā perfect for password attacks, red teaming, or Wi-Fi cracking.
cli.py ā This is the main entry point. It handles argument parsing, profile loading, passes parameters to the generator, controls the chunking logic, displays the banner, and shows a summary at the end.
core.py ā Contains the logic that generates the wordlist. It builds permutations from the keywords using toggles for uppercase, reversed, leetspeak, numbers, and special characters. Outputs a randomized unique list.
output.py ā Responsible for saving the final wordlist to disk. Supports saving in text, CSV, or JSON format with clean and minimal formatting logic.
profiles/*.json ā Optional reusable config files to define keywords, numbers, formatting and options. Makes running preconfigured attacks easier without passing long CLI arguments.
import argparse
import json
import sys # ā
Added to check for args
from core import generate_wordlist
from fileio import save_wordlist
def load_profile(profile_path):
with open(profile_path, "r") as f:
return json.load(f)
def parse_numbers(input_str):
result = []
parts = input_str.split(',')
for part in parts:
if '-' in part:
try:
start, end = map(int, part.split('-'))
result.extend([str(n) for n in range(start, end + 1)])
except ValueError:
continue
else:
result.append(part.strip())
return result
def parse_specials(input_str):
return [s.strip() for s in input_str.split(',') if s.strip()]
def main():
print(r"""
ā āā āāāāāā āāāāāā āāāāāāā āāāāāā āāāā āāāāā āāāāāāāāāāāā āāā āā
āāā ā āāāāāāā āāāāāā ā āāāāāāā āāāāāā ā āāāāāāā āāāāāāāā āāā āāāāāā āāā
āāā ā āā āāāā āāāāāā āāā āāāā āāā āāāā āāā āāāāāāāāā āāāā āāāāāāāāāā
āāā ā āā āāā āāāāāāāāāā āāāā ā ā āāāāāā āāā āāāāā āāāā ā āāā āāā
āāāāāāāā ā āāāāāāāāāāā āāāāāāāāāāā āāāāāāāāāāāāā āāāāāāāā āāāā ā āāāāāāāā
ā āāā ā ā āāāāāā ā āā āāāā āāā ā ā āāā ā āā āā ā āāā ā āā ā āāāāā
ā ā ā ā ā āā āā ā āā ā ā ā ā āā ā āā ā ā ā ā ā ā āāā ā
ā ā ā ā ā ā āā ā ā ā ā ā ā ā ā ā ā ā ā ā āā ā
ā ā ā ā ā ā ā ā ā ā ā
ā
š WordSmith - Custom Wordlist Generator
Developed by - 4c1d.burn
""")
parser = argparse.ArgumentParser(description="WordSmith - Advanced Wordlist Generator")
parser.add_argument("--profile", help="Path to a JSON profile file")
parser.add_argument("--keywords", help="Comma-separated keywords")
parser.add_argument("--uppercase", action="store_true", help="Include uppercase versions")
parser.add_argument("--reversed", action="store_true", help="Include reversed versions")
parser.add_argument("--leetspeak", action="store_true", help="Apply leetspeak mutations")
parser.add_argument("--numbers", default="", help="Append/prepend numbers (e.g. 0-100 or 1,2,3 or ranges mixed)")
parser.add_argument("--specials", default="", help="Append/prepend symbols (e.g. !,@,#)")
parser.add_argument("--chunks", type=int, default=4, help="How many wordlists to generate")
parser.add_argument("--format", choices=["1", "2", "3"], default="1", help="Output format: 1=txt, 2=csv, 3=json")
parser.add_argument("--basename", default="wordlist", help="Base filename for output")
# ā
If no args are provided, show help and exit
if len(sys.argv) == 1:
parser.print_help()
sys.exit(0)
args = parser.parse_args()
if args.profile:
profile = load_profile(args.profile)
args.keywords = ",".join(profile.get("keywords", []))
args.uppercase = profile.get("uppercase", False)
args.reversed = profile.get("reversed", False)
args.leetspeak = profile.get("leetspeak", False)
args.numbers = profile.get("numbers", "")
args.specials = profile.get("specials", "")
args.chunks = profile.get("chunks", 4)
args.format = profile.get("format", "1")
args.basename = profile.get("basename", "wordlist")
keywords = [k.strip() for k in args.keywords.split(',')]
numbers = parse_numbers(args.numbers) if args.numbers else []
specials = parse_specials(args.specials) if args.specials else []
wordlist = generate_wordlist(
keywords,
args.uppercase,
args.reversed,
numbers,
specials,
args.leetspeak
)
total_available = len(wordlist)
print(f"\nš¢ Total words generated: {total_available}")
sizes = [10000, 50000, 250000, 1000000]
while len(sizes) < args.chunks:
sizes.append(sizes[-1] * 2)
if sum(sizes[:args.chunks]) > total_available:
step = total_available // args.chunks
sizes = [step] * args.chunks
print("ā ļø Not enough entries for large chunk sizes. Adjusted to even split.")
start = 0
for i, size in enumerate(sizes[:args.chunks]):
chunk = wordlist[start:start+size]
filename = f"{args.basename}_{size}"
save_wordlist(chunk, filename, args.format)
print(f"ā
Saved {len(chunk)} entries to {filename}")
start += size
print("\nš Summary Report")
print("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā")
print(f"š Base filename : {args.basename}")
print(f"š§ Keywords used : {args.keywords}")
print(f"š Uppercase : {args.uppercase}")
print(f"š Reversed : {args.reversed}")
print(f"š¤ Leetspeak : {args.leetspeak}")
print(f"#ļøā£ Numbers : {args.numbers}")
print(f"š£ Specials : {args.specials}")
print(f"š¦ Chunks created : {args.chunks}")
print(f"š¾ Output format : {args.format}")
print("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n")
if __name__ == "__main__":
main()
import random
def apply_leetspeak(word):
leet_map = {'a': '@', 's': '$', 'o': '0', 'i': '1', 'e': '3'}
return ''.join(leet_map.get(c.lower(), c) for c in word)
def generate_wordlist(base_keywords, include_uppercase, include_reversed, numbers_list, specials, leetspeak=False):
wordlist = set()
for word in base_keywords:
wordlist.add(word)
if include_uppercase:
wordlist.add(word.upper())
if include_reversed:
wordlist.add(word[::-1])
if leetspeak:
wordlist.add(apply_leetspeak(word))
if numbers_list:
for word in list(wordlist):
for num in numbers_list:
wordlist.add(word + num)
wordlist.add(num + word)
if specials:
for word in list(wordlist):
for special in specials:
wordlist.add(word + special)
wordlist.add(special + word)
result = list(wordlist)
random.shuffle(result)
return result
import json
import csv
def save_wordlist(wordlist, filename, format_choice):
if format_choice == "1":
filename += ".txt"
with open(filename, "w") as f:
for word in wordlist:
f.write(word + "\n")
elif format_choice == "2":
filename += ".csv"
with open(filename, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["word"])
for word in wordlist:
writer.writerow([word])
elif format_choice == "3":
filename += ".json"
with open(filename, "w") as f:
json.dump(wordlist, f, indent=4)
else:
filename += ".txt"
with open(filename, "w") as f:
for word in wordlist:
f.write(word + "\n")
{
"keywords": ["cyberforge", "admin", "secure", "pa$$word", "nexus"],
"uppercase": true,
"reversed": true,
"leetspeak": true,
"numbers": "0-25,2023,2024",
"specials": "!,$,@,#",
"chunks": 3,
"format": "1",
"basename": "cyberforge_hybrid"
}