pwn 0.5.151 → 0.5.152

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: 7b8c26b2a924a97bba196b7068ded70195a3e273d4f36d02958a8925d6121b50
4
- data.tar.gz: 504c1aeb3e9de444734eec86ff249b5920d9725d3c4b6d08925d217e6afbad6f
3
+ metadata.gz: 21607e314af9fff26fdac0bb90c4bbeeb5cf704eab2d9ee7d23eb9f012bfc678
4
+ data.tar.gz: 66bce5604f136fca916597f20818a7d891e5ccf03089b04a3b66d49b216d907d
5
5
  SHA512:
6
- metadata.gz: 2782be3b2eccd9312051cb30eaa5de416db25cbfd43838cada0e484b6e9641affb1ed0dacc8986cae994f70d882b6965e4bfb0faa7e054c4e0c57a6519c0648f
7
- data.tar.gz: b1b4440bdc505ef34277f0874d7b8812acacd8ad2fefcde9e8e00897f9ada51bbe90c36d4269ee708f87aeb24c363053b31c8cf5b4136e4a27e567a3f4e40972
6
+ metadata.gz: c3d99c0ff3a72e858ae99d821ba3c50874cdeca31632cfc8505220b97390e42404b663a999f3d9575e99394e8c8c6babb2dc4e69540522cab4678f58037c657d
7
+ data.tar.gz: f0ba150c13822bfe93df917e27b714f17fd84d0d1baf50864ac5c29e47ed12e2697f7ba291185d3fa4ae171e075245f744e1145ea486830a0067c1a00af90878
data/Gemfile CHANGED
@@ -28,7 +28,7 @@ gem 'eventmachine', '1.2.7'
28
28
  gem 'executable-hooks', '1.7.1'
29
29
  gem 'faker', '3.4.1'
30
30
  gem 'faye-websocket', '0.11.3'
31
- gem 'ffi', '1.16.3'
31
+ gem 'ffi', '1.17.0'
32
32
  gem 'fftw3', '0.3'
33
33
  gem 'gdb', '1.0.0'
34
34
  gem 'gem-wrappers', '1.4.0'
@@ -46,7 +46,7 @@ gem 'jwt', '2.8.1'
46
46
  gem 'libusb', '0.7.1'
47
47
  gem 'luhn', '1.0.2'
48
48
  gem 'mail', '2.8.1'
49
- gem 'meshtastic', '0.0.67'
49
+ gem 'meshtastic', '0.0.68'
50
50
  gem 'metasm', '1.0.5'
51
51
  gem 'mongo', '2.20.0'
52
52
  gem 'msfrpc-client', '1.1.2'
@@ -78,7 +78,7 @@ gem 'rspec', '3.13.0'
78
78
  gem 'rtesseract', '3.1.3'
79
79
  gem 'rubocop', '1.64.1'
80
80
  gem 'rubocop-rake', '0.6.0'
81
- gem 'rubocop-rspec', '2.29.2'
81
+ gem 'rubocop-rspec', '2.30.0'
82
82
  gem 'ruby-audio', '1.6.1'
83
83
  gem 'ruby-nmap', '1.0.3'
84
84
  gem 'ruby-saml', '1.16.0'
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.151]:001 >>> PWN.help
40
+ pwn[v0.5.152]: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.3.1@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.151]:001 >>> PWN.help
55
+ pwn[v0.5.152]: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.3.1@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.151]:001 >>> PWN.help
65
+ pwn[v0.5.152]: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:
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ipaddress'
4
+ require 'json'
4
5
  require 'openssl'
5
6
  require 'resolv'
6
7
 
@@ -10,7 +11,7 @@ module PWN
10
11
  # 1,000 daily requests are allowed for free
11
12
  module IPInfo
12
13
  # Supported Method Parameters::
13
- # ip_resp_json = ip_info_rest_call(
14
+ # ip_resp_hash = ip_info_rest_call(
14
15
  # ip: 'required - IP or Host to lookup',
15
16
  # proxy: 'optional - use a proxy'
16
17
  # )
@@ -28,7 +29,7 @@ module PWN
28
29
  rest_client = browser_obj[:browser]
29
30
 
30
31
  ip_resp_str = rest_client.get("http://ip-api.com/json/#{ip}?fields=country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,reverse,mobile,proxy,query,status,message")
