How Leet Mode Affects Password Generation in CUPP: Configuration and Implementation
Leet mode in CUPP transforms generated passwords by substituting letters with leet-speak equivalents (such as a → 4 and e → 3) and appends these variants to the final wordlist rather than replacing the original candidates.
The Common User Passwords Profiler (CUPP) is a widely-used tool for generating targeted wordlists for security testing and password auditing. According to the Mebus/cupp source code, the optional leet mode feature systematically expands password candidates by applying character substitutions defined in external configuration files. This transformation significantly increases wordlist coverage by including common "1337 speak" variations that users frequently employ to obfuscate simple passwords.
Configuration of Leet Mode Mappings
The leet mode transformation relies on a configurable mapping stored in the cupp.cfg file. Within the [leet] section of this configuration file, specific letter-to-number substitutions are defined (for example, a=4, e=3, i=1, o=0).
During initialization, CUPP parses these mappings into the CONFIG["LEET"] dictionary. As implemented in cupp.py lines 78-84, the parser reads each key-value pair from the configuration section and stores them for use during the transformation process. This modular approach allows users to customize the leet-speak substitutions without modifying the core Python code.
The make_leet Conversion Function
The actual transformation logic resides in the make_leet() helper function found in cupp.py lines 95-99. This function iterates over the CONFIG["LEET"] dictionary and repeatedly replaces each plain letter with its corresponding leet counterpart.
For example, when processing the word "password", the function systematically substitutes characters according to the configuration rules, potentially producing variants like p4ssw0rd or p@ssw0rd depending on the defined mappings. The implementation performs these replacements sequentially across the entire mapping table, ensuring comprehensive coverage of all configured substitutions.
When Leet Mode Is Applied
Leet mode operates as an optional post-processing step that can be triggered in two different execution modes within the Mebus/cupp codebase.
Interactive Mode (-i)
When running CUPP in interactive mode with the -i flag, the script prompts the user with > Leet mode? (i.e. leet = 1337) Y/[N]: after building the normal wordlist (as seen in cupp.py lines 66-67). If the user responds with y, the script passes every entry in the intermediate list unique_lista through the make_leet() function. The transformed strings are then appended to the final output list, as implemented in lines 84-92.
Dictionary Improvement Mode (-w)
In dictionary improvement mode (-w), which enhances existing wordlists, a similar prompt appears later in the execution flow (lines 40-41). When enabled, the script transforms each generated word in unique_lista using make_leet() and merges the results back into the output list, as shown in lines 74-84. This ensures that even when improving existing dictionaries, users can benefit from leet-speak variations.
Impact on Password Generation
The critical architectural decision in CUPP's leet mode implementation is that transformed passwords are added to the normal candidates, not substituted for them. This means the final wordlist contains both the original passwords (such as john1990, admin) and their leet variants (such as j0hn1990, @dm1n).
This append-only strategy effectively doubles or triples the wordlist size depending on the number of applicable substitutions, maximizing the probability of matching real-world passwords that employ leet-speak obfuscation. The transformation applies to all candidate types, including concatenations, words with special characters, and date-appended variants.
Practical Examples
To generate a wordlist with leet mode enabled in interactive mode:
$ python3 cupp.py -i
> First Name: john
> Surname: doe
> Birthdate (DDMMYYYY): 15051990
...
> Leet mode? (i.e. leet = 1337) Y/[N]: y
[+] Now making a dictionary...
The resulting john.txt file will contain entries such as:
johnjohn1990john1990!j0hnj0hn1990j0hn1990!
To improve an existing wordlist with leet transformations:
$ python3 cupp.py -w mylist.txt
> Do you want to concatenate all words from wordlist? Y/[N]: n
> Do you want to add special chars at the end of words? Y/[N]: n
> Do you want to add some random numbers at the end of words? Y/[N]: n
> Leet mode? (i.e. leet = 1337) Y/[N]: y
[+] Now making a dictionary...
The output file mylist.txt.cupp.txt will contain the original words plus leet-transformed copies (for example, password → p4ssw0rd).
Summary
- Leet mode is configured through the [leet] section in
cupp.cfg, mapping letters to numbers likea=4ande=3. - The
make_leet()function incupp.py(lines 95-99) performs the actual character substitution using theCONFIG["LEET"]dictionary. - It can be activated in both interactive mode (
-i) and dictionary improvement mode (-w) through user prompts defined in the source code. - Transformed passwords are appended to the original wordlist rather than replacing them, significantly expanding coverage.
- This feature targets common user behaviors of replacing vowels with visually similar numbers, increasing the effectiveness of password audits.
Frequently Asked Questions
What characters does CUPP replace in leet mode?
The specific character substitutions depend on the [leet] section defined in cupp.cfg. Common defaults include a=4, e=3, i=1, o=0, and s=5, though users can customize these mappings by editing the configuration file before running the tool.
Does enabling leet mode replace the original passwords in the wordlist?
No, enabling leet mode does not replace the original passwords. According to the implementation in cupp.py lines 84-92 and 74-84, the leet-transformed variants are appended to the existing wordlist, meaning the final output contains both the original candidates and their leet-speak equivalents.
Can I use leet mode when improving an existing wordlist?
Yes, leet mode is available in dictionary improvement mode (-w). When processing an existing wordlist with the -w flag, CUPP prompts users with "Leet mode? (i.e. leet = 1337) Y/[N]:" after other transformation options, allowing you to generate leet variants of existing dictionary entries.
Where is the leet mode configuration stored in CUPP?
The leet mode configuration is stored in the cupp.cfg file in the repository root. The Python script parses this file at startup (specifically lines 78-84 in cupp.py) and stores the mappings in the CONFIG["LEET"] dictionary, which the make_leet() function references during transformation.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →