pwn 0.5.432 → 0.5.433

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d81ea28a631e0ee9113f3ddfeef28e8615744988fc4bbfff2a5a615a8929aac
4
- data.tar.gz: f367343802e440d04dba25f75d56c8f71e8ff208bf4f776d70b600f31ad12b26
3
+ metadata.gz: 387bbe4af26b617f25c04626d47edc3a6a939e7c377352a9e03e4036e61ff9b6
4
+ data.tar.gz: a498482eacaaf46d73f8af584fbfeda222f46089db1360f4dbb28fe83d4a198c
5
5
  SHA512:
6
- metadata.gz: daa53bfee771930fc864e0971957515769e14ba7a2911658fa37b89826a491debb2b49b077f2966415b1a4e44f8dd8cb832bd71718d0defb77698cb43b528a24
7
- data.tar.gz: ecd91103094b195aba6e12b94e8da3fa9b40422bbcc15089b6d0b193f77272ddcdc3e7fb43de2fe3fc5231be360f66781cfad24050b652007e966cc2bc189be9
6
+ metadata.gz: f656eb703bea4dc1bb679451d0b755c81007eddeda0c2a951f21a8f0bd093bad4edff86ebf17ccde1ec468f3f983c38aecbe6232ffc91448a28e8fa07b46d9b6
7
+ data.tar.gz: 5a70e26ea3e2c273e5d4a2edd62868799c9aa7dcfa4c8fb8e2f2cc43525234756ae020d63328fde508bf73940712eb828672d7f86bd29c46b3e2a809ce070527
data/Gemfile CHANGED
@@ -75,7 +75,7 @@ gem 'pry-doc', '1.6.0'
75
75
  gem 'rake', '13.3.0'
76
76
  gem 'rb-readline', '0.5.5'
77
77
  gem 'rbvmomi2', '3.8.0'
78
- gem 'rdoc', '6.14.2'
78
+ gem 'rdoc', '6.15.0'
79
79
  gem 'rest-client', '2.1.0'
80
80
  gem 'rex', '2.0.13'
81
81
  gem 'rmagick', '6.1.4'
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.432]:001 >>> PWN.help
40
+ pwn[v0.5.433]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](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.432]:001 >>> PWN.help
55
+ pwn[v0.5.433]: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.432]:001 >>> PWN.help
65
+ pwn[v0.5.433]: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-config=PATH', '<Optional - PWN YAML File>') do |p|
14
- opts[:pwn_config_path] = p
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-decryptor=PATH', '<Optional - Out-of-Band YAML File with :key && :iv>') do |d|
18
- opts[:pwn_decryptor_path] = d
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-config=PATH', '<Optional - PWN YAML File>') do |p|
16
- opts[:pwn_config_path] = p
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-decryptor=PATH', '<Optional - Out-of-Band YAML File with :key && :iv>') do |d|
20
- opts[:pwn_decryptor_path] = d
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
- pwn_config_path = opts[:pwn_config_path]
61
- pwn_decryptor_path = opts[:pwn_decryptor_path]
62
- if pwn_config_path
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
- pwn_config_path: pwn_config_path,
65
- pwn_decryptor_path: pwn_decryptor_path
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
@@ -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
@@ -6,6 +6,7 @@ module PWN
6
6
  # http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
7
7
  module AI
8
8
  autoload :Grok, 'pwn/ai/grok'
9
+ autoload :Introspection, 'pwn/ai/introspection'
9
10
  autoload :Ollama, 'pwn/ai/ollama'
10
11
  autoload :OpenAI, 'pwn/ai/open_ai'
11
12
 
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.refresh(
11
- # pwn_config_path: 'optional - Path to pwn.yaml file. Defaults to ~/.pwn/pwn.yaml',
12
- # pwn_decryptor_path: 'optional - Path to pwn.decryptor.yaml file. Defaults to ~/.pwn/pwn.decryptor.yaml'
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.refresh(opts = {})
16
- pwn_config_root = "#{Dir.home}/.pwn"
17
- FileUtils.mkdir_p(pwn_config_root)
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
- pwn_config_path = opts[:pwn_config_path] ||= "#{pwn_config_root}/pwn.yaml"
20
- return {} unless File.exist?(pwn_config_path)
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: pwn_config_path)
22
+ is_encrypted = PWN::Plugins::Vault.file_encrypted?(file: pwn_env_path)
23
23
 
24
24
  if is_encrypted
