pwn 0.5.613 → 0.5.617

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.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -10
  3. data/README.md +117 -17
  4. data/bin/pwn +47 -2
  5. data/bin/pwn_gqrx_scanner +75 -18
  6. data/documentation/AI-Integration.md +36 -0
  7. data/documentation/BurpSuite.md +26 -0
  8. data/documentation/Contributing.md +31 -0
  9. data/documentation/Diagrams.md +140 -0
  10. data/documentation/Drivers.md +25 -0
  11. data/documentation/General-PWN-Usage.md +60 -0
  12. data/documentation/Home.md +78 -0
  13. data/documentation/How-PWN-Works.md +62 -0
  14. data/documentation/Installation.md +75 -0
  15. data/documentation/NmapIt.md +18 -0
  16. data/documentation/Plugins.md +59 -0
  17. data/documentation/Reporting.md +28 -0
  18. data/documentation/SAST.md +32 -0
  19. data/documentation/Skills-Memory-Learning.md +44 -0
  20. data/documentation/Transparent-Browser.md +32 -0
  21. data/documentation/Troubleshooting.md +38 -0
  22. data/documentation/What-is-PWN.md +53 -0
  23. data/documentation/Why-PWN.md +48 -0
  24. data/documentation/diagrams/ai-integration-tool-calling.svg +172 -0
  25. data/documentation/diagrams/build.sh +20 -0
  26. data/documentation/diagrams/burp-vs-zap-preference.svg +69 -0
  27. data/documentation/diagrams/code-scanning-sast.svg +172 -0
  28. data/documentation/diagrams/dot/_THEME.md +27 -0
  29. data/documentation/diagrams/dot/agent-tool-registry.dot +59 -0
  30. data/documentation/diagrams/dot/ai-integration-tool-calling.dot +50 -0
  31. data/documentation/diagrams/dot/aws-cloud-security.dot +48 -0
  32. data/documentation/diagrams/dot/burp-vs-zap-preference.dot +26 -0
  33. data/documentation/diagrams/dot/code-scanning-sast.dot +49 -0
  34. data/documentation/diagrams/dot/cron-scheduling.dot +40 -0
  35. data/documentation/diagrams/dot/driver-framework.dot +39 -0
  36. data/documentation/diagrams/dot/extrospection-world-awareness.dot +55 -0
  37. data/documentation/diagrams/dot/fuzzing-workflow.dot +47 -0
  38. data/documentation/diagrams/dot/history-to-drivers.dot +34 -0
  39. data/documentation/diagrams/dot/memory-skills-detailed.dot +60 -0
  40. data/documentation/diagrams/dot/network-infra-testing.dot +54 -0
  41. data/documentation/diagrams/dot/overall-pwn-architecture.dot +115 -0
  42. data/documentation/diagrams/dot/penetration-testing-workflow.dot +60 -0
  43. data/documentation/diagrams/dot/plugin-ecosystem.dot +45 -0
  44. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +98 -0
  45. data/documentation/diagrams/dot/pwn-repl-prototyping.dot +56 -0
  46. data/documentation/diagrams/dot/reporting-pipeline.dot +46 -0
  47. data/documentation/diagrams/dot/reverse-engineering-flow.dot +43 -0
  48. data/documentation/diagrams/dot/sdr-radio-flow.dot +45 -0
  49. data/documentation/diagrams/dot/sessions-cron-automation.dot +44 -0
  50. data/documentation/diagrams/dot/swarm-multi-agent.dot +70 -0
  51. data/documentation/diagrams/dot/web-application-testing.dot +49 -0
  52. data/documentation/diagrams/dot/zero-day-research-flow.dot +49 -0
  53. data/documentation/diagrams/driver-framework.svg +111 -0
  54. data/documentation/diagrams/fuzzing-workflow.svg +160 -0
  55. data/documentation/diagrams/history-to-drivers.svg +119 -0
  56. data/documentation/diagrams/memory-skills-detailed.svg +202 -0
  57. data/documentation/diagrams/network-infra-testing.svg +183 -0
  58. data/documentation/diagrams/overall-pwn-architecture.svg +405 -0
  59. data/documentation/diagrams/penetration-testing-workflow.svg +201 -0
  60. data/documentation/diagrams/plugin-ecosystem.svg +276 -0
  61. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +306 -0
  62. data/documentation/diagrams/pwn-repl-prototyping.svg +168 -0
  63. data/documentation/diagrams/reporting-pipeline.svg +151 -0
  64. data/documentation/diagrams/reverse-engineering-flow.svg +134 -0
  65. data/documentation/diagrams/sessions-cron-automation.svg +136 -0
  66. data/documentation/diagrams/web-application-testing.svg +173 -0
  67. data/documentation/diagrams/zero-day-research-flow.svg +153 -0
  68. data/documentation/pwn-REPL.md +33 -0
  69. data/documentation/pwn-ai-Agent.md +43 -0
  70. data/git_commit.sh +1 -1
  71. data/lib/pwn/ai/agent/assembly.rb +1 -1
  72. data/lib/pwn/ai/agent/btc.rb +1 -1
  73. data/lib/pwn/ai/agent/burp_suite.rb +1 -1
  74. data/lib/pwn/ai/agent/extrospection.rb +618 -0
  75. data/lib/pwn/ai/agent/gqrx.rb +2 -2
  76. data/lib/pwn/ai/agent/hacker_one.rb +1 -1
  77. data/lib/pwn/ai/agent/introspection.rb +91 -0
  78. data/lib/pwn/ai/agent/learning.rb +379 -0
  79. data/lib/pwn/ai/agent/loop.rb +33 -3
  80. data/lib/pwn/ai/agent/metrics.rb +155 -0
  81. data/lib/pwn/ai/agent/prompt_builder.rb +32 -3
  82. data/lib/pwn/ai/agent/sast.rb +1 -1
  83. data/lib/pwn/ai/agent/swarm.rb +437 -0
  84. data/lib/pwn/ai/agent/tools/cron.rb +163 -0
  85. data/lib/pwn/ai/agent/tools/extrospection.rb +280 -0
  86. data/lib/pwn/ai/agent/tools/learning.rb +221 -0
  87. data/lib/pwn/ai/agent/tools/memory.rb +27 -0
  88. data/lib/pwn/ai/agent/tools/metrics.rb +61 -0
  89. data/lib/pwn/ai/agent/tools/sessions.rb +139 -0
  90. data/lib/pwn/ai/agent/tools/skills.rb +124 -8
  91. data/lib/pwn/ai/agent/tools/swarm.rb +229 -0
  92. data/lib/pwn/ai/agent/transparent_browser.rb +1 -1
  93. data/lib/pwn/ai/agent/vuln_gen.rb +2 -2
  94. data/lib/pwn/ai/agent.rb +5 -0
  95. data/lib/pwn/ai/anthropic.rb +19 -4
  96. data/lib/pwn/ai/grok.rb +249 -106
  97. data/lib/pwn/ai.rb +0 -1
  98. data/lib/pwn/config.rb +96 -36
  99. data/lib/pwn/cron.rb +16 -7
  100. data/lib/pwn/plugins/monkey_patch.rb +2 -2
  101. data/lib/pwn/plugins/repl.rb +158 -284
  102. data/lib/pwn/sdr/decoder/base.rb +251 -0
  103. data/lib/pwn/sdr/decoder/gsm.rb +84 -185
  104. data/lib/pwn/sdr/decoder/pocsag.rb +62 -217
  105. data/lib/pwn/sdr/decoder.rb +1 -0
  106. data/lib/pwn/sdr/gqrx.rb +446 -65
  107. data/lib/pwn/version.rb +1 -1
  108. data/spec/lib/pwn/ai/agent/extrospection_spec.rb +15 -0
  109. data/spec/lib/pwn/ai/agent/introspection_spec.rb +15 -0
  110. data/spec/lib/pwn/ai/agent/learning_spec.rb +68 -0
  111. data/spec/lib/pwn/ai/agent/metrics_spec.rb +27 -0
  112. data/spec/lib/pwn/ai/agent/swarm_spec.rb +34 -0
  113. data/spec/lib/pwn/ai/agent/tools/cron_spec.rb +40 -0
  114. data/spec/lib/pwn/ai/agent/tools/extrospection_spec.rb +40 -0
  115. data/spec/lib/pwn/ai/agent/tools/learning_spec.rb +30 -0
  116. data/spec/lib/pwn/ai/agent/tools/metrics_spec.rb +20 -0
  117. data/spec/lib/pwn/ai/agent/tools/sessions_spec.rb +35 -0
  118. data/spec/lib/pwn/ai/agent/tools/swarm_spec.rb +17 -0
  119. data/spec/lib/pwn/{ai/introspection_spec.rb → sdr/decoder/base_spec.rb} +3 -3
  120. data/third_party/pwn_rdoc.jsonl +178 -33
  121. metadata +110 -36
  122. data/documentation/PWN.png +0 -0
  123. data/documentation/PWN_Contributors_and_Users.png +0 -0
  124. data/documentation/fax-spectrogram.png +0 -0
  125. data/documentation/fax-waveform.png +0 -0
  126. data/documentation/frozen_string_literal_files_changed_from_false_to_true.txt +0 -54
  127. data/documentation/lifecycle_authz_replay.example.yaml +0 -27
  128. data/documentation/pwn_android_war_dialer_session.png +0 -0
  129. data/documentation/pwn_install.png +0 -0
  130. data/documentation/pwn_wallpaper.jpg +0 -0
  131. data/documentation/ringing-spectrogram.png +0 -0
  132. data/documentation/ringing-waveform.png +0 -0
  133. data/documentation/vulnerability_report_template.md +0 -37
  134. data/lib/pwn/ai/introspection.rb +0 -76
