pwn 0.5.432 → 0.5.434
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 +1 -1
- data/README.md +3 -3
- data/bin/pwn +4 -4
- data/bin/pwn_sast +9 -9
- data/lib/pwn/ai/grok.rb +0 -7
- data/lib/pwn/ai/introspection.rb +80 -0
- data/lib/pwn/ai/ollama.rb +0 -7
- data/lib/pwn/ai/open_ai.rb +0 -7
- data/lib/pwn/ai.rb +1 -0
- data/lib/pwn/config.rb +56 -25
- data/lib/pwn/plugins/repl.rb +38 -42
- data/lib/pwn/reports/sast.rb +5 -47
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +2 -2
- data/spec/lib/pwn/ai/introspection_spec.rb +15 -0
- data/spec/lib/pwn/config_spec.rb +11 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cdf2e676f8720fc916611068b8c6011fec4a8f655848ba3fe7eaba5370e4f75
|
4
|
+
data.tar.gz: 6f1505c1d3eb735da84c2033577638bc74aafd122d8909e817dd50313f83ebb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db901c38eddb0daa14ba19a0a370dcd174a809112bf24d76396af1cfedccb36886961176b813f32b2dcf4d839b283828aa7e7ddc91423d47e456d059808b85a4
|
7
|
+
data.tar.gz: 3e97e046c79229ff21390c782a2a3f9387c91d29682b047d8aeb0d354824b7e6c9662bc1481c80f6eb0e58b6fed5af274d7ffdce1f1651d74e09483abee8c408
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -37,7 +37,7 @@ $ cd /opt/pwn
|
|
37
37
|
$ ./install.sh
|
38
38
|
$ ./install.sh ruby-gem
|
39
39
|
$ pwn
|
40
|
-
pwn[v0.5.
|
40
|
+
pwn[v0.5.434]:001 >>> PWN.help
|
41
41
|
```
|
42
42
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
53
53
|
$ gem install --verbose pwn
|
54
54
|
$ pwn
|
55
|
-
pwn[v0.5.
|
55
|
+
pwn[v0.5.434]:001 >>> PWN.help
|
56
56
|
```
|
57
57
|
|
58
58
|
If you're using a multi-user install of RVM do:
|
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
62
62
|
$ rvmsudo gem uninstall --all --executables pwn
|
63
63
|
$ rvmsudo gem install --verbose pwn
|
64
64
|
$ pwn
|
65
|
-
pwn[v0.5.
|
65
|
+
pwn[v0.5.434]:001 >>> PWN.help
|
66
66
|
```
|
67
67
|
|
68
68
|
PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
|
data/bin/pwn
CHANGED
@@ -10,12 +10,12 @@ OptionParser.new do |options|
|
|
10
10
|
#{File.basename($PROGRAM_NAME)} [opts]
|
11
11
|
"
|
12
12
|
|
13
|
-
options.on('-YPATH', '--pwn-
|
14
|
-
opts[:
|
13
|
+
options.on('-YPATH', '--pwn-env=PATH', '<Optional - PWN YAML File>') do |p|
|
14
|
+
opts[:pwn_env_path] = p
|
15
15
|
end
|
16
16
|
|
17
|
-
options.on('-ZPATH', '--pwn-
|
18
|
-
opts[:
|
17
|
+
options.on('-ZPATH', '--pwn-dec=PATH', '<Optional - Out-of-Band YAML File with :key && :iv>') do |d|
|
18
|
+
opts[:pwn_dec_path] = d
|
19
19
|
end
|
20
20
|
end.parse!
|
21
21
|
|
data/bin/pwn_sast
CHANGED
@@ -12,12 +12,12 @@ OptionParser.new do |options|
|
|
12
12
|
"
|
13
13
|
|
14
14
|
# TODO: HOW TO LOAD THE pwn.yaml CONFIGURATION FILE FOR EVERYTHING UNLESS OVERRIDDEN???
|
15
|
-
options.on('-YPATH', '--pwn-
|
16
|
-
opts[:
|
15
|
+
options.on('-YPATH', '--pwn-env=PATH', '<Optional - PWN YAML File>') do |p|
|
16
|
+
opts[:pwn_env_path] = p
|
17
17
|
end
|
18
18
|
|
19
|
-
options.on('-ZPATH', '--pwn-
|
20
|
-
opts[:
|
19
|
+
options.on('-ZPATH', '--pwn-dec=PATH', '<Optional - Out-of-Band YAML File with :key && :iv>') do |d|
|
20
|
+
opts[:pwn_dec_path] = d
|
21
21
|
end
|
22
22
|
|
23
23
|
options.on('-uGITURI', '--uri-source-root=GITURI', '<Required - HTTP URI of Git Repo Scanned e.g. https://github.com/0dayInc/pwn/tree/master>') do |u|
|
@@ -57,12 +57,12 @@ end
|
|
57
57
|
begin
|
58
58
|
timestamp = Time.now.strftime('%Y-%m-%d_%H:%M:%S%z')
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
if
|
60
|
+
pwn_env_path = opts[:pwn_env_path]
|
61
|
+
pwn_dec_path = opts[:pwn_dec_path]
|
62
|
+
if pwn_env_path
|
63
63
|
PWN::Config.refresh(
|
64
|
-
|
65
|
-
|
64
|
+
pwn_env_path: pwn_env_path,
|
65
|
+
pwn_dec_path: pwn_dec_path
|
66
66
|
)
|
67
67
|
end
|
68
68
|
|
data/lib/pwn/ai/grok.rb
CHANGED
@@ -25,13 +25,6 @@ module PWN
|
|
25
25
|
|
26
26
|
private_class_method def self.grok_rest_call(opts = {})
|
27
27
|
token = opts[:token]
|
28
|
-
if token.nil?
|
29
|
-
PWN::Plugins::AuthenticationHelper.mask_password(
|
30
|
-
prompt: 'Grok Key'
|
31
|
-
)
|
32
|
-
PWN::CONFIG[:ai][:grok][:key] = token
|
33
|
-
end
|
34
|
-
|
35
28
|
http_method = if opts[:http_method].nil?
|
36
29
|
:get
|
37
30
|
else
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'rest-client'
|
5
|
+
require 'tty-spinner'
|
6
|
+
|
7
|
+
module PWN
|
8
|
+
module AI
|
9
|
+
# This plugin interacts with PWN::Env's `ai` data structure
|
10
|
+
# when `PWN::Env[:ai][:introspection]` is set to `true`.
|
11
|
+
module Introspection
|
12
|
+
# Supported Method Parameters::
|
13
|
+
# response = PWN::AI::Introspection.reflect
|
14
|
+
|
15
|
+
public_class_method def self.reflect
|
16
|
+
engine = PWN::Env[:ai][:active].to_s.downcase.to_sym
|
17
|
+
base_uri = PWN::Env[:ai][engine][:base_uri]
|
18
|
+
model = PWN::Env[:ai][engine][:model]
|
19
|
+
key = PWN::Env[:ai][engine][:key]
|
20
|
+
system_role_content = PWN::Env[:ai][engine][:system_role_content]
|
21
|
+
temp = PWN::Env[:ai][engine][:temp]
|
22
|
+
|
23
|
+
case engine
|
24
|
+
when :grok
|
25
|
+
response = PWN::AI::Grok.chat(
|
26
|
+
base_uri: base_uri,
|
27
|
+
token: key,
|
28
|
+
model: model,
|
29
|
+
system_role_content: system_role_content,
|
30
|
+
temp: temp,
|
31
|
+
request: request.chomp,
|
32
|
+
spinner: false
|
33
|
+
)
|
34
|
+
when :ollama
|
35
|
+
response = PWN::AI::Ollama.chat(
|
36
|
+
base_uri: base_uri,
|
37
|
+
token: key,
|
38
|
+
model: model,
|
39
|
+
system_role_content: system_role_content,
|
40
|
+
temp: temp,
|
41
|
+
request: request.chomp,
|
42
|
+
spinner: false
|
43
|
+
)
|
44
|
+
when :openai
|
45
|
+
response = PWN::AI::OpenAI.chat(
|
46
|
+
base_uri: base_uri,
|
47
|
+
token: key,
|
48
|
+
model: model,
|
49
|
+
system_role_content: system_role_content,
|
50
|
+
temp: temp,
|
51
|
+
request: request.chomp,
|
52
|
+
spinner: false
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
response
|
57
|
+
rescue StandardError => e
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
|
61
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
62
|
+
|
63
|
+
public_class_method def self.authors
|
64
|
+
"AUTHOR(S):
|
65
|
+
0day Inc. <support@0dayinc.com>
|
66
|
+
"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Display Usage for this Module
|
70
|
+
|
71
|
+
public_class_method def self.help
|
72
|
+
puts "USAGE:
|
73
|
+
#{self}.reflect
|
74
|
+
|
75
|
+
#{self}.authors
|
76
|
+
"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/pwn/ai/ollama.rb
CHANGED
@@ -27,13 +27,6 @@ module PWN
|
|
27
27
|
private_class_method def self.ollama_rest_call(opts = {})
|
28
28
|
base_uri = opts[:base_uri]
|
29
29
|
token = opts[:token]
|
30
|
-
if token.nil?
|
31
|
-
PWN::Plugins::AuthenticationHelper.mask_password(
|
32
|
-
prompt: 'Ollama Key'
|
33
|
-
)
|
34
|
-
PWN::CONFIG[:ai][:ollama][:key] = token
|
35
|
-
end
|
36
|
-
|
37
30
|
http_method = if opts[:http_method].nil?
|
38
31
|
:get
|
39
32
|
else
|
data/lib/pwn/ai/open_ai.rb
CHANGED
@@ -26,13 +26,6 @@ module PWN
|
|
26
26
|
|
27
27
|
private_class_method def self.open_ai_rest_call(opts = {})
|
28
28
|
token = opts[:token]
|
29
|
-
if token.nil?
|
30
|
-
PWN::Plugins::AuthenticationHelper.mask_password(
|
31
|
-
prompt: 'OpenAI Key'
|
32
|
-
)
|
33
|
-
PWN::CONFIG[:ai][:openai][:key] = token
|
34
|
-
end
|
35
|
-
|
36
29
|
http_method = if opts[:http_method].nil?
|
37
30
|
:get
|
38
31
|
else
|
data/lib/pwn/ai.rb
CHANGED
data/lib/pwn/config.rb
CHANGED
@@ -7,25 +7,25 @@ module PWN
|
|
7
7
|
# Used to manage PWN configuration settings within PWN drivers.
|
8
8
|
module Config
|
9
9
|
# Supported Method Parameters::
|
10
|
-
# PWN::Config.
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# PWN::Config.refresh_env(
|
11
|
+
# pwn_env_path: 'optional - Path to pwn.yaml file. Defaults to ~/.pwn/pwn.yaml',
|
12
|
+
# pwn_dec_path: 'optional - Path to pwn.decryptor.yaml file. Defaults to ~/.pwn/pwn.decryptor.yaml'
|
13
13
|
# )
|
14
14
|
|
15
|
-
public_class_method def self.
|
16
|
-
|
17
|
-
FileUtils.mkdir_p(
|
15
|
+
public_class_method def self.refresh_env(opts = {})
|
16
|
+
pwn_env_root = "#{Dir.home}/.pwn"
|
17
|
+
FileUtils.mkdir_p(pwn_env_root)
|
18
18
|
|
19
|
-
|
20
|
-
return {} unless File.exist?(
|
19
|
+
pwn_env_path = opts[:pwn_env_path] ||= "#{pwn_env_root}/pwn.yaml"
|
20
|
+
return {} unless File.exist?(pwn_env_path)
|
21
21
|
|
22
|
-
is_encrypted = PWN::Plugins::Vault.file_encrypted?(file:
|
22
|
+
is_encrypted = PWN::Plugins::Vault.file_encrypted?(file: pwn_env_path)
|
23
23
|
|
24
24
|
if is_encrypted
|
25
|
-
|
26
|
-
raise "PWN Decryptor (#{
|
25
|
+
pwn_dec_path = opts[:pwn_dec_path] ||= "#{pwn_env_root}/pwn.decryptor.yaml"
|
26
|
+
raise "PWN Decryptor (#{pwn_dec_path}) does not exist!" unless File.exist?(pwn_dec_path)
|
27
27
|
|
28
|
-
pwn_decryptor = YAML.load_file(
|
28
|
+
pwn_decryptor = YAML.load_file(pwn_dec_path, symbolize_names: true)
|
29
29
|
|
30
30
|
key = opts[:key] ||= pwn_decryptor[:key] ||= ENV.fetch('PWN_DECRYPTOR_KEY')
|
31
31
|
key = PWN::Plugins::AuthenticationHelper.mask_password(prompt: 'Decryption Key') if key.nil?
|
@@ -33,13 +33,13 @@ module PWN
|
|
33
33
|
iv = opts[:iv] ||= pwn_decryptor[:iv] ||= ENV.fetch('PWN_DECRYPTOR_IV')
|
34
34
|
iv = PWN::Plugins::AuthenticationHelper.mask_password(prompt: 'Decryption IV') if iv.nil?
|
35
35
|
|
36
|
-
|
37
|
-
file:
|
36
|
+
env = PWN::Plugins::Vault.dump(
|
37
|
+
file: pwn_env_path,
|
38
38
|
key: key,
|
39
39
|
iv: iv
|
40
40
|
)
|
41
41
|
else
|
42
|
-
|
42
|
+
env = YAML.load_file(pwn_env_path, symbolize_names: true)
|
43
43
|
end
|
44
44
|
|
45
45
|
valid_ai_engines = %i[
|
@@ -48,14 +48,22 @@ module PWN
|
|
48
48
|
ollama
|
49
49
|
]
|
50
50
|
|
51
|
-
engine =
|
52
|
-
raise "ERROR: Unsupported AI Engine: #{engine} in #{
|
51
|
+
engine = env[:ai][:active].to_s.downcase.to_sym
|
52
|
+
raise "ERROR: Unsupported AI Engine: #{engine} in #{pwn_env_path}. Supported AI Engines:\n#{valid_ai_engines.inspect}" unless valid_ai_engines.include?(engine)
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
key = env[:ai][engine][:key]
|
55
|
+
if key.nil?
|
56
|
+
key = PWN::Plugins::AuthenticationHelper.mask_password(
|
57
|
+
prompt: "#{engine} API Key"
|
58
|
+
)
|
59
|
+
env[:ai][engine][:key] = key
|
60
|
+
end
|
61
|
+
|
62
|
+
model = env[:ai][engine][:model]
|
63
|
+
system_role_content = env[:ai][engine][:system_role_content]
|
56
64
|
|
57
|
-
# Reset the ai response history on
|
58
|
-
|
65
|
+
# Reset the ai response history on env refresh
|
66
|
+
env[:ai][engine][:response_history] = {
|
59
67
|
id: '',
|
60
68
|
object: '',
|
61
69
|
model: model,
|
@@ -69,13 +77,36 @@ module PWN
|
|
69
77
|
}
|
70
78
|
|
71
79
|
# These two lines should be immutable for the session
|
72
|
-
|
73
|
-
|
80
|
+
env[:pwn_env_path] = pwn_env_path
|
81
|
+
env[:pwn_dec_path] = pwn_dec_path if is_encrypted
|
74
82
|
|
75
83
|
Pry.config.refresh = false if defined?(Pry)
|
76
84
|
|
77
|
-
PWN.send(:remove_const, :
|
78
|
-
PWN.const_set(:
|
85
|
+
PWN.send(:remove_const, :Env) if PWN.const_defined?(:Env)
|
86
|
+
PWN.const_set(:Env, env.freeze)
|
87
|
+
rescue StandardError => e
|
88
|
+
raise e
|
89
|
+
end
|
90
|
+
|
91
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
92
|
+
|
93
|
+
public_class_method def self.authors
|
94
|
+
"AUTHOR(S):
|
95
|
+
0day Inc. <support@0dayinc.com>
|
96
|
+
"
|
97
|
+
end
|
98
|
+
|
99
|
+
# Display Usage for this Module
|
100
|
+
|
101
|
+
public_class_method def self.help
|
102
|
+
puts "USAGE:
|
103
|
+
#{self}.refresh_env(
|
104
|
+
pwn_env_path: 'optional - Path to pwn.yaml file. Defaults to ~/.pwn/pwn.yaml',
|
105
|
+
pwn_dec_path: 'optional - Path to pwn.decryptor.yaml file. Defaults to ~/.pwn/pwn.decryptor.yaml'
|
106
|
+
)
|
107
|
+
|
108
|
+
#{self}.authors
|
109
|
+
"
|
79
110
|
end
|
80
111
|
end
|
81
112
|
end
|
data/lib/pwn/plugins/repl.rb
CHANGED
@@ -18,7 +18,7 @@ module PWN
|
|
18
18
|
mode = opts[:mode]
|
19
19
|
|
20
20
|
proc do |_target_self, _nest_level, pi|
|
21
|
-
|
21
|
+
PWN::Config.refresh_env(opts) if Pry.config.refresh
|
22
22
|
|
23
23
|
pi.config.pwn_repl_line += 1
|
24
24
|
line_pad = format(
|
@@ -34,8 +34,8 @@ module PWN
|
|
34
34
|
dchars = "\001\e[33m\002***\001\e[0m\002" if mode == :splat
|
35
35
|
|
36
36
|
if pi.config.pwn_asm
|
37
|
-
arch =
|
38
|
-
endian =
|
37
|
+
arch = PWN::Env[:asm][:arch] ||= PWN::Plugins::DetectOS.arch
|
38
|
+
endian = PWN::Env[:asm][:endian] ||= PWN::Plugins::DetectOS.endian
|
39
39
|
|
40
40
|
pi.config.prompt_name = "pwn.asm:#{arch}/#{endian}"
|
41
41
|
name = "\001\e[1m\002\001\e[37m\002#{pi.config.prompt_name}\001\e[0m\002"
|
@@ -44,10 +44,10 @@ module PWN
|
|
44
44
|
end
|
45
45
|
|
46
46
|
if pi.config.pwn_ai
|
47
|
-
engine =
|
48
|
-
model =
|
49
|
-
system_role_content =
|
50
|
-
temp =
|
47
|
+
engine = PWN::Env[:ai][:active].to_s.downcase.to_sym
|
48
|
+
model = PWN::Env[:ai][engine][:model]
|
49
|
+
system_role_content = PWN::Env[:ai][engine][:system_role_content]
|
50
|
+
temp = PWN::Env[:ai][engine][:temp]
|
51
51
|
pname = "pwn.ai:#{engine}"
|
52
52
|
pname = "pwn.ai:#{engine}/#{model}" if model
|
53
53
|
pname = "pwn.ai:#{engine}/#{model}.SPEAK" if pi.config.pwn_ai_speak
|
@@ -173,10 +173,10 @@ module PWN
|
|
173
173
|
|
174
174
|
reply = nil
|
175
175
|
response_history = nil
|
176
|
-
shared_chan =
|
176
|
+
shared_chan = PWN::Env[:irc][:shared_chan]
|
177
177
|
mem_chan = '#mem'
|
178
|
-
ai_agents =
|
179
|
-
ai_agents_arr =
|
178
|
+
ai_agents = PWN::Env[:irc][:ai_agent_nicks]
|
179
|
+
ai_agents_arr = PWN::Env[:irc][:ai_agent_nicks].keys
|
180
180
|
total_ai_agents = ai_agents_arr.length
|
181
181
|
mutex = Mutex.new
|
182
182
|
PWN::Plugins::ThreadPool.fill(
|
@@ -302,12 +302,12 @@ module PWN
|
|
302
302
|
next unless dm_agent == nick
|
303
303
|
|
304
304
|
response_history = ai_agents[dm_agent.to_sym][:response_history]
|
305
|
-
engine =
|
306
|
-
base_uri =
|
307
|
-
key =
|
308
|
-
temp =
|
309
|
-
model =
|
310
|
-
system_role_content =
|
305
|
+
engine = PWN::Env[:ai][:active].to_s.downcase.to_sym
|
306
|
+
base_uri = PWN::Env[:ai][engine][:base_uri]
|
307
|
+
key = PWN::Env[:ai][engine][:key] ||= ''
|
308
|
+
temp = PWN::Env[:ai][engine][:temp]
|
309
|
+
model = PWN::Env[:ai][engine][:model]
|
310
|
+
system_role_content = PWN::Env[:ai][engine][:system_role_content]
|
311
311
|
|
312
312
|
users_in_chan = PWN::Plugins::IRC.names(
|
313
313
|
irc_obj: irc_obj,
|
@@ -431,7 +431,7 @@ module PWN
|
|
431
431
|
|
432
432
|
# TODO: Use TLS for IRC Connections
|
433
433
|
# Use an IRC nCurses CLI Client
|
434
|
-
ui_nick =
|
434
|
+
ui_nick = PWN::Env[:irc][:ui_nick]
|
435
435
|
join_channels = ai_agents_arr.map { |ai_chan| "##{ai_chan}" }.join(',')
|
436
436
|
|
437
437
|
cmd0 = "/server add pwn #{host}/#{port} -notls"
|
@@ -460,24 +460,24 @@ module PWN
|
|
460
460
|
|
461
461
|
def process
|
462
462
|
pi = pry_instance
|
463
|
-
|
464
|
-
unless File.exist?(
|
465
|
-
puts "ERROR: pwn
|
463
|
+
pwn_env_path = PWN::Env[:pwn_env_path] ||= "#{Dir.home}/.pwn/pwn.yaml"
|
464
|
+
unless File.exist?(pwn_env_path)
|
465
|
+
puts "ERROR: pwn environment file not found: #{pwn_env_path}"
|
466
466
|
return
|
467
467
|
end
|
468
468
|
|
469
|
-
|
470
|
-
unless File.exist?(
|
471
|
-
puts "ERROR: pwn
|
469
|
+
pwn_dec_path = PWN::Env[:pwn_dec_path] ||= "#{Dir.home}/.pwn/pwn.decryptor.yaml"
|
470
|
+
unless File.exist?(pwn_dec_path)
|
471
|
+
puts "ERROR: pwn decryptor file not found: #{pwn_dec_path}"
|
472
472
|
return
|
473
473
|
end
|
474
474
|
|
475
|
-
decryptor = YAML.load_file(
|
475
|
+
decryptor = YAML.load_file(pwn_dec_path, symbolize_names: true)
|
476
476
|
key = decryptor[:key]
|
477
477
|
iv = decryptor[:iv]
|
478
478
|
|
479
479
|
PWN::Plugins::Vault.edit(
|
480
|
-
file:
|
480
|
+
file: pwn_env_path,
|
481
481
|
key: key,
|
482
482
|
iv: iv
|
483
483
|
)
|
@@ -530,20 +530,16 @@ module PWN
|
|
530
530
|
# Define REPL Hooks
|
531
531
|
# Welcome Banner Hook
|
532
532
|
Pry.config.hooks.add_hook(:before_session, :welcome) do |output, _binding, _pi|
|
533
|
+
PWN::Config.refresh_env(opts)
|
533
534
|
output.puts PWN::Banner.welcome
|
534
535
|
end
|
535
536
|
|
536
|
-
# Initialize pwn.yaml Configuration using :before_session Hook
|
537
|
-
Pry.config.hooks.add_hook(:before_session, :init_opts) do |_output, _binding, pi|
|
538
|
-
pi.config.pwn = PWN::Config.refresh(opts)
|
539
|
-
end
|
540
|
-
|
541
537
|
Pry.config.hooks.add_hook(:after_read, :pwn_asm_hook) do |request, pi|
|
542
538
|
if pi.config.pwn_asm && !request.chomp.empty?
|
543
539
|
request = pi.input.line_buffer
|
544
540
|
|
545
|
-
arch =
|
546
|
-
endian =
|
541
|
+
arch = PWN::Env[:asm][:arch]
|
542
|
+
endian = PWN::Env[:asm][:endian]
|
547
543
|
|
548
544
|
# Analyze request to determine if it should be processed as opcodes or asm.
|
549
545
|
straight_hex = /^[a-fA-F0-9\s]+$/
|
@@ -579,14 +575,14 @@ module PWN
|
|
579
575
|
if pi.config.pwn_ai && !request.chomp.empty?
|
580
576
|
request = pi.input.line_buffer.to_s
|
581
577
|
debug = pi.config.pwn_ai_debug
|
582
|
-
engine =
|
583
|
-
base_uri =
|
584
|
-
key =
|
585
|
-
response_history =
|
578
|
+
engine = PWN::Env[:ai][:active].to_s.downcase.to_sym
|
579
|
+
base_uri = PWN::Env[:ai][engine][:base_uri]
|
580
|
+
key = PWN::Env[:ai][engine][:key] ||= ''
|
581
|
+
response_history = PWN::Env[:ai][engine][:response_history]
|
586
582
|
speak_answer = pi.config.pwn_ai_speak
|
587
|
-
model =
|
588
|
-
system_role_content =
|
589
|
-
temp =
|
583
|
+
model = PWN::Env[:ai][engine][:model]
|
584
|
+
system_role_content = PWN::Env[:ai][engine][:system_role_content]
|
585
|
+
temp = PWN::Env[:ai][engine][:temp]
|
590
586
|
|
591
587
|
case engine
|
592
588
|
when :grok
|
@@ -655,7 +651,7 @@ module PWN
|
|
655
651
|
pp response_history
|
656
652
|
puts "\nresponse_history[:choices] Length: #{response_history[:choices].length}\n" unless response_history.nil?
|
657
653
|
end
|
658
|
-
|
654
|
+
PWN::Env[:ai][engine][:response_history] = response_history
|
659
655
|
end
|
660
656
|
end
|
661
657
|
rescue StandardError => e
|
@@ -670,8 +666,8 @@ module PWN
|
|
670
666
|
public_class_method def self.start(opts = {})
|
671
667
|
# Monkey Patch Pry, add commands, && hooks
|
672
668
|
PWN::Plugins::MonkeyPatch.pry
|
673
|
-
|
674
|
-
Pry.config.history_file = "#{
|
669
|
+
pwn_env_root = "#{Dir.home}/.pwn"
|
670
|
+
Pry.config.history_file = "#{pwn_env_root}/pwn_history"
|
675
671
|
|
676
672
|
add_commands
|
677
673
|
add_hooks(opts)
|
data/lib/pwn/reports/sast.rb
CHANGED
@@ -25,17 +25,8 @@ module PWN
|
|
25
25
|
}
|
26
26
|
report_name = opts[:report_name] ||= File.basename(Dir.pwd)
|
27
27
|
|
28
|
-
ai_instrospection = PWN::
|
29
|
-
if ai_instrospection
|
30
|
-
engine = PWN::CONFIG[:ai][:active].to_s.downcase.to_sym
|
31
|
-
base_uri = PWN::CONFIG[:ai][engine][:base_uri]
|
32
|
-
model = PWN::CONFIG[:ai][engine][:model]
|
33
|
-
key = PWN::CONFIG[:ai][engine][:key]
|
34
|
-
system_role_content = PWN::CONFIG[:ai][engine][:system_role_content]
|
35
|
-
temp = PWN::CONFIG[:ai][engine][:temp]
|
36
|
-
|
37
|
-
puts "Analyzing source code using AI engine: #{engine}\nModel: #{model}\nSystem Role Content: #{system_role_content}\nTemperature: #{temp}"
|
38
|
-
end
|
28
|
+
ai_instrospection = PWN::Env[:ai][:introspection]
|
29
|
+
puts "Analyzing source code using AI engine: #{engine}\nModel: #{model}\nSystem Role Content: #{system_role_content}\nTemperature: #{temp}" if ai_instrospection
|
39
30
|
|
40
31
|
# Calculate percentage of AI analysis based on the number of entries
|
41
32
|
total_entries = results_hash[:data].sum { |entry| entry[:line_no_and_contents].size }
|
@@ -63,44 +54,11 @@ module PWN
|
|
63
54
|
line: line_no,
|
64
55
|
source_code_snippet: source_code_snippet
|
65
56
|
}.to_json
|
66
|
-
response = nil
|
67
57
|
author = src_detail[:author].to_s.scrub.chomp.strip
|
68
58
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
response = PWN::AI::Grok.chat(
|
73
|
-
base_uri: base_uri,
|
74
|
-
token: key,
|
75
|
-
model: model,
|
76
|
-
system_role_content: system_role_content,
|
77
|
-
temp: temp,
|
78
|
-
request: request.chomp,
|
79
|
-
spinner: false
|
80
|
-
)
|
81
|
-
when :ollama
|
82
|
-
response = PWN::AI::Ollama.chat(
|
83
|
-
base_uri: base_uri,
|
84
|
-
token: key,
|
85
|
-
model: model,
|
86
|
-
system_role_content: system_role_content,
|
87
|
-
temp: temp,
|
88
|
-
request: request.chomp,
|
89
|
-
spinner: false
|
90
|
-
)
|
91
|
-
when :openai
|
92
|
-
response = PWN::AI::OpenAI.chat(
|
93
|
-
base_uri: base_uri,
|
94
|
-
token: key,
|
95
|
-
model: model,
|
96
|
-
system_role_content: system_role_content,
|
97
|
-
temp: temp,
|
98
|
-
request: request.chomp,
|
99
|
-
spinner: false
|
100
|
-
)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
59
|
+
# TODO: move PWN::AI::Introspection.reflect into each PWN::SAST::* module
|
60
|
+
# This will drastically speed up the overall SAST analysis process
|
61
|
+
response = PWN::AI::Introspection.reflect if ai_instrospection
|
104
62
|
ai_analysis = nil
|
105
63
|
if response.is_a?(Hash)
|
106
64
|
ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
|
data/lib/pwn/version.rb
CHANGED
data/lib/pwn.rb
CHANGED
@@ -26,8 +26,8 @@ module PWN
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Initialize PWN configuration file
|
29
|
-
# PWN::
|
30
|
-
PWN::Config.
|
29
|
+
# PWN::Env is the constant that stores the configuration data
|
30
|
+
PWN::Config.refresh_env
|
31
31
|
rescue StandardError => e
|
32
32
|
puts e.backtrace
|
33
33
|
raise e
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe PWN::AI::Introspection do
|
6
|
+
it 'should display information for authors' do
|
7
|
+
authors_response = PWN::AI::Introspection
|
8
|
+
expect(authors_response).to respond_to :authors
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should display information for existing help method' do
|
12
|
+
help_response = PWN::AI::Introspection
|
13
|
+
expect(help_response).to respond_to :help
|
14
|
+
end
|
15
|
+
end
|
data/spec/lib/pwn/config_spec.rb
CHANGED
@@ -4,7 +4,17 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe PWN::Config do
|
6
6
|
it 'should return data for refresh method' do
|
7
|
-
config_response = PWN::Config.
|
7
|
+
config_response = PWN::Config.refresh_env
|
8
8
|
expect(config_response).not_to be_nil
|
9
9
|
end
|
10
|
+
|
11
|
+
it 'should display information for authors' do
|
12
|
+
authors_response = PWN::Config
|
13
|
+
expect(authors_response).to respond_to :authors
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should display information for existing help method' do
|
17
|
+
help_response = PWN::Config
|
18
|
+
expect(help_response).to respond_to :help
|
19
|
+
end
|
10
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.434
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
@@ -841,14 +841,14 @@ dependencies:
|
|
841
841
|
requirements:
|
842
842
|
- - '='
|
843
843
|
- !ruby/object:Gem::Version
|
844
|
-
version: 6.
|
844
|
+
version: 6.15.0
|
845
845
|
type: :development
|
846
846
|
prerelease: false
|
847
847
|
version_requirements: !ruby/object:Gem::Requirement
|
848
848
|
requirements:
|
849
849
|
- - '='
|
850
850
|
- !ruby/object:Gem::Version
|
851
|
-
version: 6.
|
851
|
+
version: 6.15.0
|
852
852
|
- !ruby/object:Gem::Dependency
|
853
853
|
name: rest-client
|
854
854
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1720,6 +1720,7 @@ files:
|
|
1720
1720
|
- lib/pwn.rb
|
1721
1721
|
- lib/pwn/ai.rb
|
1722
1722
|
- lib/pwn/ai/grok.rb
|
1723
|
+
- lib/pwn/ai/introspection.rb
|
1723
1724
|
- lib/pwn/ai/ollama.rb
|
1724
1725
|
- lib/pwn/ai/open_ai.rb
|
1725
1726
|
- lib/pwn/aws.rb
|
@@ -2068,6 +2069,7 @@ files:
|
|
2068
2069
|
- pwn.gemspec
|
2069
2070
|
- reinstall_pwn_gemset.sh
|
2070
2071
|
- spec/lib/pwn/ai/grok_spec.rb
|
2072
|
+
- spec/lib/pwn/ai/introspection_spec.rb
|
2071
2073
|
- spec/lib/pwn/ai/ollama_spec.rb
|
2072
2074
|
- spec/lib/pwn/ai/open_ai_spec.rb
|
2073
2075
|
- spec/lib/pwn/ai_spec.rb
|