Skip to content

Commit 36aa838

Browse files
committed
updating main
1 parent c10c99b commit 36aa838

703 files changed

Lines changed: 769 additions & 47087 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ lazysentinel.db
5151
parquets/session_knowledge.parquet
5252
prompt.md
5353
knowledge_base_vuln.json
54+
graphify-out/cache/
55+
graphify-out/.graphify_*

CLAUDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bash skills/mcp_restart.sh # after editing MCP
6060
| `cli/commands/` | cmd2 `CommandSet` subpkg, auto-discovered by `cli/registry.py`. |
6161
| `core/` | Canonical `Config`, crypto, validators, `typing.Protocol` interfaces. No framework imports. |
6262
| `scripts/` | Build/maintenance: `build_command_index.py`, `patch_playbook_atomic_ids.py`. |
63-
| `tests/` | 61 files, ~1810 tests. No mocking of C2 or daemon. |
63+
| `tests/` | 62 files, ~1860 tests. No mocking of C2 or daemon. |
6464
| `lazyown-docker/` `lazygui/` | Docker + desktop GUI. |
6565
| `docs/` | GH Pages site — auto-generated by `DEPLOY.sh`, don't edit HTML. |
6666
| `lazyc2/` | Security validators (`validate_route_path`, `validate_template_name`, `is_safe_template_path`). |
@@ -216,6 +216,8 @@ Only module both CLI and C2 import. Use existing helpers:
216216
| Exploit search | `find_ss`/`find_ea`/`find_ps`/`nvddb`/`exploitalert`/`packetstormsecurity` |
217217
| HTTP req | `generate_http_req(host, port, uri, ...)` |
218218
| Input validation | `check_rhost`/`check_lhost`/`check_lport` |
219+
| Binary present? | `is_binary_present(name)``shutil.which` based, no shell |
220+
| Optional heavy dep | `from core.dependencies import optional_import, optional_attr` — bind lazily so a missing package degrades one feature, not the whole framework |
219221
| Tmux bootstrap | `ensure_tmux_session(name)` |
220222
| Emails/users/creds | `generate_emails`/`get_users_dic`/`crack_password` |
221223
| Vulnerability scan + persist | `VulnerabilityScanner().search_cves(service)``.persist(service, target, cves)` writes `sessions/vulns_<target>.json` |

QUICKSTART.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,14 @@ bash gen_cert.sh
183183
```
184184
(LazyOwn) > assign dirwordlist /path/to/wordlist.txt
185185
```
186+
187+
**A command fails with `MissingDependencyError`** — a heavy optional package (for
188+
example `pycryptodome`, `python-libnmap`, `impacket`) is not installed. The shell
189+
itself keeps running; only the dependent feature is affected. The error names the
190+
exact `pip install` command. To list every optional dependency and its status
191+
without launching the shell (useful when the install is so broken that `rich` or
192+
`cmd2` will not import):
193+
```bash
194+
python3 -m core.dependencies
195+
```
196+
Then reinstall everything with `pip install -r requirements.txt`.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ git clone https://github.com/grisuno/LazyOwn.git && cd LazyOwn && bash install.s
9999
(LazyOwn) > doctor # preflight: Python, venv, packages, certs, SecLists, tools
100100
(LazyOwn) > wizard # auto-detects lhost, walks 7 config steps
101101

102+
# Heavy optional dependencies (pycryptodome, python-libnmap, impacket, ...) are
103+
# imported lazily: a missing package degrades only its feature instead of
104+
# crashing the shell, and the dependent command raises a clear "pip install ..."
105+
# error when used. To audit them without launching the shell (works even if rich
106+
# or cmd2 are broken): python3 -m core.dependencies
107+
102108
# 3. Define your authorized scope, then recon
103109
(LazyOwn) > scope add 10.10.11.0/24 && scope mode enforce
104110
(LazyOwn) > ping && lazynmap && auto_populate && facts_show

UTILS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ This function checks if a specified binary is available in the system's PATH
7575
by using the `which` command. It returns True if the binary is found and False
7676
otherwise.
7777

78+
The lookup is performed with :func:`shutil.which`, which resolves the name
79+
against ``PATH`` without spawning a shell. This avoids the command-injection
80+
surface of interpolating ``binary_name`` into a shell string and works on
81+
platforms that do not ship the ``which`` utility.
82+
7883
:param binary_name: The name of the binary to be checked.
7984
:type binary_name: str
8085
:return: True if the binary is present, False otherwise.

