pwn 0.5.628 → 0.5.629
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +29 -21
- data/bin/pwn +35 -1
- data/bin/pwn_setup +64 -0
- data/documentation/AI-Integration.md +48 -9
- data/documentation/AWS.md +1 -1
- data/documentation/Agent-Tool-Registry.md +24 -0
- data/documentation/BurpSuite.md +4 -1
- data/documentation/CLI-Drivers.md +27 -10
- data/documentation/Configuration.md +37 -10
- data/documentation/Contributing.md +13 -3
- data/documentation/Extrospection.md +108 -98
- data/documentation/FFI.md +14 -2
- data/documentation/Fuzzing.md +3 -0
- data/documentation/General-PWN-Usage.md +12 -0
- data/documentation/Hardware.md +4 -0
- data/documentation/Home.md +4 -4
- data/documentation/How-PWN-Works.md +2 -1
- data/documentation/Installation.md +201 -37
- data/documentation/Metasploit.md +4 -1
- data/documentation/NmapIt.md +3 -0
- data/documentation/Persistence.md +5 -2
- data/documentation/Reporting.md +3 -0
- data/documentation/SDR.md +4 -0
- data/documentation/Skills-Memory-Learning.md +24 -11
- data/documentation/Swarm.md +20 -0
- data/documentation/Transparent-Browser.md +3 -0
- data/documentation/Troubleshooting.md +63 -7
- data/documentation/What-is-PWN.md +1 -1
- data/documentation/diagrams/agent-tool-registry.svg +120 -109
- data/documentation/diagrams/ai-integration-tool-calling.svg +76 -65
- data/documentation/diagrams/dot/agent-tool-registry.dot +5 -3
- data/documentation/diagrams/dot/ai-integration-tool-calling.dot +3 -2
- data/documentation/diagrams/dot/memory-skills-detailed.dot +26 -4
- data/documentation/diagrams/dot/overall-pwn-architecture.dot +6 -4
- data/documentation/diagrams/dot/persistence-filesystem.dot +4 -2
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +31 -10
- data/documentation/diagrams/dot/swarm-multi-agent.dot +7 -1
- data/documentation/diagrams/extrospection-world-awareness.svg +129 -129
- data/documentation/diagrams/memory-skills-detailed.svg +268 -137
- data/documentation/diagrams/overall-pwn-architecture.svg +188 -171
- data/documentation/diagrams/persistence-filesystem.svg +115 -85
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +407 -255
- data/documentation/diagrams/sdr-radio-flow.svg +51 -51
- data/documentation/diagrams/swarm-multi-agent.svg +156 -119
- data/documentation/pwn-REPL.md +1 -0
- data/documentation/pwn-ai-Agent.md +50 -22
- data/lib/pwn/ai/agent/dispatch.rb +1 -1
- data/lib/pwn/ai/agent/learning.rb +1 -1
- data/lib/pwn/ai/agent/loop.rb +40 -0
- data/lib/pwn/ai/agent/metrics.rb +1 -1
- data/lib/pwn/config.rb +2 -2
- data/lib/pwn/memory_index.rb +1 -1
- data/lib/pwn/plugins/repl.rb +26 -2
- data/lib/pwn/setup.rb +563 -0
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +1 -0
- data/spec/lib/pwn/setup_spec.rb +28 -0
- data/third_party/pwn_rdoc.jsonl +15 -1
- metadata +5 -1
|
@@ -1,73 +1,237 @@
|
|
|
1
1
|
# Installation
|
|
2
2
|
|
|
3
|
-
PWN
|
|
4
|
-
|
|
3
|
+
PWN ships as a **single Ruby gem** whose runtime is 100 % `autoload`ed —
|
|
4
|
+
a plugin whose native extension or OS binary is missing costs nothing until
|
|
5
|
+
you actually touch that constant. That means the install is **two steps**:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
gem install pwn # 1. get the gem (pure-Ruby core always works)
|
|
9
|
+
pwn setup # 2. doctor + provision this host's capabilities
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`pwn setup` is the built-in **doctor / provisioner** (`PWN::Setup`). It
|
|
13
|
+
detects your OS package manager (`apt` · `dnf` · `pacman` · `brew` · `port`),
|
|
14
|
+
reports which `PWN::` capabilities are usable on *this* host, and — when
|
|
15
|
+
asked — installs exactly the OS headers, external tools, and native gems
|
|
16
|
+
needed to unlock the ones you want. No `/opt/pwn` checkout, no `rvmsudo`
|
|
17
|
+
chain, no bash provisioners required.
|
|
18
|
+
|
|
19
|
+
Tested on **Kali / Debian / Ubuntu**, **Fedora**, **Arch**, and **macOS**
|
|
20
|
+
(Homebrew or MacPorts). Ruby ≥ 3.4 (RVM, rbenv, asdf, or system Ruby).
|
|
21
|
+
|
|
22
|
+
---
|
|
5
23
|
|
|
6
24
|
## Quick install (recommended)
|
|
7
25
|
|
|
8
26
|
```bash
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
gem install pwn
|
|
28
|
+
pwn setup # read-only doctor: what's usable, what's missing
|
|
29
|
+
pwn setup --profile full --yes # install everything for every PWN:: namespace
|
|
30
|
+
pwn # launch the REPL
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
pwn[v0.5.628]:001 >>> PWN.help
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If you only need a subset (e.g. web testing on a CI runner, SDR on a lab
|
|
38
|
+
box), install just that **capability profile** — see below.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## `pwn setup` — the post-install doctor & provisioner
|
|
43
|
+
|
|
44
|
+
Three equivalent spellings ship with the gem:
|
|
45
|
+
|
|
46
|
+
| Invocation | Same as |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `pwn setup [opts]` | bare-word subcommand of `bin/pwn` |
|
|
49
|
+
| `pwn_setup [opts]` | standalone driver (`bin/pwn_setup`) |
|
|
50
|
+
| `pwn --setup[=PROFILE]` | flag form; no `PROFILE` = check, `PROFILE` = deps |
|
|
51
|
+
|
|
52
|
+
### Read-only doctor (default)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
$ pwn setup # or: pwn setup --check / pwn --setup / pwn_setup
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Prints a per-capability report and **exits non-zero if anything is degraded**
|
|
59
|
+
(so you can gate CI on it):
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
PWN v0.5.628 · ruby 4.0.5 · linux x86_64 · pkg-manager: apt
|
|
63
|
+
|
|
64
|
+
~/.pwn/ ok (11 entries)
|
|
65
|
+
~/.pwn/pwn.yaml ok (encrypted, decryptor present)
|
|
66
|
+
AI engine ok anthropic (key set)
|
|
67
|
+
|
|
68
|
+
Ruby extensions
|
|
69
|
+
pg MISSING (needs: postgresql-server-dev-all) → PWN::Plugins::DAOPostgres
|
|
70
|
+
pcaprub ok → PWN::Plugins::Packet, extro_packet
|
|
71
|
+
nokogiri ok → PWN::Plugins::TransparentBrowser, PWN::WWW
|
|
72
|
+
…
|
|
73
|
+
|
|
74
|
+
External toolchain used by
|
|
75
|
+
nmap ok /usr/bin/nmap PWN::Plugins::NmapIt
|
|
76
|
+
gqrx MISSING PWN::SDR, extro_rf_tune
|
|
77
|
+
…
|
|
78
|
+
|
|
79
|
+
31 / 36 capabilities usable · 5 degraded
|
|
80
|
+
|
|
81
|
+
Run `pwn setup --deps` to install missing OS headers/tools, or
|
|
82
|
+
`pwn setup --profile <name>` for a subset. See `pwn setup --list-profiles`.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Install dependencies
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pwn setup --deps # profile :full — everything
|
|
89
|
+
pwn setup --profile web # just TransparentBrowser · Burp · ZAP · Tor
|
|
90
|
+
pwn setup --profile sdr --yes # non-interactive (CI / packer / docker)
|
|
91
|
+
pwn setup --profile net --dry-run # print the apt/dnf/brew/… commands only
|
|
92
|
+
pwn setup --list-profiles
|
|
15
93
|
```
|
|
16
94
|
|
|
95
|
+
`--deps` / `--profile` will:
|
|
96
|
+
|
|
97
|
+
1. Resolve the profile → set of native gems + external binaries.
|
|
98
|
+
2. Map those to OS packages for **your** package manager (data lives in
|
|
99
|
+
`PWN::Setup::NATIVE_GEMS` / `::TOOLCHAIN` — versioned with the gem, so
|
|
100
|
+
`gem install pwn`, git checkout, Docker, Packer and Vagrant all read the
|
|
101
|
+
same table).
|
|
102
|
+
3. Show the exact commands, prompt (unless `--yes`), run them, then
|
|
103
|
+
`gem pristine` / `gem install` any native extension that still fails to
|
|
104
|
+
load, and re-run the doctor.
|
|
105
|
+
|
|
106
|
+
### Capability profiles
|
|
107
|
+
|
|
108
|
+
`pwn setup --list-profiles` (source of truth: `PWN::Setup::PROFILES`)
|
|
109
|
+
|
|
110
|
+
| Profile | Unlocks |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `core` | `~/.pwn` bootstrap · vault · REPL — always applied |
|
|
113
|
+
| `ai` | verify at least one AI engine key/oauth in `~/.pwn/pwn.yaml` |
|
|
114
|
+
| `web` | `TransparentBrowser` · `BurpSuite` · `Zaproxy` · `extro_verify` · `extro_watch` · `sqlmap` · `tor` |
|
|
115
|
+
| `net` | `NmapIt` · `Packet` · `extro_packet` · `extro_osint` · `tshark`/`tcpdump` |
|
|
116
|
+
| `db` | `DAOPostgres` · `DAOSqlite3` · `DAOMongo` |
|
|
117
|
+
| `sdr` | `PWN::SDR` · GQRX · `PWN::FFI` DSP backends · `extro_rf_tune` · rtl-sdr / hackrf / SoapySDR |
|
|
118
|
+
| `vision` | `OCR` · `ScannableCodes` · `Reports` · `extro_vision` · tesseract / zbar / graphviz |
|
|
119
|
+
| `voice` | `PWN::Plugins::Voice` · `extro_voice` · espeak-ng / sox |
|
|
120
|
+
| `exploit` | `Metasploit` · `sqlmap` |
|
|
121
|
+
| `hardware` | `Serial` · `BusPirate` · `Android` · `BareSIP` · `extro_serial` · `extro_telecomm` |
|
|
122
|
+
| `full` | everything above |
|
|
123
|
+
|
|
124
|
+
### All flags
|
|
125
|
+
|
|
17
126
|
```text
|
|
18
|
-
pwn[
|
|
127
|
+
pwn setup [--check] [--deps] [--profile NAME] [--list-profiles]
|
|
128
|
+
[--yes] [--dry-run]
|
|
19
129
|
```
|
|
20
130
|
|
|
21
|
-
|
|
131
|
+
| Flag | Meaning |
|
|
132
|
+
|---|---|
|
|
133
|
+
| *(none)* / `-c`, `--check` | Read-only doctor. Exit 1 if any capability degraded. |
|
|
134
|
+
| `-d`, `--deps` | Install OS packages + rebuild native gems for `--profile` (default `full`). |
|
|
135
|
+
| `-p`, `--profile NAME` | One of the profiles above. Implies `--deps`. |
|
|
136
|
+
| `-l`, `--list-profiles` | Print profile table and exit. |
|
|
137
|
+
| `-y`, `--yes` | Assume yes; non-interactive (CI / Docker / Packer). |
|
|
138
|
+
| `-n`, `--dry-run` | Print the commands that *would* run, do nothing. |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## From a git checkout (contributors)
|
|
22
143
|
|
|
23
144
|
```bash
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
145
|
+
git clone https://github.com/0dayinc/pwn /opt/pwn
|
|
146
|
+
cd /opt/pwn
|
|
147
|
+
bundle install
|
|
148
|
+
rake install # or: rvmsudo rake install (multi-user RVM)
|
|
149
|
+
pwn setup --profile full --yes # same provisioner, same data tables
|
|
28
150
|
```
|
|
29
151
|
|
|
152
|
+
The legacy `./install.sh` / `packer/provisioners/pwn.sh` bash paths still
|
|
153
|
+
work, but they now simply delegate to `pwn setup` — the `case $os` package
|
|
154
|
+
lists have been consolidated into `PWN::Setup::NATIVE_GEMS` / `::TOOLCHAIN`.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Docker / Packer / Vagrant / CI
|
|
159
|
+
|
|
160
|
+
`pwn setup` is the single provisioning entry point for every image builder:
|
|
161
|
+
|
|
162
|
+
```dockerfile
|
|
163
|
+
FROM kalilinux/kali-rolling
|
|
164
|
+
RUN gem install pwn && pwn setup --profile full --yes
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
# .gitlab-ci.yml — fail the job if the runner is missing a capability
|
|
169
|
+
before_script:
|
|
170
|
+
- pwn setup --profile web --yes
|
|
171
|
+
- pwn setup --check
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# packer / vagrant provisioner
|
|
176
|
+
pwn setup --profile ${PWN_PROFILE:-full} --yes
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
30
181
|
## Upgrading
|
|
31
182
|
|
|
32
183
|
```bash
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
gem install --verbose pwn
|
|
184
|
+
gem update pwn # or: gem uninstall --all --executables pwn && gem install pwn
|
|
185
|
+
pwn setup # re-doctor — new versions may add capabilities
|
|
36
186
|
```
|
|
37
187
|
|
|
38
|
-
|
|
188
|
+
From a checkout:
|
|
39
189
|
|
|
40
190
|
```bash
|
|
41
|
-
cd /opt/pwn && git pull &&
|
|
191
|
+
cd /opt/pwn && git pull && rake install && pwn setup
|
|
42
192
|
```
|
|
43
193
|
|
|
194
|
+
---
|
|
195
|
+
|
|
44
196
|
## First-run configuration
|
|
45
197
|
|
|
46
|
-
`pwn` creates `~/.pwn/`
|
|
47
|
-
`~/.pwn/
|
|
198
|
+
The first `pwn` launch creates `~/.pwn/` and an **encrypted**
|
|
199
|
+
`~/.pwn/pwn.yaml` template. Add at least one LLM engine key with the
|
|
200
|
+
`pwn-vault` REPL command to enable `pwn-ai` — see
|
|
201
|
+
[Configuration](Configuration.md). `pwn setup` will report the AI-engine
|
|
202
|
+
row as `MISSING` until a key is set.
|
|
48
203
|
|
|
49
|
-
|
|
204
|
+
---
|
|
50
205
|
|
|
51
|
-
|
|
206
|
+
## Programmatic API — `PWN::Setup`
|
|
52
207
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
208
|
+
Everything above is a thin CLI over one autoloaded module:
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
PWN::Setup.check # → { ok:, native_gems_missing:, toolchain_missing:, pkg_manager:, os:, arch: }
|
|
212
|
+
PWN::Setup.deps(profile: :web, yes: true) # install, then re-check
|
|
213
|
+
PWN::Setup.list_profiles
|
|
214
|
+
PWN::Setup.pkg_manager # → { key: :apt, install: 'sudo apt-get install -y', sudo: true }
|
|
215
|
+
|
|
216
|
+
# The data tables — single source of truth, versioned with the gem:
|
|
217
|
+
PWN::Setup::NATIVE_GEMS # native ext → { apt:, dnf:, pacman:, brew:, port:, plugins: }
|
|
218
|
+
PWN::Setup::TOOLCHAIN # external bin → { apt:, dnf:, pacman:, brew:, port:, plugins: }
|
|
219
|
+
PWN::Setup::PROFILES # profile → { desc:, gems:, bins: }
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Adding a new native dependency or wrapped binary? Add **one row** to the
|
|
223
|
+
appropriate constant in `lib/pwn/setup.rb` — every install path (gem, git,
|
|
224
|
+
Docker, Packer, Vagrant, CI) picks it up automatically.
|
|
225
|
+
|
|
226
|
+
---
|
|
64
227
|
|
|
65
228
|
## Verify
|
|
66
229
|
|
|
67
230
|
```ruby
|
|
68
|
-
pwn[v0.5.
|
|
69
|
-
pwn[v0.5.
|
|
70
|
-
pwn[v0.5.
|
|
231
|
+
pwn[v0.5.628]:001 >>> PWN::Setup.check[:ok] # => true
|
|
232
|
+
pwn[v0.5.628]:002 >>> PWN::Plugins.constants.count # => 66
|
|
233
|
+
pwn[v0.5.628]:003 >>> PWN::SAST.constants.count # => 48
|
|
234
|
+
pwn[v0.5.628]:004 >>> pwn-ai # launches agent TUI
|
|
71
235
|
```
|
|
72
236
|
|
|
73
237
|
**Next:** [Configuration](Configuration.md) · [General Usage](General-PWN-Usage.md)
|
data/documentation/Metasploit.md
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
RPC client for `msfrpcd` — search modules, set options, run exploits, interact
|
|
4
4
|
with sessions, all from Ruby.
|
|
5
5
|
|
|
6
|
+
> **Install:** `pwn setup --profile exploit` — metasploit-framework ·
|
|
7
|
+
> sqlmap. See [Installation](Installation.md).
|
|
8
|
+
|
|
6
9
|
## Configure
|
|
7
10
|
|
|
8
11
|
```yaml
|
|
9
|
-
# ~/.pwn/
|
|
12
|
+
# ~/.pwn/pwn.yaml (edit via `pwn-vault`)
|
|
10
13
|
metasploit:
|
|
11
14
|
host: 127.0.0.1
|
|
12
15
|
port: 55553
|
data/documentation/NmapIt.md
CHANGED
|
@@ -4,6 +4,9 @@ Thin, composable wrapper over `nmap` with structured XML parsing.
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
+
> **Install:** `pwn setup --profile net` — nmap · tshark · tcpdump ·
|
|
8
|
+
> pcaprub headers · whois. See [Installation](Installation.md).
|
|
9
|
+
|
|
7
10
|
```ruby
|
|
8
11
|
r = PWN::Plugins::NmapIt.port_scan(
|
|
9
12
|
target: '10.0.0.0/24',
|
|
@@ -6,12 +6,15 @@ Every byte PWN remembers between processes lives here.
|
|
|
6
6
|
|
|
7
7
|
| Path | Owner | Format | Reset tool | Purpose |
|
|
8
8
|
|---|---|---|---|---|
|
|
9
|
-
| `
|
|
9
|
+
| `pwn.yaml` | `PWN::Config` · `PWN::Plugins::Vault` | AES-encrypted YAML | `pwn-vault` | engines, keys, agent options |
|
|
10
|
+
| `pwn.yaml.decryptor` | `PWN::Plugins::Vault` | key/IV | — | decrypts `pwn.yaml` (or set `PWN_DECRYPTOR_KEY`/`_IV`) |
|
|
10
11
|
| `memory.json` | `PWN::Memory` | JSON array | `memory_clear` | facts · prefs · lessons · env — injected into every prompt |
|
|
12
|
+
| `memory.idx` | `PWN::MemoryIndex` | JSON `{key → {sha,vec}}` | `PWN::MemoryIndex.reset` | local embedding index over `memory.json` — powers **relevance-ranked** MEMORY injection (incremental; only re-embeds changed entries) |
|
|
13
|
+
| `finetune/*.jsonl` | `PWN::AI::Agent::Learning.export_finetune` | ShareGPT / OpenAI JSONL | `rm` | supervised dataset cut from every successful session — feed to a LoRA over the local model |
|
|
11
14
|
| `skills/*.md` | `PWN::Config.load_skills` | Markdown + YAML front-matter | `skill_delete` | reusable procedures + `references:` (CWE/CVE/ATT&CK/NIST) |
|
|
12
15
|
| `learning.jsonl` | `PWN::AI::Agent::Learning` | JSON-per-line | `learning_reset` | task outcome log → success_rate |
|
|
13
16
|
| **`mistakes.json`** | **`PWN::AI::Agent::Mistakes`** | **JSON `{sig → entry}`** | **`mistakes_reset`** | **failure fingerprints · cross-session count · fix · `[REPEATING]` · `[REGRESSED]`** |
|
|
14
|
-
| `metrics.json` | `PWN::AI::Agent::Metrics` | JSON | `metrics_reset` | per-tool calls · success · avg_duration · last_error |
|
|
17
|
+
| `metrics.json` | `PWN::AI::Agent::Metrics` | JSON | `metrics_reset` | per-tool calls · success · avg_duration · last_error · **per-engine** sub-buckets |
|
|
15
18
|
| `extrospection.json` | `PWN::AI::Agent::Extrospection` | JSON | `extro_reset` | host/net/toolchain/repo/env/**rf**/**web** snapshot + previous baseline + observations[] |
|
|
16
19
|
| `extrospection/web/*.png` | `PWN::AI::Agent::Extrospection` | PNG | `rm -rf` | headless-browser screenshots from `probe_web` / `extro_watch` (opt-in) |
|
|
17
20
|
| `sessions/*.jsonl` | `PWN::Sessions` | JSON-per-line | `sessions_delete` | full transcript per pwn-ai run |
|
data/documentation/Reporting.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
+
> **Install:** `pwn setup --profile vision` — imagemagick · graphviz ·
|
|
6
|
+
> rmagick / gruff headers. See [Installation](Installation.md).
|
|
7
|
+
|
|
5
8
|
## Generators (`lib/pwn/reports/*.rb`)
|
|
6
9
|
|
|
7
10
|
| Module | Consumes | Emits |
|
data/documentation/SDR.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
+
> **Install:** `pwn setup --profile sdr` — GQRX · rtl-sdr · hackrf ·
|
|
6
|
+
> SoapySDR · multimon-ng · sox · libsndfile · libusb. See
|
|
7
|
+
> [Installation](Installation.md).
|
|
8
|
+
|
|
5
9
|
## Modules (`lib/pwn/sdr/*.rb`)
|
|
6
10
|
|
|
7
11
|
| Module | Purpose |
|
|
@@ -10,27 +10,38 @@ its own performance, turns wins into permanent capability, and — critically
|
|
|
10
10
|
|
|
11
11
|
| Store | File | Write tool | Read tool | Injected as |
|
|
12
12
|
|---|---|---|---|---|
|
|
13
|
-
| **Memory** | `memory.json` | `memory_remember` | `memory_recall` | `MEMORY` block — durable facts / prefs / lessons / env |
|
|
13
|
+
| **Memory** | `memory.json` (+ `memory.idx`) | `memory_remember` | `memory_recall` · `PWN::MemoryIndex.recall_semantic` | `MEMORY` block — durable facts / prefs / lessons / env. **Relevance-ranked** for the current request via a local embedding index when `ai.ollama.embed_model` is available; falls back to newest-first otherwise. |
|
|
14
14
|
| **Skills** | `skills/*.md` | `skill_create` · `learning_distill_skill` | `skill_list` · `skill_view` | `SKILLS` list — reusable procedures + `references:` (CWE/CVE/ATT&CK/NIST/URL) |
|
|
15
|
-
| **Learning** | `learning.jsonl` | `learning_note_outcome` · `learning_reflect` | `learning_outcomes` · `learning_stats` | `LEARNING` block — recent outcomes + success_rate |
|
|
15
|
+
| **Learning** | `learning.jsonl` | `learning_note_outcome` · `learning_reflect` | `learning_outcomes` · `learning_stats` · `Learning.exemplars_for` | `LEARNING` block — recent outcomes + success_rate. Prior *successful* traces are also spliced in as **few-shot exemplars** for local models. |
|
|
16
16
|
| **Mistakes** | `mistakes.json` | `mistakes_record` · `mistakes_resolve` · *auto on failure* | `mistakes_list` | `KNOWN MISTAKES` + `KNOWN FIXES` blocks — do-NOT-repeat + do-THIS-instead |
|
|
17
|
-
| **Metrics** | `metrics.json` | *automatic* (every Dispatch) | `metrics_summary` | `TOOL EFFECTIVENESS` block — steer tool choice |
|
|
17
|
+
| **Metrics** | `metrics.json` | *automatic* (every Dispatch) | `metrics_summary` | `TOOL EFFECTIVENESS` block — steer tool choice. **Segmented per engine** (`engine=…`) so a local model's telemetry never blends with a frontier model's. |
|
|
18
18
|
|
|
19
19
|
## The lifecycle of a lesson
|
|
20
20
|
|
|
21
21
|
```text
|
|
22
|
-
1.
|
|
22
|
+
1. PromptBuilder.budget picks per-engine caps → MemoryIndex.recall_semantic
|
|
23
|
+
picks the N MOST-RELEVANT memories for THIS request (not the N newest).
|
|
24
|
+
2. (local model) Learning.exemplars_for(request) splices a compressed prior
|
|
25
|
+
successful trace between system and user — 1 concrete example beats 25
|
|
26
|
+
abstract lessons for a small model.
|
|
27
|
+
3. (local model) Loop.plan_first forces a numbered tool plan BEFORE dispatch.
|
|
28
|
+
4. Dispatch runs a tool → Metrics.record(tool, ok?, ms, engine:)
|
|
23
29
|
↳ tool FAILED? → Mistakes.record(tool, error) (count++, cross-session)
|
|
24
30
|
↳ same sig ≥3×? → guard_repeated_failure + inline correction_hint
|
|
25
|
-
|
|
31
|
+
↳ (local) ≥ ESCALATE_AFTER_FAILS → Swarm.ask(escalation_persona) → 3-line frontier hint
|
|
32
|
+
5. Agent senses the world (opt) → extro_verify / watch / rf_tune / osint / serial / telecomm / packet / vision / voice / intel / observe
|
|
26
33
|
↳ extro_verify → :refuted → Mistakes.record(tool:'assumption', …) # proactive
|
|
27
34
|
↳ extro_verify → :confirmed → observe(:intel, ttl:30d)
|
|
28
|
-
|
|
35
|
+
6. Final answer produced → Learning.auto_introspect(session_id)
|
|
36
|
+
↳ (local) fact_check_local_final → auto extro_verify every CVE/version claim in the answer
|
|
29
37
|
↳ if auto_extrospect enabled → Extrospection.auto_extrospect # AUTO_SECTIONS only
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
7. Reflect.on(engine: reflect_engine)→ Memory.remember(lesson_xxxx, …) # teacher-student: a
|
|
39
|
+
frontier engine may WRITE the lesson a local engine READS
|
|
40
|
+
8. A whole workflow succeeded → Learning.distill_skill(name, session_id, references:)
|
|
41
|
+
9. Found a fix for a mistake → mistakes_resolve(sig, fix) → Memory :lesson "AVOID X — FIX: Y"
|
|
42
|
+
10. (weekly, cron) Learning.export_finetune → ~/.pwn/finetune/*.jsonl → LoRA over the local
|
|
43
|
+
model — the ONLY step that changes weights, not just the scaffold.
|
|
44
|
+
11. Next launch: PromptBuilder injects the budgeted blocks → the model already knows:
|
|
34
45
|
MEMORY · SKILLS · LEARNING · KNOWN MISTAKES/FIXES · TOOL EFFECTIVENESS · EXTROSPECTION
|
|
35
46
|
```
|
|
36
47
|
|
|
@@ -75,6 +86,8 @@ the `## References` section, deduplicates, and exposes them via
|
|
|
75
86
|
| `metrics_reset(confirm: true)` | fixed a broken tool; stale 0 % is misleading |
|
|
76
87
|
| `skill_delete(name)` | auto-distilled skill turned out low-quality |
|
|
77
88
|
| `learning_auto_introspect_toggle(enabled: false)` | during noisy fuzz loops |
|
|
89
|
+
| `PWN::MemoryIndex.reset` | new engagement — drop the local embedding index (`memory.idx`) so it rebuilds against the fresh `memory.json` |
|
|
90
|
+
| `PWN::AI::Agent::Learning.export_finetune(format: :sharegpt)` | you have enough successful sessions to cut a supervised dataset for the local model |
|
|
78
91
|
|
|
79
92
|
## Example questions that trigger Introspection
|
|
80
93
|
|
|
@@ -85,7 +98,7 @@ when deciding which side of the loop to exercise.
|
|
|
85
98
|
|
|
86
99
|
### Memory (`memory_remember`, `memory_recall`, `memory_forget`, `memory_clear`)
|
|
87
100
|
|
|
88
|
-
- “Remember that our preferred AI engine for long recon chains is grok
|
|
101
|
+
- “Remember that our preferred AI engine for long recon chains is `grok`.”
|
|
89
102
|
- “What do we already know about OpenSSH 8.2p1 from prior sessions?”
|
|
90
103
|
- “Forget the stale fact about the old HackRF serial — it was replaced.”
|
|
91
104
|
- “Store this as a durable lesson: always back up source files before patching.”
|
data/documentation/Swarm.md
CHANGED
|
@@ -49,6 +49,26 @@ agent_spawn(name: 'blue_team',
|
|
|
49
49
|
| `swarm_bus(swarm_id)` | Tail a bus to inspect a prior/concurrent conversation |
|
|
50
50
|
| `swarm_list` | Find a `swarm_id` to resume |
|
|
51
51
|
|
|
52
|
+
|
|
53
|
+
## Escalation persona (local-model circuit-breaker)
|
|
54
|
+
|
|
55
|
+
`Loop.run` also uses Swarm *implicitly*. When the active engine is `ollama`
|
|
56
|
+
and `ai.agent.escalation_persona` names a persona here, the loop counts
|
|
57
|
+
in-turn tool failures; once ≥ `Loop::ESCALATE_AFTER_FAILS` (default 4) it
|
|
58
|
+
calls `Swarm.ask(name: <persona>, request: "Local agent is stuck on: … Give a
|
|
59
|
+
3-line corrective hint")` and injects the reply as a synthetic
|
|
60
|
+
`frontier_hint` tool result. The **local model still authors the final
|
|
61
|
+
answer** — Learning / Metrics stay attributed to `:ollama`, and every
|
|
62
|
+
escalation is fingerprinted into `Mistakes` (tool: `'escalation'`) so
|
|
63
|
+
`export_finetune` can later teach the local model to *not* need it.
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
# ~/.pwn/pwn.yaml
|
|
67
|
+
ai:
|
|
68
|
+
agent:
|
|
69
|
+
escalation_persona: blue_team # any persona in ~/.pwn/agents.yml
|
|
70
|
+
```
|
|
71
|
+
|
|
52
72
|
## Example: adversarial exploit review
|
|
53
73
|
|
|
54
74
|
```ruby
|
|
@@ -6,6 +6,9 @@ capture. It's the traffic source for [BurpSuite](BurpSuite.md), the engine
|
|
|
6
6
|
under every [`PWN::WWW`](WWW.md) driver, and the agent's go-to for anything
|
|
7
7
|
JS-heavy.
|
|
8
8
|
|
|
9
|
+
> **Install:** `pwn setup --profile web` — chromium · geckodriver · tor ·
|
|
10
|
+
> nokogiri headers. See [Installation](Installation.md).
|
|
11
|
+
|
|
9
12
|
## Open
|
|
10
13
|
|
|
11
14
|
```ruby
|
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# Troubleshooting
|
|
2
2
|
|
|
3
|
+
## "Which capabilities are broken on this host?"
|
|
4
|
+
|
|
5
|
+
Run the built-in doctor — it tells you exactly which native gem or external
|
|
6
|
+
binary is missing, what OS package provides it, and which `PWN::` constants
|
|
7
|
+
are degraded as a result:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
$ pwn setup # or: pwn_setup / pwn --setup
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then fix a subset:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
$ pwn setup --profile web # or: net · sdr · vision · voice · db · hardware · exploit · full
|
|
17
|
+
$ pwn setup --deps --dry-run # show the apt/dnf/pacman/brew/port commands without running them
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
See [Installation](Installation.md#pwn-setup--the-post-install-doctor--provisioner)
|
|
21
|
+
for the full profile table and `PWN::Setup` API.
|
|
22
|
+
|
|
23
|
+
## `LoadError` / `cannot load such file -- pg` (or rmagick, pcaprub, …)
|
|
24
|
+
|
|
25
|
+
A native extension failed to compile because its OS headers weren't present
|
|
26
|
+
at `gem install` time. `pwn setup` knows the mapping for every package
|
|
27
|
+
manager and will install the headers **and** rebuild the gem:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
$ pwn setup --profile db # pg / sqlite3
|
|
31
|
+
$ pwn setup --profile vision # rmagick / rtesseract / oily_png / gruff
|
|
32
|
+
$ pwn setup --profile net # pcaprub
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The runtime is `autoload`ed, so a missing extension only surfaces when you
|
|
36
|
+
touch the constant that needs it — the rest of PWN keeps working.
|
|
37
|
+
|
|
38
|
+
## `nmap` / `chromium` / `gqrx` / … not found on `$PATH`
|
|
39
|
+
|
|
40
|
+
Same fix — `PWN::Setup::TOOLCHAIN` maps every wrapped binary to its OS
|
|
41
|
+
package on `apt` / `dnf` / `pacman` / `brew` / `port`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
$ pwn setup --profile web # chromium · geckodriver · burpsuite · zaproxy · sqlmap · tor
|
|
45
|
+
$ pwn setup --profile sdr # gqrx · rtl_sdr · hackrf_info · SoapySDRUtil · multimon-ng · sox
|
|
46
|
+
```
|
|
47
|
+
|
|
3
48
|
## SHIFT+ENTER submits instead of newline
|
|
4
49
|
|
|
5
50
|
`pwn-ai` / `pwn-asm` need the terminal to send a *distinct* code for
|
|
@@ -25,16 +70,17 @@ ss -tlnp | grep -E ':8080|:1337'
|
|
|
25
70
|
```
|
|
26
71
|
|
|
27
72
|
Restart via `PWN::Plugins::BurpSuite.start` / `PWN::Plugins::Zaproxy.start` or
|
|
28
|
-
fix the port
|
|
73
|
+
fix the port via `pwn-vault` (`~/.pwn/pwn.yaml`).
|
|
29
74
|
|
|
30
75
|
## `Psych::DisallowedClass` on cron/agents YAML
|
|
31
76
|
|
|
32
77
|
Fixed in current `PWN::Cron` / `Swarm` — both loaders now pass
|
|
33
|
-
`permitted_classes: [Symbol]`. If you see it, `
|
|
78
|
+
`permitted_classes: [Symbol]`. If you see it, `gem update pwn`.
|
|
34
79
|
|
|
35
80
|
## Agent stops early ("max iterations")
|
|
36
81
|
|
|
37
|
-
Raise `ai.agent.max_iters` in `~/.pwn/
|
|
82
|
+
Raise `ai.agent.max_iters` in `~/.pwn/pwn.yaml` (edit via `pwn-vault`), or
|
|
83
|
+
split the request.
|
|
38
84
|
|
|
39
85
|
## A tool is stuck at 0 % success
|
|
40
86
|
|
|
@@ -46,12 +92,22 @@ the agent away: `metrics_reset(confirm: true)`.
|
|
|
46
92
|
| Engine | Fix |
|
|
47
93
|
|---|---|
|
|
48
94
|
| grok `oauth: true` | first run prints a `https://accounts.x.ai/…` URL — open it, approve, token is cached |
|
|
49
|
-
| ollama | ensure `ollama serve` is running and `
|
|
50
|
-
| others | check `key:` under `ai.<engine>` in `~/.pwn/
|
|
95
|
+
| ollama | ensure `ollama serve` is running and `base_uri:` matches |
|
|
96
|
+
| others | check `key:` under `ai.<engine>` in `~/.pwn/pwn.yaml` (edit via `pwn-vault`) |
|
|
97
|
+
|
|
98
|
+
`pwn setup` reports the `AI engine` row as `MISSING` until a key is set.
|
|
51
99
|
|
|
52
100
|
## Diagrams won't rebuild
|
|
53
101
|
|
|
54
|
-
|
|
55
|
-
|
|
102
|
+
```bash
|
|
103
|
+
$ pwn setup --profile vision # installs graphviz (dot)
|
|
104
|
+
$ cd documentation/diagrams && ./build.sh
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## `No supported package manager found`
|
|
108
|
+
|
|
109
|
+
`PWN::Setup` supports `apt-get`, `dnf`, `pacman`, `brew`, and `port`. On other
|
|
110
|
+
systems use `pwn setup --dry-run --profile <name>` to print the package
|
|
111
|
+
list, then install equivalents by hand.
|
|
56
112
|
|
|
57
113
|
[← Home](Home.md)
|
|
@@ -20,7 +20,7 @@ tool-calling AI agent** on top of it.
|
|
|
20
20
|
| `PWN::WWW::*` | **21** | Site-specific browser automations (HackerOne, BugCrowd, Google, LinkedIn, …) |
|
|
21
21
|
| `PWN::SDR::*` | **6** | GQRX, FlipperZero, RFIDler, SonMicro, decoders, band tables |
|
|
22
22
|
| `PWN::AI::*` | **5** engines | OpenAI, Anthropic, Grok (OAuth device-flow), Gemini, Ollama |
|
|
23
|
-
| `bin/pwn_*` | **
|
|
23
|
+
| `bin/pwn_*` | **53** | Headless CLI drivers for CI/CD |
|
|
24
24
|
| Agent toolsets | **10** | terminal · pwn · memory · skills · sessions · learning · metrics · extrospection · cron · swarm |
|
|
25
25
|
|
|
26
26
|
## The three ways to use it
|