top of page

How To Create Wordlists For Hacking & Cracking

How To Create Wordlists For Hacking & Cracking | Black Hat HQ

Creating Wordlists for Hacking/Cracking


Here's how to build custom wordlists from scratch for hacking & cracking — from scraping a target to raw brute-force generation. This article is on how to create wordlists for hacking & cracking.


CeWL - Scrape A Target Website


Best method for creating a wordlist specific to the target organization.


bash

# Basic scrape
cewl https://target-org.com -w custom_words.txt

# Full production scrape
cewl https://target-org.com \
  -d 3 \           # spider depth (3 levels deep)
  -m 5 \           # minimum word length
  --lowercase \    # all lowercase output
  --with-numbers \ # append numbers to words
  -e \             # include email addresses
  --email_file emails.txt \  # separate email file
  -w target_full.txt

# Target intranet / documentation / blog only
cewl https://target-org.com/blog -d 2 -m 6 -w blog_words.txt
cewl https://docs.target-org.com -d 3 -m 5 -w docs_words.txt

# Combine and deduplicate
cat *_words.txt | sort -u > combined.txt

What CeWL captures: product names, internal project names, employee names from "About" pages, jargon, acronyms, departmental terms.


Crunch - Pattern-Based Generation


When you know the password policy but need to generate all possibilities.


bash

# Syntax: crunch <min> <max> <charset> [options]
crunch 6 8 abc123 -o output.txt

# Common patterns
crunch 6 8 -t Pass@@@@ -o output.txt    # Pass + 4 lowercase
crunch 8 8 -t Corp%%^^ -o output.txt    # Corp + 2 digits + 2 symbols

# Pattern characters:
# @ = lowercase
# , = uppercase
# % = numbers
# ^ = symbols

# Using pre-defined charsets
crunch 8 8 -f /usr/share/crunch/charset.lst mixalpha -o alpha8.txt
crunch 10 10 -f /usr/share/crunch/charset.lst mixalpha-numeric-all -o all10.txt

# Known prefix/suffix (company name patterns)
crunch 10 10 -t Target%%% -o target_numbers.txt     # Target123, Target456...
crunch 10 10 -t %%%Company -o numbers_company.txt   # 123Company, 456Company...
crunch 10 10 -t Target!%%@ -o target_complex.txt    # Target!12a...

Estimate size before generating:


bash

# crunch prints estimate before starting
crunch 6 8 abc123

# Manual: charset_length ^ password_length
# abc123 = 6 chars, 8 positions = 6^8 = 1,679,616 combinations

Hashcat Rules - Expand A Small Seed List


Take a small list of target-specific words and apply transformation rules.


bash

# Start with target-specific seed words
cat > seeds.txt << EOF
targetcorp
admin
winter2024
projectx
ceoname
cityname
EOF

# Apply rule sets
hashcat --stdout seeds.txt -r /usr/share/hashcat/rules/best64.rule > expanded.txt
hashcat --stdout seeds.txt -r /usr/share/hashcat/rules/d3ad0ne.rule > huge_expanded.txt

# String multiple rule passes
hashcat --stdout seeds.txt -r /usr/share/hashcat/rules/leetspeak.rule \
  | hashcat --stdout -r /usr/share/hashcat/rules/best64.rule \
  > super_expanded.txt

# Sort and deduplicate
sort -u huge_expanded.txt > final.txt

Key rule files:


bash

/usr/share/hashcat/rules/best64.rule              # 64 most effective rules
/usr/share/hashcat/rules/d3ad0ne.rule             # 35,000+ rules
/usr/share/hashcat/rules/OneRuleToRuleThemAll.rule # 50,000+ rules
/usr/share/hashcat/rules/rockyou-30000.rule        # RockYou-derived rules
/usr/share/hashcat/rules/leetspeak.rule            # l33t substitutions only
/usr/share/hashcat/rules/append1.rule              # Append 1 char

Custom Rules - Write Your Own


Hashcat rules are extremely flexible. Build them for target-specific patterns.


bash