cli/command_index.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"cli/commands/scan.py"
1515
],
1616
"source_sha256": {
17-
"lazyown.py": "d397fbe579e6a613002b44776b2e11003ee488d2c69cfdfde8816c37cdf9a0fa",
17+
"lazyown.py": "dcd2fd4b9d584aae9637a81dec3c2eb16a51534efd478789886a2d987a25ffa9",
1818
"cli/commands/ai.py": "f21c625015834ceff49ebc5bde7a1c56f05217556513868350d477f290da3c00",
1919
"cli/commands/audit.py": "f374f86060903ce1ca64333f191ee9a68f05588aa064e8fe02c18e2e5240d47b",
2020
"cli/commands/command_and_control.py": "35fdf900504dbedbec9c514249693d9d5122cd7cbba8cfc5ed18ed6404ac12f2",

core/README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ low-level protocol constants. Nothing in `core/` imports from `lazyown.py`,
1414
| `validators.py` | Input validation functions: IP address format check, port range check, safe path validation. Used by CLI commands before they touch `payload.json` or the filesystem. |
1515
| `protocols.py` | `typing.Protocol` definitions shared across `cli/`, `modules/`, and `skills/`: `PayloadProvider`, `CommandLister`, `TerminalIO`, `LLMBackend`, `MemoryStore`, `Selector`. Enables Dependency Inversion without circular imports. |
1616
| `console.py` | Rich console singleton and ANSI colour helpers used by `print_msg`, `print_warn`, `print_error`. |
17-
| `__init__.py` | Re-exports `Config`, `load_payload`, and the validators so callers can do `from core import Config`. |
17+
| `dependencies.py` | Graceful optional-import handling. `optional_import` / `optional_attr` bind heavy third-party packages lazily so a missing dependency (for example `pycryptodome`) degrades a single feature instead of crashing the framework at import time. `OPTIONAL_PYTHON_DEPENDENCIES` is the single source of truth for each lazily-imported package's install hint. Standard-library only, so `python3 -m core.dependencies` works even when `rich` or `cmd2` are broken. |
18+
| `__init__.py` | Re-exports `Config`, `load_payload`, the validators, and `optional_import` / `optional_attr` / `MissingDependencyError` so callers can do `from core import Config`. |
1819

1920
## Usage
2021

@@ -39,3 +40,25 @@ if not check_rhost(cfg.rhost):
3940
but adds no new logic.
4041
- All validators return `bool` — they never raise, never print, never log.
4142
Callers decide what to do on failure.
43+
- Heavy third-party packages must be bound through `optional_import` /
44+
`optional_attr`, never imported directly at module top level in
45+
`utils.py`. This keeps a single missing package from crashing the whole
46+
framework at import time. The dependent feature raises
47+
`MissingDependencyError` (with a `pip install` hint) only when actually
48+
used. The operator-facing preflight report — Python version, virtual
49+
environment, external binaries, certificates, SecLists — lives in
50+
`cli/doctor.py` (the `doctor` shell command); `core/dependencies.py` owns
51+
runtime resilience for lazily-imported Python packages only.
52+
53+
## Optional dependencies
54+
55+
```python
56+
from core.dependencies import optional_attr, optional_import
57+
58+
AES = optional_attr("Crypto.Cipher", "AES") # real class when installed
59+
pandas = optional_import("pandas") # deferred proxy when missing
60+
61+
if pandas: # proxy is falsy
62+
frame = pandas.DataFrame(rows)
63+
```
64+

core/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
print_warn,
5858
)
5959
from core.crypto import xor_encrypt_decrypt
60+
from core.dependencies import (
61+
MissingDependencyError,
62+
optional_attr,
63+
optional_import,
64+
)
6065
from core.payload_schema import (
6166
SCHEMA,
6267
FieldKind,
@@ -131,6 +136,9 @@
131136
"check_lhost",
132137
"check_lport",
133138
"check_port",
139+
"MissingDependencyError",
140+
"optional_import",
141+
"optional_attr",
134142
"SCHEMA",
135143
"FieldKind",
136144
"FieldSpec",

0 commit comments

Comments
 (0)