pwn 0.5.709 → 0.5.710
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/documentation/Installation.md +1 -1
- data/etc/default_skills/exploitdev/SKILL.md +38 -0
- data/etc/default_skills/pwn/plugins/aflplusplus/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/credential_attack/SKILL.md +7 -0
- data/etc/default_skills/pwn/plugins/credential_attack/references/urls.md +3 -0
- data/etc/default_skills/pwn/plugins/exploit_db/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/exploit_dev/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/frida/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/fuzz/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/gdb/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/k8s/SKILL.md +51 -0
- data/etc/default_skills/pwn/plugins/nuclei/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/{doctor → preflight_checker}/SKILL.md +13 -11
- data/etc/default_skills/pwn/plugins/process_tube/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/recon/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/recon/references/urls.md +1 -0
- data/etc/default_skills/pwn/plugins/semgrep/SKILL.md +48 -0
- data/etc/default_skills/pwn/plugins/volatility/SKILL.md +1 -0
- data/lib/pwn/ai/agent/prompt_builder.rb +1 -1
- data/lib/pwn/ai/agent/tools/sessions.rb +8 -1
- data/lib/pwn/ffi/stdio.rb +3 -1
- data/lib/pwn/plugins/aflplusplus.rb +21 -1
- data/lib/pwn/plugins/android.rb +9 -3
- data/lib/pwn/plugins/credential_attack.rb +62 -3
- data/lib/pwn/plugins/exploit_db.rb +69 -0
- data/lib/pwn/plugins/exploit_dev.rb +69 -3
- data/lib/pwn/plugins/frida.rb +60 -9
- data/lib/pwn/plugins/fuzz.rb +33 -0
- data/lib/pwn/plugins/gdb.rb +25 -5
- data/lib/pwn/plugins/jobs.rb +1 -0
- data/lib/pwn/plugins/k8s.rb +73 -0
- data/lib/pwn/plugins/nuclei.rb +36 -3
- data/lib/pwn/plugins/packet.rb +1 -1
- data/lib/pwn/plugins/{doctor.rb → preflight_checker.rb} +22 -5
- data/lib/pwn/plugins/process_tube.rb +20 -1
- data/lib/pwn/plugins/radare2.rb +1 -1
- data/lib/pwn/plugins/recon.rb +39 -4
- data/lib/pwn/plugins/semgrep.rb +61 -0
- data/lib/pwn/plugins/sock.rb +1 -0
- data/lib/pwn/plugins/sqlmap.rb +1 -1
- data/lib/pwn/plugins/volatility.rb +21 -2
- data/lib/pwn/plugins.rb +4 -1
- data/lib/pwn/setup.rb +13 -1
- data/lib/pwn/version.rb +1 -1
- data/spec/integration/help_contract_spec.rb +2 -0
- data/spec/lib/pwn/plugins/exploit_db_spec.rb +13 -0
- data/spec/lib/pwn/plugins/k8s_spec.rb +13 -0
- data/spec/lib/pwn/plugins/{doctor_spec.rb → preflight_checker_spec.rb} +1 -1
- data/spec/lib/pwn/plugins/semgrep_spec.rb +13 -0
- data/spec/lib/pwn/req_queue_spec.rb +168 -0
- data/third_party/pwn_rdoc.jsonl +43 -9
- metadata +20 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb2089e549bccd1c21a643fd22719f13cb3a7519c1580f9cbd3e425c66f2be91
|
|
4
|
+
data.tar.gz: d27e48a928750b279f8315e8a578071bed21403728ae7f8c5474015f75ff557e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 37c74e1e2ab80b6a872f0d533ec402b520bffd70dc1198114574b3bbe90383c9dbebe6ac9b844e79023eed1cdeefc6cb8df4cca964b186cff1e25bc718384b12
|
|
7
|
+
data.tar.gz: 703c871173f4a754b9a515b45c4fd6aa4d3e2b1590f397168a53869d7eed5a77243a69e635f3894ce61be401b4c260395b0be7b435d6dc0613067b7b9047345c
|
data/Gemfile
CHANGED
|
@@ -22,7 +22,7 @@ gem 'brakeman', '8.0.6'
|
|
|
22
22
|
gem 'bson', '5.2.0'
|
|
23
23
|
gem 'bundler', '>=4.0.19'
|
|
24
24
|
gem 'bundler-audit', '>=0.9.3'
|
|
25
|
-
gem 'bunny', '3.
|
|
25
|
+
gem 'bunny', '3.3.0'
|
|
26
26
|
gem 'colorize', '1.1.0'
|
|
27
27
|
gem 'credit_card_validations', '9.0.0'
|
|
28
28
|
gem 'curses', '1.7.0'
|
|
@@ -77,7 +77,7 @@ gem 'rbvmomi2', '3.10.0'
|
|
|
77
77
|
gem 'rdoc', '7.0.4'
|
|
78
78
|
gem 'rest-client', '2.1.0'
|
|
79
79
|
gem 'rex', '2.0.13'
|
|
80
|
-
gem 'rmagick', '7.1.
|
|
80
|
+
gem 'rmagick', '7.1.3'
|
|
81
81
|
gem 'rqrcode', '3.2.0'
|
|
82
82
|
gem 'rspec', '3.13.2'
|
|
83
83
|
gem 'rtesseract', '3.1.4'
|
|
@@ -127,7 +127,7 @@ pwn setup --list-profiles
|
|
|
127
127
|
| `voice` | `PWN::Plugins::Voice` · `extro_voice` · espeak-ng / sox |
|
|
128
128
|
| `exploit` | `Metasploit` · `sqlmap` |
|
|
129
129
|
| `hardware` | `Serial` · `BusPirate` · `Android` · `BareSIP` · `extro_serial` · `extro_telecomm` |
|
|
130
|
-
| `re` | `Radare2` · `GDB` · `ExploitDev` · `Frida` · Android RE (`apktool`/`jadx`) |
|
|
130
|
+
| `re` | `Radare2` · `GDB` · `ExploitDev` · `Frida` · Android RE (`apktool`/`jadx`) · `pwndbg` · `ropper` · `rizin` |
|
|
131
131
|
| `full` | everything above |
|
|
132
132
|
|
|
133
133
|
### All flags
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exploitdev
|
|
3
|
+
description: "Exploit-dev SOP: packing, cyclic, ROP, one_gadget, libc offsets."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exploit development
|
|
7
|
+
|
|
8
|
+
Use `PWN::Plugins::ExploitDev` from `pwn_eval` — do not shell out to pwntools unless a plugin method is missing.
|
|
9
|
+
|
|
10
|
+
## Packing
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
PWN::Plugins::ExploitDev.p32(value: 0x41414141)
|
|
14
|
+
PWN::Plugins::ExploitDev.p64(value: addr, endian: :little)
|
|
15
|
+
PWN::Plugins::ExploitDev.flat(parts: [0xdeadbeef, "A" * 32, 0x401000])
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Cyclic
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
pattern = PWN::Plugins::ExploitDev.cyclic(length: 200)
|
|
22
|
+
offset = PWN::Plugins::ExploitDev.cyclic_find(value: "Aa0A", length: 200)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Shellcode / ROP
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
PWN::Plugins::ExploitDev.shellcode(arch: 'x86_64', kind: 'execve_bin_sh')
|
|
29
|
+
PWN::Plugins::ExploitDev.gadgets(path: '/path/to/binary')
|
|
30
|
+
PWN::Plugins::ExploitDev.one_gadget(path: '/lib/x86_64-linux-gnu/libc.so.6')
|
|
31
|
+
PWN::Plugins::ExploitDev.libc_offsets(path: '/lib/x86_64-linux-gnu/libc.so.6')
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Interactive
|
|
35
|
+
|
|
36
|
+
`PWN::Plugins::ProcessTube.spawn` or `.connect` then `write_line` / `recvuntil`.
|
|
37
|
+
`PWN::Plugins::GDB.run_to_crash` / `.breakpoints` / `.core`.
|
|
38
|
+
`PWN::Plugins::Radare2.open` then `cmd` (text) or `cmdj` (JSON).
|
|
@@ -38,9 +38,16 @@ PWN::Plugins::CredentialAttack.required_bins(opts)
|
|
|
38
38
|
- `hydra`
|
|
39
39
|
- `john`
|
|
40
40
|
- `hashcat`
|
|
41
|
+
- `medusa`
|
|
42
|
+
- `identify_hash`
|
|
43
|
+
- `fetch_seclists`
|
|
41
44
|
- `authors`
|
|
42
45
|
- `help`
|
|
43
46
|
|
|
47
|
+
## References
|
|
48
|
+
|
|
49
|
+
- `references/urls.md` — URLs from source
|
|
50
|
+
|
|
44
51
|
## Source
|
|
45
52
|
|
|
46
53
|
`pwn/plugins/credential_attack.rb`
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-exploitdb
|
|
3
|
+
description: Drive PWN::Plugins::ExploitDB from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::ExploitDB
|
|
10
|
+
source: pwn/plugins/exploit_db.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::ExploitDB
|
|
14
|
+
|
|
15
|
+
searchsploit / ExploitDB plus a CPE string builder for nmap versions.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::ExploitDB` 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/exploit_db.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::ExploitDB.help
|
|
31
|
+
PWN::Plugins::ExploitDB.required_bins(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `required_bins`
|
|
37
|
+
- `search`
|
|
38
|
+
- `cve_for_cpe`
|
|
39
|
+
- `authors`
|
|
40
|
+
- `help`
|
|
41
|
+
|
|
42
|
+
## Source
|
|
43
|
+
|
|
44
|
+
`pwn/plugins/exploit_db.rb`
|
|
45
|
+
|
|
46
|
+
## Verification
|
|
47
|
+
|
|
48
|
+
`PWN::Plugins::ExploitDB.respond_to?(:required_bins)` after the
|
|
49
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-k8s
|
|
3
|
+
description: Drive PWN::Plugins::K8s from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::K8s
|
|
10
|
+
source: pwn/plugins/k8s.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::K8s
|
|
14
|
+
|
|
15
|
+
trivy / kube-hunter wrappers plus docker-socket preflight.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::K8s` 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/k8s.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::K8s.help
|
|
31
|
+
PWN::Plugins::K8s.required_bins(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `required_bins`
|
|
37
|
+
- `trivy`
|
|
38
|
+
- `kube_hunter`
|
|
39
|
+
- `docker_socket`
|
|
40
|
+
- `authors`
|
|
41
|
+
- `help`
|
|
42
|
+
- `docker_socket?`
|
|
43
|
+
|
|
44
|
+
## Source
|
|
45
|
+
|
|
46
|
+
`pwn/plugins/k8s.rb`
|
|
47
|
+
|
|
48
|
+
## Verification
|
|
49
|
+
|
|
50
|
+
`PWN::Plugins::K8s.respond_to?(:required_bins)` after the
|
|
51
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: pwn-plugins-
|
|
3
|
-
description: Drive PWN::Plugins::
|
|
2
|
+
name: pwn-plugins-preflightchecker
|
|
3
|
+
description: Drive PWN::Plugins::PreflightChecker from pwn_eval.
|
|
4
4
|
license: MIT
|
|
5
5
|
allowed-tools: [pwn, pwn_eval]
|
|
6
6
|
metadata:
|
|
7
7
|
bundled: true
|
|
8
8
|
generated: true
|
|
9
|
-
module: PWN::Plugins::
|
|
10
|
-
source: pwn/plugins/
|
|
9
|
+
module: PWN::Plugins::PreflightChecker
|
|
10
|
+
source: pwn/plugins/preflight_checker.rb
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
# PWN::Plugins::
|
|
13
|
+
# PWN::Plugins::PreflightChecker
|
|
14
14
|
|
|
15
15
|
Plugin/binary/capability preflight. Plugins declare required_bins / required_caps; HOST summaries list degraded modules without autoloading the whole plugin tree.
|
|
16
16
|
|
|
17
17
|
## When to use
|
|
18
18
|
|
|
19
|
-
Call `PWN::Plugins::
|
|
19
|
+
Call `PWN::Plugins::PreflightChecker` from `pwn_eval` when the task needs this module.
|
|
20
20
|
Do not reimplement it in shell.
|
|
21
21
|
|
|
22
22
|
## Methodologies
|
|
23
23
|
|
|
24
|
-
Generated from `pwn/plugins/
|
|
24
|
+
Generated from `pwn/plugins/preflight_checker.rb`. Prefer the public class methods below.
|
|
25
25
|
Class methods take `(opts = {})` and read `opts`.
|
|
26
26
|
|
|
27
27
|
## How to call
|
|
28
28
|
|
|
29
29
|
```ruby
|
|
30
|
-
PWN::Plugins::
|
|
31
|
-
PWN::Plugins::
|
|
30
|
+
PWN::Plugins::PreflightChecker.help
|
|
31
|
+
PWN::Plugins::PreflightChecker.required_bins(opts)
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## Public methods
|
|
@@ -38,6 +38,7 @@ PWN::Plugins::Doctor.required_bins(opts)
|
|
|
38
38
|
- `require_bin`
|
|
39
39
|
- `cap_net_raw`
|
|
40
40
|
- `require_cap_net_raw`
|
|
41
|
+
- `service`
|
|
41
42
|
- `check`
|
|
42
43
|
- `host_summary`
|
|
43
44
|
- `authors`
|
|
@@ -46,12 +47,13 @@ PWN::Plugins::Doctor.required_bins(opts)
|
|
|
46
47
|
- `cap_net_raw?`
|
|
47
48
|
- `require_bin!`
|
|
48
49
|
- `require_cap_net_raw!`
|
|
50
|
+
- `service?`
|
|
49
51
|
|
|
50
52
|
## Source
|
|
51
53
|
|
|
52
|
-
`pwn/plugins/
|
|
54
|
+
`pwn/plugins/preflight_checker.rb`
|
|
53
55
|
|
|
54
56
|
## Verification
|
|
55
57
|
|
|
56
|
-
`PWN::Plugins::
|
|
58
|
+
`PWN::Plugins::PreflightChecker.respond_to?(:required_bins)` after the
|
|
57
59
|
module is loaded. Read the source for parameter names.
|
|
@@ -3,3 +3,4 @@
|
|
|
3
3
|
- https://api.certspotter.com/v1/issuances?domain=#{URI.encode_www_form_component(domain
|
|
4
4
|
- https://crt.sh/?q=#{URI.encode_www_form_component(domain
|
|
5
5
|
- https://crt.sh/?q=#{URI.encode_www_form_component(
|
|
6
|
+
- https://api.hackertarget.com/hostsearch/?q=#{URI.encode_www_form_component(domain
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-plugins-semgrep
|
|
3
|
+
description: Drive PWN::Plugins::Semgrep from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::Plugins::Semgrep
|
|
10
|
+
source: pwn/plugins/semgrep.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::Plugins::Semgrep
|
|
14
|
+
|
|
15
|
+
semgrep wrapper feeding SAST-shaped findings.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::Plugins::Semgrep` 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/semgrep.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::Semgrep.help
|
|
31
|
+
PWN::Plugins::Semgrep.required_bins(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `required_bins`
|
|
37
|
+
- `scan`
|
|
38
|
+
- `authors`
|
|
39
|
+
- `help`
|
|
40
|
+
|
|
41
|
+
## Source
|
|
42
|
+
|
|
43
|
+
`pwn/plugins/semgrep.rb`
|
|
44
|
+
|
|
45
|
+
## Verification
|
|
46
|
+
|
|
47
|
+
`PWN::Plugins::Semgrep.respond_to?(:required_bins)` after the
|
|
48
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -199,7 +199,7 @@ module PWN
|
|
|
199
199
|
eval_s = ToolGuard.deadline_s(kind: :eval) if defined?(ToolGuard)
|
|
200
200
|
shell_s = ToolGuard.deadline_s(kind: :shell) if defined?(ToolGuard)
|
|
201
201
|
load_line = "load1=#{snap[:load1]} ncpu=#{snap[:ncpu]} mem_avail_mb=#{snap[:mem_avail_mb]}"
|
|
202
|
-
doc = (PWN::Plugins::
|
|
202
|
+
doc = (PWN::Plugins::PreflightChecker.host_summary if defined?(PWN::Plugins::PreflightChecker))
|
|
203
203
|
"#{load_line} pwn_eval/shell timeout = conservative seconds for this host " \
|
|
204
204
|
"(defaults eval=#{eval_s || 20}s shell=#{shell_s || 30}s, clamped). " \
|
|
205
205
|
"#{doc}"
|
|
@@ -31,7 +31,14 @@ PWN::AI::Agent::Registry.register(
|
|
|
31
31
|
limit: args[:limit] || 12,
|
|
32
32
|
exclude_session_id: exclude,
|
|
33
33
|
include_current: args[:include_current] == true
|
|
34
|
-
)
|
|
34
|
+
).tap do |hits|
|
|
35
|
+
sid = exclude.to_s
|
|
36
|
+
next if sid.empty? || !defined?(PWN::Plugins::ArtifactRegistry)
|
|
37
|
+
|
|
38
|
+
artifacts = PWN::Plugins::ArtifactRegistry.list(session_id: sid)
|
|
39
|
+
hits[:artifacts] = artifacts if hits.is_a?(Hash)
|
|
40
|
+
hits << { artifacts: artifacts } if hits.is_a?(Array) && artifacts.any?
|
|
41
|
+
end
|
|
35
42
|
}
|
|
36
43
|
)
|
|
37
44
|
|
data/lib/pwn/ffi/stdio.rb
CHANGED
|
@@ -34,7 +34,9 @@ module PWN
|
|
|
34
34
|
# Display Usage for this Module
|
|
35
35
|
|
|
36
36
|
public_class_method def self.help
|
|
37
|
-
puts
|
|
37
|
+
# libc `puts` is attached on this module; use Kernel so $stdout capture
|
|
38
|
+
# (rspec help_contract) and the REPL both see Ruby IO, not fd 1 raw.
|
|
39
|
+
Kernel.puts "USAGE:
|
|
38
40
|
# Run available and return its result
|
|
39
41
|
#{self}.available?
|
|
40
42
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'open3'
|
|
4
|
+
require 'digest'
|
|
4
5
|
|
|
5
6
|
module PWN
|
|
6
7
|
module Plugins
|
|
@@ -11,7 +12,7 @@ module PWN
|
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
public_class_method def self.fuzz(opts = {})
|
|
14
|
-
PWN::Plugins::
|
|
15
|
+
PWN::Plugins::PreflightChecker.require_bin!(name: 'afl-fuzz')
|
|
15
16
|
in_dir = opts[:in_dir] || opts[:corpus]
|
|
16
17
|
out_dir = opts[:out_dir] || opts[:output]
|
|
17
18
|
target = opts[:target]
|
|
@@ -23,6 +24,19 @@ module PWN
|
|
|
23
24
|
{ stdout: stdout, stderr: stderr, exit: status.exitstatus }
|
|
24
25
|
end
|
|
25
26
|
|
|
27
|
+
public_class_method def self.crash_triage(opts = {})
|
|
28
|
+
out_dir = (opts[:out_dir] || opts[:output]).to_s
|
|
29
|
+
raise 'ERROR: out_dir is required' if out_dir.empty?
|
|
30
|
+
|
|
31
|
+
crashes = Dir[File.join(out_dir, '**/crashes/id:*')]
|
|
32
|
+
hashes = crashes.map { |p| [p, Digest::SHA256.file(p).hexdigest] }
|
|
33
|
+
{
|
|
34
|
+
crashes: crashes,
|
|
35
|
+
unique: hashes.map(&:last).uniq,
|
|
36
|
+
asan: crashes.any? { |p| File.binread(p).include?('AddressSanitizer') }
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
26
40
|
public_class_method def self.authors
|
|
27
41
|
"AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
|
|
28
42
|
end
|
|
@@ -42,6 +56,12 @@ module PWN
|
|
|
42
56
|
args: 'optional - Array args value consumed by #fuzz'
|
|
43
57
|
)
|
|
44
58
|
|
|
59
|
+
# Dedup AFL++ crash files by sha256 and note AddressSanitizer hits.
|
|
60
|
+
#{self}.crash_triage(
|
|
61
|
+
out_dir: 'required - AFL output directory containing crashes/',
|
|
62
|
+
output: 'optional - alias for out_dir'
|
|
63
|
+
)
|
|
64
|
+
|
|
45
65
|
# Print the AUTHOR(S) string for this module.
|
|
46
66
|
#{self}.authors
|
|
47
67
|
"
|
data/lib/pwn/plugins/android.rb
CHANGED
|
@@ -1286,16 +1286,22 @@ module PWN
|
|
|
1286
1286
|
decoded = File.join(out, 'apktool')
|
|
1287
1287
|
jadx_out = File.join(out, 'jadx')
|
|
1288
1288
|
steps = []
|
|
1289
|
-
if PWN::Plugins::
|
|
1289
|
+
if PWN::Plugins::PreflightChecker.bin?(name: 'apktool')
|
|
1290
1290
|
system('apktool', 'd', '-f', '-o', decoded, apk)
|
|
1291
1291
|
steps << :apktool
|
|
1292
1292
|
end
|
|
1293
|
-
if PWN::Plugins::
|
|
1293
|
+
if PWN::Plugins::PreflightChecker.bin?(name: 'jadx')
|
|
1294
1294
|
FileUtils.mkdir_p(jadx_out)
|
|
1295
1295
|
system('jadx', '-d', jadx_out, apk)
|
|
1296
1296
|
steps << :jadx
|
|
1297
1297
|
end
|
|
1298
|
-
|
|
1298
|
+
manifest = File.join(decoded, 'AndroidManifest.xml')
|
|
1299
|
+
perms = []
|
|
1300
|
+
if File.file?(manifest)
|
|
1301
|
+
txt = File.read(manifest)
|
|
1302
|
+
perms = txt.scan(/android:name="([^"]+)"/).flatten.grep(/PERMISSION|permission/)
|
|
1303
|
+
end
|
|
1304
|
+
{ out_dir: out, steps: steps, apk: apk, permissions: perms, manifest: (File.file?(manifest) ? manifest : nil) }
|
|
1299
1305
|
end
|
|
1300
1306
|
|
|
1301
1307
|
# Author(s):: 0day Inc. <support@0dayinc.com>
|
|
@@ -19,7 +19,7 @@ module PWN
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
public_class_method def self.hydra(opts = {})
|
|
22
|
-
PWN::Plugins::
|
|
22
|
+
PWN::Plugins::PreflightChecker.require_bin!(name: 'hydra')
|
|
23
23
|
target = opts[:target].to_s
|
|
24
24
|
service = (opts[:service] || 'ssh').to_s
|
|
25
25
|
user = opts[:user] || opts[:login]
|
|
@@ -33,7 +33,7 @@ module PWN
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
public_class_method def self.john(opts = {})
|
|
36
|
-
PWN::Plugins::
|
|
36
|
+
PWN::Plugins::PreflightChecker.require_bin!(name: 'john')
|
|
37
37
|
hashfile = opts[:hashfile] || opts[:file]
|
|
38
38
|
raise 'ERROR: hashfile is required' if hashfile.to_s.empty?
|
|
39
39
|
|
|
@@ -42,7 +42,7 @@ module PWN
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
public_class_method def self.hashcat(opts = {})
|
|
45
|
-
PWN::Plugins::
|
|
45
|
+
PWN::Plugins::PreflightChecker.require_bin!(name: 'hashcat')
|
|
46
46
|
hashfile = opts[:hashfile] || opts[:file]
|
|
47
47
|
mode = (opts[:mode] || 0).to_i
|
|
48
48
|
wordlist = opts[:wordlist] || File.join(WORDLISTS, 'rockyou.txt')
|
|
@@ -50,6 +50,45 @@ module PWN
|
|
|
50
50
|
{ stdout: stdout, stderr: stderr, exit: status.exitstatus }
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
public_class_method def self.medusa(opts = {})
|
|
54
|
+
PWN::Plugins::PreflightChecker.require_bin!(name: 'medusa')
|
|
55
|
+
target = opts[:target].to_s
|
|
56
|
+
raise 'ERROR: target is required' if target.empty?
|
|
57
|
+
|
|
58
|
+
cmd = ['medusa', '-h', target, '-u', (opts[:user] || 'root').to_s, '-P', (opts[:wordlist] || File.join(WORDLISTS, 'rockyou.txt')).to_s, '-M', (opts[:module] || 'ssh').to_s]
|
|
59
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
|
60
|
+
{ stdout: stdout, stderr: stderr, exit: status.exitstatus }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
public_class_method def self.identify_hash(opts = {})
|
|
64
|
+
sample = (opts[:hash] || opts[:sample]).to_s
|
|
65
|
+
raise 'ERROR: hash is required' if sample.empty?
|
|
66
|
+
|
|
67
|
+
if PWN::Plugins::PreflightChecker.bin?(name: 'hashid')
|
|
68
|
+
stdout, = Open3.capture3('hashid', sample)
|
|
69
|
+
return { hash: sample, tool: 'hashid', stdout: stdout }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
kind = case sample
|
|
73
|
+
when /\A\$2[aby]\$/ then 'bcrypt'
|
|
74
|
+
when /\A[a-f0-9]{32}\z/i then 'md5'
|
|
75
|
+
when /\A[a-f0-9]{40}\z/i then 'sha1'
|
|
76
|
+
when /\A[a-f0-9]{64}\z/i then 'sha256'
|
|
77
|
+
else 'unknown'
|
|
78
|
+
end
|
|
79
|
+
{ hash: sample, kind: kind }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
public_class_method def self.fetch_seclists(opts = {})
|
|
83
|
+
dest = (opts[:dest] || File.join(WORDLISTS, 'SecLists')).to_s
|
|
84
|
+
return dest if Dir.exist?(dest)
|
|
85
|
+
|
|
86
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
87
|
+
url = opts[:url] || 'https://github.com/danielmiessler/SecLists.git'
|
|
88
|
+
stdout, stderr, status = Open3.capture3('git', 'clone', '--depth', '1', url, dest)
|
|
89
|
+
{ dest: dest, stdout: stdout, stderr: stderr, exit: status.exitstatus }
|
|
90
|
+
end
|
|
91
|
+
|
|
53
92
|
public_class_method def self.authors
|
|
54
93
|
"AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
|
|
55
94
|
end
|
|
@@ -89,6 +128,26 @@ module PWN
|
|
|
89
128
|
wordlist: 'optional - wordlist value consumed by #hashcat'
|
|
90
129
|
)
|
|
91
130
|
|
|
131
|
+
# Run medusa against a host (lockout-aware: keep -t low).
|
|
132
|
+
#{self}.medusa(
|
|
133
|
+
target: 'required - hostname or IP',
|
|
134
|
+
user: 'optional - username (defaults to root)',
|
|
135
|
+
wordlist: 'optional - password list path',
|
|
136
|
+
module: 'optional - medusa module name (defaults to ssh)'
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Guess a hash type from a sample (hashid if present, else length heuristics).
|
|
140
|
+
#{self}.identify_hash(
|
|
141
|
+
hash: 'required - hash string to identify',
|
|
142
|
+
sample: 'optional - alias for hash'
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Clone SecLists into ~/.pwn/wordlists/SecLists when missing.
|
|
146
|
+
#{self}.fetch_seclists(
|
|
147
|
+
dest: 'optional - destination directory',
|
|
148
|
+
url: 'optional - git URL (defaults to danielmiessler/SecLists)'
|
|
149
|
+
)
|
|
150
|
+
|
|
92
151
|
# Print the AUTHOR(S) string for this module.
|
|
93
152
|
#{self}.authors
|
|
94
153
|
"
|