pwn 0.5.426 → 0.5.428

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: d6bbdb81c1c0df4969edc99d219a625265fa48d5af722628a2a77d3ead2741cb
4
- data.tar.gz: 68e09e473021b7b574074f737c066e06cc0276171eb74f99f9c8495f34a8825d
3
+ metadata.gz: cb4a896d76b2eff5600f7e7464227b6223a4287e4cd4e6fba7a60df29d40bc64
4
+ data.tar.gz: 93dbd97045e6ac60c4a46446bb8c681629ab462186092657e4f75bdb975eb7c9
5
5
  SHA512:
6
- metadata.gz: 3e279405371694e5d6c602a869662fab95ebdd18f7b207734a6023a4c0d2d98a3ddf903f03f150d966c14fbb02a7e9dda36ad8eef77850eacebf870179c5ff56
7
- data.tar.gz: e832fd158b5427c267e6240d8c7473d766ce1a9fdc53c5ff3353e08933cc4f3c2e2cc45a93f6b270092d6b38e1ccacc2d4a437fdc7983c201c71cb68dcc978d5
6
+ metadata.gz: 50aaa55f8d403788d10610c52a877bc99494678c0606b9d83fcdf623470faae899bfa6e095e0de4114832575184308d5a9303d0b5f1f15d0038f3e13b5c9e1b1
7
+ data.tar.gz: fdc901980719c87ac59a14e247f352074271ed8b43572bdbd446462fb621e772db5cb065c117c07b55c68caee5bd559094e536c5316c958af8fcab1f5f7ad602
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.426]:001 >>> PWN.help
40
+ pwn[v0.5.428]: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.426]:001 >>> PWN.help
55
+ pwn[v0.5.428]: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.426]:001 >>> PWN.help
65
+ pwn[v0.5.428]: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:
@@ -18,7 +18,11 @@ module PWN
18
18
  mode = opts[:mode]
19
19
 
20
20
  proc do |_target_self, _nest_level, pi|
21
- PWN::Plugins::Vault.refresh_config_for_repl(opts) if Pry.config.refresh_config
21
+ if Pry.config.refresh
22
+ # puts "Refreshing PWN env via #{opts[:yaml_config_path]}"
23
+ opts[:pi] = pi
24
+ PWN::Plugins::Vault.refresh_config_for_repl(opts)
25
+ end
22
26
 
23
27
  pi.config.pwn_repl_line += 1