@@ -0,0 +1,38 @@
1
+ # Troubleshooting
2
+
3
+ ## Common Issues
4
+
5
+ ### Burp / ZAP Proxy Problems
6
+ - Prefer `PWN::Plugins::BurpSuite`
7
+ - 502 errors usually mean upstream proxy not listening or crashed. Check with `ps`, `ss -tlnp`, restart via plugin methods.
8
+
9
+ ### Ruby / Gemset Issues
10
+ - Use RVM and the gemset defined in `.ruby-version` / `.ruby-gemset`.
11
+ - Re-run `./install.sh ruby-gem` or the vagrant provisioner after Ruby upgrades.
12
+
13
+ ### AI / LLM Authentication
14
+ - Grok uses OAuth device flow (public client) — see `xai_grok_oauth_device_flow` skill.
15
+ - Store credentials via `PWN::Config` or environment as documented.
16
+
17
+ ### SHIFT+ENTER Not Working in pwn-ai
18
+ - Requires tmux `extended-keys on` on **both** inner and outer sides.
19
+ - See recent lessons in memory for exact tmux config.
20
+
21
+ ### Git / Permissions
22
+ - Run `sudo chown -R $USER:$USER /opt/pwn` if permission issues after install.
23
+
24
+ ## Diagnostics
25
+
26
+ ```bash
27
+ pwn
28
+ PWN.help
29
+ # Inside REPL:
30
+ PWN::Config
31
+ PWN::Plugins::PWNLogger
32
+ ```
33
+
34
+ Check `~/.pwn/` for logs, metrics, learning files.
35
+
36
+ Report bugs via GitHub issues with full reproduction + `pwn` version.
37
+
38
+ [[Diagrams]]
@@ -0,0 +1,53 @@
1
+ # What is PWN
2
+
3
+ **PWN** (pronounced /pōn/ — "pone") is an open-source **offensive-security
4
+ automation framework** and **continuous-security-integration** platform,
5
+ distributed as a Ruby gem.
6
+
7
+ It gives security researchers, red teamers, bug-bounty hunters and DevSecOps
8
+ engineers a single, scriptable surface over the entire offensive toolchain —
9
+ from OSINT and network discovery, through web/cloud/hardware/radio
10
+ exploitation, to reporting and disclosure — and puts a **self-improving,
11
+ tool-calling AI agent** on top of it.
12
+
13
+ ## In numbers
14
+
15
+ | Namespace | Count | What it is |
16
+ |---|---|---|
17
+ | `PWN::Plugins::*` | **66** | Wrappers for external + native tooling (Burp, Nmap, Metasploit, Shodan, browsers, serial, …) |
18
+ | `PWN::SAST::*` | **48** | Static-analysis rules across C/Java/Go/Python/Ruby/Scala/PHP/TS |
19
+ | `PWN::AWS::*` | **90** | One module per AWS service for cloud enumeration |
20
+ | `PWN::WWW::*` | **21** | Site-specific browser automations (HackerOne, BugCrowd, Google, LinkedIn, …) |
21
+ | `PWN::SDR::*` | **6** | GQRX, FlipperZero, RFIDler, SonMicro, decoders, band tables |
22
+ | `PWN::AI::*` | **5** engines | OpenAI, Anthropic, Grok (OAuth device-flow), Gemini, Ollama |
23
+ | `bin/pwn_*` | **52** | Headless CLI drivers for CI/CD |
24
+ | Agent toolsets | **10** | terminal · pwn · memory · skills · sessions · learning · metrics · extrospection · cron · swarm |
25
+
26
+ ## The three ways to use it
27
+
28
+ 1. **`pwn` REPL** — a Pry shell with the whole `PWN::` namespace pre-loaded.
29
+ Prototype an attack chain interactively, one method call at a time.
30
+ 2. **`pwn-ai`** — a natural-language TUI (or `pwn --ai "…"` one-shot) where an
31
+ LLM plans and executes those same method calls for you, records what
32
+ worked, and gets better at it.
33
+ 3. **`bin/pwn_*` drivers** — thin CLIs over the plugins, for cron and CI/CD.
34
+
35
+ ## What makes it different
36
+
37
+ - **Everything is Ruby, everything is a method.** No YAML DSLs, no plugins-in-a-
38
+ black-box. If you can call it in the REPL, the AI agent can call it, a driver
39
+ can call it, and a cron job can call it.
40
+ - **Closed self-improvement loop.** Metrics + Learning (introspection) and
41
+ Snapshot + Drift + Intel (extrospection) feed `extro_correlate`, which tells
42
+ the agent whether a failure was *its* fault or *the world* changed — and
43
+ writes the lesson back into the prompt for next time.
44
+ - **Native multi-agent.** `PWN::AI::Agent::Swarm` runs personas (each a full
45
+ tool-calling agent, optionally on a *different* LLM engine) that debate,
46
+ broadcast and share an append-only bus — no IRC daemon, no external service.
47
+
48
+ ![Overall Architecture](diagrams/overall-pwn-architecture.svg)
49
+
50
+ **Next:** [Why PWN](Why-PWN.md) · [How PWN Works](How-PWN-Works.md) ·
51
+ [Installation](Installation.md)
52
+
53
+ [← Home](Home.md)
@@ -0,0 +1,48 @@
1
+ # Why PWN
2
+
3
+ ## The problem
4
+
5
+ Offensive security is a **toolchain problem**. A single engagement touches
6
+ `nmap`, `burp`, `msfconsole`, a headless browser, `adb`, `gqrx`, three cloud
7
+ consoles, a fuzzer, `radare2`, a spreadsheet of findings, and a bug-bounty
8
+ submission form. Each tool has its own config, its own output format, and its
9
+ own idea of what a "target" is. Gluing them together is 80 % of the job — and
10
+ that glue is rewritten, badly, on every engagement.
11
+
12
+ Meanwhile, LLM agents are extraordinary at *planning* attack chains but have no
13
+ reliable, auditable way to *execute* them against a real host.
14
+
15
+ ## The design bet
16
+
17
+ PWN bets that the right abstraction is **plain Ruby methods with a uniform
18
+ `opts = {}` signature**, exposed simultaneously to:
19
+
20
+ - a human in a REPL,
21
+ - an LLM in a tool-calling loop,
22
+ - a shell script in CI,
23
+ - a cron job at 3 am.
24
+
25
+ Because every capability is a method, the same line of code works in all four
26
+ contexts. Because every method is open-source Ruby, it's auditable — critical
27
+ when the caller is an autonomous agent.
28
+
29
+ ## Why open primitives matter
30
+
31
+ | Closed / black-box | PWN |
32
+ |---|---|
33
+ | "Trust our scanner" | `cat lib/pwn/sast/sql.rb` — read the regex yourself |
34
+ | Per-seat licence for the glue | MIT-licensed glue; bring your own Burp Pro / Nessus key |
35
+ | Agent output is a PDF | Agent output is a `PWN::Reports` object *and* a distilled skill *and* a memory entry |
36
+ | One vendor's model | Five interchangeable engines; swarm can pit them against each other |
37
+
38
+ ## Why the self-improvement loop matters
39
+
40
+ A pentest framework that doesn't learn repeats the same dead-end scans forever.
41
+ PWN records **per-tool success rate**, **per-task outcome**, **host drift**,
42
+ and **external CVE intel**, then correlates them so tomorrow's run starts where
43
+ today's finished. See [Skills, Memory & Learning](Skills-Memory-Learning.md)
44
+ and [Extrospection](Extrospection.md).
45
+
46
+ **Next:** [How PWN Works](How-PWN-Works.md)
47
+
48
+ [← Home](Home.md)
@@ -0,0 +1,172 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 14.1.2 (0)
5
+ -->
6
+ <!-- Title: PWN_AI_Integration Pages: 1 -->
7
+ <svg width="680pt" height="496pt"
8
+ viewBox="0.00 0.00 680.00 496.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 453.2)">
10
+ <title>PWN_AI_Integration</title>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-453.2 636.7,-453.2 636.7,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="98.75" y="-388" font-family="sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::AI — Multi&#45;Provider LLM Integration</text>
13
+ <text xml:space="preserve" text-anchor="start" x="186.12" y="-376.55" font-family="sans-Serif" font-size="11.00" fill="#94a3b8">one Agent Loop · five interchangeable engines</text>
14
+ <g id="clust1" class="cluster">
15
+ <title>cluster_c</title>
16
+ <path fill="#2e1065" stroke="#6d28d9" d="M213.25,-8C213.25,-8 365,-8 365,-8 371,-8 377,-14 377,-20 377,-20 377,-351 377,-351 377,-357 371,-363 365,-363 365,-363 213.25,-363 213.25,-363 207.25,-363 201.25,-357 201.25,-351 201.25,-351 201.25,-20 201.25,-20 201.25,-14 207.25,-8 213.25,-8"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="289.12" y="-340" font-family="sans-Serif" font-size="20.00" fill="#ddd6fe">PWN::AI::* Clients</text>
18
+ </g>
19
+ <g id="clust3" class="cluster">
20
+ <title>cluster_api</title>
21
+ <path fill="#450a0a" stroke="#b91c1c" stroke-dasharray="5,2" d="M468,-8C468,-8 581.5,-8 581.5,-8 587.5,-8 593.5,-14 593.5,-20 593.5,-20 593.5,-351 593.5,-351 593.5,-357 587.5,-363 581.5,-363 581.5,-363 468,-363 468,-363 462,-363 456,-357 456,-351 456,-351 456,-20 456,-20 456,-14 462,-8 468,-8"/>
22
+ <text xml:space="preserve" text-anchor="middle" x="524.75" y="-340" font-family="sans-Serif" font-size="20.00" fill="#fecaca">Provider APIs</text>
23
+ </g>
24
+ <!-- Loop -->
25
+ <g id="node1" class="node">
26
+ <title>Loop</title>
27
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="2" d="M102.25,-188C102.25,-188 12,-188 12,-188 6,-188 0,-182 0,-176 0,-176 0,-164 0,-164 0,-158 6,-152 12,-152 12,-152 102.25,-152 102.25,-152 108.25,-152 114.25,-158 114.25,-164 114.25,-164 114.25,-176 114.25,-176 114.25,-182 108.25,-188 102.25,-188"/>
28
+ <text xml:space="preserve" text-anchor="middle" x="57.12" y="-172.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">PWN::AI::Agent::Loop</text>
29
+ <text xml:space="preserve" text-anchor="middle" x="57.12" y="-160.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">tool&#45;calling harness</text>
30
+ </g>
31
+ <!-- OpenAI -->
32
+ <g id="node2" class="node">
33
+ <title>OpenAI</title>
34
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M303.62,-324C303.62,-324 273.62,-324 273.62,-324 267.62,-324 261.62,-318 261.62,-312 261.62,-312 261.62,-300 261.62,-300 261.62,-294 267.62,-288 273.62,-288 273.62,-288 303.62,-288 303.62,-288 309.62,-288 315.62,-294 315.62,-300 315.62,-300 315.62,-312 315.62,-312 315.62,-318 309.62,-324 303.62,-324"/>
35
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-302.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">OpenAI</text>
36
+ </g>
37
+ <!-- Loop&#45;&gt;OpenAI -->
38
+ <g id="edge1" class="edge">
39
+ <title>Loop&#45;&gt;OpenAI</title>
40
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M80.78,-188.81C108.07,-210.83 155.92,-247.41 201.25,-272 217.35,-280.74 236.19,-288.42 252.15,-294.26"/>
41
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="250.85,-296.77 259.33,-296.82 252.73,-291.49 250.85,-296.77"/>
42
+ </g>
43
+ <!-- Anthropic -->
44
+ <g id="node3" class="node">
45
+ <title>Anthropic</title>
46
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M305.25,-256C305.25,-256 272,-256 272,-256 266,-256 260,-250 260,-244 260,-244 260,-232 260,-232 260,-226 266,-220 272,-220 272,-220 305.25,-220 305.25,-220 311.25,-220 317.25,-226 317.25,-232 317.25,-232 317.25,-244 317.25,-244 317.25,-250 311.25,-256 305.25,-256"/>
47
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-234.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Anthropic</text>
48
+ </g>
49
+ <!-- Loop&#45;&gt;Anthropic -->
50
+ <g id="edge2" class="edge">
51
+ <title>Loop&#45;&gt;Anthropic</title>
52
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M115.15,-186.9C157.31,-199.39 213.54,-216.05 250.15,-226.9"/>
53
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="249.12,-229.51 257.59,-229.1 250.71,-224.14 249.12,-229.51"/>
54
+ </g>
55
+ <!-- Grok -->
56
+ <g id="node4" class="node">
57
+ <title>Grok</title>
58
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M324.75,-188C324.75,-188 252.5,-188 252.5,-188 246.5,-188 240.5,-182 240.5,-176 240.5,-176 240.5,-164 240.5,-164 240.5,-158 246.5,-152 252.5,-152 252.5,-152 324.75,-152 324.75,-152 330.75,-152 336.75,-158 336.75,-164 336.75,-164 336.75,-176 336.75,-176 336.75,-182 330.75,-188 324.75,-188"/>
59
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-172.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Grok</text>
60
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-160.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">OAuth device flow</text>
61
+ </g>
62
+ <!-- Loop&#45;&gt;Grok -->
63
+ <g id="edge3" class="edge">
64
+ <title>Loop&#45;&gt;Grok</title>
65
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M115.15,-170C150.34,-170 195.32,-170 230.53,-170"/>
66
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="230.21,-172.8 238.21,-170 230.21,-167.2 230.21,-172.8"/>
67
+ </g>
68
+ <!-- Gemini -->
69
+ <g id="node5" class="node">
70
+ <title>Gemini</title>
71
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M303.62,-120C303.62,-120 273.62,-120 273.62,-120 267.62,-120 261.62,-114 261.62,-108 261.62,-108 261.62,-96 261.62,-96 261.62,-90 267.62,-84 273.62,-84 273.62,-84 303.62,-84 303.62,-84 309.62,-84 315.62,-90 315.62,-96 315.62,-96 315.62,-108 315.62,-108 315.62,-114 309.62,-120 303.62,-120"/>
72
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-98.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Gemini</text>
73
+ </g>
74
+ <!-- Loop&#45;&gt;Gemini -->
75
+ <g id="edge4" class="edge">
76
+ <title>Loop&#45;&gt;Gemini</title>
77
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M115.15,-153.1C157.92,-140.43 215.17,-123.47 251.73,-112.64"/>
78
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="252.25,-115.4 259.12,-110.44 250.66,-110.03 252.25,-115.4"/>
79
+ </g>
80
+ <!-- Ollama -->
81
+ <g id="node6" class="node">
82
+ <title>Ollama</title>
83
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M303.62,-52C303.62,-52 273.62,-52 273.62,-52 267.62,-52 261.62,-46 261.62,-40 261.62,-40 261.62,-28 261.62,-28 261.62,-22 267.62,-16 273.62,-16 273.62,-16 303.62,-16 303.62,-16 309.62,-16 315.62,-22 315.62,-28 315.62,-28 315.62,-40 315.62,-40 315.62,-46 309.62,-52 303.62,-52"/>
84
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-36.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Ollama</text>
85
+ <text xml:space="preserve" text-anchor="middle" x="288.62" y="-24.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">(local)</text>
86
+ </g>
87
+ <!-- Loop&#45;&gt;Ollama -->
88
+ <g id="edge5" class="edge">
89
+ <title>Loop&#45;&gt;Ollama</title>
90
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M80.78,-151.19C108.07,-129.17 155.92,-92.59 201.25,-68 217.35,-59.26 236.19,-51.58 252.15,-45.74"/>
91
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="252.73,-48.51 259.33,-43.18 250.85,-43.23 252.73,-48.51"/>
92
+ </g>
93
+ <!-- A1 -->
94
+ <g id="node7" class="node">
95
+ <title>A1</title>
96
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M553.25,-324C553.25,-324 495.25,-324 495.25,-324 489.25,-324 483.25,-318 483.25,-312 483.25,-312 483.25,-300 483.25,-300 483.25,-294 489.25,-288 495.25,-288 495.25,-288 553.25,-288 553.25,-288 559.25,-288 565.25,-294 565.25,-300 565.25,-300 565.25,-312 565.25,-312 565.25,-318 559.25,-324 553.25,-324"/>
97
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-302.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">api.openai.com</text>
98
+ </g>
99
+ <!-- OpenAI&#45;&gt;A1 -->
100
+ <g id="edge6" class="edge">
101
+ <title>OpenAI&#45;&gt;A1</title>
102
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M315.97,-306C353.96,-306 424.85,-306 473.03,-306"/>
103
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="472.98,-308.8 480.98,-306 472.98,-303.2 472.98,-308.8"/>
104
+ </g>
105
+ <!-- A2 -->
106
+ <g id="node8" class="node">
107
+ <title>A2</title>
108
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M558.88,-256C558.88,-256 489.62,-256 489.62,-256 483.62,-256 477.62,-250 477.62,-244 477.62,-244 477.62,-232 477.62,-232 477.62,-226 483.62,-220 489.62,-220 489.62,-220 558.88,-220 558.88,-220 564.88,-220 570.88,-226 570.88,-232 570.88,-232 570.88,-244 570.88,-244 570.88,-250 564.88,-256 558.88,-256"/>
109
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-234.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">api.anthropic.com</text>
110
+ </g>
111
+ <!-- Anthropic&#45;&gt;A2 -->
112
+ <g id="edge7" class="edge">
113
+ <title>Anthropic&#45;&gt;A2</title>
114
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M317.81,-238C354.74,-238 420.36,-238 467.51,-238"/>
115
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="467.31,-240.8 475.31,-238 467.31,-235.2 467.31,-240.8"/>
116
+ </g>
117
+ <!-- A3 -->
118
+ <g id="node9" class="node">
119
+ <title>A3</title>
120
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M539.25,-188C539.25,-188 509.25,-188 509.25,-188 503.25,-188 497.25,-182 497.25,-176 497.25,-176 497.25,-164 497.25,-164 497.25,-158 503.25,-152 509.25,-152 509.25,-152 539.25,-152 539.25,-152 545.25,-152 551.25,-158 551.25,-164 551.25,-164 551.25,-176 551.25,-176 551.25,-182 545.25,-188 539.25,-188"/>
121
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-172.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">api.x.ai</text>
122
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-160.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">auth.x.ai</text>
123
+ </g>
124
+ <!-- Grok&#45;&gt;A3 -->
125
+ <g id="edge8" class="edge">
126
+ <title>Grok&#45;&gt;A3</title>
127
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M337.18,-170C381.49,-170 446.6,-170 486.89,-170"/>
128
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="486.84,-172.8 494.84,-170 486.84,-167.2 486.84,-172.8"/>
129
+ </g>
130
+ <!-- A4 -->
131
+ <g id="node10" class="node">
132
+ <title>A4</title>
133
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M562.25,-120C562.25,-120 486.25,-120 486.25,-120 480.25,-120 474.25,-114 474.25,-108 474.25,-108 474.25,-96 474.25,-96 474.25,-90 480.25,-84 486.25,-84 486.25,-84 562.25,-84 562.25,-84 568.25,-84 574.25,-90 574.25,-96 574.25,-96 574.25,-108 574.25,-108 574.25,-114 568.25,-120 562.25,-120"/>
134
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-104.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">generativelanguage</text>
135
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-92.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">.googleapis.com</text>
136
+ </g>
137
+ <!-- Gemini&#45;&gt;A4 -->
138
+ <g id="edge9" class="edge">
139
+ <title>Gemini&#45;&gt;A4</title>
140
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M315.97,-102C351.62,-102 416.24,-102 463.88,-102"/>
141
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="463.81,-104.8 471.81,-102 463.81,-99.2 463.81,-104.8"/>
142
+ </g>
143
+ <!-- A5 -->
144
+ <g id="node11" class="node">
145
+ <title>A5</title>
146
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.3" d="M554.38,-52C554.38,-52 494.12,-52 494.12,-52 488.12,-52 482.12,-46 482.12,-40 482.12,-40 482.12,-28 482.12,-28 482.12,-22 488.12,-16 494.12,-16 494.12,-16 554.38,-16 554.38,-16 560.38,-16 566.38,-22 566.38,-28 566.38,-28 566.38,-40 566.38,-40 566.38,-46 560.38,-52 554.38,-52"/>
147
+ <text xml:space="preserve" text-anchor="middle" x="524.25" y="-30.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">localhost:11434</text>
148
+ </g>
149
+ <!-- Ollama&#45;&gt;A5 -->
150
+ <g id="edge10" class="edge">
151
+ <title>Ollama&#45;&gt;A5</title>
152
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M315.97,-34C353.63,-34 423.6,-34 471.75,-34"/>
153
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="471.71,-36.8 479.71,-34 471.71,-31.2 471.71,-36.8"/>
154
+ </g>
155
+ <!-- Cfg -->
156
+ <g id="node12" class="node">
157
+ <title>Cfg</title>
158
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M108.25,-82.75C108.25,-85.78 85.33,-88.25 57.12,-88.25 28.92,-88.25 6,-85.78 6,-82.75 6,-82.75 6,-33.25 6,-33.25 6,-30.22 28.92,-27.75 57.12,-27.75 85.33,-27.75 108.25,-30.22 108.25,-33.25 108.25,-33.25 108.25,-82.75 108.25,-82.75"/>
159
+ <path fill="none" stroke="#334155" stroke-width="1.3" d="M108.25,-82.75C108.25,-79.72 85.33,-77.25 57.12,-77.25 28.92,-77.25 6,-79.72 6,-82.75"/>
160
+ <text xml:space="preserve" text-anchor="middle" x="57.12" y="-66.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">PWN::Config</text>
161
+ <text xml:space="preserve" text-anchor="middle" x="57.12" y="-54.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">~/.pwn/config.yml</text>
162
+ <text xml:space="preserve" text-anchor="middle" x="57.12" y="-42.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">engine · key · oauth</text>
163
+ </g>
164
+ <!-- Cfg&#45;&gt;Loop -->
165
+ <g id="edge11" class="edge">
166
+ <title>Cfg&#45;&gt;Loop</title>
167
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M57.12,-88.6C57.12,-104.97 57.12,-125 57.12,-141.1"/>
168
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="54.33,-141.06 57.13,-149.06 59.93,-141.06 54.33,-141.06"/>
169
+ <text xml:space="preserve" text-anchor="middle" x="48.88" y="-116.83" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">active engine</text>
170
+ </g>
171
+ </g>
172
+ </svg>
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bash
2
+ # Regenerate every PWN data-flow diagram SVG from its .dot source.
3
+ # Usage: ./build.sh # build all
4
+ # ./build.sh foo.dot # build one
5
+ set -euo pipefail
6
+ cd "$(dirname "$0")"
7
+ DOT_BIN="${DOT_BIN:-dot}"
8
+ SRC_DIR="dot"
9
+ build_one() {
10
+ local src="$1"
11
+ local base="$(basename "$src" .dot)"
12
+ echo " [dot] ${base}.svg"
13
+ "$DOT_BIN" -Tsvg "-Gfontnames=svg" "$src" -o "${base}.svg"
14
+ }
15
+ if [[ $# -gt 0 ]]; then
16
+ for f in "$@"; do build_one "$f"; done
17
+ else
18
+ for f in "$SRC_DIR"/*.dot; do build_one "$f"; done
19
+ fi
20
+ echo "[done] $(ls -1 *.svg | wc -l) SVG diagram(s) in $(pwd)"
@@ -0,0 +1,69 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 14.1.2 (0)
5
+ -->
6
+ <!-- Title: PWN_BurpVsZap Pages: 1 -->
7
+ <svg width="639pt" height="421pt"
8
+ viewBox="0.00 0.00 639.00 421.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 377.9)">
10
+ <title>PWN_BurpVsZap</title>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-377.9 595.45,-377.9 595.45,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="8" y="-312.7" font-family="sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">Web Proxy Selection — BurpSuite ⭐ preferred over ZAP</text>
13
+ <!-- Need -->
14
+ <g id="node1" class="node">
15
+ <title>Need</title>
16
+ <polygon fill="#7dd3fc" stroke="#334155" stroke-width="1.3" points="286.12,-302.7 214.04,-263.1 286.12,-223.5 358.21,-263.1 286.12,-302.7"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="286.12" y="-265.6" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Need web proxy /</text>
18
+ <text xml:space="preserve" text-anchor="middle" x="286.12" y="-253.6" font-family="sans-Serif" font-size="10.00" fill="#0f172a">active scanner?</text>
19
+ </g>
20
+ <!-- Burp -->
21
+ <g id="node2" class="node">
22
+ <title>Burp</title>
23
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="2" d="M259.88,-147C259.88,-147 122.38,-147 122.38,-147 116.38,-147 110.38,-141 110.38,-135 110.38,-135 110.38,-115 110.38,-115 110.38,-109 116.38,-103 122.38,-103 122.38,-103 259.88,-103 259.88,-103 265.88,-103 271.88,-109 271.88,-115 271.88,-115 271.88,-135 271.88,-135 271.88,-141 265.88,-147 259.88,-147"/>
24
+ <text xml:space="preserve" text-anchor="middle" x="191.12" y="-133.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">PWN::Plugins::BurpSuite</text>
25
+ <text xml:space="preserve" text-anchor="middle" x="191.12" y="-121.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">headless · REST · richer scanner</text>
26
+ <text xml:space="preserve" text-anchor="middle" x="191.12" y="-109.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">BApp ecosystem</text>
27
+ </g>
28
+ <!-- Need&#45;&gt;Burp -->
29
+ <g id="edge1" class="edge">
30
+ <title>Need&#45;&gt;Burp</title>
31
+ <path fill="none" stroke="#34d399" stroke-width="2" d="M263.68,-235.55C252.87,-222.34 239.99,-205.92 229.38,-190.5 222.14,-179.99 214.84,-168.07 208.59,-157.37"/>
32
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="2" points="211.09,-156.11 204.68,-150.58 206.24,-158.91 211.09,-156.11"/>
33
+ <text xml:space="preserve" text-anchor="middle" x="267.25" y="-181.95" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">Burp Pro available</text>
34
+ </g>
35
+ <!-- Zap -->
36
+ <g id="node3" class="node">
37
+ <title>Zap</title>
38
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M429.88,-143C429.88,-143 334.38,-143 334.38,-143 328.38,-143 322.38,-137 322.38,-131 322.38,-131 322.38,-119 322.38,-119 322.38,-113 328.38,-107 334.38,-107 334.38,-107 429.88,-107 429.88,-107 435.88,-107 441.88,-113 441.88,-119 441.88,-119 441.88,-131 441.88,-131 441.88,-137 435.88,-143 429.88,-143"/>
39
+ <text xml:space="preserve" text-anchor="middle" x="382.12" y="-127.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">PWN::Plugins::Zaproxy</text>
40
+ <text xml:space="preserve" text-anchor="middle" x="382.12" y="-115.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">OSS fallback</text>
41
+ </g>
42
+ <!-- Need&#45;&gt;Zap -->
43
+ <g id="edge2" class="edge">
44
+ <title>Need&#45;&gt;Zap</title>
45
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M306.02,-233.9C323.14,-209.63 347.62,-174.92 364.16,-151.47"/>
46
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="366.4,-153.15 368.73,-144.99 361.83,-149.92 366.4,-153.15"/>
47
+ <text xml:space="preserve" text-anchor="middle" x="358.47" y="-181.95" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">fallback</text>
48
+ </g>
49
+ <!-- Both -->
50
+ <g id="node4" class="node">
51
+ <title>Both</title>
52
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M390.5,-36C390.5,-36 181.75,-36 181.75,-36 175.75,-36 169.75,-30 169.75,-24 169.75,-24 169.75,-12 169.75,-12 169.75,-6 175.75,0 181.75,0 181.75,0 390.5,0 390.5,0 396.5,0 402.5,-6 402.5,-12 402.5,-12 402.5,-24 402.5,-24 402.5,-30 396.5,-36 390.5,-36"/>
53
+ <text xml:space="preserve" text-anchor="middle" x="286.12" y="-20.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Same downstream:</text>
54
+ <text xml:space="preserve" text-anchor="middle" x="286.12" y="-8.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">TransparentBrowser proxy · Reports · DefectDojo</text>
55
+ </g>
56
+ <!-- Burp&#45;&gt;Both -->
57
+ <g id="edge3" class="edge">
58
+ <title>Burp&#45;&gt;Both</title>
59
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M210.81,-102.24C226.22,-85.21 247.65,-61.52 263.72,-43.77"/>
60
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="265.63,-45.83 268.92,-38.02 261.48,-42.07 265.63,-45.83"/>
61
+ </g>
62
+ <!-- Zap&#45;&gt;Both -->
63
+ <g id="edge4" class="edge">
64
+ <title>Zap&#45;&gt;Both</title>
65
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M366.27,-106.66C350.57,-89.49 326.37,-63.02 308.67,-43.66"/>
66
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="310.79,-41.83 303.33,-37.82 306.66,-45.61 310.79,-41.83"/>
67
+ </g>
68
+ </g>
69
+ </svg>
@@ -0,0 +1,172 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 14.1.2 (0)
5
+ -->
6
+ <!-- Title: PWN_SAST Pages: 1 -->
7
+ <svg width="818pt" height="484pt"
8
+ viewBox="0.00 0.00 818.00 484.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 441.2)">
10
+ <title>PWN_SAST</title>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-441.2 775.2,-441.2 775.2,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="131.25" y="-376" font-family="sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::SAST — Static Application Security Testing</text>
13
+ <text xml:space="preserve" text-anchor="start" x="229.88" y="-364.55" font-family="sans-Serif" font-size="11.00" fill="#94a3b8">48 rules · multi&#45;language · bin/pwn_sast · Reports::SAST</text>
14
+ <g id="clust1" class="cluster">
15
+ <title>cluster_engine</title>
16
+ <path fill="#022c22" stroke="#047857" d="M178,-138C178,-138 290.75,-138 290.75,-138 296.75,-138 302.75,-144 302.75,-150 302.75,-150 302.75,-274 302.75,-274 302.75,-280 296.75,-286 290.75,-286 290.75,-286 178,-286 178,-286 172,-286 166,-280 166,-274 166,-274 166,-150 166,-150 166,-144 172,-138 178,-138"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="234.38" y="-263" font-family="sans-Serif" font-size="20.00" fill="#a7f3d0">SAST Engine</text>
18
+ </g>
19
+ <g id="clust2" class="cluster">
20
+ <title>cluster_rules</title>
21
+ <path fill="#422006" stroke="#a16207" d="M384.75,-8C384.75,-8 538.75,-8 538.75,-8 544.75,-8 550.75,-14 550.75,-20 550.75,-20 550.75,-339 550.75,-339 550.75,-345 544.75,-351 538.75,-351 538.75,-351 384.75,-351 384.75,-351 378.75,-351 372.75,-345 372.75,-339 372.75,-339 372.75,-20 372.75,-20 372.75,-14 378.75,-8 384.75,-8"/>
22
+ <text xml:space="preserve" text-anchor="middle" x="461.75" y="-328" font-family="sans-Serif" font-size="20.00" fill="#fde68a">Rule Families (48)</text>
23
+ </g>
24
+ <g id="clust3" class="cluster">
25
+ <title>cluster_out</title>
26
+ <path fill="#2e1065" stroke="#6d28d9" d="M632.75,-138C632.75,-138 712,-138 712,-138 718,-138 724,-144 724,-150 724,-150 724,-274 724,-274 724,-280 718,-286 712,-286 712,-286 632.75,-286 632.75,-286 626.75,-286 620.75,-280 620.75,-274 620.75,-274 620.75,-150 620.75,-150 620.75,-144 626.75,-138 632.75,-138"/>
27
+ <text xml:space="preserve" text-anchor="middle" x="672.38" y="-263" font-family="sans-Serif" font-size="20.00" fill="#ddd6fe">Output</text>
28
+ </g>
29
+ <!-- Src -->
30
+ <g id="node1" class="node">
31
+ <title>Src</title>
32
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.3" d="M76,-214C76,-214 12,-214 12,-214 6,-214 0,-208 0,-202 0,-202 0,-190 0,-190 0,-184 6,-178 12,-178 12,-178 76,-178 76,-178 82,-178 88,-184 88,-190 88,-190 88,-202 88,-202 88,-208 82,-214 76,-214"/>
33
+ <text xml:space="preserve" text-anchor="middle" x="44" y="-198.88" font-family="sans-Serif" font-size="10.00" fill="#0f172a">📁 &#160;Source Tree</text>
34
+ <text xml:space="preserve" text-anchor="middle" x="44" y="-186.12" font-family="sans-Serif" font-size="10.00" fill="#0f172a">git clone / repo</text>
35
+ </g>
36
+ <!-- Factory -->
37
+ <g id="node2" class="node">
38
+ <title>Factory</title>
39
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M261.75,-182C261.75,-182 206,-182 206,-182 200,-182 194,-176 194,-170 194,-170 194,-158 194,-158 194,-152 200,-146 206,-146 206,-146 261.75,-146 261.75,-146 267.75,-146 273.75,-152 273.75,-158 273.75,-158 273.75,-170 273.75,-170 273.75,-176 267.75,-182 261.75,-182"/>
40
+ <text xml:space="preserve" text-anchor="middle" x="233.88" y="-166.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">SAST::Factory</text>
41
+ <text xml:space="preserve" text-anchor="middle" x="233.88" y="-154.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">rule loader</text>
42
+ </g>
43
+ <!-- Src&#45;&gt;Factory -->
44
+ <g id="edge1" class="edge">
45
+ <title>Src&#45;&gt;Factory</title>
46
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M88.57,-188.58C117.01,-183.73 154.19,-177.4 183.69,-172.38"/>
47
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="184.02,-175.16 191.44,-171.06 183.08,-169.64 184.02,-175.16"/>
48
+ </g>
49
+ <!-- TCE -->
50
+ <g id="node3" class="node">
51
+ <title>TCE</title>
52
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.3" d="M265.88,-247C265.88,-247 201.88,-247 201.88,-247 195.88,-247 189.88,-241 189.88,-235 189.88,-235 189.88,-223 189.88,-223 189.88,-217 195.88,-211 201.88,-211 201.88,-211 265.88,-211 265.88,-211 271.88,-211 277.88,-217 277.88,-223 277.88,-223 277.88,-235 277.88,-235 277.88,-241 271.88,-247 265.88,-247"/>
53
+ <text xml:space="preserve" text-anchor="middle" x="233.88" y="-231.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">TestCaseEngine</text>
54
+ <text xml:space="preserve" text-anchor="middle" x="233.88" y="-219.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">generate probes</text>
55
+ </g>
56
+ <!-- Src&#45;&gt;TCE -->
57
+ <g id="edge2" class="edge">
58
+ <title>Src&#45;&gt;TCE</title>
59
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M88.57,-203.65C115.84,-208.44 151.15,-214.65 180.02,-219.72"/>
60
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="179.24,-222.42 187.6,-221.05 180.2,-216.91 179.24,-222.42"/>
61
+ </g>
62
+ <!-- Cmd -->
63
+ <g id="node4" class="node">
64
+ <title>Cmd</title>
65
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M515.75,-52C515.75,-52 406.75,-52 406.75,-52 400.75,-52 394.75,-46 394.75,-40 394.75,-40 394.75,-28 394.75,-28 394.75,-22 400.75,-16 406.75,-16 406.75,-16 515.75,-16 515.75,-16 521.75,-16 527.75,-22 527.75,-28 527.75,-28 527.75,-40 527.75,-40 527.75,-46 521.75,-52 515.75,-52"/>
66
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-36.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">cmd_execution_*</text>
67
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-24.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">java · py · ruby · go · scala</text>
68
+ </g>
69
+ <!-- Factory&#45;&gt;Cmd -->
70
+ <g id="edge3" class="edge">
71
+ <title>Factory&#45;&gt;Cmd</title>
72
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M257.15,-145.65C283.5,-124.59 329.29,-90 372.75,-67 379.97,-63.18 387.73,-59.58 395.54,-56.28"/>
73
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="396.54,-58.89 402.88,-53.27 394.42,-53.71 396.54,-58.89"/>
74
+ </g>
75
+ <!-- Web -->
76
+ <g id="node5" class="node">
77
+ <title>Web</title>
78
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M526.62,-117C526.62,-117 395.88,-117 395.88,-117 389.88,-117 383.88,-111 383.88,-105 383.88,-105 383.88,-93 383.88,-93 383.88,-87 389.88,-81 395.88,-81 395.88,-81 526.62,-81 526.62,-81 532.62,-81 538.62,-87 538.62,-93 538.62,-93 538.62,-105 538.62,-105 538.62,-111 532.62,-117 526.62,-117"/>
79
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-101.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">csrf · redirect · redos</text>
80
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-89.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">inner/outer_html · location_hash</text>
81
+ </g>
82
+ <!-- Factory&#45;&gt;Web -->
83
+ <g id="edge4" class="edge">
84
+ <title>Factory&#45;&gt;Web</title>
85
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M274.39,-152.6C305.35,-143.68 349.28,-131 386.67,-120.22"/>
86
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="387.22,-122.98 394.13,-118.07 385.67,-117.6 387.22,-122.98"/>
87
+ </g>
88
+ <!-- Cryp -->
89
+ <g id="node6" class="node">
90
+ <title>Cryp</title>
91
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M519.5,-182C519.5,-182 403,-182 403,-182 397,-182 391,-176 391,-170 391,-170 391,-158 391,-158 391,-152 397,-146 403,-146 403,-146 519.5,-146 519.5,-146 525.5,-146 531.5,-152 531.5,-158 531.5,-158 531.5,-170 531.5,-170 531.5,-176 525.5,-182 519.5,-182"/>
92
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-166.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">md5 · ssl · keystore</text>
93
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-154.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">padding_oracle · private_key</text>
94
+ </g>
95
+ <!-- Factory&#45;&gt;Cryp -->
96
+ <g id="edge5" class="edge">
97
+ <title>Factory&#45;&gt;Cryp</title>
98
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M274.39,-164C303.83,-164 345,-164 381.11,-164"/>
99
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="380.69,-166.8 388.69,-164 380.69,-161.2 380.69,-166.8"/>
100
+ </g>
101
+ <!-- Data -->
102
+ <g id="node7" class="node">
103
+ <title>Data</title>
104
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M510.88,-247C510.88,-247 411.62,-247 411.62,-247 405.62,-247 399.62,-241 399.62,-235 399.62,-235 399.62,-223 399.62,-223 399.62,-217 405.62,-211 411.62,-211 411.62,-211 510.88,-211 510.88,-211 516.88,-211 522.88,-217 522.88,-223 522.88,-223 522.88,-235 522.88,-235 522.88,-241 516.88,-247 510.88,-247"/>
105
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-231.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">sql · eval · deserial_java</text>
106
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-219.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">log4j · php_type_juggling</text>
107
+ </g>
108
+ <!-- TCE&#45;&gt;Data -->
109
+ <g id="edge6" class="edge">
110
+ <title>TCE&#45;&gt;Data</title>
111
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M278.33,-229C309.8,-229 353.03,-229 389.45,-229"/>
112
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="389.07,-231.8 397.07,-229 389.07,-226.2 389.07,-231.8"/>
113
+ </g>
114
+ <!-- Mem -->
115
+ <g id="node8" class="node">
116
+ <title>Mem</title>
117
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.3" d="M491,-312C491,-312 431.5,-312 431.5,-312 425.5,-312 419.5,-306 419.5,-300 419.5,-300 419.5,-288 419.5,-288 419.5,-282 425.5,-276 431.5,-276 431.5,-276 491,-276 491,-276 497,-276 503,-282 503,-288 503,-288 503,-300 503,-300 503,-306 497,-312 491,-312"/>
118
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-296.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">banned_c_calls</text>
119
+ <text xml:space="preserve" text-anchor="middle" x="461.25" y="-284.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">use_after_free</text>
120
+ </g>
121
+ <!-- TCE&#45;&gt;Mem -->
122
+ <g id="edge7" class="edge">
123
+ <title>TCE&#45;&gt;Mem</title>
124
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M278.33,-241.53C315.99,-252.39 370.49,-268.11 410.01,-279.51"/>
125
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="408.85,-282.09 417.32,-281.62 410.41,-276.71 408.85,-282.09"/>
126
+ </g>
127
+ <!-- Report -->
128
+ <g id="node9" class="node">
129
+ <title>Report</title>
130
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M701.75,-182C701.75,-182 643,-182 643,-182 637,-182 631,-176 631,-170 631,-170 631,-158 631,-158 631,-152 637,-146 643,-146 643,-146 701.75,-146 701.75,-146 707.75,-146 713.75,-152 713.75,-158 713.75,-158 713.75,-170 713.75,-170 713.75,-176 707.75,-182 701.75,-182"/>
131
+ <text xml:space="preserve" text-anchor="middle" x="672.38" y="-166.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">Reports::SAST</text>
132
+ <text xml:space="preserve" text-anchor="middle" x="672.38" y="-154.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">HTML + JSON</text>
133
+ </g>
134
+ <!-- Cmd&#45;&gt;Report -->
135
+ <g id="edge8" class="edge">
136
+ <title>Cmd&#45;&gt;Report</title>
137
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M520.12,-52.52C530.59,-56.72 541.2,-61.57 550.75,-67 586.16,-87.14 621.93,-117.44 645.22,-138.81"/>
138
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="643.12,-140.67 650.88,-144.07 646.93,-136.57 643.12,-140.67"/>
139
+ </g>
140
+ <!-- Web&#45;&gt;Report -->
141
+ <g id="edge9" class="edge">
142
+ <title>Web&#45;&gt;Report</title>
143
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M522.18,-117.63C553.54,-127.38 591.51,-139.17 621.29,-148.43"/>
144
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="620.3,-151.06 628.77,-150.76 621.96,-145.71 620.3,-151.06"/>
145
+ </g>
146
+ <!-- Cryp&#45;&gt;Report -->
147
+ <g id="edge10" class="edge">
148
+ <title>Cryp&#45;&gt;Report</title>
149
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M531.89,-164C560.86,-164 593.87,-164 620.51,-164"/>
150
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="620.42,-166.8 628.42,-164 620.42,-161.2 620.42,-166.8"/>
151
+ </g>
152
+ <!-- DD -->
153
+ <g id="node10" class="node">
154
+ <title>DD</title>
155
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.3" d="M704,-247C704,-247 640.75,-247 640.75,-247 634.75,-247 628.75,-241 628.75,-235 628.75,-235 628.75,-223 628.75,-223 628.75,-217 634.75,-211 640.75,-211 640.75,-211 704,-211 704,-211 710,-211 716,-217 716,-223 716,-223 716,-235 716,-235 716,-241 710,-247 704,-247"/>
156
+ <text xml:space="preserve" text-anchor="middle" x="672.38" y="-231.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">DefectDojo</text>
157
+ <text xml:space="preserve" text-anchor="middle" x="672.38" y="-219.5" font-family="sans-Serif" font-size="10.00" fill="#0f172a">import / reimport</text>
158
+ </g>
159
+ <!-- Data&#45;&gt;DD -->
160
+ <g id="edge11" class="edge">
161
+ <title>Data&#45;&gt;DD</title>
162
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M523.3,-229C553.39,-229 589.33,-229 618.26,-229"/>
163
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="618.22,-231.8 626.22,-229 618.22,-226.2 618.22,-231.8"/>
164
+ </g>
165
+ <!-- Mem&#45;&gt;DD -->
166
+ <g id="edge12" class="edge">
167
+ <title>Mem&#45;&gt;DD</title>
168
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M503.57,-281.16C536.68,-270.87 583.34,-256.36 619.05,-245.26"/>
169
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="619.66,-248.01 626.47,-242.96 618,-242.66 619.66,-248.01"/>
170
+ </g>
171
+ </g>
172
+ </svg>
@@ -0,0 +1,27 @@
1
+ # PWN Diagram Visual Theme
2
+
3
+ All `.dot` files in this directory share one visual language so the rendered
4
+ SVGs feel like a single coherent product.
5
+
6
+ | Element | Color | Hex |
7
+ |----------------------|-----------|-----------|
8
+ | Background | slate-900 | `#0f172a` |
9
+ | Cluster border | slate-700 | `#334155` |
10
+ | Cluster fill | slate-800 | `#1e293b` |
11
+ | Actor / Entry (blue) | sky-300 | `#7dd3fc` |
12
+ | AI / Agent (purple) | violet-300| `#c4b5fd` |
13
+ | Capability (green) | emerald-300| `#6ee7b7`|
14
+ | Persistence (amber) | amber-300 | `#fcd34d` |
15
+ | Target / Danger (red)| rose-300 | `#fda4af` |
16
+ | Edge default | slate-400 | `#94a3b8` |
17
+ | Edge highlight | sky-400 | `#38bdf8` |
18
+
19
+ Layout rules (to avoid criss-crossed edges):
20
+ 1. `rankdir=TB` (or `LR` for pipelines), `newrank=true`, `splines=spline`.
21
+ 2. Group every layer with `{rank=same; ...}` — edges go layer→layer only.
22
+ 3. Side/back edges use `constraint=false` + `style=dashed` and are kept to ≤3 per diagram.
23
+ 4. One `subgraph cluster_*` per logical layer with a translucent fill.
24
+ 5. Node order inside a rank matches edge destinations in the next rank
25
+ (Graphviz then draws parallel non-crossing edges).
26
+
27
+ Rebuild everything: `./build.sh` (from `documentation/diagrams/`).