pwn 0.5.683 → 0.5.685
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 +17 -10
- data/documentation/Agent-Tool-Registry.md +3 -5
- data/documentation/CLI-Drivers.md +27 -28
- data/documentation/Configuration.md +5 -7
- data/documentation/Contributing.md +2 -2
- data/documentation/Cron.md +11 -7
- data/documentation/Diagrams.md +2 -2
- data/documentation/General-PWN-Usage.md +1 -1
- data/documentation/Home.md +8 -7
- data/documentation/How-PWN-Works.md +10 -10
- data/documentation/Installation.md +19 -3
- data/documentation/Persistence.md +3 -2
- data/documentation/Plugins.md +3 -3
- data/documentation/Reinforcement-Learning.md +102 -100
- data/documentation/SAST.md +1 -1
- data/documentation/Session-Workflow.md +132 -0
- data/documentation/Sessions.md +2 -1
- data/documentation/Skills-Memory-Learning.md +20 -0
- data/documentation/Troubleshooting.md +2 -2
- data/documentation/What-is-PWN.md +3 -3
- data/documentation/Why-PWN.md +1 -1
- data/documentation/diagrams/agent-tool-registry.svg +152 -152
- data/documentation/diagrams/cron-scheduling.svg +141 -121
- data/documentation/diagrams/dot/agent-tool-registry.dot +4 -4
- data/documentation/diagrams/dot/cron-scheduling.dot +10 -7
- data/documentation/diagrams/dot/driver-framework.dot +1 -1
- data/documentation/diagrams/dot/memory-skills-detailed.dot +1 -1
- data/documentation/diagrams/dot/overall-pwn-architecture.dot +5 -5
- data/documentation/diagrams/dot/persistence-filesystem.dot +2 -2
- data/documentation/diagrams/dot/plugin-ecosystem.dot +2 -2
- data/documentation/diagrams/dot/sessions-cron-automation.dot +1 -1
- data/documentation/diagrams/dot/task-summarizer.dot +18 -16
- data/documentation/diagrams/driver-framework.svg +1 -1
- data/documentation/diagrams/memory-skills-detailed.svg +85 -84
- data/documentation/diagrams/overall-pwn-architecture.svg +93 -93
- data/documentation/diagrams/persistence-filesystem.svg +5 -5
- data/documentation/diagrams/plugin-ecosystem.svg +101 -100
- data/documentation/diagrams/sessions-cron-automation.svg +7 -6
- data/documentation/diagrams/task-summarizer.svg +166 -156
- data/documentation/pwn-ai-Agent.md +13 -11
- data/etc/default_skills/bug-bounty-hunting/SKILL.md +70 -0
- data/etc/default_skills/deep-exploitation/SKILL.md +74 -0
- data/etc/default_skills/hardware-and-firmware-testing/SKILL.md +83 -0
- data/etc/default_skills/osint/SKILL.md +147 -0
- data/etc/default_skills/penetration-testing/SKILL.md +81 -0
- data/etc/default_skills/red-teaming/SKILL.md +70 -0
- data/etc/default_skills/reverse-engineering-binaries/SKILL.md +70 -0
- data/etc/default_skills/sast-code-scans/SKILL.md +66 -0
- data/etc/default_skills/social-engineering/SKILL.md +67 -0
- data/etc/default_skills/vulnerability-research-fundamentals/SKILL.md +74 -0
- data/etc/default_skills/web-application-penetration-testing/SKILL.md +68 -0
- data/lib/pwn/ai/agent/dispatch.rb +52 -1
- data/lib/pwn/ai/agent/loop.rb +170 -190
- data/lib/pwn/ai/agent/mistakes.rb +6 -6
- data/lib/pwn/ai/agent/open_goal.rb +83 -0
- data/lib/pwn/ai/agent/prompt_builder.rb +3 -5
- data/lib/pwn/ai/agent/tool_guard.rb +1 -46
- data/lib/pwn/ai/agent/tools/ruby_eval.rb +0 -10
- data/lib/pwn/ai/agent/tools/shell.rb +0 -6
- data/lib/pwn/ai/agent.rb +1 -0
- data/lib/pwn/config.rb +63 -2
- data/lib/pwn/cron.rb +18 -5
- data/lib/pwn/migrate.rb +2 -0
- data/lib/pwn/plugins/repl.rb +9 -4
- data/lib/pwn/plugins/tty_spinner.rb +64 -17
- data/lib/pwn/version.rb +1 -1
- data/spec/integration/config_spec.rb +37 -0
- data/spec/integration/persistence_roundtrip_spec.rb +2 -1
- data/spec/integration/reinforced_feedback_loop_spec.rb +6 -11
- data/spec/lib/pwn/ai/agent/dispatch_spec.rb +38 -82
- data/spec/lib/pwn/ai/agent/loop_spec.rb +230 -17
- data/spec/lib/pwn/ai/agent/mistakes_spec.rb +7 -0
- data/spec/lib/pwn/ai/agent/open_goal_spec.rb +37 -0
- data/spec/lib/pwn/ai/agent/signal_hygiene_spec.rb +5 -8
- data/spec/lib/pwn/ai/agent/tools/shell_spec.rb +10 -18
- data/spec/lib/pwn/cron_spec.rb +13 -3
- data/spec/lib/pwn/plugins/repl_spec.rb +17 -0
- data/spec/lib/pwn/plugins/tty_spinner_spec.rb +14 -0
- data/third_party/pwn_rdoc.jsonl +25 -5
- metadata +15 -2
- data/documentation/PWN_Contributors_and_Users.png +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4969508ce00cf858c5dfd06506e306f37d86e3d0671f07c3d3c021fa603b49d8
|
|
4
|
+
data.tar.gz: 6e23201a56add7514b8a12de42ee930aba424e33329bc9c608bd3dc4c2ce0473
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 980664beb783d0a4c4aed5df5548d8f3c839e47afadd566a35f5b3b4413d6242e6c6da54319cacc91ceb7a3f8f5756f8268d29876b6277fdfda2e2f4475a251d
|
|
7
|
+
data.tar.gz: de6ce8fac7cc8c1dda8989faef831c4c32bf88141d188b113aa16b7b0035f3062505fc4cb843ea2b7f9e179306f66060ab8fbc1e4c8a325169a274f5784ef79f
|
data/README.md
CHANGED
|
@@ -33,9 +33,9 @@ can run those same methods for you.
|
|
|
33
33
|
Red teamers, pentesters, and vulnerability researchers get one place to script
|
|
34
34
|
and automate instead of gluing together a pile of separate CLIs.
|
|
35
35
|
|
|
36
|
-
**In numbers:**
|
|
37
|
-
service wrappers · 22 `PWN::WWW` site drivers · 53 `bin/pwn_*`
|
|
38
|
-
6 LLM engines · 13 agent toolsets ·
|
|
36
|
+
**In numbers:** 67 `PWN::Plugins` · 48 `PWN::SAST` modules · 90 `PWN::AWS`
|
|
37
|
+
service wrappers · 22 `PWN::WWW` site drivers · 54 executables (`pwn` + 53 `bin/pwn_*`) ·
|
|
38
|
+
6 LLM engines · 13 agent toolsets · 87 LLM-callable tools.
|
|
39
39
|
|
|
40
40
|
Full page: [What is PWN](documentation/What-is-PWN.md)
|
|
41
41
|
|
|
@@ -119,11 +119,12 @@ message bus:
|
|
|
119
119
|

|
|
120
120
|
|
|
121
121
|
Long-running turns also show **executive task briefs** (not raw commands) via
|
|
122
|
-
`TaskSummarizer`.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
`TaskSummarizer`. There is no request type. Every request gets an English
|
|
123
|
+
task compass (`emit_plan!` on submit, `about_to` as `task k/n` before each
|
|
124
|
+
tool batch). Duplicate briefs are suppressed. Budget-hot turns skip extra
|
|
125
|
+
counterfactual forks and only strip tools on the last iteration when the
|
|
126
|
+
original request is already satisfied. Yesterday's scars do not lower this
|
|
127
|
+
request's `max_iters` (default 777).
|
|
127
128
|
|
|
128
129
|
Full pages: [How PWN Works](documentation/How-PWN-Works.md) ·
|
|
129
130
|
[All data-flow diagrams](documentation/Diagrams.md)
|
|
@@ -136,9 +137,9 @@ The complete wiki lives in this repo at **[`documentation/Home.md`](documentatio
|
|
|
136
137
|
|
|
137
138
|
| Start Here | Entry Points | AI Subsystem | Capabilities |
|
|
138
139
|
|---|---|---|---|
|
|
139
|
-
| [What is PWN](documentation/What-is-PWN.md) | [`pwn` REPL](documentation/pwn-REPL.md) | [AI / LLM Integration](documentation/AI-Integration.md) | [Plugins (
|
|
140
|
+
| [What is PWN](documentation/What-is-PWN.md) | [`pwn` REPL](documentation/pwn-REPL.md) | [AI / LLM Integration](documentation/AI-Integration.md) | [Plugins (67)](documentation/Plugins.md) |
|
|
140
141
|
| [Why PWN](documentation/Why-PWN.md) | [`pwn-ai` Agent](documentation/pwn-ai-Agent.md) | [Agent Tool Registry](documentation/Agent-Tool-Registry.md) | [SAST (48)](documentation/SAST.md) |
|
|
141
|
-
| [How PWN Works](documentation/How-PWN-Works.md) | [CLI Drivers (
|
|
142
|
+
| [How PWN Works](documentation/How-PWN-Works.md) | [CLI Drivers (54)](documentation/CLI-Drivers.md) | [Memory · Skills · Learning](documentation/Skills-Memory-Learning.md) | [AWS (90)](documentation/AWS.md) |
|
|
142
143
|
| [Installation](documentation/Installation.md) | [Build a Driver](documentation/Drivers.md) | [Mistakes (neg-feedback)](documentation/Mistakes.md) | [WWW (22)](documentation/WWW.md) |
|
|
143
144
|
| [General Usage](documentation/General-PWN-Usage.md) | | [Reinforcement Learning](documentation/Reinforcement-Learning.md) | [SDR / Radio](documentation/SDR.md) |
|
|
144
145
|
| [Configuration](documentation/Configuration.md) | | [Extrospection](documentation/Extrospection.md) | [Hardware](documentation/Hardware.md) |
|
|
@@ -181,6 +182,12 @@ $ pwn setup --profile net --dry-run
|
|
|
181
182
|
Also available as `pwn_setup` (standalone driver) and `pwn --setup[=PROFILE]`.
|
|
182
183
|
The doctor exits non-zero when capabilities are degraded, so CI can gate on it.
|
|
183
184
|
|
|
185
|
+
First launch seeds bundled operator skills into `~/.pwn/skills/` from
|
|
186
|
+
`etc/default_skills/` when those names are missing (vulnerability research,
|
|
187
|
+
pentest, red team, SAST, RE, hardware, social engineering, and related).
|
|
188
|
+
Existing `SKILL.md` files are never overwritten.
|
|
189
|
+
|
|
190
|
+
|
|
184
191
|
<!--[](https://youtu.be/G7iLUY4FzsI)-->
|
|
185
192
|
|
|
186
193
|
Full page: [Installation](documentation/Installation.md) ·
|
|
@@ -6,7 +6,7 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
|
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
## Toolsets to tools (13 toolsets ·
|
|
9
|
+
## Toolsets to tools (13 toolsets · 87 tools)
|
|
10
10
|
|
|
11
11
|
| Toolset | Tools | Backed by |
|
|
12
12
|
|---|---|---|
|
|
@@ -34,9 +34,7 @@ those without the full learning surface.
|
|
|
34
34
|
`shell` and `pwn_eval` share `PWN::AI::Agent::ToolGuard`
|
|
35
35
|
(`lib/pwn/ai/agent/tool_guard.rb`) before they run. The guard remaps common
|
|
36
36
|
wrong keys, rejects ellipsis placeholders, refuses bash-only syntax unless
|
|
37
|
-
`ai.agent.shell_bash` is true (default runner is `/bin/sh`)
|
|
38
|
-
host-discovery unless the request is in-scope or `ai.agent.recon_authorized`
|
|
39
|
-
is true.
|
|
37
|
+
`ai.agent.shell_bash` is true (default runner is `/bin/sh`).
|
|
40
38
|
|
|
41
39
|
The `policy` toolset is inspect-only. `policy_stats`, `policy_evaluate`, and
|
|
42
40
|
`policy_recommend` read the live Q / REINFORCE table. Reset is Ruby-only, so a
|
|
@@ -69,7 +67,7 @@ PWN::AI::Agent::Registry.definitions(relevance: 'nmap sweep 10.0.0.0/8', top_k:
|
|
|
69
67
|
PWN::AI::Agent::Registry.rank(query: 'run a shell command') # inspect ranking
|
|
70
68
|
PWN::AI::Agent::Registry.preference_order # Env / DEFAULT_PREFERENCE
|
|
71
69
|
PWN::AI::Agent::Registry.toolsets # -> the 13 names above
|
|
72
|
-
PWN::AI::Agent::Registry.all.count # ->
|
|
70
|
+
PWN::AI::Agent::Registry.all.count # -> 87
|
|
73
71
|
```
|
|
74
72
|
|
|
75
73
|
Frontier engines leave `tool_router` off (unless you set it) and receive the
|
|
@@ -9,34 +9,33 @@ without a REPL or an LLM.
|
|
|
9
9
|
## Full list
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
|
-
pwn
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
pwn_jenkins_useradd
|
|
12
|
+
pwn pwn_jenkins_update_plugins
|
|
13
|
+
pwn_ai_red_team pwn_jenkins_useradd
|
|
14
|
+
pwn_android_war_dialer pwn_mail_agent
|
|
15
|
+
pwn_autoinc_version pwn_msf_postgres_login
|
|
16
|
+
pwn_aws_describe_resources pwn_nessus_cloud_scan_crud
|
|
17
|
+
pwn_bdba_groups pwn_nessus_cloud_vulnscan
|
|
18
|
+
pwn_bdba_scan pwn_nexpose
|
|
19
|
+
pwn_burp_suite_pro_active_rest_api_scan pwn_nmap_discover_tcp_udp
|
|
20
|
+
pwn_burp_suite_pro_active_scan pwn_openvas_vulnscan
|
|
21
|
+
pwn_char_base64_encoding pwn_pastebin_sample_filter
|
|
22
|
+
pwn_char_dec_encoding pwn_phone
|
|
23
|
+
pwn_char_hex_escaped_encoding pwn_rdoc_to_jsonl
|
|
24
|
+
pwn_char_html_entity_encoding pwn_sast
|
|
25
|
+
pwn_char_unicode_escaped_encoding pwn_serial_check_voicemail
|
|
26
|
+
pwn_char_url_encoding pwn_serial_msr206
|
|
27
|
+
pwn_crt_sh pwn_serial_qualcomm_commands
|
|
28
|
+
pwn_defectdojo_engagement_create pwn_serial_son_micro_sm132_rfid
|
|
29
|
+
pwn_defectdojo_importscan pwn_setup
|
|
30
|
+
pwn_defectdojo_reimportscan pwn_shodan_graphql_introspection
|
|
31
|
+
pwn_diff_csv_files_w_column_exclude pwn_shodan_search
|
|
32
|
+
pwn_domain_reversewhois pwn_simple_http_server
|
|
33
|
+
pwn_fuzz_net_app_proto pwn_web_cache_deception
|
|
34
|
+
pwn_gqrx_scanner pwn_www_checkip
|
|
35
|
+
pwn_jenkins_create_job pwn_www_uri_buster
|
|
36
|
+
pwn_jenkins_create_view pwn_xss_dom_vectors
|
|
37
|
+
pwn_jenkins_install_plugin pwn_zaproxy_active_rest_api_scan
|
|
38
|
+
pwn_jenkins_thinBackup_aws_s3 pwn_zaproxy_active_scan
|
|
40
39
|
```
|
|
41
40
|
|
|
42
41
|
Run any with `--help` for its flags.
|
|
@@ -118,7 +118,7 @@ ai:
|
|
|
118
118
|
|
|
119
119
|
agent:
|
|
120
120
|
native_tools: true # Use provider-native tool_calls / function-calling. false → legacy text-parsed tool protocol.
|
|
121
|
-
max_iters:
|
|
121
|
+
max_iters: 777 # Hard cap on tool-call rounds per user turn. Scars do not lower it.
|
|
122
122
|
task_summary: true # Executive task briefs via TaskSummarizer (plan + about_to). false disables.
|
|
123
123
|
task_summary_every: 5 # When task_summary_verbose: emit Progress every N completed tools.
|
|
124
124
|
task_summary_interval_s: 8.0 # When verbose: also emit when this many seconds elapsed.
|
|
@@ -129,11 +129,10 @@ ai:
|
|
|
129
129
|
auto_extrospect: true # Ambient baseline after every final answer (host/repo/env ONLY - never launches burpsuite/zaproxy/msf/gqrx). Sense tools stay on-demand.
|
|
130
130
|
defer_introspect: true # Run auto_introspect on a background thread AFTER the user-visible reply (default on). Specs/cron stay inline.
|
|
131
131
|
prompt_cache: true # Engine-native prefix cache. Anthropic cache_control, OpenAI prompt_cache_key, Grok x-grok-conv-id, Gemini systemInstruction split. Ollama / Open WebUI have none.
|
|
132
|
-
recon_authorized: false # Allow live subnet sweeps / raw-socket discovery tools this session
|
|
133
132
|
shell_bash: false # true -> run shell via bash -lc. Default is /bin/sh.
|
|
134
133
|
plan_first: ~ # Plan-then-act pre-pass. nil = auto (true when ai.active is ollama or openwebui).
|
|
135
134
|
tool_router: ~ # Dynamic tool-set slimming. nil = auto (true for ollama / openwebui).
|
|
136
|
-
tool_preference: # Same order as CORE_TOOLS
|
|
135
|
+
tool_preference: # Same order as CORE_TOOLS: memory_recall, session_recall, skills_recall, pwn_eval, shell, mistakes_record, mistakes_resolve, learning_note_outcome, memory_remember. Current session is injected separately.
|
|
137
136
|
- memory_recall
|
|
138
137
|
- session_recall
|
|
139
138
|
- skills_recall
|
|
@@ -253,7 +252,7 @@ targets: # Optional - engagement-scope URLs/hosts. Mer
|
|
|
253
252
|
|
|
254
253
|
```ruby
|
|
255
254
|
PWN::Env[:ai][:active] # => :grok
|
|
256
|
-
PWN::Env.dig(:ai, :agent, :max_iters) # =>
|
|
255
|
+
PWN::Env.dig(:ai, :agent, :max_iters) # => 777
|
|
257
256
|
PWN::EnvRedacted[:ai][:grok][:key] # => ">>> REDACTED >>> ..."
|
|
258
257
|
|
|
259
258
|
# Edit + re-encrypt + reload without leaving the REPL:
|
|
@@ -303,7 +302,7 @@ PWN::Config.refresh_env
|
|
|
303
302
|
| Key path | Type | Default | Consumed by | Purpose |
|
|
304
303
|
|---|---|---|---|---|
|
|
305
304
|
| `ai.agent.native_tools` | Boolean | `true` | `PWN::Plugins::REPL` (`pwn-ai` cmd) | Use provider-native `tool_calls` / function-calling. `false` falls back to the legacy text-parsed tool protocol. |
|
|
306
|
-
| `ai.agent.max_iters` | Integer | `
|
|
305
|
+
| `ai.agent.max_iters` | Integer | `777` | `PWN::AI::Agent::Loop.run`, `PWN::AI::Agent::Swarm` | Hard cap on tool-call rounds per user turn. Budget-hot scars and overconfidence do not lower this request's runway. |
|
|
307
306
|
| `ai.agent.task_summary` | Boolean | `true` | `PWN::AI::Agent::TaskSummarizer`, `Loop` | Master switch for executive task briefs (`emit_plan!` / `about_to`). |
|
|
308
307
|
| `ai.agent.task_summary_every` | Integer | `5` | `TaskSummarizer.every_n` | Verbose progress cadence (tools). |
|
|
309
308
|
| `ai.agent.task_summary_interval_s` | Float | `8.0` | `TaskSummarizer.interval_s` | Verbose progress cadence (seconds). |
|
|
@@ -313,11 +312,10 @@ PWN::Config.refresh_env
|
|
|
313
312
|
| `ai.agent.auto_introspect` | Boolean | `true` | `PWN::AI::Agent::Learning.auto_introspect` | Run outcome logging + lesson mining after every final answer. Toggle live via `learning_auto_introspect_toggle`. |
|
|
314
313
|
| `ai.agent.auto_extrospect` | Boolean | `true` | `PWN::AI::Agent::Extrospection.auto_extrospect` | Ambient baseline after every final answer (`AUTO_SECTIONS` = host/repo/env only; never spawns GUI/JVM tools). Sense tools (`intel`/`verify`/`watch`/`rf_tune`/`observe`) stay on-demand. Toggle live via `extro_auto_toggle`. |
|
|
315
314
|
| `ai.agent.toolsets` | Array\<String\> \| `nil` | `nil` (all) | `bin/pwn`, `PWN::Plugins::REPL`, `PWN::AI::Agent::Registry` | Allow-list of toolsets exposed to the agent. Valid: `cron`, `curriculum`, `extrospection`, `learning`, `memory`, `metrics`, `policy`, `pwn`, `reward`, `sessions`, `skills`, `swarm`, `terminal`. |
|
|
316
|
-
| `ai.agent.recon_authorized` | Boolean | `false` | `PWN::AI::Agent::ToolGuard.recon_authorized?` / `Loop.recon_authorized?` | When true (or the user request contains in-scope / engagement language), live host-discovery tools may run. Default refuses unauthorized sweeps. |
|
|
317
315
|
| `ai.agent.shell_bash` | Boolean | `false` | `PWN::AI::Agent::ToolGuard.shell_bash?` | When true, `shell` runs via `bash -lc` so bash-only syntax is allowed. Default is POSIX `/bin/sh` and bashisms are rejected with a rewrite hint. |
|
|
318
316
|
| `ai.agent.plan_first` | Boolean \| `nil` | `nil` (auto: `true` when `ai.active` is `ollama` or `openwebui`) | `PWN::AI::Agent::Loop.plan_first` | Plan-then-act pre-pass: the model must emit a numbered tool plan (as an assistant message) *before* it may dispatch anything. Cheap chain-of-thought scaffolding for local models. |
|
|
319
317
|
| `ai.agent.tool_router` | Boolean \| `nil` | `nil` (auto: `true` for `ollama` / `openwebui`) | `PWN::AI::Agent::Registry.definitions` | Dynamic tool-set slimming: expose only `Registry::CORE_TOOLS` + the top-K keyword-relevant schemas for *this* request. Ties break on historical `Metrics` success rate, then `ai.agent.tool_preference`. |
|
|
320
|
-
| `ai.agent.tool_preference` | Array\<String\> | `memory_recall`, `session_recall`, `skills_recall`, `pwn_eval`, `shell`, `mistakes_record`, `mistakes_resolve`, `learning_note_outcome`, `memory_remember` | `PWN::AI::Agent::Registry.preference_order` / `.rank` / `.apply_preference`, `Policy` | Same order as `CORE_TOOLS`. Current session is injected
|
|
318
|
+
| `ai.agent.tool_preference` | Array\<String\> | `memory_recall`, `session_recall`, `skills_recall`, `pwn_eval`, `shell`, `mistakes_record`, `mistakes_resolve`, `learning_note_outcome`, `memory_remember` | `PWN::AI::Agent::Registry.preference_order` / `.rank` / `.apply_preference`, `Policy` | Same order as `CORE_TOOLS`. Current session is injected as RECENT TURNS. Explicit empty list disables preference. |
|
|
321
319
|
| `ai.agent.defer_introspect` | Boolean | `true` | `PWN::AI::Agent::TurnFinalizer` | Run `Learning.auto_introspect` on a background thread after the user-visible reply. Specs and cron stay inline. |
|
|
322
320
|
| `ai.agent.prompt_cache` | Boolean | `true` | `PWN::AI::Agent::PromptCache` | Engine-native prefix cache. Anthropic uses `cache_control`; OpenAI uses `prompt_cache_key`; Grok uses `x-grok-conv-id`; Gemini splits `systemInstruction`. Ollama and Open WebUI have no native prefix-cache field. |
|
|
323
321
|
| `ai.agent.local_introspect` | Symbol | `failure_only` | `PWN::AI::Agent::Learning.auto_introspect` | End-of-turn introspect policy for local engines: `always` · `failure_only` · `every_n` (with `introspect_every_n`). |
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
lib/pwn/ # all namespaces
|
|
7
7
|
lib/pwn/setup.rb # PWN::Setup - doctor/provisioner data tables
|
|
8
8
|
lib/pwn/migrate.rb # PWN::Migrate - ~/.pwn state doctor / auto-migrator
|
|
9
|
-
lib/pwn/plugins/ #
|
|
9
|
+
lib/pwn/plugins/ # 67 plugin modules
|
|
10
10
|
lib/pwn/ai/agent/ # agent core
|
|
11
11
|
lib/pwn/ai/agent/tools/ # LLM tool registrations
|
|
12
|
-
bin/ # 53 pwn_* drivers + pwn (incl. pwn_setup)
|
|
12
|
+
bin/ # 54 executables: 53 pwn_* drivers + pwn (incl. pwn_setup)
|
|
13
13
|
spec/ # RSpec (incl. conventions_spec)
|
|
14
14
|
documentation/ # this wiki + diagrams
|
|
15
15
|
```
|
data/documentation/Cron.md
CHANGED
|
@@ -36,15 +36,19 @@ does not remove existing per-job lines.
|
|
|
36
36
|
|
|
37
37
|
## Seeded self-improvement jobs (`PWN::Cron.install_defaults`)
|
|
38
38
|
|
|
39
|
-
`pwn setup --migrate` (schema `v1`) seeds
|
|
39
|
+
`pwn setup --migrate` (schema `v1`) seeds five jobs into every fresh
|
|
40
40
|
`~/.pwn/cron/jobs.yml` via `PWN::Cron.install_defaults`:
|
|
41
41
|
|
|
42
|
-
| Name | Schedule | Ruby |
|
|
43
|
-
|
|
44
|
-
| `curriculum_practice_nightly` | `0 3 * * *` | `
|
|
45
|
-
| `curriculum_offline_judge` | `30 3 * * *` | `
|
|
46
|
-
| `curriculum_train_weekly` | `0 4 * * 0` | `
|
|
47
|
-
| `learning_consolidate_nightly` | `0 5 * * *` | `
|
|
42
|
+
| Name | Schedule | Enabled | Ruby |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| `curriculum_practice_nightly` | `0 3 * * *` | **no** | `Curriculum.practice(limit: 3)` - opt-in; runs `Loop.run` with real tools |
|
|
45
|
+
| `curriculum_offline_judge` | `30 3 * * *` | **no** | `Curriculum.offline_judge(...)` - opt-in; spends API tokens |
|
|
46
|
+
| `curriculum_train_weekly` | `0 4 * * 0` | **no** | `Curriculum.train_and_gate(dry_run: true)` - opt-in; needs trainer+GPU to actually train |
|
|
47
|
+
| `learning_consolidate_nightly` | `0 5 * * *` | **yes** | `Learning.consolidate` - memory GC |
|
|
48
|
+
| `pwn_stores_lean_nightly` | `15 5 * * *` | **yes** | `Learning.gc_stores!` - lean memory, learning.jsonl, mistakes, policy, sessions |
|
|
49
|
+
|
|
50
|
+
- **practice / judge / train** ship **disabled**. Practice self-plays via `Loop.run` (shell, browsers). Judge hits the live model. Train is a no-op without a LoRA trainer. Enable with `cron_enable` when you want that loop.
|
|
51
|
+
- **consolidate + lean** stay on: they only touch `~/.pwn` files so the injected MEMORY / LEARNING / session tail stays high-signal.
|
|
48
52
|
|
|
49
53
|
- **practice** - top unresolved `Mistakes` under `Reward.judge`; auto-`resolve` with ≥2 holdouts
|
|
50
54
|
- **offline_judge** - backfill outcome/process labels + plan calibration from PLAN `p(success)=` so `:failure_only` local introspect does not starve the corpus; also runs `Reward.warm_sentinel` so the reward-sentinel window can fill on local hosts
|
data/documentation/Diagrams.md
CHANGED
|
@@ -23,7 +23,7 @@ groups) so lines never criss-cross.
|
|
|
23
23
|
[source](diagrams/dot/persistence-filesystem.dot) · doc: [Persistence](Persistence.md)
|
|
24
24
|

|
|
25
25
|
|
|
26
|
-
### Plugin Ecosystem (
|
|
26
|
+
### Plugin Ecosystem (67 modules)
|
|
27
27
|
[source](diagrams/dot/plugin-ecosystem.dot) · doc: [Plugins](Plugins.md)
|
|
28
28
|

|
|
29
29
|
|
|
@@ -68,7 +68,7 @@ groups) so lines never criss-cross.
|
|
|
68
68
|
[source](diagrams/dot/ai-integration-tool-calling.dot) · doc: [AI Integration](AI-Integration.md)
|
|
69
69
|

|
|
70
70
|
|
|
71
|
-
### Agent Tool Registry (13 toolsets ·
|
|
71
|
+
### Agent Tool Registry (13 toolsets · 87 tools)
|
|
72
72
|
[source](diagrams/dot/agent-tool-registry.dot) · doc: [Agent Tool Registry](Agent-Tool-Registry.md)
|
|
73
73
|

|
|
74
74
|
|
|
@@ -24,7 +24,7 @@ See [Installation](Installation.md) for every flag and the
|
|
|
24
24
|
|
|
25
25
|
```ruby
|
|
26
26
|
PWN.help # top-level help
|
|
27
|
-
PWN::Plugins.constants.sort # list all
|
|
27
|
+
PWN::Plugins.constants.sort # list all 67 plugins
|
|
28
28
|
PWN::Plugins::NmapIt.help # per-plugin usage
|
|
29
29
|
PWN::Setup.check # capability doctor from inside the REPL
|
|
30
30
|
PWN::Migrate.status # ~/.pwn state-file compatibility rows
|
data/documentation/Home.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> **PWN** (/pōn/) - an open-source offensive-security automation framework and
|
|
4
4
|
> continuous-security-integration platform written in Ruby.
|
|
5
|
-
>
|
|
6
|
-
>
|
|
5
|
+
> 67 plugins · 48 SAST modules · 90 AWS wrappers · 22 WWW drivers · 54 CLI
|
|
6
|
+
> executables · 6 LLM engines · a self-improving multi-agent AI · one REPL.
|
|
7
7
|
|
|
8
8
|
**Repo root:** `/opt/pwn` · **This wiki:** `/opt/pwn/documentation/` ·
|
|
9
9
|
**Rebuild diagrams:** `documentation/diagrams/build.sh`
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|---|---|
|
|
29
29
|
| [The `pwn` REPL](pwn-REPL.md) | Pry shell with the whole `PWN::` namespace pre-loaded |
|
|
30
30
|
| [`pwn-ai` Autonomous Agent](pwn-ai-Agent.md) | Natural-language TUI + `pwn --ai PROMPT` one-shot · **TaskSummarizer** briefs · iteration budget guard |
|
|
31
|
-
| [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) |
|
|
31
|
+
| [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) | 54 headless executables (`pwn` + 53 `pwn_*`) for CI/CD |
|
|
32
32
|
| [Drivers (build your own)](Drivers.md) | Turn a REPL session into a shipped binary |
|
|
33
33
|
|
|
34
34
|
## 🤖 AI Subsystem (`PWN::AI`)
|
|
@@ -36,20 +36,21 @@
|
|
|
36
36
|
| | |
|
|
37
37
|
|---|---|
|
|
38
38
|
| [AI / LLM Integration](AI-Integration.md) | OpenAI · Anthropic · Grok (OAuth) · Gemini · Ollama · Open WebUI |
|
|
39
|
-
| [Agent Tool Registry](Agent-Tool-Registry.md) | 13 toolsets · **
|
|
40
|
-
| [Memory · Skills · Learning](Skills-Memory-Learning.md) | Introspection -
|
|
39
|
+
| [Agent Tool Registry](Agent-Tool-Registry.md) | 13 toolsets · **87** LLM-callable tools |
|
|
40
|
+
| [Memory · Skills · Learning](Skills-Memory-Learning.md) | Introspection - self-improvement loop + 10 bundled skills on first launch |
|
|
41
41
|
| [Mistakes](Mistakes.md) | **Negative feedback** - fingerprint failures · do-NOT-repeat · `[REPEATING]`/`[REGRESSED]` · inline self-correction |
|
|
42
42
|
| [Reinforcement Learning](Reinforcement-Learning.md) | **`Reward` + `Curriculum` + `Policy`** - outcome/process judges · preference ledger · self-play practice · live Q / REINFORCE (advisory) · export-ready LoRA gate |
|
|
43
43
|
| [Extrospection](Extrospection.md) | World-awareness - snapshot · drift · intel · **watch** · **verify** · **rf_tune** · **osint** · serial · telecomm · packet · vision · voice · correlate |
|
|
44
44
|
| [Swarm (Multi-Agent)](Swarm.md) | Personas · ask · debate · broadcast · shared bus |
|
|
45
45
|
| [Sessions](Sessions.md) | Transcript persistence + reflection |
|
|
46
|
-
| [
|
|
46
|
+
| [Session Workflow](Session-Workflow.md) | Keywords: `continue` / last session / write-then-read |
|
|
47
|
+
| [Cron](Cron.md) | Scheduled jobs. Hygiene seeds on; curriculum practice/judge/train ship off |
|
|
47
48
|
|
|
48
49
|
## 🧩 Capability Namespaces (`lib/pwn/*`)
|
|
49
50
|
|
|
50
51
|
| | |
|
|
51
52
|
|---|---|
|
|
52
|
-
| [Plugins (
|
|
53
|
+
| [Plugins (67)](Plugins.md) | Every `PWN::Plugins::*` module by category |
|
|
53
54
|
| ↳ [BurpSuite](BurpSuite.md) ⭐ | Preferred web proxy / scanner |
|
|
54
55
|
| ↳ [TransparentBrowser](Transparent-Browser.md) | Headless / visible browser automation |
|
|
55
56
|
| ↳ [NmapIt](NmapIt.md) | Network discovery |
|
|
@@ -20,16 +20,16 @@ hardware).
|
|
|
20
20
|
| `pwn-ai` | `lib/pwn/ai/agent/loop.rb` | Agent TUI inside the REPL |
|
|
21
21
|
| `pwn --ai PROMPT` | `bin/pwn` | Headless one-shot agent (CI-friendly) |
|
|
22
22
|
| `pwn setup` | `lib/pwn/setup.rb` · `bin/pwn_setup` | Post-install doctor + capability provisioner + `--migrate` state doctor (also `pwn --setup[=PROFILE]`) |
|
|
23
|
-
| `bin/pwn_*` |
|
|
24
|
-
| `PWN::Cron` | `lib/pwn/cron.rb` | Scheduled jobs
|
|
23
|
+
| `bin/pwn_*` + `pwn` | 54 files | Thin OptionParser wrappers plus the `pwn` REPL / one-shot agent |
|
|
24
|
+
| `PWN::Cron` | `lib/pwn/cron.rb` | Scheduled jobs + background worker (`pwn setup`). Fresh install seeds hygiene on (`learning_consolidate_nightly`, `pwn_stores_lean_nightly`) and curriculum practice/judge/train off |
|
|
25
25
|
|
|
26
26
|
## L2 - AI agent core (`lib/pwn/ai/agent/`)
|
|
27
27
|
|
|
28
28
|
| Module | Role |
|
|
29
29
|
|---|---|
|
|
30
|
-
| `Loop` | plan → **TaskSummarizer** briefs → dispatch tool_calls → observe → repeat until final answer
|
|
31
|
-
| **`TaskSummarizer`** | Executive UX: every request gets an English task compass (`emit_plan!` · `about_to` as `task k/n`)
|
|
32
|
-
| `Registry` | JSON-Schema function definitions grouped into 13 **toolsets** · **87 tools** · `CORE_TOOLS` = `DEFAULT_PREFERENCE` (`memory_recall` · `session_recall` · `skills_recall` · `pwn_eval` · `shell`) |
|
|
30
|
+
| `Loop` | plan → **TaskSummarizer** briefs → dispatch tool_calls → observe → repeat until final answer. Scars do not lower `max_iters` (default 777). Last-iter strips tools only when the original request is already satisfied |
|
|
31
|
+
| **`TaskSummarizer`** | Executive UX: every request gets an English task compass (`emit_plan!` · `about_to` as `task k/n`) - no statement/question/goal type |
|
|
32
|
+
| `Registry` | JSON-Schema function definitions grouped into 13 **toolsets** · **87 tools** · `CORE_TOOLS` = `DEFAULT_PREFERENCE` (`memory_recall` · `session_recall` · `skills_recall` · `pwn_eval` · `shell` · `mistakes_record` · `mistakes_resolve` · `learning_note_outcome` · `memory_remember`) |
|
|
33
33
|
| `Dispatch` / `Result` | execute a tool, capture stdout/value/error/duration |
|
|
34
34
|
| `PromptBuilder` | inject MEMORY / SKILLS / LEARNING / **KNOWN MISTAKES + FIXES** / METRICS / **POLICY** / EXTROSPECTION / RECENT TURNS |
|
|
35
35
|
| `Metrics` · `Learning` · `Reflect` · **`Policy`** | **introspection** - how well am I doing? (Policy is live Q / REINFORCE, advisory rank only) |
|
|
@@ -45,8 +45,8 @@ call, and [Reinforcement Learning](Reinforcement-Learning.md) for how
|
|
|
45
45
|
|
|
46
46
|
## L3 - Capability namespaces (`lib/pwn/*`)
|
|
47
47
|
|
|
48
|
-
`Plugins` (
|
|
49
|
-
`Bounty` · `Reports` · `FFI` · `Banner` · **`Setup`** · **`Migrate`**. Each is
|
|
48
|
+
`Plugins` (67) · `SAST` (48) · `WWW` (22) · `AWS` (90) · `SDR` · `Blockchain` ·
|
|
49
|
+
`Bounty` · `Reports` · `FFI` · `Banner` · **`Setup`** · **`Migrate`**. First launch also seeds bundled skills from `etc/default_skills/`. Each is
|
|
50
50
|
a plain module of `public_class_method def self.x(opts = {})` methods -
|
|
51
51
|
callable the same way from the REPL, from `pwn_eval`, or from a driver.
|
|
52
52
|
|
|
@@ -75,9 +75,9 @@ Q / REINFORCE when the judge scores the turn, and **the prompt blocks**
|
|
|
75
75
|
(MEMORY · SKILLS · LEARNING · KNOWN MISTAKES/FIXES · TOOL EFFECTIVENESS ·
|
|
76
76
|
POLICY · EXTROSPECTION · RECENT TURNS) are re-injected into the next system
|
|
77
77
|
prompt.
|
|
78
|
-
Nightly cron
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
Nightly hygiene cron trims `~/.pwn` stores. Curriculum practice, offline
|
|
79
|
+
judge, and weekly LoRA train ship seeded but disabled; turn them on with
|
|
80
|
+
`cron_enable` when you want that loop:
|
|
81
81
|
|
|
82
82
|

|
|
83
83
|
|
|
@@ -246,8 +246,24 @@ pwn setup --profile ${PWN_PROFILE:-full} --yes
|
|
|
246
246
|
## First-run configuration
|
|
247
247
|
|
|
248
248
|
The first `pwn` launch creates `~/.pwn/` and an **encrypted**
|
|
249
|
-
`~/.pwn/pwn.yaml` template.
|
|
250
|
-
|
|
249
|
+
`~/.pwn/pwn.yaml` template. It also seeds bundled skills into
|
|
250
|
+
`~/.pwn/skills/` when those names are missing:
|
|
251
|
+
|
|
252
|
+
- `vulnerability-research-fundamentals`
|
|
253
|
+
- `deep-exploitation`
|
|
254
|
+
- `bug-bounty-hunting`
|
|
255
|
+
- `sast-code-scans`
|
|
256
|
+
- `reverse-engineering-binaries`
|
|
257
|
+
- `penetration-testing`
|
|
258
|
+
- `web-application-penetration-testing`
|
|
259
|
+
- `red-teaming`
|
|
260
|
+
- `hardware-and-firmware-testing`
|
|
261
|
+
- `social-engineering`
|
|
262
|
+
- `osint`
|
|
263
|
+
|
|
264
|
+
Source lives in the gem at `etc/default_skills/`. `PWN::Config.install_default_skills`
|
|
265
|
+
is idempotent and never overwrites an edited `SKILL.md`. Add at least one
|
|
266
|
+
LLM engine key with the `pwn-vault` REPL command to enable `pwn-ai` - see
|
|
251
267
|
[Configuration](Configuration.md). `pwn setup` will report the AI-engine
|
|
252
268
|
row as `MISSING` until a key is set.
|
|
253
269
|
|
|
@@ -293,7 +309,7 @@ Vagrant, CI) picks it up automatically.
|
|
|
293
309
|
```ruby
|
|
294
310
|
pwn[CURRENT_VERSION]:001 >>> PWN::Setup.check[:ok] # => true
|
|
295
311
|
pwn[CURRENT_VERSION]:002 >>> PWN::Migrate.needed? # => false
|
|
296
|
-
pwn[CURRENT_VERSION]:003 >>> PWN::Plugins.constants.count # =>
|
|
312
|
+
pwn[CURRENT_VERSION]:003 >>> PWN::Plugins.constants.count # => 67
|
|
297
313
|
pwn[CURRENT_VERSION]:004 >>> PWN::SAST.constants.count # => 48
|
|
298
314
|
pwn[CURRENT_VERSION]:005 >>> pwn-ai # launches agent TUI
|
|
299
315
|
```
|
|
@@ -11,7 +11,7 @@ Every byte PWN remembers between processes lives here.
|
|
|
11
11
|
| **`.schema`** | **`PWN::Migrate`** | JSON `{schema:,pwn_version:,at:}` | `pwn setup --migrate` | **schema stamp - drives the one-line drift warning on launch** |
|
|
12
12
|
| `memory.json` | `PWN::Memory` | JSON array | `memory_clear` | facts · prefs · lessons · env - injected into every prompt |
|
|
13
13
|
| `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) |
|
|
14
|
-
| `skills/<name>/SKILL.md` | `PWN::Config.load_skills` | **[agentskills.io](https://agentskills.io) spec** - `name`+`description` YAML front-matter | `skill_delete` | reusable procedures + `metadata.references
|
|
14
|
+
| `skills/<name>/SKILL.md` | `PWN::Config.load_skills` | **[agentskills.io](https://agentskills.io) spec** - `name`+`description` YAML front-matter | `skill_delete` | reusable procedures + `metadata.references:`. Fresh install seeds bundled skills from `etc/default_skills/` via `PWN::Config.install_default_skills` (never overwrites an existing file). Legacy flat `skills/*.md` auto-migrated by `skill_migrate_legacy` / `pwn setup --migrate --fix`. |
|
|
15
15
|
| `learning.jsonl` | `PWN::AI::Agent::Learning` | JSON-per-line | `learning_reset` | task outcome log → success_rate |
|
|
16
16
|
| **`preferences.jsonl`** | **`PWN::AI::Agent::Reward`** | JSON-per-line `{prompt,rejected,chosen,source}` | `rm` | **DPO/KTO/ORPO preference-pair ledger - user_correction · mistakes_resolve · counterfactual · critic · curriculum** |
|
|
17
17
|
| **`mistakes.json`** | **`PWN::AI::Agent::Mistakes`** | **JSON `{sig → entry}`** | **`mistakes_reset`** | **failure fingerprints · cross-session count · fix · `[REPEATING]` · `[REGRESSED]`** |
|
|
@@ -24,7 +24,8 @@ Every byte PWN remembers between processes lives here.
|
|
|
24
24
|
| `extrospection/packet/*.pcap` | `Extrospection` | pcap | `rm -rf` | bounded captures from `extro_packet(action: :capture)` |
|
|
25
25
|
| `extrospection/voice/*` | `Extrospection` | wav / txt | `rm -rf` | TTS/STT artifacts from `extro_voice` |
|
|
26
26
|
| `sessions/*.jsonl` | `PWN::Sessions` | JSON-per-line | `sessions_delete` | full transcript per pwn-ai run (with per-step `step_reward` from `Reward.prm`) |
|
|
27
|
-
| `
|
|
27
|
+
| `open_goal.json` | `PWN::AI::Agent::OpenGoal` | JSON | delete the file | unfinished host-work request so `continue` / `resume` picks it up |
|
|
28
|
+
| `cron/jobs.yml` | `PWN::Cron` | YAML | `cron_remove` | scheduled jobs. Fresh install seeds hygiene (`learning_consolidate_nightly` + `pwn_stores_lean_nightly` **on**) and curriculum practice/judge/train **off** |
|
|
28
29
|
| `cron/log/*.log` | `PWN::Cron` | text | rm | last_run output |
|
|
29
30
|
| `agents.yml` | `PWN::AI::Agent::Swarm` | YAML | edit / `agent_spawn` | persona registry |
|
|
30
31
|
| `swarm/<id>/bus.jsonl` | `Swarm` | JSON-per-line | rm -rf | append-only multi-agent chat |
|
data/documentation/Plugins.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# `PWN::Plugins` - All
|
|
1
|
+
# `PWN::Plugins` - All 67 Modules
|
|
2
2
|
|
|
3
3
|
Every plugin is a plain Ruby module of `public_class_method def self.x(opts = {})`
|
|
4
4
|
methods with self-documenting `.help`. Source: `lib/pwn/plugins/*.rb`.
|
|
@@ -93,7 +93,7 @@ show-source PWN::Plugins::Fuzz.generate
|
|
|
93
93
|
|
|
94
94
|
### Utility
|
|
95
95
|
`FileFu` · `ThreadPool` · `Log` · `PWNLogger` · `Char` · `XXD` · `DetectOS` ·
|
|
96
|
-
`CreditCard` · `SSN` · `EIN` · `VIN` · `PS` · `MonkeyPatch` · `REPL`
|
|
96
|
+
`CreditCard` · `SSN` · `EIN` · `VIN` · `PS` · `MonkeyPatch` · `REPL` · `TTYSpinner`
|
|
97
97
|
|
|
98
98
|
## Full alphabetical list
|
|
99
99
|
|
|
@@ -104,6 +104,6 @@ HackerOne Hunter IPInfo IRC Jenkins JiraDataCenter JSONPathify Log MailAgent
|
|
|
104
104
|
Metasploit MonkeyPatch MSR206 NessusCloud NexposeVulnScan NmapIt OAuth2 OCR
|
|
105
105
|
OpenAPI OpenVAS Packet PDFParse Pony PS PWNLogger RabbitMQ REPL ScannableCodes
|
|
106
106
|
Serial Shodan SlackClient Sock Spider SSN ThreadPool Tor TransparentBrowser
|
|
107
|
-
TwitterAPI URIScheme Vault VIN Voice Vsphere XXD Zaproxy`
|
|
107
|
+
TTYSpinner TwitterAPI URIScheme Vault VIN Voice Vsphere XXD Zaproxy`
|
|
108
108
|
|
|
109
109
|
[← Home](Home.md) · [Diagrams](Diagrams.md)
|