pwn 0.5.615 → 0.5.618
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +109 -85
- data/README.md.bak +200 -0
- data/bin/pwn +47 -2
- data/bin/pwn_gqrx_scanner +75 -18
- data/documentation/AI-Integration.md +42 -26
- data/documentation/AWS.md +57 -0
- data/documentation/Agent-Tool-Registry.md +56 -0
- data/documentation/Banner.md +17 -0
- data/documentation/Blockchain.md +18 -0
- data/documentation/Bounty.md +21 -0
- data/documentation/BurpSuite.md +41 -16
- data/documentation/CLI-Drivers.md +58 -0
- data/documentation/Configuration.md +66 -0
- data/documentation/Contributing.md +33 -19
- data/documentation/Cron.md +47 -0
- data/documentation/Diagrams.md +123 -40
- data/documentation/Drivers.md +43 -16
- data/documentation/Extrospection.md +54 -0
- data/documentation/FFI.md +14 -0
- data/documentation/Fuzzing.md +36 -0
- data/documentation/General-PWN-Usage.md +50 -30
- data/documentation/Hardware.md +40 -0
- data/documentation/Home.md +78 -51
- data/documentation/How-PWN-Works.md +59 -57
- data/documentation/Installation.md +53 -28
- data/documentation/Metasploit.md +34 -0
- data/documentation/NmapIt.md +18 -12
- data/documentation/PWN.png +0 -0
- data/documentation/PWN_Contributors_and_Users.png +0 -0
- data/documentation/Persistence.md +38 -0
- data/documentation/Plugins.md +97 -47
- data/documentation/Reporting.md +25 -18
- data/documentation/SAST.md +39 -22
- data/documentation/SDR.md +40 -0
- data/documentation/Sessions.md +39 -0
- data/documentation/Skills-Memory-Learning.md +49 -29
- data/documentation/Swarm.md +71 -0
- data/documentation/Transparent-Browser.md +26 -22
- data/documentation/Troubleshooting.md +44 -25
- data/documentation/WWW.md +32 -0
- data/documentation/What-is-PWN.md +51 -32
- data/documentation/Why-PWN.md +41 -11
- data/documentation/diagrams/agent-tool-registry.svg +284 -0
- data/documentation/diagrams/ai-integration-tool-calling.svg +141 -103
- data/documentation/diagrams/aws-cloud-security.svg +166 -0
- data/documentation/diagrams/build.sh +20 -0
- data/documentation/diagrams/burp-vs-zap-preference.svg +47 -62
- data/documentation/diagrams/code-scanning-sast.svg +139 -79
- data/documentation/diagrams/cron-scheduling.svg +148 -0
- data/documentation/diagrams/dot/_THEME.md +27 -0
- data/documentation/diagrams/dot/agent-tool-registry.dot +59 -0
- data/documentation/diagrams/dot/ai-integration-tool-calling.dot +47 -20
- data/documentation/diagrams/dot/aws-cloud-security.dot +48 -0
- data/documentation/diagrams/dot/burp-vs-zap-preference.dot +23 -12
- data/documentation/diagrams/dot/code-scanning-sast.dot +46 -18
- data/documentation/diagrams/dot/cron-scheduling.dot +40 -0
- data/documentation/diagrams/dot/driver-framework.dot +36 -14
- data/documentation/diagrams/dot/extrospection-world-awareness.dot +55 -0
- data/documentation/diagrams/dot/fuzzing-workflow.dot +44 -24
- data/documentation/diagrams/dot/hardware-hacking.dot +48 -0
- data/documentation/diagrams/dot/history-to-drivers.dot +31 -17
- data/documentation/diagrams/dot/memory-skills-detailed.dot +57 -25
- data/documentation/diagrams/dot/network-infra-testing.dot +51 -19
- data/documentation/diagrams/dot/overall-pwn-architecture.dot +110 -44
- data/documentation/diagrams/dot/penetration-testing-workflow.dot +56 -25
- data/documentation/diagrams/dot/persistence-filesystem.dot +29 -0
- data/documentation/diagrams/dot/plugin-ecosystem.dot +41 -27
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +87 -46
- data/documentation/diagrams/dot/pwn-repl-prototyping.dot +49 -30
- data/documentation/diagrams/dot/reporting-pipeline.dot +43 -14
- data/documentation/diagrams/dot/reverse-engineering-flow.dot +40 -18
- data/documentation/diagrams/dot/sdr-radio-flow.dot +45 -0
- data/documentation/diagrams/dot/sessions-cron-automation.dot +41 -14
- data/documentation/diagrams/dot/swarm-multi-agent.dot +70 -0
- data/documentation/diagrams/dot/web-application-testing.dot +45 -23
- data/documentation/diagrams/dot/zero-day-research-flow.dot +46 -24
- data/documentation/diagrams/driver-framework.svg +87 -66
- data/documentation/diagrams/extrospection-world-awareness.svg +185 -0
- data/documentation/diagrams/fuzzing-workflow.svg +128 -115
- data/documentation/diagrams/hardware-hacking.svg +163 -0
- data/documentation/diagrams/history-to-drivers.svg +84 -82
- data/documentation/diagrams/memory-skills-detailed.svg +167 -119
- data/documentation/diagrams/network-infra-testing.svg +146 -84
- data/documentation/diagrams/overall-pwn-architecture.svg +356 -185
- data/documentation/diagrams/penetration-testing-workflow.svg +161 -108
- data/documentation/diagrams/persistence-filesystem.svg +174 -0
- data/documentation/diagrams/plugin-ecosystem.svg +225 -121
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +257 -185
- data/documentation/diagrams/pwn-repl-prototyping.svg +126 -137
- data/documentation/diagrams/reporting-pipeline.svg +128 -68
- data/documentation/diagrams/reverse-engineering-flow.svg +100 -80
- data/documentation/diagrams/sdr-radio-flow.svg +146 -0
- data/documentation/diagrams/sessions-cron-automation.svg +112 -68
- data/documentation/diagrams/swarm-multi-agent.svg +225 -0
- data/documentation/diagrams/web-application-testing.svg +136 -100
- data/documentation/diagrams/zero-day-research-flow.svg +116 -112
- data/documentation/fax-spectrogram.png +0 -0
- data/documentation/fax-waveform.png +0 -0
- data/documentation/pwn-REPL.md +40 -24
- data/documentation/pwn-ai-Agent.md +59 -30
- data/documentation/pwn_android_war_dialer_session.png +0 -0
- data/documentation/pwn_install.png +0 -0
- data/documentation/pwn_wallpaper.jpg +0 -0
- data/documentation/ringing-spectrogram.png +0 -0
- data/documentation/ringing-waveform.png +0 -0
- data/git_commit.sh +1 -1
- data/lib/pwn/ai/agent/assembly.rb +1 -1
- data/lib/pwn/ai/agent/btc.rb +1 -1
- data/lib/pwn/ai/agent/burp_suite.rb +1 -1
- data/lib/pwn/ai/agent/extrospection.rb +618 -0
- data/lib/pwn/ai/agent/gqrx.rb +2 -2
- data/lib/pwn/ai/agent/hacker_one.rb +1 -1
- data/lib/pwn/ai/agent/introspection.rb +91 -0
- data/lib/pwn/ai/agent/learning.rb +6 -4
- data/lib/pwn/ai/agent/loop.rb +15 -0
- data/lib/pwn/ai/agent/prompt_builder.rb +10 -1
- data/lib/pwn/ai/agent/sast.rb +1 -1
- data/lib/pwn/ai/agent/swarm.rb +437 -0
- data/lib/pwn/ai/agent/tools/cron.rb +163 -0
- data/lib/pwn/ai/agent/tools/extrospection.rb +280 -0
- data/lib/pwn/ai/agent/tools/learning.rb +108 -0
- data/lib/pwn/ai/agent/tools/memory.rb +27 -0
- data/lib/pwn/ai/agent/tools/metrics.rb +61 -0
- data/lib/pwn/ai/agent/tools/sessions.rb +139 -0
- data/lib/pwn/ai/agent/tools/skills.rb +30 -0
- data/lib/pwn/ai/agent/tools/swarm.rb +229 -0
- data/lib/pwn/ai/agent/transparent_browser.rb +1 -1
- data/lib/pwn/ai/agent/vuln_gen.rb +2 -2
- data/lib/pwn/ai/agent.rb +3 -0
- data/lib/pwn/ai/anthropic.rb +19 -4
- data/lib/pwn/ai.rb +0 -1
- data/lib/pwn/config.rb +10 -23
- data/lib/pwn/cron.rb +16 -7
- data/lib/pwn/plugins/repl.rb +90 -281
- data/lib/pwn/sdr/decoder/base.rb +251 -0
- data/lib/pwn/sdr/decoder/gsm.rb +84 -185
- data/lib/pwn/sdr/decoder/pocsag.rb +62 -217
- data/lib/pwn/sdr/decoder.rb +1 -0
- data/lib/pwn/sdr/gqrx.rb +446 -65
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/ai/agent/extrospection_spec.rb +15 -0
- data/spec/lib/pwn/ai/agent/introspection_spec.rb +15 -0
- data/spec/lib/pwn/ai/agent/swarm_spec.rb +34 -0
- data/spec/lib/pwn/ai/agent/tools/cron_spec.rb +40 -0
- data/spec/lib/pwn/ai/agent/tools/extrospection_spec.rb +40 -0
- data/spec/lib/pwn/ai/agent/tools/metrics_spec.rb +20 -0
- data/spec/lib/pwn/ai/agent/tools/sessions_spec.rb +35 -0
- data/spec/lib/pwn/ai/agent/tools/swarm_spec.rb +17 -0
- data/spec/lib/pwn/{ai/introspection_spec.rb → sdr/decoder/base_spec.rb} +3 -3
- data/third_party/pwn_rdoc.jsonl +199 -37
- metadata +65 -3
- data/lib/pwn/ai/introspection.rb +0 -76
data/bin/pwn_gqrx_scanner
CHANGED
|
@@ -72,6 +72,33 @@ PWN::Driver::Parser.new do |options|
|
|
|
72
72
|
options.on('-wLOC', '--location=LOC', '<Optional - Location string to include in AI analysis (e.g. "New York, NY", 90210, GPS coords, etc.)>') do |l|
|
|
73
73
|
opts[:location] = l
|
|
74
74
|
end
|
|
75
|
+
options.on('--fft-scan', '<Optional - Use fast FFT-based panoramic scanning via #fast_scan_range (much faster) instead of #scan_range. Applies to profile or --scan-ranges>') do |f|
|
|
76
|
+
opts[:fft_scan] = f
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
options.on('-SRATE', '--sample-rate=RATE', '<Optional --fft-scan - Visible span/sample_rate in Hz (default 1_000_000)>') do |s|
|
|
80
|
+
opts[:sample_rate] = s
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
options.on('-NINT', '--nfft=INT', '<Optional --fft-scan - FFT bin size (default 2048)>') do |n|
|
|
84
|
+
opts[:nfft] = n
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
options.on('-AINT', '--avg=INT', '<Optional --fft-scan - FFT averages (default 2)>') do |a|
|
|
88
|
+
opts[:avg] = a
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
options.on('-CSEC', '--capture-secs=SEC', '<Optional --fft-scan - Capture seconds per chunk (default 0.03)>') do |c|
|
|
92
|
+
opts[:capture_secs] = c
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
options.on('--keep-spectrum', '<Optional --fft-scan - Keep full spectrum data in output (large)>') do |k|
|
|
96
|
+
opts[:keep_spectrum] = k
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
options.on('-ODB', '--strength-offset-db=FLOAT', '<Optional - Power offset in dB (default 0.0)>') do |o|
|
|
100
|
+
opts[:strength_offset_db] = o
|
|
101
|
+
end
|
|
75
102
|
end.parse!
|
|
76
103
|
|
|
77
104
|
begin
|
|
@@ -146,24 +173,54 @@ begin
|
|
|
146
173
|
# Merge opts one last time to ensure parameters passed to the driver are included
|
|
147
174
|
opts.merge!(band_plans[profile.to_sym]) unless profile.nil?
|
|
148
175
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
176
|
+
fft_scan = opts[:fft_scan]
|
|
177
|
+
sample_rate = opts[:sample_rate] || 1_000_000
|
|
178
|
+
sample_rate = sample_rate.to_i
|
|
179
|
+
nfft = opts[:nfft] || 2048
|
|
180
|
+
nfft = nfft.to_i
|
|
181
|
+
avgv = opts[:avg] || 2
|
|
182
|
+
avgv = avgv.to_i
|
|
183
|
+
capture_secs = opts[:capture_secs] || 0.03
|
|
184
|
+
capture_secs = capture_secs.to_f
|
|
185
|
+
keep_spectrum = opts[:keep_spectrum] ? true : false
|
|
186
|
+
strength_offset_db = opts[:strength_offset_db]
|
|
187
|
+
strength_offset_db = strength_offset_db.to_f unless strength_offset_db.nil?
|
|
188
|
+
|
|
189
|
+
if fft_scan
|
|
190
|
+
puts '[*] --fft-scan requested: using fast FFT panoramic mode (#fast_scan_range)'
|
|
191
|
+
fast_resp = PWN::SDR::GQRX.fast_scan_range(
|
|
192
|
+
gqrx_sock: gqrx_sock,
|
|
193
|
+
ranges: ranges,
|
|
194
|
+
sample_rate: sample_rate,
|
|
195
|
+
nfft: nfft,
|
|
196
|
+
avg: avgv,
|
|
197
|
+
capture_secs: capture_secs,
|
|
198
|
+
strength_lock: strength_lock,
|
|
199
|
+
keep_spectrum: keep_spectrum,
|
|
200
|
+
strength_offset_db: strength_offset_db,
|
|
201
|
+
scan_log: scan_log
|
|
202
|
+
)
|
|
203
|
+
puts "FFT Scan complete: #{fast_resp[:total]} signals found."
|
|
204
|
+
else
|
|
205
|
+
PWN::SDR::GQRX.scan_range(
|
|
206
|
+
gqrx_sock: gqrx_sock,
|
|
207
|
+
ranges: ranges,
|
|
208
|
+
demodulator_mode: demodulator_mode,
|
|
209
|
+
bandwidth: bandwidth,
|
|
210
|
+
audio_gain_db: audio_gain_db,
|
|
211
|
+
squelch: squelch,
|
|
212
|
+
precision: precision,
|
|
213
|
+
strength_lock: strength_lock,
|
|
214
|
+
rf_gain: rf_gain,
|
|
215
|
+
intermediate_gain: intermediate_gain,
|
|
216
|
+
baseband_gain: baseband_gain,
|
|
217
|
+
keep_looping: keep_looping,
|
|
218
|
+
scan_log: scan_log,
|
|
219
|
+
decoder: decoder,
|
|
220
|
+
location: location
|
|
221
|
+
)
|
|
222
|
+
puts 'Scan Complete.'
|
|
223
|
+
end
|
|
167
224
|
rescue StandardError => e
|
|
168
225
|
raise e
|
|
169
226
|
rescue Interrupt
|
|
@@ -1,36 +1,52 @@
|
|
|
1
|
-
# AI
|
|
1
|
+
# AI / LLM Integration — `PWN::AI`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
One agent loop, five interchangeable engines. Swap providers by changing one
|
|
4
|
+
line in `~/.pwn/config.yml`; the tool-calling contract is normalised so the
|
|
5
|
+
agent code never cares which model is behind it.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+