24
28
  line_pad = format(
@@ -34,8 +38,8 @@ module PWN
34
38
  dchars = "\001\e[33m\002***\001\e[0m\002" if mode == :splat
35
39
 
36
40
  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
41
+ arch = pi.config.pwn[:asm][:arch] ||= PWN::Plugins::DetectOS.arch
42
+ endian = pi.config.pwn[:asm][:endian] ||= PWN::Plugins::DetectOS.endian
39
43
 
40
44
  pi.config.prompt_name = "pwn.asm:#{arch}/#{endian}"
41
45
  name = "\001\e[1m\002\001\e[37m\002#{pi.config.prompt_name}\001\e[0m\002"
@@ -44,10 +48,10 @@ module PWN
44
48
  end
45
49
 
46
50
  if pi.config.pwn_ai
47
- ai_engine = pi.config.pwn_ai_engine
48
- model = pi.config.pwn_ai_model
49
- system_role_content = pi.config.pwn_ai_system_role_content
50
- temp = pi.config.pwn_ai_temp
51
+ ai_engine = pi.config.pwn[:ai_engine]
52
+ model = pi.config.pwn[ai_engine][:model]
53
+ system_role_content = pi.config.pwn[ai_engine][:system_role_content]
54
+ temp = pi.config.pwn[ai_engine][:temp]
51
55
  pname = "pwn.ai:#{ai_engine}"
52
56
  pname = "pwn.ai:#{ai_engine}/#{model}" if model
53
57
  pname = "pwn.ai:#{ai_engine}/#{model}.SPEAK" if pi.config.pwn_ai_speak
@@ -173,10 +177,10 @@ module PWN
173
177
 
174
178
  reply = nil
175
179
  response_history = nil
176
- shared_chan = pi.config.pwn_irc[:shared_chan]
180
+ shared_chan = pi.config.pwn[:irc][:shared_chan]
177
181
  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
182
+ ai_agents = pi.config.pwn[:irc][:ai_agent_nicks]
183
+ ai_agents_arr = pi.config.pwn[:irc][:ai_agent_nicks].keys
180
184
  total_ai_agents = ai_agents_arr.length
181
185
  mutex = Mutex.new
182
186
  PWN::Plugins::ThreadPool.fill(
@@ -302,15 +306,12 @@ module PWN
302
306
  next unless dm_agent == nick
303
307
 
304
308
  response_history = ai_agents[dm_agent.to_sym][:response_history]
305
- ai_engine = pi.config.pwn_ai_engine
306
- ai_base_uri = pi.config.pwn_ai_base_uri
307
- ai_key = pi.config.pwn_ai_key
308
- ai_key ||= ''
309
- ai_temp = pi.config.pwn_ai_temp
310
-
311
- model = pi.config.pwn_ai_model
312
- system_role_content = pi.config.pwn_ai_system_role_content
313
- temp = pi.config.pwn_ai_temp
309
+ ai_engine = pi.config.pwn[:ai_engine]
310
+ base_uri = pi.config.pwn[ai_engine][:base_uri]
311
+ key = pi.config.pwn[ai_engine][:key] ||= ''
312
+ temp = pi.config.pwn[ai_engine][:temp]
313
+ model = pi.config.pwn[ai_engine][:model]
314
+ system_role_content = pi.config.pwn[ai_engine][:system_role_content]
314
315
 
315
316
  users_in_chan = PWN::Plugins::IRC.names(
316
317
  irc_obj: irc_obj,
@@ -344,10 +345,10 @@ module PWN
344
345
  case ai_engine
345
346
  when :grok
346
347
  response = PWN::AI::Grok.chat(
347
- base_uri: ai_base_uri,
348
- token: ai_key,
348
+ base_uri: base_uri,
349
+ token: key,
349
350
  model: model,
350
- temp: ai_temp,
351
+ temp: temp,
351
352
  system_role_content: system_role_content,
352
353
  request: request,
353
354
  response_history: response_history,
@@ -355,10 +356,10 @@ module PWN
355
356
  )
356
357
  when :ollama
357
358
  response = PWN::AI::Ollama.chat(
358
- base_uri: ai_base_uri,
359
- token: ai_key,
359
+ base_uri: base_uri,
360
+ token: key,
360
361
  model: model,
361
- temp: ai_temp,
362
+ temp: temp,
362
363
  system_role_content: system_role_content,
363
364
  request: request,
364
365
  response_history: response_history,
@@ -366,10 +367,10 @@ module PWN
366
367
  )
367
368
  when :openai
368
369
  response = PWN::AI::OpenAI.chat(
369
- base_uri: ai_base_uri,
370
- token: ai_key,
370
+ base_uri: base_uri,
371
+ token: key,
371
372
  model: model,
372
- temp: ai_temp,
373
+ temp: temp,
373
374
  system_role_content: system_role_content,
374
375
  request: request,
375
376
  response_history: response_history,
@@ -434,7 +435,7 @@ module PWN
434
435
 
435
436
  # TODO: Use TLS for IRC Connections
436
437
  # Use an IRC nCurses CLI Client
437
- ui_nick = pi.config.pwn_irc[:ui_nick]
438
+ ui_nick = pi.config.pwn[:irc][:ui_nick]
438
439
  join_channels = ai_agents_arr.map { |ai_chan| "##{ai_chan}" }.join(',')
439
440
 
440
441
  cmd0 = "/server add pwn #{host}/#{port} -notls"
@@ -538,10 +539,8 @@ module PWN
538
539
 
539
540
  # Initialize pwn.yaml Configuration using :before_session Hook
540
541
  Pry.config.hooks.add_hook(:before_session, :init_opts) do |_output, _binding, pi|
542
+ # puts "Refreshing PWN env via #{opts[:yaml_config_path]}"
541
543
  opts[:pi] = pi
542
- Pry.config.yaml_config_path = opts[:yaml_config_path]
543
- Pry.config.yaml_decryptor_path = opts[:yaml_decryptor_path]
544
-
545
544
  PWN::Plugins::Vault.refresh_config_for_repl(opts)
546
545
  end
547
546
 
@@ -549,8 +548,8 @@ module PWN
549
548
  if pi.config.pwn_asm && !request.chomp.empty?
550
549
  request = pi.input.line_buffer
551
550
 
552
- arch = pi.config.pwn_asm_arch
553
- endian = pi.config.pwn_asm_endian
551
+ arch = pi.config.pwn[:asm][:arch]
552
+ endian = pi.config.pwn[:asm][:endian]
554
553
 
555
554
  # Analyze request to determine if it should be processed as opcodes or asm.
556
555
  straight_hex = /^[a-fA-F0-9\s]+$/
@@ -586,29 +585,27 @@ module PWN
586
585
  if pi.config.pwn_ai && !request.chomp.empty?
587
586
  request = pi.input.line_buffer.to_s
588
587
  debug = pi.config.pwn_ai_debug
589
- ai_engine = pi.config.pwn_ai_engine.to_s.to_sym
590
- ai_key = pi.config.pwn_ai_key
591
- ai_key ||= ''
592
- if ai_key.empty?
593
- ai_key = PWN::Plugins::AuthenticationHelper.mask_password(
588
+ ai_engine = pi.config.pwn[:ai_engine]
589
+ base_uri = pi.config.pwn[ai_engine][:base_uri]
590
+ key = pi.config.pwn[ai_engine][:key] ||= ''
591
+ if key.empty?
592
+ key = PWN::Plugins::AuthenticationHelper.mask_password(
594
593
  prompt: 'pwn-ai Key'
595
594
  )
596
- pi.config.pwn_ai_key = ai_key
595
+ pi.config.pwn[ai_engine][:key] = key
597
596
  end
598
597
 
599
598
  response_history = pi.config.pwn_ai_response_history
600
599
  speak_answer = pi.config.pwn_ai_speak
601
- model = pi.config.pwn_ai_model
602
- system_role_content = pi.config.pwn_ai_system_role_content
603
- temp = pi.config.pwn_ai_temp
604
-
605
- ai_base_uri = pi.config.pwn_ai_base_uri
600
+ model = pi.config.pwn[ai_engine][:model]
601
+ system_role_content = pi.config.pwn[ai_engine][:system_role_content]
602
+ temp = pi.config.pwn[ai_engine][:temp]
606
603
 
607
604
  case ai_engine
608
605
  when :grok
609
606
  response = PWN::AI::Grok.chat(
610
- base_uri: ai_base_uri,
611
- token: ai_key,
607
+ base_uri: base_uri,
608
+ token: key,
612
609
  model: model,
613
610
  system_role_content: system_role_content,
614
611
  temp: temp,
@@ -619,8 +616,8 @@ module PWN
619
616
  )
620
617
  when :ollama
621
618
  response = PWN::AI::Ollama.chat(
622
- base_uri: ai_base_uri,
623
- token: ai_key,
619
+ base_uri: base_uri,
620
+ token: key,
624
621
  model: model,
625
622
  system_role_content: system_role_content,
626
623
  temp: temp,
@@ -631,8 +628,8 @@ module PWN
631
628
  )
632
629
  when :openai
633
630
  response = PWN::AI::OpenAI.chat(
634
- base_uri: ai_base_uri,
635
- token: ai_key,
631
+ base_uri: base_uri,
632
+ token: key,
636
633
  model: model,
637
634
  system_role_content: system_role_content,
638
635
  temp: temp,
@@ -173,7 +173,7 @@ module PWN
173
173
  system(relative_editor, file)
174
174
 
175
175
  # If the Pry object exists, set refresh_config to true
176
- Pry.config.refresh_config = true if defined?(Pry)
176
+ Pry.config.refresh = true if defined?(Pry)
177
177
 
178
178
  encrypt(
179
179
  file: file,
@@ -245,7 +245,8 @@ module PWN
245
245
 
246
246
  return false unless File.exist?(yaml_config_path)
247
247
 
248
- pi = opts[:pi] ||= Pry
248
+ pi = opts[:pi]
249
+ raise 'ERROR: Pry instance is required.' if pi.nil?
249
250
 
250
251
  is_encrypted = PWN::Plugins::Vault.file_encrypted?(file: yaml_config_path)
251
252
 
@@ -270,52 +271,41 @@ module PWN
270
271
  else
271
272
  yaml_config = YAML.load_file(yaml_config_path, symbolize_names: true)
272
273
  end
273
- pi.config.p = yaml_config
274
- Pry.config.p = yaml_config
275
274
 
276
275
  valid_ai_engines = %i[
277
276
  grok
278
277
  openai
279
278
  ollama
280
279
  ]
281
- ai_engine = yaml_config[:ai_engine].to_s.downcase.to_sym
282
280
 
281
+ # Convert ai_engine to symbol and downcase to ensure stability
282
+ yaml_config[:ai_engine] = yaml_config[:ai_engine].to_s.downcase.to_sym
283
+ pi.config.pwn = yaml_config
284
+ ai_engine = pi.config.pwn[:ai_engine]
283
285
  raise "ERROR: Unsupported AI Engine: #{ai_engine} in #{yaml_config_path}. Supported AI Engines:\n#{valid_ai_engines.inspect}" unless valid_ai_engines.include?(ai_engine)
284
286
 
285
- pi.config.pwn_ai_engine = ai_engine
286
- Pry.config.pwn_ai_engine = ai_engine
287
-
288
- pi.config.pwn_ai_base_uri = pi.config.p[ai_engine][:base_uri]
289
- Pry.config.pwn_ai_base_uri = pi.config.pwn_ai_base_uri
290
-
291
- pi.config.pwn_ai_key = pi.config.p[ai_engine][:key]
292
- Pry.config.pwn_ai_key = pi.config.pwn_ai_key
293
-
294
- pi.config.pwn_ai_model = pi.config.p[ai_engine][:model]
295
- Pry.config.pwn_ai_model = pi.config.pwn_ai_model
296
-
297
- pi.config.pwn_ai_system_role_content = pi.config.p[ai_engine][:system_role_content]
298
- Pry.config.pwn_ai_system_role_content = pi.config.pwn_ai_system_role_content
299
-
300
- pi.config.pwn_ai_temp = pi.config.p[ai_engine][:temp]
301
- Pry.config.pwn_ai_temp = pi.config.pwn_ai_temp
302
-
303
- pi.config.pwn_asm_arch = pi.config.p[:asm][:arch]
304
- Pry.config.pwn_asm_arch = pi.config.pwn_asm_arch
305
-
306
- pi.config.pwn_asm_endian = pi.config.p[:asm][:endian]
307
- Pry.config.pwn_asm_endian = pi.config.pwn_asm_endian
308
-
309
- pi.config.pwn_irc = pi.config.p[:irc]
310
- Pry.config.pwn_irc = pi.config.pwn_irc
311
-
312
- pi.config.pwn_hunter = pi.config.p[:hunter][:api_key]
313
- Pry.config.pwn_hunter = pi.config.pwn_hunter
314
-
315
- pi.config.pwn_shodan = pi.config.p[:shodan][:api_key]
316
- Pry.config.pwn_shodan = pi.config.pwn_shodan
317
-
318
- Pry.config.refresh_config = false
287
+ model = pi.config.pwn[ai_engine][:model]
288
+ system_role_content = pi.config.pwn[ai_engine][:system_role_content]
289
+
290
+ # Reset the ai response history for new configurations
291
+ pi.config.pwn_ai_response_history = {
292
+ id: '',
293
+ object: '',
294
+ model: model,
295
+ usage: {},
296
+ choices: [
297
+ {
298
+ role: 'system',
299
+ content: system_role_content
300
+ }
301
+ ]
302
+ }
303
+
304
+ # These two lines should be immutable for the session
305
+ pi.config.pwn[:yaml_config_path] = yaml_config_path
306
+ pi.config.pwn[:yaml_decryptor_path] = yaml_decryptor_path if is_encrypted
307
+
308
+ Pry.config.refresh = false
319
309
 
320
310
  true
321
311
  rescue StandardError => e
@@ -44,7 +44,7 @@ module PWN
44
44
  raise 'ERROR: AI Model is required for AI engine ollama.' if ai_engine == :ollama && ai_model.nil?
45
45
 
46
46
  ai_key = opts[:ai_key] ||= PWN::Plugins::AuthenticationHelper.mask_password(prompt: "#{ai_engine} Token")
47
- ai_system_role_content = opts[:ai_system_role_content] ||= 'Confidence score of 0-10 this is vulnerable (0 being not vulnerable, moving upwards in confidence of exploitation). Provide additional context to assist penetration tester assessment.'
47
+ ai_system_role_content = opts[:ai_system_role_content] ||= 'Your sole purpose is to analyze source code snippets and generate an Exploit Prediction Scoring System (EPSS) score between 0% - 100%. Just generate a score unless score is higher than 75% in which a code fic should also be included.'
48
48
  ai_temp = opts[:ai_temp] ||= 0.1
49
49
 
50
50
  puts "Analyzing source code using AI engine: #{ai_engine}\nModel: #{ai_model}\nSystem Role Content: #{ai_system_role_content}\nTemperature: #{ai_temp}"
@@ -64,12 +64,19 @@ module PWN
64
64
  spin.auto_spin
65
65
 
66
66
  results_hash[:data].each do |hash_line|
67
+ git_repo_root_uri = hash_line[:filename][:git_repo_root_uri]
68
+ filename = hash_line[:filename][:entry]
67
69
  hash_line[:line_no_and_contents].each do |src_detail|
68
70
  entry_count += 1
69
71
  percent_complete = (entry_count.to_f / total_entries * 100).round(2)
70
- request = src_detail[:contents]
71
- response = nil
72
72
  line_no = src_detail[:line_no]
73
+ source_code_snippet = src_detail[:contents]
74
+ request = {
75
+ scm_uri: "#{git_repo_root_uri}/#{filename}",
76
+ line: line_no,
77
+ source_code_snippet: source_code_snippet
78
+ }.to_json
79
+ response = nil
73
80
  author = src_detail[:author].to_s.scrub.chomp.strip
74
81
 
75
82
  case ai_engine
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.426'
4
+ VERSION = '0.5.428'
5
5
  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.426
4
+ version: 0.5.428
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.