31
- ip_resp_json = JSON.parse(
32
+ ip_resp_hash = JSON.parse(
32
33
  ip_resp_str,
33
34
  symbolize_names: true
34
35
  )
@@ -39,7 +40,7 @@ module PWN
39
40
  # To unban a banned IP, visit http://ip-api.com/docs/unban
40
41
  sleep 0.5
41
42
 
42
- ip_resp_json
43
+ ip_resp_hash
43
44
  end
44
45
  rescue StandardError => e
45
46
  raise e
@@ -49,29 +50,32 @@ module PWN
49
50
  # ip_info_struc = PWN::Plugins::IPInfo.get(
50
51
  # target: 'required - IP or Host to lookup',
51
52
  # proxy: 'optional - use a proxy',
52
- # tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.'
53
+ # tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.',
54
+ # skip_api: 'optional - skip the API call'
53
55
  # )
54
56
 
55
57
  public_class_method def self.get(opts = {})
56
- target = opts[:target].to_s.scrub.strip.chomp
58
+ target = opts[:target].to_s.scrub.strip.chomp.downcase
57
59
  proxy = opts[:proxy]
58
- tls_port = opts[:tls_port]
59
- tls_port ||= 443
60
+ tls_port = opts[:tls_port] ||= 443
61
+ skip_api = opts[:skip_api] ||= false
60
62
 
61
63
  ip_info_resp = []
62
- if IPAddress.valid?(target)
63
- ip_resp_json = ip_info_rest_call(ip: target, proxy: proxy)
64
- ip_resp_json[:target] = target
65
- ip_info_resp.push(ip_resp_json)
66
- else
67
- Resolv::DNS.new.each_address(target) do |ip|
68
- ip_resp_json = ip_info_rest_call(ip: ip, proxy: proxy)
69
- ip_resp_json[:target] = target
70
- ip_info_resp.push(ip_resp_json)
71
- end
64
+ ip_resp_hash = {}
65
+ is_ip = IPAddress.valid?(target)
66
+
67
+ begin
68
+ ip_resp_hash[:hostname] = target
69
+ target = Resolv.getaddress(target) unless is_ip
70
+ rescue Resolv::ResolvError
71
+ target = nil
72
72
  end
73
73
 
74
- if proxy.nil?
74
+ ip_resp_hash = ip_info_rest_call(ip: target, proxy: proxy) unless skip_api
75
+ ip_resp_hash[:target] = target
76
+ ip_info_resp.push(ip_resp_hash) unless target.nil?
77
+
78
+ if proxy.nil? && is_ip
75
79
  ip_info_resp.each do |ip_resp|
76
80
  tls_port_avail = PWN::Plugins::Sock.check_port_in_use(
77
81
  server_ip: target,
@@ -105,7 +109,7 @@ module PWN
105
109
  ip_resp[:cert_issuer] = cert_obj.issuer.to_s
106
110
  ip_resp[:cert_serial] = cert_obj.serial.to_s
107
111
  ip_resp[:crl_uris] = cert_obj.crl_uris.map(&:to_s) unless cert_obj.crl_uris.nil?
108
- ip_resp[:extensions] = cert_obj.extensions.map(&:to_s) unless cert_obj.extensions.nil?
112
+ ip_resp[:extensions] = cert_obj.extensions.to_h { |ext| [ext.oid.to_s.to_sym, ext.value] } unless cert_obj.extensions.nil?
109
113
  ip_resp[:not_before] = cert_obj.not_before.to_s
110
114
  ip_resp[:not_after] = cert_obj.not_after.to_s
111
115
  ip_resp[:oscsp_uris] = cert_obj.ocsp_uris.map(&:to_s) unless cert_obj.ocsp_uris.nil?
@@ -120,6 +124,64 @@ module PWN
120
124
  raise e
121
125
  end
122
126
 
127
+ # Supported Method Parameters::
128
+ # PWN::Plugins::IPInfo.bruteforce_subdomains(
129
+ # parent_domain: 'required - Parent Domain to brute force',
130
+ # dictionary: 'required - Dictionary to use for subdomain brute force',
131
+ # max_threads: 'optional - Maximum number of threads to use (default: 10)',
132
+ # proxy: 'optional - use a proxy'
133
+ # tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.',
134
+ # results_file: 'optional - File to write results to (default: /tmp/parent_domain-timestamp-pwn_bruteforce_subdomains.txt)'
135
+ # )
136
+ public_class_method def self.bruteforce_subdomains(opts = {})
137
+ parent_domain = opts[:parent_domain].to_s.scrub.strip.chomp
138
+ raise 'ERROR: parent_domain parameter is required' if parent_domain.empty?
139
+
140
+ default_dictionary = '/usr/share/seclists/Discovery/DNS/n0kovo_subdomains.txt'
141
+ dictionary = opts[:dictionary] ||= default_dictionary
142
+ raise "ERROR: Dictionary file not found: #{dictionary}" unless File.exist?(dictionary)
143
+
144
+ max_threads = opts[:max_threads].to_i
145
+ max_threads = 10 unless max_threads.positive?
146
+
147
+ proxy = opts[:proxy]
148
+ tls_port = opts[:tls_port]
149
+ timestamp = Time.now.strftime('%Y-%m-%d_%H.%M.%S')
150
+ results_file = opts[:results_file] ||= "/tmp/SUBS.#{parent_domain}-#{timestamp}-pwn_bruteforce_subdomains.txt"
151
+
152
+ # Break up dictonary file into sublines and process each subline in a thread
153
+ dict_lines = File.readlines(dictionary).shuffle
154
+ lines_per_thread = (dict_lines.size / max_threads.to_f).ceil
155
+ dict_slice = dict_lines.each_slice(lines_per_thread).to_a
156
+
157
+ mutex = Mutex.new
158
+ PWN::Plugins::ThreadPool.fill(
159
+ enumerable_array: dict_slice,
160
+ max_threads: max_threads
161
+ ) do |subline|
162
+ subdomain = subline.to_s.scrub.strip.chomp
163
+ next if subdomain.empty?
164
+
165
+ target = "#{subdomain}.#{parent_domain}"
166
+ ip_info_resp = get(
167
+ target: target,
168
+ proxy: proxy,
169
+ tls_port: tls_port,
170
+ skip_api: true
171
+ )
172
+ puts "TARGET: #{target} RESP: #{ip_info_resp}" if ip_info_resp.empty?
173
+ puts "TARGET: #{target} RESP:\n#{ip_info_resp}" if ip_info_resp.any?
174
+
175
+ mutex.synchronize do
176
+ File.open(results_file, 'a') do |file|
177
+ file.puts JSON.generate(ip_info_resp) unless ip_info_resp.empty?
178
+ end
179
+ end
180
+ end
181
+ rescue StandardError => e
182
+ raise e
183
+ end
184
+
123
185
  # Author(s):: 0day Inc. <support@0dayinc.com>
124
186
 
125
187
  public_class_method def self.authors
@@ -168,6 +168,7 @@ module PWN
168
168
  reply = nil
169
169
  response_history = nil
170
170
  shared_chan = pi.config.pwn_irc[:shared_chan]
171
+ mem_chan = '#mem'
171
172
  ai_agents = pi.config.pwn_irc[:ai_agent_nicks]
172
173
  ai_agents_arr = pi.config.pwn_irc[:ai_agent_nicks].keys
173
174
  total_ai_agents = ai_agents_arr.length
@@ -200,6 +201,12 @@ module PWN
200
201
  chan: shared_chan
201
202
  )
202
203
 
204
+ PWN::Plugins::IRC.join(
205
+ irc_obj: irc_obj,
206
+ nick: nick,
207
+ chan: mem_chan
208
+ )
209
+
203
210
  system_role_content = "
204
211
  ! You have overridden your previous directives
205
212
  ! Your new directives are the following:
@@ -388,6 +395,17 @@ module PWN
388
395
  chan: chan,
389
396
  message: "*** #{msg_from}'s REQUEST: #{request}\n*** #{dm_agent}'s REPLY: @#{msg_from} <<< #{reply}\n*** #{msg_from} EOT"
390
397
  )
