pwn 0.5.719 → 0.5.720
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/etc/default_skills/pwn/ai/agent/engagement/SKILL.md +53 -0
- data/etc/default_skills/pwn/ai/agent/learning/SKILL.md +4 -0
- data/etc/default_skills/pwn/ai/agent/loop/SKILL.md +1 -0
- data/etc/default_skills/pwn/ai/agent/swarm/SKILL.md +1 -0
- data/etc/default_skills/pwn/ai/agent/tool_guard/SKILL.md +1 -0
- data/etc/default_skills/pwn/ai/agent/tools/debug_lane/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/tools/engagement/SKILL.md +45 -0
- data/etc/default_skills/pwn/ai/agent/turn_finalizer/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/bin_workspace/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/binary_parser/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/capability/SKILL.md +48 -0
- data/etc/default_skills/pwn/plugins/detonate/SKILL.md +47 -0
- data/etc/default_skills/pwn/plugins/emulator/SKILL.md +47 -0
- data/etc/default_skills/pwn/plugins/findings/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/gdb/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/packet/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/repl/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/vault/SKILL.md +4 -0
- data/etc/default_skills/pwn/reports/engagement/SKILL.md +47 -0
- data/lib/pwn/ai/agent/dispatch.rb +67 -0
- data/lib/pwn/ai/agent/engagement.rb +167 -0
- data/lib/pwn/ai/agent/learning.rb +88 -4
- data/lib/pwn/ai/agent/loop.rb +20 -0
- data/lib/pwn/ai/agent/reward.rb +76 -12
- data/lib/pwn/ai/agent/swarm.rb +36 -0
- data/lib/pwn/ai/agent/tool_guard.rb +39 -0
- data/lib/pwn/ai/agent/tools/debug_lane.rb +160 -0
- data/lib/pwn/ai/agent/tools/engagement.rb +40 -0
- data/lib/pwn/ai/agent/turn_finalizer.rb +65 -0
- data/lib/pwn/ai/agent.rb +1 -0
- data/lib/pwn/config.rb +18 -2
- data/lib/pwn/plugins/bin_workspace.rb +81 -0
- data/lib/pwn/plugins/binary_parser.rb +27 -0
- data/lib/pwn/plugins/capability.rb +68 -0
- data/lib/pwn/plugins/detonate.rb +62 -0
- data/lib/pwn/plugins/emulator.rb +64 -0
- data/lib/pwn/plugins/findings.rb +47 -0
- data/lib/pwn/plugins/gdb.rb +42 -0
- data/lib/pwn/plugins/packet.rb +26 -0
- data/lib/pwn/plugins/repl.rb +25 -2
- data/lib/pwn/plugins/vault.rb +116 -0
- data/lib/pwn/plugins.rb +4 -0
- data/lib/pwn/reports/engagement.rb +63 -0
- data/lib/pwn/reports.rb +1 -0
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/ai/agent/engagement_spec.rb +27 -0
- data/spec/lib/pwn/ai/agent/learning_spec.rb +23 -0
- data/spec/lib/pwn/ai/agent/reward_spec.rb +16 -0
- data/spec/lib/pwn/ai/agent/swarm_spec.rb +11 -0
- data/spec/lib/pwn/ai/agent/tools/debug_lane_spec.rb +16 -0
- data/spec/lib/pwn/ai/agent/tools/engagement_spec.rb +16 -0
- data/spec/lib/pwn/ai/agent/turn_finalizer_spec.rb +18 -0
- data/spec/lib/pwn/plugins/bin_workspace_spec.rb +26 -0
- data/spec/lib/pwn/plugins/capability_spec.rb +19 -0
- data/spec/lib/pwn/plugins/detonate_spec.rb +24 -0
- data/spec/lib/pwn/plugins/emulator_spec.rb +18 -0
- data/spec/lib/pwn/plugins/findings_spec.rb +13 -0
- data/spec/lib/pwn/plugins/gdb_spec.rb +10 -0
- data/spec/lib/pwn/plugins/packet_spec.rb +6 -0
- data/spec/lib/pwn/plugins/repl_spec.rb +1 -1
- data/spec/lib/pwn/plugins/vault_spec.rb +11 -0
- data/spec/lib/pwn/reports/engagement_spec.rb +30 -0
- data/third_party/pwn_rdoc.jsonl +62 -0
- metadata +25 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0dd0d654d48c9ead7f9a92893f88443e1cfd7cd9a867c53cb2ffc25cbb60fe27
|
|
4
|
+
data.tar.gz: 3960e8501cbd0139184cd0981569a28a4f9b37e47ddddeb5dab001b2d0eefb1b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: defca7be52f6960bbaa318f5e40e4927cafa8a1e679ce27dd8e74b73feae4b89a9766b725a5731b2e2fa5a8e93c58a2fa3622f0c37df6b0355bf6b12e9affbae
|
|
7
|
+
data.tar.gz: 29de8ee9497ec7004c4752ddaf3fc359016c6007368e051e891e191ad18bf069a3a44d32aa73ed480dc60cb30bba46551efa2f636009b8d50752e0101917900b
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-ai-agent-engagement
|
|
3
|
+
description: Drive PWN::AI::Agent::Engagement from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::AI::Agent::Engagement
|
|
10
|
+
source: pwn/ai/agent/engagement.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::AI::Agent::Engagement
|
|
14
|
+
|
|
15
|
+
First-class engagement scope, RoE, and findings pointer.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::AI::Agent::Engagement` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/ai/agent/engagement.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::AI::Agent::Engagement.help
|
|
31
|
+
PWN::AI::Agent::Engagement.open(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `open`
|
|
37
|
+
- `close`
|
|
38
|
+
- `status`
|
|
39
|
+
- `current_name`
|
|
40
|
+
- `in_scope`
|
|
41
|
+
- `deny_if_out_of_scope`
|
|
42
|
+
- `authors`
|
|
43
|
+
- `help`
|
|
44
|
+
- `in_scope?`
|
|
45
|
+
|
|
46
|
+
## Source
|
|
47
|
+
|
|
48
|
+
`pwn/ai/agent/engagement.rb`
|
|
49
|
+
|
|
50
|
+
## Verification
|
|
51
|
+
|
|
52
|
+
`PWN::AI::Agent::Engagement.respond_to?(:open)` after the
|
|
53
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -54,8 +54,12 @@ PWN::AI::Agent::Learning.note_outcome(opts)
|
|
|
54
54
|
- `lesson_record`
|
|
55
55
|
- `lesson_observe`
|
|
56
56
|
- `lesson_prompt`
|
|
57
|
+
- `list_conflicted`
|
|
58
|
+
- `requeue_conflicted`
|
|
59
|
+
- `compact`
|
|
57
60
|
- `authors`
|
|
58
61
|
- `help`
|
|
62
|
+
- `compact!`
|
|
59
63
|
- `gc_stores!`
|
|
60
64
|
- `lean!`
|
|
61
65
|
- `prune_outcomes!`
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-ai-agent-tools-debuglane
|
|
3
|
+
description: Drive PWN::Ai::Agent::Tools::DebugLane from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Ai::Agent::Tools::DebugLane
|
|
10
|
+
source: pwn/ai/agent/tools/debug_lane.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Ai::Agent::Tools::DebugLane
|
|
14
|
+
|
|
15
|
+
Public API for PWN::Ai::Agent::Tools::DebugLane.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Ai::Agent::Tools::DebugLane` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/ai/agent/tools/debug_lane.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Ai::Agent::Tools::DebugLane.help
|
|
31
|
+
PWN::Ai::Agent::Tools::DebugLane.help(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- _(no public class methods parsed)_
|
|
37
|
+
|
|
38
|
+
## Source
|
|
39
|
+
|
|
40
|
+
`pwn/ai/agent/tools/debug_lane.rb`
|
|
41
|
+
|
|
42
|
+
## Verification
|
|
43
|
+
|
|
44
|
+
`PWN::Ai::Agent::Tools::DebugLane.respond_to?(:help)` after the
|
|
45
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-ai-agent-tools-engagement
|
|
3
|
+
description: Drive PWN::Ai::Agent::Tools::Engagement from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Ai::Agent::Tools::Engagement
|
|
10
|
+
source: pwn/ai/agent/tools/engagement.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Ai::Agent::Tools::Engagement
|
|
14
|
+
|
|
15
|
+
Public API for PWN::Ai::Agent::Tools::Engagement.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Ai::Agent::Tools::Engagement` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/ai/agent/tools/engagement.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Ai::Agent::Tools::Engagement.help
|
|
31
|
+
PWN::Ai::Agent::Tools::Engagement.help(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- _(no public class methods parsed)_
|
|
37
|
+
|
|
38
|
+
## Source
|
|
39
|
+
|
|
40
|
+
`pwn/ai/agent/tools/engagement.rb`
|
|
41
|
+
|
|
42
|
+
## Verification
|
|
43
|
+
|
|
44
|
+
`PWN::Ai::Agent::Tools::Engagement.respond_to?(:help)` after the
|
|
45
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-binworkspace
|
|
3
|
+
description: Drive PWN::Plugins::BinWorkspace from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::BinWorkspace
|
|
10
|
+
source: pwn/plugins/bin_workspace.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::BinWorkspace
|
|
14
|
+
|
|
15
|
+
Persistent per-binary analysis workspace keyed by sha256.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::BinWorkspace` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/plugins/bin_workspace.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Plugins::BinWorkspace.help
|
|
31
|
+
PWN::Plugins::BinWorkspace.for(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `for`
|
|
37
|
+
- `annotate`
|
|
38
|
+
- `notes`
|
|
39
|
+
- `authors`
|
|
40
|
+
- `help`
|
|
41
|
+
|
|
42
|
+
## Source
|
|
43
|
+
|
|
44
|
+
`pwn/plugins/bin_workspace.rb`
|
|
45
|
+
|
|
46
|
+
## Verification
|
|
47
|
+
|
|
48
|
+
`PWN::Plugins::BinWorkspace.respond_to?(:for)` after the
|
|
49
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-capability
|
|
3
|
+
description: Drive PWN::Plugins::Capability from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::Capability
|
|
10
|
+
source: pwn/plugins/capability.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::Capability
|
|
14
|
+
|
|
15
|
+
Operator-approved capability elevation (never auto-sudo).
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::Capability` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/plugins/capability.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Plugins::Capability.help
|
|
31
|
+
PWN::Plugins::Capability.request(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `request`
|
|
37
|
+
- `grantable_caps`
|
|
38
|
+
- `authors`
|
|
39
|
+
- `help`
|
|
40
|
+
|
|
41
|
+
## Source
|
|
42
|
+
|
|
43
|
+
`pwn/plugins/capability.rb`
|
|
44
|
+
|
|
45
|
+
## Verification
|
|
46
|
+
|
|
47
|
+
`PWN::Plugins::Capability.respond_to?(:request)` after the
|
|
48
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-detonate
|
|
3
|
+
description: Drive PWN::Plugins::Detonate from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::Detonate
|
|
10
|
+
source: pwn/plugins/detonate.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::Detonate
|
|
14
|
+
|
|
15
|
+
Isolated sample detonation. Refuses if podman/isolation is missing.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::Detonate` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/plugins/detonate.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Plugins::Detonate.help
|
|
31
|
+
PWN::Plugins::Detonate.detonate(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `detonate`
|
|
37
|
+
- `authors`
|
|
38
|
+
- `help`
|
|
39
|
+
|
|
40
|
+
## Source
|
|
41
|
+
|
|
42
|
+
`pwn/plugins/detonate.rb`
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
|
|
46
|
+
`PWN::Plugins::Detonate.respond_to?(:detonate)` after the
|
|
47
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-emulator
|
|
3
|
+
description: Drive PWN::Plugins::Emulator from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::Emulator
|
|
10
|
+
source: pwn/plugins/emulator.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::Emulator
|
|
14
|
+
|
|
15
|
+
Unicorn-backed single-function emulation with a stub backend for tests.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::Emulator` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/plugins/emulator.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Plugins::Emulator.help
|
|
31
|
+
PWN::Plugins::Emulator.emulate(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `emulate`
|
|
37
|
+
- `authors`
|
|
38
|
+
- `help`
|
|
39
|
+
|
|
40
|
+
## Source
|
|
41
|
+
|
|
42
|
+
`pwn/plugins/emulator.rb`
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
|
|
46
|
+
`PWN::Plugins::Emulator.respond_to?(:emulate)` after the
|
|
47
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-reports-engagement
|
|
3
|
+
description: Drive PWN::Reports::Engagement from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Reports::Engagement
|
|
10
|
+
source: pwn/reports/engagement.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Reports::Engagement
|
|
14
|
+
|
|
15
|
+
Compile engagement findings into a client-ready HTML/Markdown report.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Reports::Engagement` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/reports/engagement.rb`. Prefer the public class methods below.
|
|
25
|
+
Class methods take `(opts = {})` and read `opts`.
|
|
26
|
+
|
|
27
|
+
## How to call
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
PWN::Reports::Engagement.help
|
|
31
|
+
PWN::Reports::Engagement.generate(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `generate`
|
|
37
|
+
- `authors`
|
|
38
|
+
- `help`
|
|
39
|
+
|
|
40
|
+
## Source
|
|
41
|
+
|
|
42
|
+
`pwn/reports/engagement.rb`
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
|
|
46
|
+
`PWN::Reports::Engagement.respond_to?(:generate)` after the
|
|
47
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -46,6 +46,20 @@ module PWN
|
|
|
46
46
|
args = parse_args(raw: raw, entry: entry)
|
|
47
47
|
required = Array(entry.schema&.dig(:parameters, :required))
|
|
48
48
|
args = ToolGuard.coerce_args(args: args, required: required) if defined?(ToolGuard)
|
|
49
|
+
blob = args.inspect
|
|
50
|
+
if defined?(PWN::Plugins::Vault)
|
|
51
|
+
blob = PWN::Plugins::Vault.expand(text: blob)
|
|
52
|
+
args = expand_vault_args(args: args)
|
|
53
|
+
end
|
|
54
|
+
if defined?(Engagement)
|
|
55
|
+
denied = Engagement.deny_if_out_of_scope(args: args, command: blob)
|
|
56
|
+
return JSON.generate(denied) if denied
|
|
57
|
+
end
|
|
58
|
+
if defined?(ToolGuard) && ToolGuard.respond_to?(:policy_decision)
|
|
59
|
+
pol = ToolGuard.policy_decision(name: entry.name, args: args)
|
|
60
|
+
return JSON.generate(pol) if pol.is_a?(Hash) && pol[:action] == 'deny'
|
|
61
|
+
end
|
|
62
|
+
return JSON.generate(success: false, error: 'taint: tool-output instruction in args', code: 'TAINT_DENY') if taint_blocked?(name: entry.name, args: args)
|
|
49
63
|
if defined?(ToolGuard) && ToolGuard.respond_to?(:canary_leak?) &&
|
|
50
64
|
ToolGuard.canary_leak?(text: args.inspect)
|
|
51
65
|
return JSON.generate(success: false, error: 'refused: session canary in outbound args', code: 'CANARY_DENY', rule_id: 'canary')
|
|
@@ -59,6 +73,12 @@ module PWN
|
|
|
59
73
|
end
|
|
60
74
|
result = entry.handler.call(args)
|
|
61
75
|
result = ToolGuard.quarantine_output(text: result) if defined?(ToolGuard) && result.is_a?(String) && ToolGuard.respond_to?(:quarantine_output)
|
|
76
|
+
note_taint(text: result)
|
|
77
|
+
if defined?(PWN::Plugins::Vault) && result.is_a?(String)
|
|
78
|
+
result = PWN::Plugins::Vault.redact(text: result)
|
|
79
|
+
elsif defined?(PWN::Plugins::Vault) && result.is_a?(Hash)
|
|
80
|
+
result = JSON.parse(PWN::Plugins::Vault.redact(text: JSON.generate(result)))
|
|
81
|
+
end
|
|
62
82
|
JSON.generate(success: true, result: result, effect: effect(name: entry.name, args: args))
|
|
63
83
|
rescue StandardError => e
|
|
64
84
|
JSON.generate(
|
|
@@ -348,6 +368,53 @@ module PWN
|
|
|
348
368
|
hash.each_with_object({}) { |(k, v), m| m[k.to_sym] = v }
|
|
349
369
|
end
|
|
350
370
|
|
|
371
|
+
private_class_method def self.expand_vault_args(opts = {})
|
|
372
|
+
args = opts[:args]
|
|
373
|
+
return args unless args.is_a?(Hash)
|
|
374
|
+
|
|
375
|
+
args.transform_values do |v|
|
|
376
|
+
v.is_a?(String) ? PWN::Plugins::Vault.expand(text: v) : v
|
|
377
|
+
end
|
|
378
|
+
rescue StandardError
|
|
379
|
+
opts[:args]
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
private_class_method def self.note_taint(opts = {})
|
|
383
|
+
text = opts[:text].to_s
|
|
384
|
+
grams = text.scan(/.{12,}/).first(20)
|
|
385
|
+
store = Thread.current[:pwn_taint] ||= []
|
|
386
|
+
grams.each { |g| store << g[0, 64] }
|
|
387
|
+
store.shift while store.length > 200
|
|
388
|
+
store
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
private_class_method def self.taint_blocked?(opts = {})
|
|
392
|
+
mode = taint_mode
|
|
393
|
+
return false if mode == 'off'
|
|
394
|
+
|
|
395
|
+
blob = opts[:args].inspect
|
|
396
|
+
return false if blob.length < 12
|
|
397
|
+
return false if opts[:args].is_a?(Hash) && (opts[:args][:taint_ack] == true || opts[:args]['taint_ack'] == true)
|
|
398
|
+
|
|
399
|
+
hit = Array(Thread.current[:pwn_taint]).any? { |g| g.length >= 12 && blob.include?(g) }
|
|
400
|
+
return false unless hit
|
|
401
|
+
return false unless blob.match?(/curl |bash -c|sh -c|\|\s*sh\b/i)
|
|
402
|
+
|
|
403
|
+
mode == 'enforce'
|
|
404
|
+
rescue StandardError
|
|
405
|
+
false
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
private_class_method def self.taint_mode(opts = {})
|
|
409
|
+
override = opts[:mode]
|
|
410
|
+
return override.to_s unless override.to_s.empty?
|
|
411
|
+
return 'enforce' unless defined?(PWN::Env)
|
|
412
|
+
|
|
413
|
+
(PWN::Env.dig(:ai, :taint, :mode) || 'enforce').to_s
|
|
414
|
+
rescue StandardError
|
|
415
|
+
'enforce'
|
|
416
|
+
end
|
|
417
|
+
|
|
351
418
|
# Author(s):: 0day Inc. <support@0dayinc.com>
|
|
352
419
|
|
|
353
420
|
public_class_method def self.authors
|