|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
- Anthropic
|
|
9
|
-
- Google Gemini
|
|
10
|
-
- xAI Grok (full OAuth device flow support, public client)
|
|
11
|
-
- Ollama (local)
|
|
12
|
-
- Others via extensible client design
|
|
9
|
+
## Supported engines
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
| Engine | Client | Auth | Notes |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `openai` | `PWN::AI::OpenAI` | `key:` | function-calling native |
|
|
14
|
+
| `anthropic` | `PWN::AI::Anthropic` | `key:` | tool-use native |
|
|
15
|
+
| `grok` | `PWN::AI::Grok` | `key:` **or** `oauth: true` | OAuth = RFC-8628 device-code flow using xAI's public Grok-CLI client id (no secret) — see skill `xai_grok_oauth_device_flow` |
|
|
16
|
+
| `gemini` | `PWN::AI::Gemini` | `key:` | function-calling native |
|
|
17
|
+
| `ollama` | `PWN::AI::Ollama` | none | local, `base_url:` + `model:` |
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
- `PWN::AI::Agent` — the autonomous tool-calling harness
|
|
18
|
-
- `pwn-ai` command inside REPL launches the TUI
|
|
19
|
+
## Selecting an engine
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
```yaml
|
|
22
|
+
# ~/.pwn/config.yml
|
|
23
|
+
ai:
|
|
24
|
+
engine: grok
|
|
25
|
+
grok:
|
|
26
|
+
oauth: true # first run opens https://accounts.x.ai/… device page
|
|
27
|
+
```
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- memory (recall/remember)
|
|
27
|
-
- learning & metrics
|
|
29
|
+
```ruby
|
|
30
|
+
# at runtime
|
|
31
|
+
PWN::Env[:ai][:engine] = :ollama
|
|
32
|
+
```
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
## Direct client use (no agent)
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
```ruby
|
|
37
|
+
resp = PWN::AI::Anthropic.chat(
|
|
38
|
+
messages: [{ role: 'user', content: 'Explain CVE-2024-1234 in one line' }]
|
|
39
|
+
)
|
|
40
|
+
puts resp[:content]
|
|
41
|
+
```
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
## Model diversity in Swarm
|
|
44
|
+
|
|
45
|
+
Because each persona in [`agents.yml`](Swarm.md) can override `engine:`, an
|
|
46
|
+
`agent_debate` can literally pit Claude against Grok against a local Llama —
|
|
47
|
+
real antagonism, not one model role-playing three voices.
|
|
48
|
+
|
|
49
|
+
**See also:** [pwn-ai Agent](pwn-ai-Agent.md) ·
|
|
50
|
+
[Agent Tool Registry](Agent-Tool-Registry.md) · [Swarm](Swarm.md)
|
|
51
|
+
|
|
52
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# `PWN::AWS` — Cloud Security (90 service wrappers)
|
|
2
|
+
|
|
3
|
+
One thin module per AWS service, each wrapping the official `aws-sdk-*` gem
|
|
4
|
+
with the PWN `opts = {}` convention so they compose in the REPL and in
|
|
5
|
+
`pwn_eval`.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Credentials
|
|
10
|
+
|
|
11
|
+
Standard AWS SDK chain: `~/.aws/credentials` profile, env vars
|
|
12
|
+
(`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN`), or
|
|
13
|
+
instance profile. Optionally pin in `~/.pwn/config.yml` under `aws:`.
|
|
14
|
+
|
|
15
|
+
## Quick enumeration
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
PWN::AWS::STS.get_caller_identity
|
|
19
|
+
PWN::AWS::IAM.list_users
|
|
20
|
+
PWN::AWS::EC2.describe_instances(region: 'us-east-1')
|
|
21
|
+
PWN::AWS::S3.list_buckets
|
|
22
|
+
PWN::AWS::Lambda.list_functions
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
CLI: `pwn_aws_describe_resources -r us-east-1 -o out/`
|
|
26
|
+
|
|
27
|
+
## Service groups
|
|
28
|
+
|
|
29
|
+
| Group | Modules |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Identity | `IAM` `STS` `CognitoIdentity` `CognitoIdentityProvider` `CognitoSync` `DirectoryService` |
|
|
32
|
+
| Compute | `EC2` `ECS` `ECR` `Lambda` `LambdaPreview` `Batch` `Lightsail` `ElasticBeanstalk` `AutoScaling` `ApplicationAutoScaling` `AppStream` |
|
|
33
|
+
| Storage | `S3` `Glacier` `EFS` `StorageGateway` `Snowball` |
|
|
34
|
+
| Data | `DynamoDB` `DynamoDBStreams` `RDS` `Redshift` `ElastiCache` `SimpleDB` `ElasticsearchService` |
|
|
35
|
+
| Network | `Route53` `Route53Domains` `ElasticLoadBalancing` `ElasticLoadBalancingV2` `APIGateway` `CloudFront` `DirectConnect` `WAF` `WAFRegional` `Shield` |
|
|
36
|
+
| Crypto | `KMS` `CloudHSM` `ACM` |
|
|
37
|
+
| Ops / Logs | `CloudTrail` `CloudWatch` `CloudWatchLogs` `CloudWatchEvents` `ConfigService` `SSM` `Health` `Inspector` `XRay` |
|
|
38
|
+
| Dev | `CodeBuild` `CodeCommit` `CodeDeploy` `CodePipeline` |
|
|
39
|
+
| Messaging | `SNS` `SQS` `SES` `Pinpoint` `Kinesis` `KinesisAnalytics` `Firehose` |
|
|
40
|
+
| ML / Media | `Rekognition` `Polly` `MachineLearning` `Lex` `ElasticTranscoder` |
|
|
41
|
+
| Infra | `CloudFormation` `CloudSearch` `CloudSearchDomain` `OpsWorks` `OpsWorksCM` `ServiceCatalog` `DataPipleline` `EMR` `SWF` `States` |
|
|
42
|
+
| IoT / Other | `IoT` `IoTDataPlane` `DeviceFarm` `GameLift` `Workspaces` `Support` `Budgets` `ImportExport` `SMS` `DatabaseMigrationService` `ApplicationDiscoveryService` `MarketplaceCommerceAnalytics` `MarketplaceMetering` |
|
|
43
|
+
|
|
44
|
+
## Offensive patterns
|
|
45
|
+
|
|
46
|
+
- **Enumerate** → `IAM` policies, `EC2` userdata, `Lambda` env vars, `S3`
|
|
47
|
+
bucket ACLs, `SSM` parameters.
|
|
48
|
+
- **Misconfig** → public `S3`, wildcard `IAM` actions, unencrypted `RDS`,
|
|
49
|
+
missing `CloudTrail`.
|
|
50
|
+
- **Escalate** → `iam:PassRole` + `lambda:Invoke`, `ssm:SendCommand`,
|
|
51
|
+
`ec2:RunInstances` with instance profile.
|
|
52
|
+
- **Persist** → new access key, Lambda backdoor, EC2 userdata.
|
|
53
|
+
|
|
54
|
+
Record everything with `extro_observe(source: 'aws', …)` so
|
|
55
|
+
[Extrospection](Extrospection.md) can correlate later.
|
|
56
|
+
|
|
57
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Agent Tool Registry
|
|
2
|
+
|
|
3
|
+
`PWN::AI::Agent::Registry` (`lib/pwn/ai/agent/registry.rb`) collects every
|
|
4
|
+
LLM-callable function into named **toolsets**. A persona is granted a subset of
|
|
5
|
+
toolsets; the JSON-Schema for each tool is what the model actually sees.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Toolsets → Tools
|
|
10
|
+
|
|
11
|
+
| Toolset | Tools | Backed by |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `terminal` | `shell` | `Open3.capture3` on the host |
|
|
14
|
+
| `pwn` | `pwn_eval` | `TOPLEVEL_BINDING.eval` in the live REPL process |
|
|
15
|
+
| `memory` | `memory_remember` · `memory_recall` · `memory_forget` · `memory_clear` | `PWN::Memory` → `~/.pwn/memory.json` |
|
|
16
|
+
| `skills` | `skill_list` · `skill_view` · `skill_create` · `skill_add_reference` · `skill_delete` | `~/.pwn/skills/*.md` |
|
|
17
|
+
| `sessions` | `sessions_list` · `sessions_view` · `sessions_current` · `sessions_delete` · `sessions_stats` | `PWN::Sessions` → `~/.pwn/sessions/` |
|
|
18
|
+
| `learning` | `learning_note_outcome` · `learning_reflect` · `learning_distill_skill` · `learning_stats` · `learning_outcomes` · `learning_consolidate` · `learning_reset` · `learning_auto_reflect_toggle` | `PWN::AI::Agent::Learning` → `~/.pwn/learning.jsonl` |
|
|
19
|
+
| `metrics` | `metrics_summary` · `metrics_reset` | `PWN::AI::Agent::Metrics` → `~/.pwn/metrics.json` |
|
|
20
|
+
| `extrospection` | `extro_snapshot` · `extro_drift` · `extro_observe` · `extro_observations` · `extro_intel` · `extro_correlate` · `extro_stats` · `extro_reset` · `extro_auto_toggle` | `PWN::AI::Agent::Extrospection` → `~/.pwn/extrospection.json` |
|
|
21
|
+
| `cron` | `cron_list` · `cron_create` · `cron_run` · `cron_enable` · `cron_disable` · `cron_remove` | `PWN::Cron` → `~/.pwn/cron/jobs.yml` |
|
|
22
|
+
| `swarm` | `agent_list` · `agent_spawn` · `agent_ask` · `agent_debate` · `agent_broadcast` · `swarm_bus` · `swarm_list` | `PWN::AI::Agent::Swarm` → `~/.pwn/agents.yml` + `~/.pwn/swarm/` |
|
|
23
|
+
|
|
24
|
+
## Adding a tool
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
# lib/pwn/ai/agent/tools/my_thing.rb
|
|
28
|
+
PWN::AI::Agent::Registry.register(
|
|
29
|
+
name: 'my_thing_do',
|
|
30
|
+
toolset: 'my_thing',
|
|
31
|
+
description: 'One-line summary the LLM will read.',
|
|
32
|
+
parameters: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: { target: { type: 'string' } },
|
|
35
|
+
required: ['target']
|
|
36
|
+
}
|
|
37
|
+
) do |args|
|
|
38
|
+
PWN::Plugins::MyThing.do(target: args['target'])
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Drop the file in `lib/pwn/ai/agent/tools/`, it's auto-loaded on next launch.
|
|
43
|
+
|
|
44
|
+
## Restricting a persona
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
# ~/.pwn/agents.yml
|
|
48
|
+
recon:
|
|
49
|
+
role: "Passive OSINT only. Never touch the target directly."
|
|
50
|
+
toolsets: [terminal, pwn, memory, extrospection] # no swarm, no cron
|
|
51
|
+
engine: ollama
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**See also:** [pwn-ai Agent](pwn-ai-Agent.md) · [Swarm](Swarm.md)
|
|
55
|
+
|
|
56
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# `PWN::Banner` — Startup Art
|
|
2
|
+
|
|
3
|
+
15 ANSI banners; one is picked at random every time the REPL starts. Purely
|
|
4
|
+
cosmetic, entirely necessary.
|
|
5
|
+
|
|
6
|
+
`Anon · Bubble · Cheshire · CodeCave · DontPanic · ForkBomb · FSociety ·
|
|
7
|
+
JmpEsp · Matrix · Ninja · OffTheAir · Pirate · Radare2 · Radare2AI ·
|
|
8
|
+
WhiteRabbit`
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
puts PWN::Banner::Matrix.get
|
|
12
|
+
welcome-banner # REPL command: redraw a random one
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add your own: drop a module in `lib/pwn/banner/` implementing `self.get`.
|
|
16
|
+
|
|
17
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# `PWN::Blockchain` — BTC · ETH
|
|
2
|
+
|
|
3
|
+
Lightweight helpers for on-chain recon and wallet interaction.
|
|
4
|
+
Source: `lib/pwn/blockchain/*.rb`.
|
|
5
|
+
|
|
6
|
+
| Module | Purpose |
|
|
7
|
+
|---|---|
|
|
8
|
+
| `PWN::Blockchain::BTC` | Address balance/UTXO lookup, tx broadcast, key helpers |
|
|
9
|
+
| `PWN::Blockchain::ETH` | Address balance, contract call, event log query |
|
|
10
|
+
|
|
11
|
+
Also exposed to the agent via `PWN::AI::Agent::BTC` for wallet-aware prompts.
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
PWN::Blockchain::BTC.balance(address: 'bc1q…')
|
|
15
|
+
PWN::Blockchain::ETH.call(contract: '0x…', method: 'owner()')
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# `PWN::Bounty` — Bug-Bounty Lifecycle Tooling
|
|
2
|
+
|
|
3
|
+
| Module | Purpose |
|
|
4
|
+
|---|---|
|
|
5
|
+
| `PWN::Bounty::LifecycleAuthzReplay` | Record an authenticated browser session, then replay every request under a *different* principal to surface horizontal/vertical authz bugs |
|
|
6
|
+
|
|
7
|
+
Pairs naturally with:
|
|
8
|
+
|
|
9
|
+
- [`PWN::WWW::HackerOne`](WWW.md) / `BugCrowd` / `Synack` — programme navigation
|
|
10
|
+
- `PWN::Plugins::HackerOne` — submissions API
|
|
11
|
+
- [`PWN::Plugins::BurpSuite`](BurpSuite.md) — capture the session to replay
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
PWN::Bounty::LifecycleAuthzReplay.start(
|
|
15
|
+
har_path: 'admin_session.har',
|
|
16
|
+
replay_as: { cookie: 'session=LOW_PRIV_TOKEN' },
|
|
17
|
+
proxy: 'http://127.0.0.1:8080'
|
|
18
|
+
)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
[← Home](Home.md) · [WWW](WWW.md)
|
data/documentation/BurpSuite.md
CHANGED
|
@@ -1,26 +1,51 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `PWN::Plugins::BurpSuite` ⭐
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
The **preferred** web proxy / scanner in PWN (see
|
|
4
|
+
[Burp vs ZAP](Diagrams.md#burp--vs-zap-selection)). Wraps Burp Suite
|
|
5
|
+
Professional's headless mode + REST API.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+

|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## Configure
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
```yaml
|
|
12
|
+
# ~/.pwn/config.yml
|
|
13
|
+
burp:
|
|
14
|
+
jar: /opt/burpsuite_pro/burpsuite_pro.jar
|
|
15
|
+
api_key: <REST-API-KEY>
|
|
16
|
+
bind_ip: 127.0.0.1
|
|
17
|
+
proxy_port: 8080
|
|
18
|
+
api_port: 1337
|
|
19
|
+
```
|
|
10
20
|
|
|
11
|
-
|
|
12
|
-
- `PWN::Plugins::BurpSuite.stop`
|
|
13
|
-
- `PWN::Plugins::BurpSuite.get_sitemap(...)`
|
|
14
|
-
- `PWN::Plugins::BurpSuite.send_request(...)`
|
|
15
|
-
- Live spidering and scanning orchestration
|
|
16
|
-
- Integration with TransparentBrowser for proxied browsing
|
|
21
|
+
## Core methods
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
```ruby
|
|
24
|
+
burp = PWN::Plugins::BurpSuite.start(headless: true)
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
# drive traffic through it
|
|
27
|
+
b = PWN::Plugins::TransparentBrowser.open(
|
|
28
|
+
browser_type: :headless, proxy: 'http://127.0.0.1:8080')
|
|
29
|
+
b[:browser].goto 'https://target'
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
# scan
|
|
32
|
+
PWN::Plugins::BurpSuite.active_scan(burp_obj: burp,
|
|
33
|
+
target_url: 'https://target')
|
|
34
|
+
issues = PWN::Plugins::BurpSuite.get_scan_issues(burp_obj: burp)
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
PWN::Plugins::BurpSuite.stop(burp_obj: burp)
|
|
37
|
+
```
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
## CLI drivers
|
|
40
|
+
|
|
41
|
+
- `pwn_burp_suite_pro_active_scan -t URL -o out/`
|
|
42
|
+
- `pwn_burp_suite_pro_active_rest_api_scan` — pure REST, no JVM spawn
|
|
43
|
+
|
|
44
|
+
## Why preferred over ZAP
|
|
45
|
+
|
|
46
|
+
Richer scanner, larger BApp ecosystem, more reliable REST surface. `Zaproxy`
|
|
47
|
+
remains as an OSS fallback and is API-compatible enough that swapping is a
|
|
48
|
+
one-line change.
|
|
49
|
+
|
|
50
|
+
[← Home](Home.md) · [Transparent-Browser](Transparent-Browser.md) ·
|
|
51
|
+
[Plugins](Plugins.md)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# CLI Drivers — `bin/pwn_*`
|
|
2
|
+
|
|
3
|
+
52 headless executables, each a thin `OptionParser` wrapper over one plugin
|
|
4
|
+
(or one workflow). They exist so CI/CD can call PWN without a REPL or an LLM.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Full list
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
pwn pwn_jenkins_thinBackup_aws_s3
|
|
12
|
+
pwn_android_war_dialer pwn_jenkins_update_plugins
|
|
13
|
+
pwn_autoinc_version pwn_jenkins_useradd
|
|
14
|
+
pwn_aws_describe_resources pwn_mail_agent
|
|
15
|
+
pwn_bdba_groups pwn_msf_postgres_login
|
|
16
|
+
pwn_bdba_scan pwn_nessus_cloud_scan_crud
|
|
17
|
+
pwn_burp_suite_pro_active_rest_api_scan pwn_nessus_cloud_vulnscan
|
|
18
|
+
pwn_burp_suite_pro_active_scan pwn_nexpose
|
|
19
|
+
pwn_char_base64_encoding pwn_nmap_discover_tcp_udp
|
|
20
|
+
pwn_char_dec_encoding pwn_openvas_vulnscan
|
|
21
|
+
pwn_char_hex_escaped_encoding pwn_pastebin_sample_filter
|
|
22
|
+
pwn_char_html_entity_encoding pwn_phone
|
|
23
|
+
pwn_char_unicode_escaped_encoding pwn_rdoc_to_jsonl
|
|
24
|
+
pwn_char_url_encoding pwn_sast
|
|
25
|
+
pwn_crt_sh pwn_serial_check_voicemail
|
|
26
|
+
pwn_defectdojo_engagement_create pwn_serial_msr206
|
|
27
|
+
pwn_defectdojo_importscan pwn_serial_qualcomm_commands
|
|
28
|
+
pwn_defectdojo_reimportscan pwn_serial_son_micro_sm132_rfid
|
|
29
|
+
pwn_diff_csv_files_w_column_exclude pwn_shodan_graphql_introspection
|
|
30
|
+
pwn_domain_reversewhois pwn_shodan_search
|
|
31
|
+
pwn_fuzz_net_app_proto pwn_simple_http_server
|
|
32
|
+
pwn_gqrx_scanner pwn_web_cache_deception
|
|
33
|
+
pwn_jenkins_create_job pwn_www_checkip
|
|
34
|
+
pwn_jenkins_create_view pwn_www_uri_buster
|
|
35
|
+
pwn_jenkins_install_plugin pwn_xss_dom_vectors
|
|
36
|
+
pwn_zaproxy_active_rest_api_scan
|
|
37
|
+
pwn_zaproxy_active_scan
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run any with `--help` for its flags.
|
|
41
|
+
|
|
42
|
+
## Typical CI usage
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
# .gitlab-ci.yml
|
|
46
|
+
sast:
|
|
47
|
+
image: 0dayinc/pwn:latest
|
|
48
|
+
script:
|
|
49
|
+
- pwn_sast -d "$CI_PROJECT_DIR" -o sast_out/
|
|
50
|
+
- pwn_defectdojo_importscan -f sast_out/report.json -e "$DD_ENGAGEMENT"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Write your own
|
|
54
|
+
|
|
55
|
+
See [Drivers](Drivers.md) — copy any file in `bin/`, swap the plugin call,
|
|
56
|
+
`rake install`, done.
|
|
57
|
+
|
|
58
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Configuration — `~/.pwn/config.yml`
|
|
2
|
+
|
|
3
|
+
Everything configurable lives in one YAML file, loaded by `PWN::Config` at
|
|
4
|
+
startup and available in-process as `PWN::Env`.
|
|
5
|
+
|
|
6
|
+
## Minimal example
|
|
7
|
+
|
|
8
|
+
```yaml
|
|
9
|
+
# ~/.pwn/config.yml
|
|
10
|
+
ai:
|
|
11
|
+
engine: anthropic # openai | anthropic | grok | gemini | ollama
|
|
12
|
+
anthropic:
|
|
13
|
+
key: sk-ant-…
|
|
14
|
+
openai:
|
|
15
|
+
key: sk-…
|
|
16
|
+
grok:
|
|
17
|
+
oauth: true # RFC-8628 device flow, no client_secret
|
|
18
|
+
ollama:
|
|
19
|
+
base_url: http://localhost:11434
|
|
20
|
+
model: llama3.1:70b
|
|
21
|
+
agent:
|
|
22
|
+
max_iters: 40 # tool-loop cap per turn
|
|
23
|
+
max_depth: 3 # swarm recursion cap
|
|
24
|
+
auto_reflect: true # Learning.auto_reflect after every final answer
|
|
25
|
+
auto_extrospect: true # Extrospection.auto_extrospect likewise
|
|
26
|
+
|
|
27
|
+
burp:
|
|
28
|
+
jar: /opt/burpsuite_pro/burpsuite_pro.jar
|
|
29
|
+
api_key: …
|
|
30
|
+
|
|
31
|
+
metasploit:
|
|
32
|
+
host: 127.0.0.1
|
|
33
|
+
port: 55553
|
|
34
|
+
user: msf
|
|
35
|
+
pass: …
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Reading / writing at runtime
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
PWN::Env[:ai][:engine] # => :anthropic
|
|
42
|
+
PWN::Env[:ai][:agent][:auto_reflect] # => true
|
|
43
|
+
PWN::Config.reload!
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Sections PWN looks for
|
|
47
|
+
|
|
48
|
+
| Key path | Consumed by |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `ai.engine` | `PWN::AI::Agent::Loop` — which client to instantiate |
|
|
51
|
+
| `ai.<engine>.key` / `.oauth` | `PWN::AI::OpenAI` / `Anthropic` / `Grok` / `Gemini` / `Ollama` |
|
|
52
|
+
| `ai.agent.max_iters` | hard stop on tool-call rounds |
|
|
53
|
+
| `ai.agent.max_depth` | `Swarm` recursion guard |
|
|
54
|
+
| `ai.agent.auto_reflect` | toggle `Learning.auto_reflect` |
|
|
55
|
+
| `ai.agent.auto_extrospect` | toggle `Extrospection.auto_extrospect` |
|
|
56
|
+
| `burp.*` | `PWN::Plugins::BurpSuite` |
|
|
57
|
+
| `metasploit.*` | `PWN::Plugins::Metasploit` |
|
|
58
|
+
| `zap.*` | `PWN::Plugins::Zaproxy` |
|
|
59
|
+
| `shodan.key` / `hunter.key` / … | respective OSINT plugins |
|
|
60
|
+
| `aws.*` | `PWN::AWS::*` (falls back to standard AWS SDK env/instance-profile) |
|
|
61
|
+
|
|
62
|
+
## Other files under `~/.pwn/`
|
|
63
|
+
|
|
64
|
+
See [Persistence](Persistence.md) for the full map.
|
|
65
|
+
|
|
66
|
+
[← Home](Home.md)
|
|
@@ -1,31 +1,45 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Repo layout
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```text
|
|
6
|
+
lib/pwn/ # all namespaces
|
|
7
|
+
lib/pwn/plugins/ # 66 plugin modules
|
|
8
|
+
lib/pwn/ai/agent/ # agent core
|
|
9
|
+
lib/pwn/ai/agent/tools/ # LLM tool registrations
|
|
10
|
+
bin/ # 52 pwn_* drivers
|
|
11
|
+
spec/ # RSpec (incl. conventions_spec)
|
|
12
|
+
documentation/ # this wiki + diagrams
|
|
13
|
+
```
|
|
6
14
|
|
|
7
|
-
|
|
8
|
-
- Improvements to existing modules
|
|
9
|
-
- New SAST signatures
|
|
10
|
-
- AI skills (see [Skills-Memory-Learning](Skills-Memory-Learning.md))
|
|
11
|
-
- Better documentation / wiki pages
|
|
12
|
-
- Bridges to more commercial/open security tools
|
|
13
|
-
- Bug reports with clear reproduction steps
|
|
15
|
+
## Conventions (enforced by `spec/conventions_spec.rb`)
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
1. Every public module method is `public_class_method def self.name(opts = {})`.
|
|
18
|
+
2. Every arg-accepting `def self.*` uses **exactly** `(opts = {})` — no
|
|
19
|
+
positional args, no keyword args.
|
|
20
|
+
3. Every module has `self.help` returning a usage string.
|
|
21
|
+
4. `# frozen_string_literal: true` at the top of every `.rb`.
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
2. Open an issue or PR on https://github.com/0dayInc/pwn
|
|
19
|
-
3. For large features, discuss first via email (support@0dayinc.com) or GitHub.
|
|
23
|
+
## Quality gates
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
```bash
|
|
26
|
+
rvmsudo rake # rubocop + rspec — must be zero offenses
|
|
27
|
+
```
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
## Adding a plugin
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
1. `lib/pwn/plugins/my_thing.rb` following the conventions above.
|
|
32
|
+
2. Autoload entry in `lib/pwn/plugins.rb`.
|
|
33
|
+
3. `spec/lib/pwn/plugins/my_thing_spec.rb`.
|
|
34
|
+
4. Optional `bin/pwn_my_thing` driver (see [Drivers](Drivers.md)).
|
|
35
|
+
5. Optional agent tool in `lib/pwn/ai/agent/tools/` (see
|
|
36
|
+
[Agent Tool Registry](Agent-Tool-Registry.md)).
|
|
37
|
+
6. Update [Plugins.md](Plugins.md) and, if it changes a data flow, the
|
|
38
|
+
relevant `.dot` in `documentation/diagrams/dot/` → `./build.sh`.
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
## Commit / release
|
|
28
41
|
|
|
29
|
-
|
|
42
|
+
`./git_commit.sh` bumps `PWN::VERSION`, regenerates
|
|
43
|
+
`third_party/pwn_rdoc.jsonl`, runs the gates, and pushes.
|
|
30
44
|
|
|
31
|
-
[
|
|
45
|
+
[← Home](Home.md)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Cron — Scheduled Autonomous Jobs
|
|
2
|
+
|
|
3
|
+
`PWN::Cron` (`lib/pwn/cron.rb`) stores job definitions in
|
|
4
|
+
`~/.pwn/cron/jobs.yml` and can install a matching system-`crontab` line that
|
|
5
|
+
invokes `PWN::Cron.run(<id>)` on schedule.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Job kinds
|
|
10
|
+
|
|
11
|
+
| Kind | Executed as | Use for |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `prompt:` | `pwn --ai "<prompt>"` one-shot | "Re-scan scope nightly and diff findings" |
|
|
14
|
+
| `ruby:` | `TOPLEVEL_BINDING.eval` in-process | Direct `PWN::Plugins` calls |
|
|
15
|
+
| `script:` | `exec` external file | Anything not in Ruby |
|
|
16
|
+
|
|
17
|
+
## Tools
|
|
18
|
+
|
|
19
|
+
| Tool | Purpose |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `cron_create(schedule:, prompt:/ruby:/script:, install_crontab:)` | Define a job |
|
|
22
|
+
| `cron_list` | id · name · schedule · enabled · last_run · last_status |
|
|
23
|
+
| `cron_run(id:)` | Fire immediately (updates last_run/last_status) |
|
|
24
|
+
| `cron_enable` / `cron_disable` | Toggle without deleting |
|
|
25
|
+
| `cron_remove` | Delete from `jobs.yml` (does **not** scrub crontab — `crontab -e` yourself) |
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
cron_create(
|
|
31
|
+
name: 'nightly_scope_sweep',
|
|
32
|
+
schedule: '0 2 * * *',
|
|
33
|
+
prompt: 'extro_snapshot, then NmapIt sweep 10.0.0.0/24, extro_observe every '\
|
|
34
|
+
'new open port, extro_correlate, and post a one-paragraph summary.',
|
|
35
|
+
install_crontab: true
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
At 02:00 the system cron fires `PWN::Cron.run`, which spins up a headless
|
|
40
|
+
`pwn-ai` turn. Because `auto_reflect` and `auto_extrospect` are on, the run
|
|
41
|
+
also updates Learning/Metrics/Extrospection — so tomorrow's interactive
|
|
42
|
+
session already knows what changed overnight.
|
|
43
|
+
|
|
44
|
+
**See also:** [Sessions](Sessions.md) · [Extrospection](Extrospection.md) ·
|
|
45
|
+
[CLI Drivers](CLI-Drivers.md)
|
|
46
|
+
|
|
47
|
+
[← Home](Home.md)
|