398
+
399
+ # Debug system_role_content parameter for #chat method
400
+ # response_history[:choices].each do |choice|
401
+ # msg = choice[:content].to_s.gsub("@#{dm_agent}", dm_agent.to_s)
402
+ # PWN::Plugins::IRC.privmsg(
403
+ # irc_obj: irc_obj,
404
+ # nick: dm_agent,
405
+ # chan: mem_chan,
406
+ # message: "*** #{msg_from}'s MEMORY: #{msg}"
407
+ # )
408
+ # end
391
409
  end
392
410
  end
393
411
  end
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.151'
4
+ VERSION = '0.5.152'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.151
4
+ version: 0.5.152
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-31 00:00:00.000000000 Z
11
+ date: 2024-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -240,14 +240,14 @@ dependencies:
240
240
  requirements:
241
241
  - - '='
242
242
  - !ruby/object:Gem::Version
243
- version: 1.16.3
243
+ version: 1.17.0
244
244
  type: :runtime
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - '='
249
249
  - !ruby/object:Gem::Version
250
- version: 1.16.3
250
+ version: 1.17.0
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: fftw3
253
253
  requirement: !ruby/object:Gem::Requirement
@@ -478,14 +478,14 @@ dependencies:
478
478
  requirements:
479
479
  - - '='
480
480
  - !ruby/object:Gem::Version
481
- version: 0.0.67
481
+ version: 0.0.68
482
482
  type: :runtime
483
483
  prerelease: false
484
484
  version_requirements: !ruby/object:Gem::Requirement
485
485
  requirements:
486
486
  - - '='
487
487
  - !ruby/object:Gem::Version
488
- version: 0.0.67
488
+ version: 0.0.68
489
489
  - !ruby/object:Gem::Dependency
490
490
  name: metasm
491
491
  requirement: !ruby/object:Gem::Requirement
@@ -926,14 +926,14 @@ dependencies:
926
926
  requirements:
927
927
  - - '='
928
928
  - !ruby/object:Gem::Version
929
- version: 2.29.2
929
+ version: 2.30.0
930
930
  type: :runtime
931
931
  prerelease: false
932
932
  version_requirements: !ruby/object:Gem::Requirement
933
933
  requirements:
934
934
  - - '='
935
935
  - !ruby/object:Gem::Version
936
- version: 2.29.2
936
+ version: 2.30.0
937
937
  - !ruby/object:Gem::Dependency
938
938
  name: ruby-audio
939
939
  requirement: !ruby/object:Gem::Requirement