25
- pwn_decryptor_path = opts[:pwn_decryptor_path] ||= "#{pwn_config_root}/pwn.decryptor.yaml"
26
- raise "PWN Decryptor (#{pwn_decryptor_path}) does not exist!" unless File.exist?(pwn_decryptor_path)
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(pwn_decryptor_path, symbolize_names: true)
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
- config = PWN::Plugins::Vault.dump(
37
- file: pwn_config_path,
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
- config = YAML.load_file(pwn_config_path, symbolize_names: true)
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 = config[:ai][:active].to_s.downcase.to_sym
52
- raise "ERROR: Unsupported AI Engine: #{engine} in #{pwn_config_path}. Supported AI Engines:\n#{valid_ai_engines.inspect}" unless valid_ai_engines.include?(engine)
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
- model = config[:ai][engine][:model]
55
- system_role_content = config[:ai][engine][:system_role_content]
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 config refresh
58
- config[:ai][engine][:response_history] = {
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
- config[:pwn_config_path] = pwn_config_path
73
- config[:pwn_decryptor_path] = pwn_decryptor_path if is_encrypted
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, :CONFIG) if PWN.const_defined?(:CONFIG)
78
- PWN.const_set(:CONFIG, config)
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
@@ -18,7 +18,7 @@ module PWN
18
18
  mode = opts[:mode]
19
19
 
20
20
  proc do |_target_self, _nest_level, pi|
21
- pi.config.pwn = PWN::Config.refresh(opts) if Pry.config.refresh
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 = pi.config.pwn[:asm][:arch] ||= PWN::Plugins::DetectOS.arch
38
- endian = pi.config.pwn[:asm][:endian] ||= PWN::Plugins::DetectOS.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 = pi.config.pwn[:ai][:active].to_s.downcase.to_sym
48
- model = pi.config.pwn[:ai][engine][:model]
49
- system_role_content = pi.config.pwn[:ai][engine][:system_role_content]
50
- temp = pi.config.pwn[:ai][engine][: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 = pi.config.pwn[:irc][:shared_chan]
176
+ shared_chan = PWN::Env[:irc][:shared_chan]
177
177
  mem_chan = '#mem'
178
- ai_agents = pi.config.pwn[:irc][:ai_agent_nicks]
179
- ai_agents_arr = pi.config.pwn[:irc][:ai_agent_nicks].keys
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 = pi.config.pwn[:ai][:active].to_s.downcase.to_sym
306
- base_uri = pi.config.pwn[:ai][engine][:base_uri]
307
- key = pi.config.pwn[:ai][engine][:key] ||= ''
308
- temp = pi.config.pwn[:ai][engine][:temp]
309
- model = pi.config.pwn[:ai][engine][:model]
310
- system_role_content = pi.config.pwn[:ai][engine][: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 = pi.config.pwn[:irc][: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
- pwn_config_path = pi.config.pwn_config_path ||= "#{Dir.home}/.pwn/pwn.yaml"
464
- unless File.exist?(pwn_config_path)
465
- puts "ERROR: pwn.yaml not found: #{pwn_config_path}"
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
- pwn_decryptor_path = pi.config.pwn_decryptor_path ||= "#{Dir.home}/.pwn/pwn.decryptor.yaml"
470
- unless File.exist?(pwn_decryptor_path)
471
- puts "ERROR: pwn.decryptor.yaml not found: #{pwn_decryptor_path}"
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(pwn_decryptor_path, symbolize_names: true)
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: pwn_config_path,
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 = pi.config.pwn[:asm][:arch]
546
- endian = pi.config.pwn[:asm][: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 = pi.config.pwn[:ai][:active].to_s.downcase.to_sym
583
- base_uri = pi.config.pwn[:ai][engine][:base_uri]
584
- key = pi.config.pwn[:ai][engine][:key] ||= ''
585
- response_history = pi.config.pwn[:ai][engine][: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 = pi.config.pwn[:ai][engine][:model]
588
- system_role_content = pi.config.pwn[:ai][engine][:system_role_content]
589
- temp = pi.config.pwn[:ai][engine][: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
- pi.config.pwn[:ai][engine][:response_history] = response_history
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
- pwn_config_root = "#{Dir.home}/.pwn"
674
- Pry.config.history_file = "#{pwn_config_root}/pwn_history"
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)
@@ -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::CONFIG[:ai][:introspection]
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
- if ai_instrospection
70
- case engine
71
- when :grok
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.432'
4
+ VERSION = '0.5.433'
5
5
  end
data/lib/pwn.rb CHANGED
@@ -26,8 +26,8 @@ module PWN
26
26
  end
27
27
 
28
28
  # Initialize PWN configuration file
29
- # PWN::CONFIG is the constant that stores the configuration data
30
- PWN::Config.refresh
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
@@ -7,4 +7,14 @@ describe PWN::Config do
7
7
  config_response = PWN::Config.refresh
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.432
4
+ version: 0.5.433
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.14.2
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.14.2
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