# Create custom rule file
cat > my_rules.rule << 'EOF'
# Append common years
$2 $0 $2 $4
$2 $0 $2 $5
$2 $0 $2 $6

# Append special chars
$!
$@
$#
$$

# Capitalize first letter
c

# Capitalize all
u

# l33t speak
sa@
se3
si1
so0

# Append seasons and years
$s $p $r $i $n $g $2 $4
$s $u $m $m $e $r $2 $4
$f $a $l $l $2 $4
$w $i $n $t $e $r $2 $4

# Company-specific patterns
$T $a $r $g $e $t
$2 $0 $2 $4 $!
EOF

# Apply
hashcat --stdout seeds.txt -r my_rules.rule > custom_expanded.txt

Bash / Python Mutation Scripts


For patterns that hashcat rules can't easily express.


Append Numbers (0-999)


bash

cat seeds.txt | while read word; do
  echo "$word"
  for i in $(seq 0 999); do
    echo "${word}${i}"
    echo "${word}$(printf '%03d' $i)"  # zero-padded
  done
done > with_numbers.txt

Append Special Characters


bash

cat seeds.txt | while read word; do
  echo "$word"
  for char in '!' '@' '#' '$' '%' '&' '*' '?' '-'; do
    echo "${word}${char}"
  done
done > with_special.txt

Capitalization Variants


bash

cat seeds.txt | while read word; do
  echo "$word"                  # original
  echo "${word^}"               # First letter capital
  echo "${word^^}"              # ALL CAPS
  echo "${word,,}"              # all lowercase
done > case_variants.txt

Python — Full Custom Generator


python

#!/usr/bin/env python3
"""Generate a custom wordlist for a specific target."""

import itertools
import argparse

def generate(company, locations, departments, years, special_chars):
    words = []
    
    # Base terms
    base = [company.lower(), company.upper(), company.capitalize()]
    
    # Add locations
    for loc in locations:
        base.extend([loc.lower(), loc.capitalize()])
    
    # Add departments
    for dept in departments:
        base.extend([dept.lower(), dept.capitalize()])
    
    # Simple mutations
    for word in base:
        words.append(word)
        # Append years
        for year in years:
            words.append(f"{word}{year}")
            words.append(f"{word}_{year}")
        # Append special chars
        for char in special_chars:
            words.append(f"{word}{char}")
        # Capitalize + year + special
        words.append(f"{word.capitalize()}{years[0]}{special_chars[0]}")
    
    # Numbered combinations
    for word in base:
        for i in range(0, 100):
            words.append(f"{word}{i:02d}")
    
    # Leet speak
    leet_map = str.maketrans('aeiots', '431075')
    for word in base:
        words.append(word.translate(leet_map))
    
    return sorted(set(words))

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--company', required=True)
    parser.add_argument('-l', '--locations', nargs='+', default=[])
    parser.add_argument('-d', '--departments', nargs='+', default=['IT','HR','Sales','Finance','Dev'])
    parser.add_argument('-y', '--years', nargs='+', default=['2024','2025','2026'])
    parser.add_argument('-s', '--special', nargs='+', default=['!','@','#','$'])
    parser.add_argument('-o', '--output', default='custom_wordlist.txt')
    
    args = parser.parse_args()
    words = generate(
        args.company, args.locations, args.departments,
        args.years, args.special
    )
    
    with open(args.output, 'w') as f:
        f.write('\n'.join(words))
    
    print(f"[+] Generated {len(words):,} words → {args.output}")

# Usage:
# python wordgen.py -c TargetCorp -l "NewYork" "Dallas" "Remote" -d "DevOps" "SecOps" -y "2024" "2025"

Keyboard Walk Generator


Generate patterns people actually type — keyboard walks.


bash

pip install kwprocessor

# Generate keyboard walks of 6-12 characters
kwp /usr/share/kwprocessor/keymaps/en-us.keymap \
  -s 6 -e 12 -o keyboard_walks.txt

# Common keyboard-only passwords:
start position: q → qwerty, qwertyuiop, qazwsx...
start position: 1 → 123456, 1qaz2wsx, 1q2w3e4r...

Date-Based Patterns


People love using dates. Generate all reasonable combinations.


bash

# Python date generator
python3 << 'EOF'
import datetime

formats = [
    "%m%d%Y",    # 04201988
    "%m%d%y",    # 042088
    "%m-%d-%Y",  # 04-20-1988
    "%m/%d/%Y",  # 04/20/1988
    "%B%Y",      # April1988
    "%b%Y",      # Apr1988
    "%b%d",      # Apr20
    "%Y%m%d",    # 19880420
]

start = datetime.date(1950, 1, 1)
end = datetime.date(2010, 12, 31)

current = start
with open("dates.txt", "w") as f:
    while current <= end:
        for fmt in formats:
            f.write(current.strftime(fmt) + "\n")
        current += datetime.timedelta(days=1)
EOF

# This generates millions — filter for minimum length
awk 'length($0) >= 8' dates.txt > dates_min8.txt

Combine Everything Into A Final Wordlist


bash

#!/bin/bash
# build_wordlist.sh — assemble a targeted wordlist

TARGET="$1"
OUTPUT="${2:-final_wordlist.txt}"

echo "[*] Building wordlist for: $TARGET"

# 1. Crawl target website
echo "[1/6] Crawling website..."
cewl "https://$TARGET" -d 2 -m 4 --lowercase -w crawl_raw.txt 2>/dev/null

# 2. Add related terms
echo "[2/6] Adding seed terms..."
cat > seeds.txt << EOF
$TARGET
$(echo $TARGET | tr -d '.com' | tr -d '.org')
admin
administrator
root
password
welcome
default
EOF

# 3. Combine crawl + seeds
cat crawl_raw.txt seeds.txt > combined.txt

# 4. Apply hashcat rules
echo "[3/6] Applying rules..."
hashcat --stdout combined.txt -r /usr/share/hashcat/rules/best64.rule 2>/dev/null > expanded.txt

# 5. Add year/special mutations
echo "[4/6] Adding year/special mutations..."
cat expanded.txt | while read word; do
  echo "$word"
  for year in 2024 2025 2026; do
    echo "${word}${year}"
  done
  for char in '!' '@' '#'; do
    echo "${word}${char}"
  done
done > mutated.txt

# 6. Sort, deduplicate, filter
echo "[5/6] Cleaning..."
sort -u mutated.txt | awk 'length($0) >= 6 && length($0) <= 32' > "$OUTPUT"

echo "[6/6] Done: ${OUTPUT} — $(wc -l < "$OUTPUT") words"

# Cleanup
rm crawl_raw.txt seeds.txt combined.txt expanded.txt mutated.txt

Usage:


bash

chmod +x build_wordlist.sh
./build_wordlist.sh target-org.com

Wordlist Optimization


Before using, optimize for the target:


bash

# Filter by password policy
awk 'length($0) >= 8 && length($0) <= 24' input.txt > filtered.txt

# Must contain at least one digit
grep '[0-9]' input.txt > with_digit.txt

# Must contain upper, lower, and digit
grep -P '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)' input.txt > complex.txt

# Remove pure numbers (rarely work for humans)
grep -v '^[0-9]*$' input.txt > no_pure_numbers.txt

# Prioritization — most common patterns first
# Words with numbers at end are more common
sort input.txt -o sorted.txt
# Then manually move high-value targets to top

Quick Size Reference


Method

Input Size

Output Size

Time

CeWL (crawl)

1 website

500–5,000 words

1–5 min

Hashcat best64.rule

1,000 words

~64,000 words

Seconds

Hashcat d3ad0ne.rule

1,000 words

~35 million words

Minutes

Crunch (6-char numeric)

1 million

Seconds

Crunch (8-char alpha)

208 billion

DON'T

Date generator

~2 million

Minutes

Keyboard walks

~500,000

Seconds


Enroll In Online Cybersecurity & Hacking Classes/Courses | Black Hat HQ

Comments


bottom of page