How to Debug Issues Encountered During CUPP Password Generation

To debug CUPP password generation issues, verify your cupp.cfg configuration integrity, check intermediate data structures by adding print statements after read_config() and generate_wordlist_from_profile(), and use the built-in test suite in test_cupp.py to isolate failures.

CUPP (Common User Passwords Profiler) generates targeted wordlists through multi-stage processing defined in the Mebus/cupp repository. When password generation fails, produces empty files, or crashes unexpectedly, systematic debugging requires tracing data flow through configuration loading, profile collection, and wordlist synthesis. Understanding the specific function signatures and file locations in cupp.py enables rapid identification of root causes.

Understanding CUPP's Password Generation Pipeline

CUPP builds password wordlists in five distinct stages. Debugging requires checking each boundary where data transforms from one structure to another.

Configuration Loading

In cupp.py, the read_config() function (lines L52-L74) parses cupp.cfg and populates the global CONFIG dictionary. If this stage fails, all subsequent operations lack necessary parameters for years, special characters, and leet transformations.

Profile Collection

The interactive() function (lines L299-L376) prompts users for personal data and stores it in a profile dictionary. Input validation errors here—such as improperly formatted birthdates—cause downstream generation failures or crashes.

Wordlist Synthesis and Filtering

The generate_wordlist_from_profile() function (lines L721-L806) expands the profile into combinatorial strings, adds optional special characters, random numbers, and leet transformations. Generated candidates are filtered by length bounds (wcfrom, wcto) at lines L986-L1000 before the final list is written to disk via print_to_file() (lines L19-L35).

Common CUPP Password Generation Issues and Solutions

Empty or Missing Output Files

When no file is created or the output file is empty, read_config() likely failed due to a missing cupp.cfg or malformed sections. Insert a temporary print(CONFIG) immediately after the function call at line 23, or run python -c "import cupp; cupp.read_config('cupp.cfg'); print(cupp.CONFIG)" to verify the dictionary populated correctly.

KeyError on CONFIG Dictionary

A KeyError such as CONFIG['global'] indicates required configuration sections (years, specialchars, etc.) are missing or contain syntax errors. Open cupp.cfg and confirm all required keys exist, comparing your file against the sample in the repository.

Empty Wordlist During Concatenation

If listic is empty, concatenation loops are skipped entirely. This occurs when the source wordlist file passed to -w is empty or unreadable. Print the size of listic after reading (around line 84) and verify the file exists using os.path.isfile.

Special Character Handling Issues

Duplicate or missing special characters result from spechars1 not being set to y or an empty chars list in the configuration. Verify that CONFIG['global']['chars'] contains the expected characters (default is !@#$%^&*) and that you answered the interactive prompt with y.

Leet Mode Produces Unexpected Strings

Incorrect leet transformations stem from an incomplete or overwritten LEET mapping. Print CONFIG['LEET'] after read_config() (line 84) and check that each entry matches the cupp.cfg file definitions.

ValueError in Random Number Generation

When the random-number component raises a ValueError, the numfrom/numto values in the nums section are either non-integers or have numfrom > numto. Ensure these values are numeric and properly ordered.

Profile Parsing Crashes

Program crashes during profile parsing typically occur when the birthdate string length is not exactly 8 characters. Validate input length or add a guard clause: if len(profile['birthdate']) != 8: raise ValueError("Birthdate must be 8 digits").

Step-by-Step Debugging Workflow

Follow this systematic approach to isolate failures in the Mebus/cupp codebase:

  1. Enable verbose prints – Add print("[DEBUG] <msg>", var) at the start of each stage (config loading, profile creation, and each combination loop) to trace data flow.

  2. Use pdb – Insert import pdb; pdb.set_trace() where you suspect the list becomes empty, such as after komb_unique = {...} near line 441, to inspect variable states interactively.

  3. Run unit tests selectively – The repository ships with a comprehensive test suite (test_cupp.py). Execute the failing test with pytest -k generate_wordlist_from_profile -vv to get a detailed traceback.

  4. Mock inputs – The tests already patch builtins.input. Extend this approach to reproduce the exact interaction that caused the failure (see test_interactive in test_cupp.py.

  5. Check file system side-effects – After each run, verify that expected files exist (*.cupp.txt, alectodb-*.txt, etc.) using os.path.isfile to confirm output stages executed.

Practical Debugging Code Examples

Add debug dumps to key functions to expose internal state:


# Example: add a debug dump of the configuration

def read_config(filename):
    # ... existing code ...

    print("[DEBUG] Loaded CONFIG:", CONFIG)   # <-- add this line

    # ...

Inspect the filtered list before writing to prevent empty output:


# Example: inspect the length-filtered list before writing

def print_to_file(filename, unique_list_finished):
    print("[DEBUG] Final list size:", len(unique_list_finished))  # <-- add

    # ...

Run targeted tests to isolate specific functionality:


# Example: run a single test with verbose output

$ pytest -k test_generate_wordlist_from_profile -vv

Mock a problematic profile to test edge cases without manual input:


# Mocking a problematic profile (e.g. missing birthdate digits)

from unittest.mock import patch
with patch("builtins.input", side_effect=[
    "John", "Doe", "jdoe", "1234", "", "", "", "", "", "", "", "", "y", "y", "y"
]):
    interactive()   # will hit the birthdate length check and raise an error

Summary

  • Configuration integrity is the most common root cause; verify cupp.cfg exists and contains all required sections (global, years, specialchars, LEET) before debugging other components.
  • Data validation occurs at multiple boundaries; check profile dictionary contents after interactive() and listic contents before combination loops.
  • Line-specific debugging targets cupp.py (config), L299-L376 (profile), and L721-L806 (generation) for most issues.
  • Test-driven isolation using pytest -k against test_cupp.py provides faster feedback than manual interactive testing.
  • File system verification confirms that print_to_file() actually receives non-empty lists filtered by wcfrom and wcto bounds.

Frequently Asked Questions

Why is my CUPP output file empty?

An empty output file typically indicates that read_config() failed to populate the global CONFIG dictionary, or the wordlist filtering at lines L986-L1000 removed all candidates based on length constraints (wcfrom/wcto). Verify the configuration loaded correctly and check the length bounds in cupp.cfg match your expected password lengths.

How do I fix KeyError: 'global' in CUPP?

This error occurs when the cupp.cfg file is missing the [global] section or contains syntax errors that prevent Python's ConfigParser from reading it. Compare your local file against the repository's cupp.cfg sample to ensure all required sections ([global], [years], [specialchars], [nums], [LEET]) are present and properly formatted with key-value pairs.

Why are special characters not appearing in generated passwords?

Special characters require two conditions: the chars key in cupp.cfg must contain your desired symbols (default: !@#$%^&*), and the interactive prompt for special characters must be answered with y to set spechars1 to y. Check both CONFIG['global']['chars'] and the profile's spechars1 value during debugging.

How can I test CUPP without entering interactive data every time?

Use the mocking pattern from test_cupp.py to patch builtins.input with a predefined list of responses. This allows you to programmatically test interactive() and generate_wordlist_from_profile() with specific edge cases, such as incomplete birthdates or unusual name combinations, without manual intervention.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →