pwn 0.5.724 → 0.5.728
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/Gemfile +4 -4
- data/bin/pwn-ai +6 -0
- data/bin/pwn-capd +14 -0
- data/documentation/AI-Integration.md +3 -2
- data/documentation/Agent-Tool-Registry.md +3 -1
- data/documentation/Capability-Broker-Sandbox.md +136 -0
- data/documentation/LoRaPHY-LICENSE.txt +25 -0
- data/documentation/Proxy-Skills-Hygiene.md +102 -0
- data/documentation/Recon-Findings-API.md +31 -0
- data/documentation/SDR-Decoder-Coverage.md +550 -0
- data/documentation/Swarm.md +38 -3
- data/etc/default_skills/pwn/ai/agent/engagement_memory/SKILL.md +46 -0
- data/etc/default_skills/pwn/ai/agent/manifest/SKILL.md +49 -0
- data/etc/default_skills/pwn/ai/agent/profiles/SKILL.md +46 -0
- data/etc/default_skills/pwn/ai/agent/request_runtime/SKILL.md +46 -0
- data/etc/default_skills/pwn/ai/agent/skill_consolidation/SKILL.md +48 -0
- data/etc/default_skills/pwn/ai/agent/tool_guard/SKILL.md +3 -2
- data/etc/default_skills/pwn/ai/agent/tools/http_replay/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/tools/recon_run/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/tools/sandbox/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/tools/skills_consolidate/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/turn_finalizer/SKILL.md +3 -0
- data/etc/default_skills/pwn/ai/cli/SKILL.md +48 -0
- data/etc/default_skills/pwn/ai/context/SKILL.md +2 -0
- data/etc/default_skills/pwn/ai/context_ingestion/SKILL.md +56 -0
- data/etc/default_skills/pwn/ai/context_ingestion/references/urls.md +3 -0
- data/etc/default_skills/pwn/ffi/dsp_native/SKILL.md +51 -0
- data/etc/default_skills/pwn/ffi/hack_rf/SKILL.md +1 -1
- data/etc/default_skills/pwn/plugins/binary_analysis/SKILL.md +50 -0
- data/etc/default_skills/pwn/plugins/capability_broker/SKILL.md +47 -0
- data/etc/default_skills/pwn/plugins/capability_broker/daemon/SKILL.md +50 -0
- data/etc/default_skills/pwn/plugins/findings/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/mitm_proxy/SKILL.md +56 -0
- data/etc/default_skills/pwn/plugins/mitm_proxy/references/urls.md +3 -0
- data/etc/default_skills/pwn/plugins/process_tube/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/radare2/SKILL.md +4 -0
- data/etc/default_skills/pwn/plugins/recon/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/repl/SKILL.md +5 -0
- data/etc/default_skills/pwn/plugins/rop/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/sandbox/SKILL.md +50 -0
- data/etc/default_skills/pwn/plugins/sandbox/driver/SKILL.md +53 -0
- data/etc/default_skills/pwn/plugins/vault/SKILL.md +4 -2
- data/etc/default_skills/pwn/redaction/SKILL.md +48 -0
- data/etc/default_skills/pwn/reports/SKILL.md +1 -0
- data/etc/default_skills/pwn/sdr/decoder/adsb/SKILL.md +4 -1
- data/etc/default_skills/pwn/sdr/decoder/apt/SKILL.md +4 -3
- data/etc/default_skills/pwn/sdr/decoder/base/SKILL.md +1 -1
- data/etc/default_skills/pwn/sdr/decoder/bluetooth/SKILL.md +5 -3
- data/etc/default_skills/pwn/sdr/decoder/dect/SKILL.md +9 -3
- data/etc/default_skills/pwn/sdr/decoder/dect/references/urls.md +3 -0
- data/etc/default_skills/pwn/sdr/decoder/dsp/SKILL.md +2 -1
- data/etc/default_skills/pwn/sdr/decoder/flex/SKILL.md +2 -1
- data/etc/default_skills/pwn/sdr/decoder/gps/SKILL.md +7 -3
- data/etc/default_skills/pwn/sdr/decoder/gsm/SKILL.md +3 -1
- data/etc/default_skills/pwn/sdr/decoder/iridium/SKILL.md +5 -3
- data/etc/default_skills/pwn/sdr/decoder/lora/SKILL.md +2 -1
- data/etc/default_skills/pwn/sdr/decoder/lte/SKILL.md +2 -1
- data/etc/default_skills/pwn/sdr/decoder/morse/SKILL.md +3 -2
- data/etc/default_skills/pwn/sdr/decoder/p25/SKILL.md +9 -3
- data/etc/default_skills/pwn/sdr/decoder/p25/references/urls.md +3 -0
- data/etc/default_skills/pwn/sdr/decoder/pager/SKILL.md +3 -2
- data/etc/default_skills/pwn/sdr/decoder/pocsag/SKILL.md +6 -2
- data/etc/default_skills/pwn/sdr/decoder/rds/SKILL.md +2 -1
- data/etc/default_skills/pwn/sdr/decoder/rfid/SKILL.md +9 -3
- data/etc/default_skills/pwn/sdr/decoder/rfid/references/urls.md +4 -0
- data/etc/default_skills/pwn/sdr/decoder/rtl433/SKILL.md +9 -3
- data/etc/default_skills/pwn/sdr/decoder/rtl433/references/urls.md +4 -0
- data/etc/default_skills/pwn/sdr/decoder/rtty/SKILL.md +3 -2
- data/etc/default_skills/pwn/sdr/decoder/tempest/SKILL.md +51 -0
- data/etc/default_skills/pwn/sdr/decoder/wifi/SKILL.md +10 -3
- data/etc/default_skills/pwn/sdr/decoder/wifi/references/urls.md +3 -0
- data/etc/default_skills/pwn/sdr/decoder/zigbee/SKILL.md +13 -3
- data/etc/default_skills/pwn/sdr/decoder/zigbee/references/urls.md +3 -0
- data/etc/default_skills/pwn/session_trace/SKILL.md +50 -0
- data/ext/pwn_dsp/.gitignore +4 -0
- data/ext/pwn_dsp/README.md +81 -0
- data/ext/pwn_dsp/benchmark-results.json +321 -0
- data/ext/pwn_dsp/benchmark.rb +38 -0
- data/ext/pwn_dsp/build.rb +19 -0
- data/ext/pwn_dsp/pwn_dsp.c +72 -0
- data/ext/pwn_gsm/.gitignore +4 -0
- data/ext/pwn_gsm/README.md +61 -0
- data/ext/pwn_gsm/benchmark-results.json +24 -0
- data/ext/pwn_gsm/benchmark.rb +44 -0
- data/ext/pwn_gsm/build.rb +7 -0
- data/ext/pwn_gsm/fixtures/generate.py +41 -0
- data/ext/pwn_gsm/pwn_gsm.c +40 -0
- data/ext/pwn_lte/.gitignore +3 -0
- data/ext/pwn_lte/README.md +108 -0
- data/ext/pwn_lte/benchmark-results.json +19 -0
- data/ext/pwn_lte/benchmark.rb +52 -0
- data/ext/pwn_lte/build.rb +13 -0
- data/ext/pwn_lte/pwn_lte.c +101 -0
- data/ext/pwn_rds/.gitignore +2 -0
- data/ext/pwn_rds/README.md +17 -0
- data/ext/pwn_rds/build.rb +15 -0
- data/ext/pwn_rds/stream_verify.rb +53 -0
- data/ext/pwn_rds/verify.rb +24 -0
- data/lib/pwn/ai/agent/dispatch.rb +143 -6
- data/lib/pwn/ai/agent/engagement_memory.rb +137 -0
- data/lib/pwn/ai/agent/learning.rb +1 -1
- data/lib/pwn/ai/agent/loop.rb +110 -65
- data/lib/pwn/ai/agent/manifest.rb +178 -0
- data/lib/pwn/ai/agent/mistakes.rb +38 -3
- data/lib/pwn/ai/agent/profiles.rb +103 -0
- data/lib/pwn/ai/agent/registry.rb +2 -0
- data/lib/pwn/ai/agent/request_runtime.rb +94 -0
- data/lib/pwn/ai/agent/reward.rb +35 -22
- data/lib/pwn/ai/agent/skill_consolidation.rb +151 -0
- data/lib/pwn/ai/agent/swarm.rb +22 -27
- data/lib/pwn/ai/agent/tool_guard.rb +27 -2
- data/lib/pwn/ai/agent/tools/finding_record.rb +27 -23
- data/lib/pwn/ai/agent/tools/http_replay.rb +23 -0
- data/lib/pwn/ai/agent/tools/recon_run.rb +27 -0
- data/lib/pwn/ai/agent/tools/ruby_eval.rb +4 -8
- data/lib/pwn/ai/agent/tools/sandbox.rb +28 -0
- data/lib/pwn/ai/agent/tools/shell.rb +17 -27
- data/lib/pwn/ai/agent/tools/skills_consolidate.rb +34 -0
- data/lib/pwn/ai/agent/tools/swarm.rb +9 -3
- data/lib/pwn/ai/agent/turn_finalizer.rb +88 -19
- data/lib/pwn/ai/agent.rb +8 -3
- data/lib/pwn/ai/cli.rb +91 -0
- data/lib/pwn/ai/context.rb +7 -0
- data/lib/pwn/ai/context_ingestion.rb +213 -0
- data/lib/pwn/ai/gemini.rb +6 -2
- data/lib/pwn/ai/grok.rb +12 -1
- data/lib/pwn/ai/ollama.rb +3 -1
- data/lib/pwn/ai/open_ai.rb +40 -5
- data/lib/pwn/ai/open_web_ui.rb +3 -1
- data/lib/pwn/ai/tools/README.md +74 -0
- data/lib/pwn/ai/tools/core.yaml +20 -0
- data/lib/pwn/ai/tools/host.yaml +10 -0
- data/lib/pwn/ai.rb +1 -0
- data/lib/pwn/config.rb +7 -0
- data/lib/pwn/ffi/adalm_pluto.rb +20 -14
- data/lib/pwn/ffi/dsp_native.rb +121 -0
- data/lib/pwn/ffi/hack_rf.rb +43 -19
- data/lib/pwn/ffi/rtl_sdr.rb +7 -1
- data/lib/pwn/ffi/soapy_sdr.rb +23 -7
- data/lib/pwn/ffi.rb +1 -0
- data/lib/pwn/migrate.rb +21 -1
- data/lib/pwn/plugins/binary_analysis.rb +104 -0
- data/lib/pwn/plugins/capability_broker/daemon.rb +284 -0
- data/lib/pwn/plugins/capability_broker.rb +57 -0
- data/lib/pwn/plugins/findings.rb +108 -10
- data/lib/pwn/plugins/ghidra_headless.rb +52 -33
- data/lib/pwn/plugins/ghidra_scripts/PwnExport.java +62 -0
- data/lib/pwn/plugins/log.rb +30 -11
- data/lib/pwn/plugins/mitm_proxy.rb +282 -0
- data/lib/pwn/plugins/monkey_patch.rb +5 -1
- data/lib/pwn/plugins/packet.rb +32 -129
- data/lib/pwn/plugins/process_tube.rb +12 -0
- data/lib/pwn/plugins/pwn_logger.rb +2 -1
- data/lib/pwn/plugins/radare2.rb +121 -0
- data/lib/pwn/plugins/recon.rb +173 -0
- data/lib/pwn/plugins/repl.rb +174 -60
- data/lib/pwn/plugins/rop.rb +103 -0
- data/lib/pwn/plugins/sandbox/Dockerfile +5 -0
- data/lib/pwn/plugins/sandbox/driver.rb +251 -0
- data/lib/pwn/plugins/sandbox.rb +65 -0
- data/lib/pwn/plugins/transparent_browser.rb +11 -0
- data/lib/pwn/plugins/vault.rb +88 -21
- data/lib/pwn/plugins.rb +5 -0
- data/lib/pwn/redaction.rb +70 -0
- data/lib/pwn/reports/html.rb +9 -0
- data/lib/pwn/reports/json.rb +2 -1
- data/lib/pwn/reports/markdown.rb +6 -0
- data/lib/pwn/reports.rb +42 -0
- data/lib/pwn/sdr/decoder/adsb.rb +240 -21
- data/lib/pwn/sdr/decoder/apt.rb +119 -63
- data/lib/pwn/sdr/decoder/base.rb +362 -305
- data/lib/pwn/sdr/decoder/bluetooth.rb +282 -46
- data/lib/pwn/sdr/decoder/dect.rb +155 -28
- data/lib/pwn/sdr/decoder/dsp.rb +126 -23
- data/lib/pwn/sdr/decoder/flex.rb +118 -16
- data/lib/pwn/sdr/decoder/gps.rb +320 -16
- data/lib/pwn/sdr/decoder/gsm.rb +230 -55
- data/lib/pwn/sdr/decoder/iridium.rb +221 -26
- data/lib/pwn/sdr/decoder/lora.rb +349 -6
- data/lib/pwn/sdr/decoder/lte.rb +201 -55
- data/lib/pwn/sdr/decoder/morse.rb +37 -3
- data/lib/pwn/sdr/decoder/p25.rb +282 -12
- data/lib/pwn/sdr/decoder/pager.rb +34 -3
- data/lib/pwn/sdr/decoder/pocsag.rb +162 -29
- data/lib/pwn/sdr/decoder/rds.rb +167 -77
- data/lib/pwn/sdr/decoder/rfid.rb +226 -25
- data/lib/pwn/sdr/decoder/rtl433.rb +245 -25
- data/lib/pwn/sdr/decoder/rtty.rb +39 -10
- data/lib/pwn/sdr/decoder/tempest.rb +318 -0
- data/lib/pwn/sdr/decoder/wifi.rb +333 -25
- data/lib/pwn/sdr/decoder/zigbee.rb +326 -54
- data/lib/pwn/sdr/decoder.rb +2 -0
- data/lib/pwn/sdr/gqrx.rb +13 -3
- data/lib/pwn/session_trace.rb +163 -0
- data/lib/pwn/sessions.rb +17 -32
- data/lib/pwn/setup.rb +4 -0
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +2 -0
- data/spec/conventions_spec.rb +1 -1
- data/spec/fixtures/sdr/gps/README.md +77 -0
- data/spec/fixtures/sdr/gps/cttc-lnav.json +33 -0
- data/spec/fixtures/sdr/gsm/README.md +40 -0
- data/spec/fixtures/sdr/gsm/bad-crc.cs16 +0 -0
- data/spec/fixtures/sdr/gsm/sch.cs16 +0 -0
- data/spec/fixtures/sdr/gsm/vectors.json +16 -0
- data/spec/fixtures/sdr/iridium/README.md +115 -0
- data/spec/fixtures/sdr/iridium/TOOLKIT-LICENSE.txt +28 -0
- data/spec/fixtures/sdr/iridium/ira-row-19.cf32 +0 -0
- data/spec/fixtures/sdr/iridium/ira-row-19.cs16 +0 -0
- data/spec/fixtures/sdr/iridium/ira-row-43.cf32 +0 -0
- data/spec/fixtures/sdr/iridium/ira-row-43.cs16 +3 -0
- data/spec/fixtures/sdr/iridium/ira-row-5.cf32 +0 -0
- data/spec/fixtures/sdr/iridium/ira-row-5.cs16 +0 -0
- data/spec/fixtures/sdr/iridium/source-rows.tsv +3 -0
- data/spec/fixtures/sdr/iridium/vectors.json +50 -0
- data/spec/fixtures/sdr/lora/README.md +125 -0
- data/spec/fixtures/sdr/lora/benchmark-results.json +142 -0
- data/spec/fixtures/sdr/lora/benchmark.txt +20 -0
- data/spec/fixtures/sdr/lora/generate.txt +31 -0
- data/spec/fixtures/sdr/lora/generate_modes.txt +47 -0
- data/spec/fixtures/sdr/lora/mode-0.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-1.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-10.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-11.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-12.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-13.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-2.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-3.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-4.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-5.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-6.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-7.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-8.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/mode-9.cf32.gz +0 -0
- data/spec/fixtures/sdr/lora/modes.json +637 -0
- data/spec/fixtures/sdr/lora/sf7-cr1.cf32 +0 -0
- data/spec/fixtures/sdr/lora/sf7-cr4.cf32 +0 -0
- data/spec/fixtures/sdr/lora/sf8-cr2.cf32 +0 -0
- data/spec/fixtures/sdr/lora/sf8-cr3.cf32 +0 -0
- data/spec/fixtures/sdr/lora/vectors.json +189 -0
- data/spec/fixtures/sdr/lte/SRSRAN-LICENSE +661 -0
- data/spec/fixtures/sdr/lte/signal.1.92M.dat +0 -0
- data/spec/fixtures/sdr/p25/README.md +24 -0
- data/spec/fixtures/sdr/p25/tsdu3.bin +1 -0
- data/spec/fixtures/sdr/p25/updu.bin +2 -0
- data/spec/fixtures/sdr/rds/LICENSE +18 -0
- data/spec/fixtures/sdr/rds/README.md +10 -0
- data/spec/fixtures/sdr/rds/mpx-testfile-yksi.flac +0 -0
- data/spec/fixtures/sdr/rfid/LICENSE.txt +674 -0
- data/spec/fixtures/sdr/rfid/README.md +30 -0
- data/spec/fixtures/sdr/rfid/fdxb_animal.pm3 +10000 -0
- data/spec/fixtures/sdr/rfid/fdxb_extended.pm3 +10000 -0
- data/spec/fixtures/sdr/rtl433/README.md +81 -0
- data/spec/fixtures/sdr/rtl433/acurite_th_609_001.cu8 +118 -0
- data/spec/fixtures/sdr/rtl433/acurite_th_609_001.json +6 -0
- data/spec/fixtures/sdr/rtl433/toyota.cu8 +9 -0
- data/spec/fixtures/sdr/rtl433/toyota.json +1 -0
- data/spec/fixtures/sdr/rtl433/wh31.cu8 +66 -0
- data/spec/fixtures/sdr/rtl433/wh31.json +2 -0
- data/spec/integration/dispatch_spec.rb +2 -2
- data/spec/integration/native_ruby_helpers_spec.rb +23 -0
- data/spec/lib/pwn/ai/agent/dispatch_policy_spec.rb +142 -0
- data/spec/lib/pwn/ai/agent/engagement_memory_spec.rb +74 -0
- data/spec/lib/pwn/ai/agent/loop_artifacts_spec.rb +48 -0
- data/spec/lib/pwn/ai/agent/loop_spec.rb +128 -6
- data/spec/lib/pwn/ai/agent/manifest_spec.rb +46 -0
- data/spec/lib/pwn/ai/agent/mistakes_precision_spec.rb +57 -0
- data/spec/lib/pwn/ai/agent/profiles_spec.rb +49 -0
- data/spec/lib/pwn/ai/agent/request_runtime_spec.rb +55 -0
- data/spec/lib/pwn/ai/agent/reward_spec.rb +69 -2
- data/spec/lib/pwn/ai/agent/skill_consolidation_spec.rb +64 -0
- data/spec/lib/pwn/ai/agent/swarm_spec.rb +173 -0
- data/spec/lib/pwn/ai/agent/tool_guard_spec.rb +8 -0
- data/spec/lib/pwn/ai/agent/tools/finding_record_spec.rb +9 -0
- data/spec/lib/pwn/ai/agent/tools/http_replay_spec.rb +22 -0
- data/spec/lib/pwn/ai/agent/tools/recon_run_spec.rb +15 -0
- data/spec/lib/pwn/ai/agent/tools/sandbox_spec.rb +15 -0
- data/spec/lib/pwn/ai/agent/tools/shell_spec.rb +2 -2
- data/spec/lib/pwn/ai/agent/tools/skills_consolidate_spec.rb +22 -0
- data/spec/lib/pwn/ai/agent/tools/swarm_spec.rb +14 -0
- data/spec/lib/pwn/ai/agent/turn_finalizer_spec.rb +55 -1
- data/spec/lib/pwn/ai/cli_spec.rb +102 -0
- data/spec/lib/pwn/ai/context_ingestion_spec.rb +80 -0
- data/spec/lib/pwn/ai/gemini_spec.rb +19 -0
- data/spec/lib/pwn/ai/open_ai_oauth_transport_spec.rb +35 -0
- data/spec/lib/pwn/ai/open_ai_spec.rb +12 -0
- data/spec/lib/pwn/config_spec.rb +10 -0
- data/spec/lib/pwn/ffi/adalm_pluto_spec.rb +47 -0
- data/spec/lib/pwn/ffi/dsp_native_spec.rb +53 -0
- data/spec/lib/pwn/ffi/hack_rf_spec.rb +36 -0
- data/spec/lib/pwn/ffi/rtl_sdr_spec.rb +16 -0
- data/spec/lib/pwn/ffi/soapy_sdr_spec.rb +24 -0
- data/spec/lib/pwn/migrate_spec.rb +28 -0
- data/spec/lib/pwn/plugins/binary_analysis_spec.rb +41 -0
- data/spec/lib/pwn/plugins/capability_broker/daemon_spec.rb +241 -0
- data/spec/lib/pwn/plugins/capability_broker_spec.rb +22 -0
- data/spec/lib/pwn/plugins/findings_spec.rb +2 -1
- data/spec/lib/pwn/plugins/findings_structured_spec.rb +72 -0
- data/spec/lib/pwn/plugins/log_spec.rb +3 -3
- data/spec/lib/pwn/plugins/mitm_proxy_spec.rb +78 -0
- data/spec/lib/pwn/plugins/monkey_patch_spec.rb +7 -0
- data/spec/lib/pwn/plugins/packet_spec.rb +8 -0
- data/spec/lib/pwn/plugins/process_tube_spec.rb +7 -0
- data/spec/lib/pwn/plugins/recon_pipeline_spec.rb +129 -0
- data/spec/lib/pwn/plugins/repl_spec.rb +121 -0
- data/spec/lib/pwn/plugins/rop_spec.rb +14 -0
- data/spec/lib/pwn/plugins/sandbox/driver_spec.rb +37 -0
- data/spec/lib/pwn/plugins/sandbox_spec.rb +128 -0
- data/spec/lib/pwn/plugins/transparent_browser_spec.rb +28 -0
- data/spec/lib/pwn/plugins/vault_credentials_spec.rb +54 -0
- data/spec/lib/pwn/redaction_spec.rb +126 -0
- data/spec/lib/pwn/sdr/decoder/adsb_spec.rb +262 -4
- data/spec/lib/pwn/sdr/decoder/apt_spec.rb +124 -0
- data/spec/lib/pwn/sdr/decoder/base_iq_spec.rb +3 -11
- data/spec/lib/pwn/sdr/decoder/base_spec.rb +457 -6
- data/spec/lib/pwn/sdr/decoder/bluetooth_spec.rb +213 -0
- data/spec/lib/pwn/sdr/decoder/dect_spec.rb +138 -0
- data/spec/lib/pwn/sdr/decoder/dsp_native_spec.rb +105 -0
- data/spec/lib/pwn/sdr/decoder/flex_spec.rb +206 -0
- data/spec/lib/pwn/sdr/decoder/gps_spec.rb +154 -0
- data/spec/lib/pwn/sdr/decoder/gsm_spec.rb +161 -0
- data/spec/lib/pwn/sdr/decoder/iridium_spec.rb +131 -0
- data/spec/lib/pwn/sdr/decoder/lora_spec.rb +291 -0
- data/spec/lib/pwn/sdr/decoder/lte_spec.rb +199 -0
- data/spec/lib/pwn/sdr/decoder/morse_spec.rb +41 -0
- data/spec/lib/pwn/sdr/decoder/p25_spec.rb +170 -0
- data/spec/lib/pwn/sdr/decoder/pager_spec.rb +26 -0
- data/spec/lib/pwn/sdr/decoder/pocsag_spec.rb +87 -0
- data/spec/lib/pwn/sdr/decoder/rds_spec.rb +92 -0
- data/spec/lib/pwn/sdr/decoder/rfid_spec.rb +94 -0
- data/spec/lib/pwn/sdr/decoder/rtl433_spec.rb +79 -0
- data/spec/lib/pwn/sdr/decoder/rtty_spec.rb +54 -0
- data/spec/lib/pwn/sdr/decoder/tempest_spec.rb +192 -0
- data/spec/lib/pwn/sdr/decoder/wifi_spec.rb +208 -0
- data/spec/lib/pwn/sdr/decoder/zigbee_spec.rb +169 -0
- data/spec/lib/pwn/sdr/gqrx_spec.rb +126 -0
- data/spec/lib/pwn/session_trace_spec.rb +78 -0
- data/spec/lib/pwn/setup_spec.rb +17 -0
- data/spec/spec_helper.rb +2 -0
- data/third_party/pwn_rdoc.jsonl +304 -45
- metadata +189 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0018be9794020a4b996e0d67a076e2741ca124d475f1439a047a77ecc0667d9d'
|
|
4
|
+
data.tar.gz: 46eae2746ab67af7ace35e7dc4caa6e09897a187ec7295a6fe5b103a33262722
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dd8e061914bb0941234e210a8ea346d4f11dbd0babcd5137e93fe529b094826459b469f6cfb5d2e8cabdc306bbb8471df5703275035a9e8d27fc36352b50ec84
|
|
7
|
+
data.tar.gz: 4f361334ec04c20998333623be5c2d5b97ab27189dc52f1d4fda470ff40e743c38f58b1ae37b85244557a1f7eaf93954abd3baafdcb96c8bc8d57eb4fc71ff98
|
data/Gemfile
CHANGED
|
@@ -49,7 +49,7 @@ gem 'jwt', '3.2.0'
|
|
|
49
49
|
gem 'libusb', '0.8.0'
|
|
50
50
|
gem 'luhn', '3.0.0'
|
|
51
51
|
gem 'mail', '2.9.1'
|
|
52
|
-
gem 'mcp', '1.5.
|
|
52
|
+
gem 'mcp', '1.5.1'
|
|
53
53
|
gem 'meshtastic', '0.0.175'
|
|
54
54
|
gem 'metasm', '1.0.6'
|
|
55
55
|
gem 'mongo', '2.25.0'
|
|
@@ -88,9 +88,9 @@ gem 'ruby-audio', '1.6.1'
|
|
|
88
88
|
gem 'ruby-nmap', '1.0.3'
|
|
89
89
|
gem 'ruby-saml', '1.18.1'
|
|
90
90
|
gem 'rvm', '1.11.3.9'
|
|
91
|
-
gem 'savon', '2.17.
|
|
92
|
-
gem 'selenium-devtools', '0.
|
|
93
|
-
gem 'selenium-webdriver', '4.
|
|
91
|
+
gem 'savon', '2.17.5'
|
|
92
|
+
gem 'selenium-devtools', '0.153.0'
|
|
93
|
+
gem 'selenium-webdriver', '4.49.0'
|
|
94
94
|
gem 'slack-ruby-client', '3.2.0'
|
|
95
95
|
gem 'socksify', '1.8.1'
|
|
96
96
|
gem 'spreadsheet', '1.3.5'
|
data/bin/pwn-ai
ADDED
data/bin/pwn-capd
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Deploy the reviewed Ruby library tree with this executable, never setcap Ruby.
|
|
5
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
6
|
+
require 'pwn'
|
|
7
|
+
require 'pwn/plugins/capability_broker/daemon'
|
|
8
|
+
|
|
9
|
+
begin
|
|
10
|
+
PWN::Plugins::CapabilityBroker::Daemon.main(argv: ARGV)
|
|
11
|
+
rescue StandardError => e
|
|
12
|
+
warn "pwn-capd: #{e.message}"
|
|
13
|
+
exit 1
|
|
14
|
+
end
|
|
@@ -113,8 +113,9 @@ puts resp[:content]
|
|
|
113
113
|
|
|
114
114
|
## Model diversity in Swarm
|
|
115
115
|
|
|
116
|
-
Because each persona in [`agents.yml`](Swarm.md) can override `engine
|
|
117
|
-
`agent_debate` can
|
|
116
|
+
Because each persona in [`agents.yml`](Swarm.md) can override `engine:` and
|
|
117
|
+
`model:`, an `agent_debate` can compare different models on the same provider
|
|
118
|
+
or several *different providers* against each other - real
|
|
118
119
|
antagonism, not one model role-playing three voices. The same mechanism backs
|
|
119
120
|
`ai.agent.escalation_persona`: when a local model is stuck, `Loop.run` asks a
|
|
120
121
|
frontier persona for a 3-line corrective hint and injects it as a synthetic
|
|
@@ -10,10 +10,11 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
|
|
|
10
10
|
|
|
11
11
|
| Toolset | Tools | Backed by |
|
|
12
12
|
|---|---|---|
|
|
13
|
+
| `http` | `http_proxy_start` · `http_proxy_stop` · `http_proxy_entries` · `http_proxy_rules` · `http_replay` | `PWN::Plugins::MitmProxy`: native HTTP HAR capture/replay; opaque CONNECT tunnels |
|
|
13
14
|
| `terminal` | `shell` | `Open3.capture3` on the host, after `PWN::AI::Agent::ToolGuard` |
|
|
14
15
|
| `pwn` | `pwn_eval` | `TOPLEVEL_BINDING.eval` in the live REPL process, after `ToolGuard` |
|
|
15
16
|
| `memory` | `memory_remember` · `memory_recall` · `memory_forget` · `memory_clear` · **`memory_lean`** | `PWN::Memory` → `~/.pwn/memory.json` |
|
|
16
|
-
| `skills` | **`skills_recall`** · `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` · `skill_migrate_legacy` | `~/.pwn/skills/<name>/SKILL.md` (**[agentskills.io](https://agentskills.io) spec**; legacy flat `*.md` auto-migrated) |
|
|
17
|
+
| `skills` | `skills_consolidate` · **`skills_recall`** · `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` · `skill_migrate_legacy` | `~/.pwn/skills/<name>/SKILL.md` (**[agentskills.io](https://agentskills.io) spec**; legacy flat `*.md` auto-migrated) |
|
|
17
18
|
| `sessions` | **`session_recall`** · `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` · **`sessions_lean`** | `PWN::Sessions` → `~/.pwn/sessions/` |
|
|
18
19
|
| `learning` | `learning_note_outcome` · `learning_reflect` · `learning_distill_skill` · `learning_stats` · `learning_outcomes` · `learning_consolidate` · `learning_reset` · `learning_auto_introspect_toggle` · **`learning_gc_stores`** · **`learning_purge_noise`** · **`mistakes_list`** · **`mistakes_record`** · **`mistakes_resolve`** · **`mistakes_reset`** · **`mistakes_lean`** · **`reward_judge`** · **`reward_prm`** · **`reward_sentinel`** · **`reward_preferences`** · **`reward_export_dpo`** · **`reward_warm_sentinel`** · **`reward_scrub_preferences`** · **`reward_preference_balance`** · **`curriculum_practice`** · **`curriculum_train`** · **`curriculum_hindsight`** · **`curriculum_offline_judge`** · **`curriculum_preference_balance`** | `PWN::AI::Agent::Learning` + `Mistakes` + `Reward` + `Curriculum` → `~/.pwn/learning.jsonl` + `~/.pwn/mistakes.json` + `~/.pwn/preferences.jsonl` + `~/.pwn/curriculum/` + `~/.pwn/finetune/` |
|
|
19
20
|
| `reward` | **`reward_generator_mix`** | `PWN::AI::Agent::Reward.generator_mix` → online preference source-mix controller (`preferences.jsonl`) |
|
|
@@ -23,6 +24,7 @@ toolsets; the JSON-Schema for each tool is what the model actually sees.
|
|
|
23
24
|
| `extrospection` | `extro_snapshot` · `extro_drift` · `extro_observe` · `extro_observations` · `extro_intel` · **`extro_watch`** · **`extro_verify`** · **`extro_rf_tune`** · **`extro_osint`** · **`extro_serial`** · **`extro_telecomm`** · **`extro_packet`** · **`extro_vision`** · **`extro_voice`** · `extro_correlate` · `extro_stats` · `extro_reset` · `extro_auto_toggle` | `PWN::AI::Agent::Extrospection` (+ Serial/Packet/OCR/Voice/BareSIP/TransparentBrowser/GQRX) → `~/.pwn/extrospection.json` |
|
|
24
25
|
| `cron` | `cron_list` · `cron_create` · `cron_run` · `cron_enable` · `cron_disable` · `cron_remove` | `PWN::Cron` → `~/.pwn/cron/jobs.yml` |
|
|
25
26
|
| `swarm` | `agent_list` · `agent_spawn` · `agent_ask` · `agent_debate` · `agent_broadcast` · `swarm_bus` · `swarm_list` | `PWN::AI::Agent::Swarm` → `~/.pwn/agents.yml` + `~/.pwn/swarm/` |
|
|
27
|
+
| `manifest` | `host_os_type` | YAML tool declarations in `lib/pwn/ai/tools/*.yaml` via `PWN::AI::Agent::Manifest` |
|
|
26
28
|
|
|
27
29
|
The `learning` toolset is deliberately large: **Mistakes** (negative feedback),
|
|
28
30
|
**Reward** (outcome and process judges, sentinel, preference ledger) and
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Capability broker and disposable sandbox
|
|
2
|
+
|
|
3
|
+
## pwn-capd (P8)
|
|
4
|
+
|
|
5
|
+
The native Ruby helper speaks one bounded JSON request per Unix connection.
|
|
6
|
+
Ruby `Socket` and `pack` implement AF_PACKET send/capture and pcap encoding;
|
|
7
|
+
the existing `ffi` gem calls Linux libc `prctl`, `capget` and `capset`.
|
|
8
|
+
There is no Python runtime or fallback. Read-only ARP/ND queries retain the
|
|
9
|
+
`/usr/sbin/ip` (iproute2) dependency, executed as an argument vector with a
|
|
10
|
+
clean environment, bounded output and a five-second deadline.
|
|
11
|
+
Linux SO_PEERCRED authenticates the configured caller UID; the client also
|
|
12
|
+
checks the daemon UID. The socket is mode 0600. Only explicitly configured
|
|
13
|
+
interfaces are accepted. Operations: `status`, `raw_send` (base64 Ethernet
|
|
14
|
+
frame), `capture` (bounded in-memory pcap), `arp` / `nd` (typed IP kernel
|
|
15
|
+
neighbor-cache queries). There is no command endpoint, arbitrary privileged
|
|
16
|
+
output path, firewall mutation, or implicit sudo. ARP/ND currently query cache;
|
|
17
|
+
they do not actively solicit neighbors or mutate entries.
|
|
18
|
+
|
|
19
|
+
Requests are limited to 100,000 bytes including the newline; each connection
|
|
20
|
+
has a 35-second total deadline. Ethernet sends accept 14..65,535 decoded bytes.
|
|
21
|
+
Captures accept 1..128 packets, at most 30 seconds, and 4,096 bytes per packet.
|
|
22
|
+
The helper sets `no_new_privs`, intersects effective/permitted capabilities
|
|
23
|
+
with CAP_NET_RAW/CAP_NET_ADMIN, and clears both inheritable words before
|
|
24
|
+
handling requests. It never adds a capability. Existing socket paths (including
|
|
25
|
+
symlinks) and writable or foreign-owned socket directories are refused.
|
|
26
|
+
|
|
27
|
+
Unprivileged protocol and native-executable smoke (no raw packets or privilege grants):
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
bundle exec rspec spec/lib/pwn/plugins/capability_broker_spec.rb spec/lib/pwn/plugins/capability_broker/daemon_spec.rb
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Operator installation (NOT executed by the application): install the reviewed
|
|
34
|
+
PWN Ruby package and its dependencies root-owned, including `bin/pwn-capd`,
|
|
35
|
+
`lib/pwn/plugins/capability_broker.rb` and
|
|
36
|
+
`lib/pwn/plugins/capability_broker/daemon.rb`. Keep the package's `bin/` and
|
|
37
|
+
`lib/` layout intact; point the service ExecStart at that package's
|
|
38
|
+
`bin/pwn-capd`. A root-managed installed-gem executable may also be exposed
|
|
39
|
+
as `/usr/local/libexec/pwn-capd` (mode 0755). The executable, library tree,
|
|
40
|
+
Ruby interpreter, gems and all ancestor directories must be administrator
|
|
41
|
+
controlled and non-writable by clients. Clear user-controlled `RUBYOPT`,
|
|
42
|
+
`RUBYLIB`, `GEM_HOME`, `GEM_PATH` and Bundler environment settings in the
|
|
43
|
+
service; use only the reviewed installation's dependency paths.
|
|
44
|
+
Do **not** setcap the shared Ruby interpreter
|
|
45
|
+
or this script: Linux ignores script file capabilities, and granting a shared
|
|
46
|
+
interpreter network privileges exposes every script. Use a dedicated systemd
|
|
47
|
+
service with `User=<operator>`, `AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN`,
|
|
48
|
+
`CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN`, `NoNewPrivileges=yes`,
|
|
49
|
+
`ProtectSystem=strict`, `ProtectHome=yes`, `RuntimeDirectory=pwn-capd`,
|
|
50
|
+
`RestrictAddressFamilies=AF_UNIX AF_PACKET AF_NETLINK`, and the reviewed helper
|
|
51
|
+
as ExecStart. The socket owner and configured peer UID must match that operator.
|
|
52
|
+
Enable a preconfigured unit with `sudo systemctl start pwn-capd`.
|
|
53
|
+
For an audited one-shot sudo launch use:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
sudo /usr/local/libexec/pwn-capd --uid "$(id -u)" --interface lo
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Never authorize unrestricted sudo access to arbitrary helper arguments. Pin
|
|
60
|
+
UID, socket and interface in sudoers. Only add engagement interfaces after
|
|
61
|
+
operator review. CAP_NET_ADMIN is reserved for future neighbor management;
|
|
62
|
+
current operations need CAP_NET_RAW, while neighbor queries are read-only.
|
|
63
|
+
|
|
64
|
+
Ruby API (explicit require until central autoload is integrated):
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
require 'pwn/plugins/capability_broker'
|
|
68
|
+
PWN::Plugins::CapabilityBroker.request(operation: 'status')
|
|
69
|
+
PWN::Plugins::CapabilityBroker.request(operation: 'arp', iface: 'lo', address: '127.0.0.1')
|
|
70
|
+
PWN::Plugins::CapabilityBroker.request(operation: 'nd', iface: 'lo', address: '::1')
|
|
71
|
+
# Packet.send(pkt:, iface:, socket:) and Packet.capture(path:, count:, timeout:, iface:, socket:)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`PWN_CAPD_SOCKET` overrides `/run/pwn-capd/control.sock`. Capture artifacts are
|
|
75
|
+
written and read back by the unprivileged client, never by the daemon.
|
|
76
|
+
Absent broker returns degraded error and missing local CAP_NET_RAW accurately;
|
|
77
|
+
there is no fabricated capture path or privileged Ruby remediation.
|
|
78
|
+
|
|
79
|
+
## Sandbox (P13)
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
require 'pwn/plugins/sandbox'
|
|
83
|
+
PWN::Plugins::Sandbox.run(binary: '/path/safe-fixture', argv: [], stdin: '', timeout: 10, memory_mb: 256)
|
|
84
|
+
PWN::Plugins::Sandbox.fuzz(target: '/path/safe-fixture', corpus: '/path/seeds', minutes: 1, seed: 0)
|
|
85
|
+
s = PWN::Plugins::Sandbox.snapshot(binary: '/path/safe-fixture')
|
|
86
|
+
PWN::Plugins::Sandbox.rollback(snapshot: s[:snapshot], backend: 'bwrap')
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Docker is default, image `pwn-sandbox:local`; it must be provisioned locally,
|
|
90
|
+
with `/usr/bin/ruby`, strace, GDB, and target runtime libraries. The controller
|
|
91
|
+
and isolated worker use Ruby stdlib only; no Python interpreter is launched by
|
|
92
|
+
the sandbox driver (GDB itself may include Python support). No implicit
|
|
93
|
+
pull, installation, daemon startup or host-execution fallback occurs. Use the
|
|
94
|
+
included `lib/pwn/plugins/sandbox/Dockerfile` to build explicitly. Network none,
|
|
95
|
+
read-only root/artifacts, unprivileged UID, all caps dropped, no-new-privileges,
|
|
96
|
+
pid/cpu/memory/swap constraints, disposable bounded tmpfs, forced cleanup.
|
|
97
|
+
Instrumentation runs are separate replays with the same input, not observation
|
|
98
|
+
of the original execution. Signals, PC, backtrace, raw GDB output are returned;
|
|
99
|
+
exploitable classification is `unknown` if the GDB plugin is absent. No invented
|
|
100
|
+
classification. Current `-nx` configuration deliberately does not load arbitrary
|
|
101
|
+
user GDB startup scripts. Install a reviewed exploitable plugin into the image
|
|
102
|
+
and extend its explicit initialization if classification is required.
|
|
103
|
+
|
|
104
|
+
Explicit `backend: 'bwrap'` works without a Docker daemon where unprivileged
|
|
105
|
+
user namespaces are permitted. It exposes only read-only system runtime trees
|
|
106
|
+
and target artifact, creates fresh user/network/PID/mount namespaces, and hides
|
|
107
|
+
home. It is a **weaker resource tier**: per-process RLIMIT_AS, not an aggregate
|
|
108
|
+
cgroup budget or fork-bomb protection. Use Docker/microVM for hostile samples.
|
|
109
|
+
No automatic backend fallback. Snapshot/rollback means verified immutable input
|
|
110
|
+
copies and fresh disposable environments, **not live process/VM checkpoints**.
|
|
111
|
+
Fuzzing is bounded seeded bit-flip stdin mutation, not coverage-guided AFL.
|
|
112
|
+
|
|
113
|
+
Tools register via `require 'pwn/ai/agent/tools/sandbox'`: `sandbox_run` and
|
|
114
|
+
`sandbox_fuzz`; normal Registry discovery finds that file.
|
|
115
|
+
|
|
116
|
+
Sandbox verification (safe bwrap fixtures require working unprivileged namespaces):
|
|
117
|
+
```
|
|
118
|
+
bundle exec rspec spec/lib/pwn/plugins/sandbox_spec.rb spec/lib/pwn/plugins/sandbox/driver_spec.rb
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The tests exercise `/bin/true`, read-only mounts, namespace isolation without
|
|
122
|
+
network requests, timeouts, resource limits, SIGSEGV/GDB/strace replay,
|
|
123
|
+
byte-exact stdin mutation and snapshot integrity. Docker command/cleanup unit
|
|
124
|
+
checks are not evidence of a running Docker backend. The GDB fixture requests
|
|
125
|
+
1024 MiB: this host's GDB can exhaust the default 256 MiB address-space budget.
|
|
126
|
+
Instrumentation failures retain raw output and an unknown classification.
|
|
127
|
+
|
|
128
|
+
Fuzz seeds are reproducible within this Ruby implementation, not bit-for-bit
|
|
129
|
+
compatible with Python's PRNG sequence. Each iteration retains the execution
|
|
130
|
+
and replay budget plus bounded backend startup/cleanup overhead; the minutes
|
|
131
|
+
budget stops starting new iterations, rather than preempting cleanup.
|
|
132
|
+
|
|
133
|
+
Safe real Docker smoke after explicit provisioning:
|
|
134
|
+
```
|
|
135
|
+
bundle exec ruby -Ilib -rpwn/plugins/sandbox -e 'p PWN::Plugins::Sandbox.run(binary: "/bin/true")'
|
|
136
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
LoRa PHY coding equations in lib/pwn/sdr/decoder/lora.rb are adapted from
|
|
2
|
+
https://github.com/jkadbear/LoRaPHY/blob/4fddd9a7b47682781c663608bfc4f196e4bf656d/LoRaPHY.m
|
|
3
|
+
|
|
4
|
+
The MIT License (MIT)
|
|
5
|
+
|
|
6
|
+
Copyright (C) 2020-2022 jkadbear, jkadbear@gmail.com
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
9
|
+
a copy of this software and associated documentation files (the
|
|
10
|
+
"Software"), to deal in the Software without restriction, including
|
|
11
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
12
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
13
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
14
|
+
the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be
|
|
17
|
+
included in all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
20
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
21
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
22
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
23
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
24
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
25
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Native HTTP capture and skill hygiene
|
|
2
|
+
|
|
3
|
+
## Native HTTP proxy (P16)
|
|
4
|
+
|
|
5
|
+
`PWN::Plugins::MitmProxy` uses WEBrick's native proxy/CONNECT transport and
|
|
6
|
+
Net::HTTP for interception. It does not require mitmproxy, Burp, or ZAP.
|
|
7
|
+
Only backend `native` is accepted. HTTPS CONNECT tunnels work, but their
|
|
8
|
+
contents are **not decrypted**: captured entries explicitly have
|
|
9
|
+
`_capture: opaque_connect`. HTTP requests and responses are captured to HAR 1.2.
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require 'pwn/plugins/mitm_proxy'
|
|
13
|
+
proxy = PWN::Plugins::MitmProxy.start(har_path: '/tmp/engagement.har')
|
|
14
|
+
browser = PWN::Plugins::TransparentBrowser.open(
|
|
15
|
+
browser_type: :headless_chrome, capture_proxy: proxy
|
|
16
|
+
)
|
|
17
|
+
# Navigate the browser using its normal API. Chrome loopback bypass is disabled.
|
|
18
|
+
entries = PWN::Plugins::MitmProxy.entries(proxy: proxy)
|
|
19
|
+
entry = PWN::Plugins::MitmProxy.http_replay(
|
|
20
|
+
proxy: proxy, request_id: entries.first[:_request_id],
|
|
21
|
+
mutations: { method: 'POST', path: '/fixture', headers: { 'X-Test' => 'yes' }, body: 'sample' }
|
|
22
|
+
)
|
|
23
|
+
# Close the browser separately, then stop its caller-owned proxy:
|
|
24
|
+
PWN::Plugins::MitmProxy.stop(proxy: proxy)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Agent toolset `http`: `http_proxy_start`, `http_proxy_entries`,
|
|
28
|
+
`http_proxy_rules`, `http_replay`, `http_proxy_stop`. Lifecycle tools return
|
|
29
|
+
JSON descriptors; subsequent calls use `proxy_id: descriptor[:id]`.
|
|
30
|
+
The plugin also accepts `proxy:` descriptors. IDs are process-local, not
|
|
31
|
+
persistent replay handles after restart.
|
|
32
|
+
|
|
33
|
+
Replace the entire active rule list with `rules(proxy:, rules:)`. Rules are
|
|
34
|
+
literal substitutions (not regex):
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
[{ phase: 'request', field: 'header:x-test', match: 'old', replace: 'new' },
|
|
38
|
+
{ phase: 'response', field: 'body', match: 'old', replace: 'new' }]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Fields are `body`, request-only `url`, or `header:NAME`. Replay mutations are
|
|
42
|
+
`method`, `url`, `path`, `query`, `headers`, `body`; null header values remove
|
|
43
|
+
headers. Hop-by-hop/framing headers are regenerated. Binary HAR bodies use
|
|
44
|
+
base64 encoding. Replay does not mutate the original captured entry.
|
|
45
|
+
|
|
46
|
+
HAR files contain **unredacted traffic**, including any cookies and credentials
|
|
47
|
+
sent by the operator. They are created mode 0600; use engagement storage and
|
|
48
|
+
retention controls. Only loopback fixtures are used by the regression tests.
|
|
49
|
+
There is no built-in scope policy for proxy traffic; enforcement belongs in
|
|
50
|
+
engagement network isolation or the central scope layer. Binding is loopback
|
|
51
|
+
by default. Upstream HTTP timeout defaults to 30 seconds. Bodies and the
|
|
52
|
+
session capture collection are currently buffered in memory, not streamed.
|
|
53
|
+
|
|
54
|
+
## On-demand skills consolidation (P19)
|
|
55
|
+
|
|
56
|
+
`PWN::AI::Agent::SkillConsolidation.consolidate(content:, evidence: {}, now:,
|
|
57
|
+
stale_days: 90)` returns a pure proposal: `content`, `version`, `changed`,
|
|
58
|
+
`deduplicated`, `promoted`, and `review`.
|
|
59
|
+
|
|
60
|
+
- Deduplicates RL notes, ignoring leading date annotations and whitespace.
|
|
61
|
+
- Conflicting text for one feedback ID, explicit negation against a SOP line,
|
|
62
|
+
regressed proofs, and stale verification move to a **not active SOP** review
|
|
63
|
+
section. Unmanaged SOP prose is never automatically deleted or rewritten.
|
|
64
|
+
- Promotions require resolved status, three distinct explicitly successful
|
|
65
|
+
verification sessions, and recent non-future verification. Failure counts
|
|
66
|
+
and failure-session IDs do not count as successful evidence.
|
|
67
|
+
- Managed promoted procedures are rechecked for stale or regressed proofs.
|
|
68
|
+
- Stamps `<!-- pwn-skill-version: HASH12 updated: ISO8601 -->` after YAML
|
|
69
|
+
frontmatter; unchanged content remains byte-identical on subsequent passes.
|
|
70
|
+
|
|
71
|
+
`consolidate_file(path:)` previews by default. Applying requires
|
|
72
|
+
`dry_run: false, confirm: true, expected_sha256: preview[:source_sha256]`.
|
|
73
|
+
It serializes cooperating consolidation writers, checks the original content,
|
|
74
|
+
keeps a content-addressed backup, atomically replaces the file, and verifies
|
|
75
|
+
readback. Symlink files are rejected. No weekly job is installed.
|
|
76
|
+
|
|
77
|
+
Agent tool `skills_consolidate(name:, dry_run: true)` targets an already
|
|
78
|
+
installed skill; it does not accept model-provided verification evidence.
|
|
79
|
+
It reloads the skill index after an explicitly confirmed write.
|
|
80
|
+
|
|
81
|
+
## Precise correction evidence (P20) and integration hooks
|
|
82
|
+
|
|
83
|
+
Docker socket permissions, registry pull denial and template parsing remain
|
|
84
|
+
distinct classes/signatures. Generic path fixes cannot resolve non-path
|
|
85
|
+
failures; raw-socket fixes cannot resolve ordinary filesystem/daemon
|
|
86
|
+
permissions. Legacy incompatible fixes are excluded from KNOWN FIXES.
|
|
87
|
+
|
|
88
|
+
For promotion evidence, the successful verification hook should call:
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
PWN::AI::Agent::Mistakes.note_hint_outcome(
|
|
92
|
+
signature: signature, helped: true, session_id: verified_session_id
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Failed hints clear that stability evidence. `skills_consolidate` consumes
|
|
97
|
+
`verified_sessions` and `last_verified` keyed by the existing RL signature.
|
|
98
|
+
The parent loop must pass `session_id` only after real verification; callers
|
|
99
|
+
that omit it cannot promote notes merely by incrementing a counter.
|
|
100
|
+
Session-recall/index consumers can read the `pwn-skill-version` stamp and
|
|
101
|
+
prefer current installed content over historical SOP text. This module does
|
|
102
|
+
not modify central loop or session-recall selection behavior.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Recon / Findings integration (P17 / P10)
|
|
2
|
+
|
|
3
|
+
## Parent integration hooks
|
|
4
|
+
|
|
5
|
+
- Existing autoloaded `PWN::Plugins::Recon` now exposes `run(opts)`; no new plugin autoload needed. New agent registration file: `lib/pwn/ai/agent/tools/recon_run.rb` (normal Registry discovery).
|
|
6
|
+
- `finding_record` handler uses `PWN::Plugins::Findings.record_structured(opts)`. The loop can treat `ArgumentError` as incomplete finding input; **do not infer a working PoC from accepted input**. No Loop/config/CLI changes in this patch.
|
|
7
|
+
- P3 hook: `Recon.run(..., ingest: true)` calls `PWN::AI::Context.ingest(path, session_id: engagement_id, **ingest_options)` after atomic persistence and JSON readback. `ingestor: callable` supports an alternate implementation with the same signature. Ingestion failure is returned in `result[:ingestion]` without discarding recon evidence. Preserve the literal asset ID in ingested chunks. Plugin callers opt in; the agent tool defaults ingestion on.
|
|
8
|
+
|
|
9
|
+
## Recon model
|
|
10
|
+
|
|
11
|
+
`Recon.run(target: '127.0.0.1', modules: %w[nmap banner tls], ports: [443], engagement_id: 'lab', ingest: true)`.
|
|
12
|
+
|
|
13
|
+
Single hostname/IP target (no arbitrary CLI switches, URL, CIDR, or shell command), explicit integer ports, per-operation timeout 15 seconds by default (maximum 300). `nmap` uses an unprivileged TCP connect scan, without sudo or NSE. Existing `NmapIt` API remains untouched. `banner` passively reads up to 4096 bytes; it does not send an HTTP request. `tls` collects the certificate with `trust_verified: false` (not a trust audit). Optional `subfinder` and `nuclei` run **only if explicitly named**, and unavailable tools return module status rather than fabricate results. Nuclei observations are not automatically promoted to findings.
|
|
14
|
+
|
|
15
|
+
Output: `{schema_version: 1, engagement_id:, assets: [{id:, address:, protocol:, port:, observations: [], evidence_paths: []}], modules: [], path:, ingestion: ...}`.
|
|
16
|
+
|
|
17
|
+
Stored at `~/.pwn/engagements/<engagement>/recon/assets.json`; `root:` overrides the engagements directory for isolated fixtures. Raw scan evidence is persisted beside it. IDs are `asset-` plus the first 24 hex SHA256 characters of lowercase address, protocol, port joined by `|`. Repeated same-identity observations merge across runs, not overwrite other assets. DNS names and resolved IPs are distinct identities unless the source explicitly supplies the same address; the pipeline does not silently infer aliases.
|
|
18
|
+
|
|
19
|
+
Use `affected_asset: asset[:id]` and `evidence_paths: asset[:evidence_paths]` in a structured finding. Stable IDs survive report generation and JSON ingestion unchanged.
|
|
20
|
+
|
|
21
|
+
## Strict findings boundary and compatibility
|
|
22
|
+
|
|
23
|
+
`record_structured` requires title, CWE identifier (`CWE-<positive integer>`), complete CVSS 3.0/3.1 base vector and matching numeric base score, affected_asset, nonempty existing readable absolute evidence_paths, nonempty PoC command/code string, attack_chain_refs array, remediation string, and numeric confidence 0..1. Chain refs must already exist in the same engagement. Invalid input raises before appending. CVSS 2/4, temporal/environmental vectors are explicitly unsupported (rejected, not normalized).
|
|
24
|
+
|
|
25
|
+
Legacy `Findings.record`, query/report, chain, render, and SARIF output remain callable; legacy record is not the strict API. Agent record and chain operations are strict. Existing query/export tool operations remain available. Accepted structured rows mark `verification_status: not_executed`; evidence hashes prove captured bytes, not exploit execution. Severity is derived from the validated score. No automatic escalation for linked findings.
|
|
26
|
+
|
|
27
|
+
Markdown/HTML/JSON report payloads compose connected explicit references into attack-chain sections, preserving all finding fields. Combined severity is maximum recorded constituent severity with a rationale explicitly disclaiming escalation and combined exploitability. This is not a computed CVSS chain score.
|
|
28
|
+
|
|
29
|
+
## Verification boundaries
|
|
30
|
+
|
|
31
|
+
Specs use disposable localhost TCP/TLS fixtures and real nmap connect scans. Optional external scanner outputs are parser fixtures, not internet engagements. Context hook failures are visible; embeddings are never synthesized. No remote scanning is necessary to run these focused specs.
|