# How to Add Custom Wordlists for Brute Force Attacks in LazyOwn

> Learn how to add custom wordlists for brute force attacks in LazyOwn using payload.json, the assign command, or the --wordlist flag to enhance your security testing.

- Repository: [Grisuno/lazyown](https://github.com/grisuno/lazyown)
- Tags: how-to-guide
- Published: 2026-03-02

---

**You can add custom wordlists in LazyOwn by editing the [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) configuration file, using the interactive `assign` command in the shell, or passing the `--wordlist` flag directly to individual modules.**

LazyOwn is an open-source penetration testing framework that centralizes runtime configuration through a parameter dictionary system. Understanding how to add custom wordlists for brute force attacks in LazyOwn allows security professionals to tailor dictionary attacks to specific environments without modifying module source code directly.

## Understanding LazyOwn's Centralized Wordlist Architecture

LazyOwn manages all runtime options through a **parameter dictionary** (`self.params`) that is populated from [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) when the interactive shell initializes. According to the source code in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py), the configuration loading occurs at startup:

```python

# lazyown.py – loading the payload

with open('payload.json', 'r') as file:
    config = json.load(file)
self.params = {
    "wordlist": config.get("wordlist"),
    "usrwordlist": config.get("usrwordlist"),
    ...
}

```

The **`wordlist`** key serves as the default dictionary for all brute-force and fuzzing modules, including [`lazybrutesshuserenum.sh`](https://github.com/grisuno/lazyown/blob/main/lazybrutesshuserenum.sh), [`lazylfi2rce.py`](https://github.com/grisuno/lazyown/blob/main/lazylfi2rce.py), and [`lazyown_bprfuzzer.py`](https://github.com/grisuno/lazyown/blob/main/lazyown_bprfuzzer.py). Because this value is centralized, updating it once propagates to every tool that references `self.params["wordlist"]`.

## Method 1: Edit payload.json for Persistent Configuration

To permanently change the default wordlist for every LazyOwn session, modify the **[`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json)** file in the project root. This approach is ideal when you want to replace the default [`/usr/share/wordlists/rockyou.txt`](https://github.com/grisuno/lazyown/blob/main//usr/share/wordlists/rockyou.txt) with a custom dictionary.

Locate the `wordlist` entry and update the path:

```json
{
  "wordlist": "/home/user/custom_wordlist.txt",
  "usrwordlist": "/home/user/custom_userlist.txt",
  ...
}

```

After saving the file, restart LazyOwn. The new configuration loads into `self.params` during initialization (lines 28-31 in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py)), and all subsequent brute-force operations will use your custom list.

## Method 2: Use the assign Command for Temporary Changes

For temporary changes that do not persist across sessions, use the built-in **`assign`** command within the LazyOwn interactive shell. This method updates `self.params` in-memory without modifying [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json).

The `assign` logic is implemented in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) (lines 1093-1114) and validates parameter names before updating the dictionary:

```bash
$ lazyown
> assign wordlist /opt/wordlists/mylist.txt
[wordlist] assign to /opt/wordlists/mylist.txt
> lazybrutesshuserenum

```

This approach is particularly useful when switching between wordlists during a single engagement, as the change takes effect immediately for the current session only.

## Method 3: Pass Wordlists via CLI Arguments

Individual modules can accept wordlist paths directly through command-line arguments, overriding the global `self.params` configuration. This method is optimal for running single modules from the terminal without entering the interactive shell.

For example, [`lazylfi2rce.py`](https://github.com/grisuno/lazyown/blob/main/lazylfi2rce.py) defines a required `--wordlist` flag (line 50) that accepts a custom dictionary path:

```bash
$ python3 modules/lazylfi2rce.py \
    --rhost 10.10.10.10 \
    --rport 80 \
    --lhost 10.10.10.11 \
    --lport 4444 \
    --field file \
    --wordlist /tmp/custom_passlist.txt

```

Similarly, the fuzzer module [`lazyown_bprfuzzer.py`](https://github.com/grisuno/lazyown/blob/main/lazyown_bprfuzzer.py) supports the `-w` or `--wordlist` argument (lines 226-230), falling back to `self.params["wordlist"]` only when the argument is omitted.

## How Wordlist Parameters Propagate Through the Codebase

Understanding the propagation pipeline helps clarify why these three methods work interchangeably. The flow follows three stages:

1. **Parameter Loading**: When `LazyOwnShell` starts, it calls `Config(load_payload())`, which reads [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) into `self.params` (lines 28-31 in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py)).

2. **Command Construction**: Modules build system commands by interpolating the wordlist path directly from `self.params`. For example, the SSH user enumeration functionality constructs commands as shown in lines 2074-2075:

   ```python
   wordlist = self.params["wordlist"]
   self.cmd(f"{path}/modules/lazybrutesshuserenum.sh {wordlist} {rhost}")
   ```

3. **Shell Execution**: The constructed command executes via `os.system` or `subprocess`, passing the wordlist path to external scripts like [`lazybrutesshuserenum.sh`](https://github.com/grisuno/lazyown/blob/main/lazybrutesshuserenum.sh), which reads the file from `$1` (lines 12-14 and 23).

Because the path is centralized in `self.params`, any update—whether through JSON editing, the `assign` command, or CLI arguments—immediately affects all dependent brute-force operations.

## Practical Implementation Examples

### SSH Brute-Force with Custom Userlists

When performing SSH user enumeration, combine the global wordlist with the `usrwordlist` parameter to test both custom usernames and passwords:

```bash
> assign usrwordlist /opt/wordlists/usernames.txt
> assign wordlist /opt/wordlists/passwords.txt
> lazybrutesshuserenum 192.168.1.100

```

The [`lazybrutesshuserenum.sh`](https://github.com/grisuno/lazyown/blob/main/lazybrutesshuserenum.sh) script receives these paths as positional arguments and iterates through them line-by-line.

### Web Fuzzing with lazyown_bprfuzzer.py

The built-in fuzzer allows runtime wordlist specification through the `-w` flag, or it defaults to `self.params["wordlist"]` (lines 165-170):

```bash
> assign wordlist /usr/share/wordlists/dirbuster/common.txt
> lazyfuzz -u http://target.com/FUZZ -m GET

```

Or override for a single run:

```bash
> lazyfuzz -u http://target.com/login -m POST -w /tmp/custom_paths.txt

```

## Summary

- **Centralized Configuration**: LazyOwn stores the default wordlist path in `self.params["wordlist"]`, loaded from [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) at startup.
- **Three Update Methods**: Edit [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) for permanent changes, use `assign wordlist <path>` for temporary session changes, or pass `--wordlist` to individual modules for single executions.
- **Immediate Propagation**: Changes to `self.params` instantly affect all modules including [`lazybrutesshuserenum.sh`](https://github.com/grisuno/lazyown/blob/main/lazybrutesshuserenum.sh), [`lazylfi2rce.py`](https://github.com/grisuno/lazyown/blob/main/lazylfi2rce.py), and [`lazyown_bprfuzzer.py`](https://github.com/grisuno/lazyown/blob/main/lazyown_bprfuzzer.py).
- **Source Code References**: Key implementation details reside in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) (lines 28-31, 1093-1114, 2074-2075) and various modules in the `modules/` directory.

## Frequently Asked Questions

### Where does LazyOwn store the default wordlist configuration?

LazyOwn stores the default configuration in **[`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json)** at the project root. The `wordlist` key within this JSON file defaults to [`/usr/share/wordlists/rockyou.txt`](https://github.com/grisuno/lazyown/blob/main//usr/share/wordlists/rockyou.txt) and is loaded into `self.params` when the shell initializes (lines 28-31 in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py)).

### Can I use multiple wordlists simultaneously in LazyOwn?

Yes, LazyOwn supports separate wordlists for different purposes through distinct parameter keys. Use **`wordlist`** for password lists and **`usrwordlist`** for username lists. Both can be configured via [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json) or the `assign` command, allowing simultaneous brute-force attacks against multiple vectors.

### Do I need to restart LazyOwn after using the assign command?

No, the **`assign`** command updates `self.params` in-memory immediately (lines 1093-1114 in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py)). Changes take effect instantly for subsequent commands in the current session, though they do not persist after exiting the shell unless you also update [`payload.json`](https://github.com/grisuno/lazyown/blob/main/payload.json).

### Which modules support the --wordlist CLI argument?

Not all modules accept CLI arguments, but several key ones do, including **[`lazylfi2rce.py`](https://github.com/grisuno/lazyown/blob/main/lazylfi2rce.py)** (line 50) and **[`lazyown_bprfuzzer.py`](https://github.com/grisuno/lazyown/blob/main/lazyown_bprfuzzer.py)** (lines 226-230). Modules written as bash scripts, such as [`lazybrutesshuserenum.sh`](https://github.com/grisuno/lazyown/blob/main/lazybrutesshuserenum.sh), receive the wordlist path as a positional argument constructed from `self.params["wordlist"]` rather than through direct CLI parsing.