pwn 0.5.529 → 0.5.531

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: 2837cafb8268a67d624fd9115ee04597fe9edf7f126bde373f181be6ae7859bb
4
- data.tar.gz: 2855cbda367a81a7c854c08edcf0f0d1d59f96321df8c23b3834003e99bb4df3
3
+ metadata.gz: db0acc490e9b6e0dca25ce2a5b5bcd2b19f435f129ae0221857842c267941c32
4
+ data.tar.gz: 53374f569fcd0484a59c1c74e1d160872c6fab8afb375b7a7ac19fdc7d4682d8
5
5
  SHA512:
6
- metadata.gz: cf65609b278025eb8e3bceac9be6be4cdbd89aacf4cd506945da1b6c9b6285de2008b3bb00d7f540fe4587229649e708e0c01cf0583bf2f61f73bff985234324
7
- data.tar.gz: 669851be6eaedebc14a193767f930c6101fd9fae7e843ddf2ed74642979ce8d1e02dde0e48d4eb8b9f1ac0f20fda7a009114b506085351b1e9bf31e68e97f418
6
+ metadata.gz: 447ff1c3aa6d7118145b4a20f555f3c5c541423f0b8799b486cf1c3ef8cb5ef2181e0676608a7aa164da72be87d8f515d1f9c7af3fdf792ddd26c95b4edc6234
7
+ data.tar.gz: 99ac0586844bb9b0693fa83eb406b35419d940bbff7cace73df0aa0c0da50c8bf059137cbe9aed40d63a68b9bfb7a44457fe54103fc81204b060f1e2a2dce713
data/Gemfile CHANGED
@@ -11,7 +11,7 @@ gemspec
11
11
  # In some circumstances custom flags are passed to gems in order
12
12
  # to build appropriately. Defer to ./reinstall_pwn_gemset.sh
13
13
  # to review these custom flags (e.g. pg, serialport, etc).
14
- gem 'activesupport', '<8.1.1'
14
+ gem 'activesupport', '<8.1.2'
15
15
  gem 'anemone', '0.7.2'
16
16
  gem 'authy', '3.0.1'
17
17
  gem 'aws-sdk', '3.3.0'
@@ -24,14 +24,14 @@ gem 'bundler', '>=4.0.3'
24
24
  gem 'bundler-audit', '>=0.9.3'
25
25
  gem 'bunny', '2.24.0'
26
26
  gem 'colorize', '1.1.0'
27
- gem 'credit_card_validations', '7.0.0'
27
+ gem 'credit_card_validations', '7.1.0'
28
28
  gem 'curses', '1.5.3'
29
29
  gem 'diffy', '3.4.4'
30
30
  gem 'eventmachine', '1.2.7'
31
31
  gem 'executable-hooks', '1.7.1'
32
32
  gem 'faker', '3.5.3'
33
33
  gem 'faye-websocket', '0.12.0'
34
- gem 'ffi', '1.17.2'
34
+ gem 'ffi', '1.17.3'
35
35
  # gem 'fftw3', '0.3'
36
36
  gem 'gdb', '1.0.0'
37
37
  gem 'gem-wrappers', '1.4.0'
@@ -49,7 +49,7 @@ gem 'jwt', '3.1.2'
49
49
  gem 'libusb', '0.7.2'
50
50
  gem 'luhn', '3.0.0'
51
51
  gem 'mail', '2.9.0'
52
- gem 'meshtastic', '0.0.149'
52
+ gem 'meshtastic', '0.0.151'
53
53
  gem 'metasm', '1.0.5'
54
54
  gem 'mongo', '2.22.0'
55
55
  gem 'msfrpc-client', '1.1.2'
@@ -58,7 +58,7 @@ gem 'net-ldap', '0.20.0'
58
58
  gem 'net-openvpn', '0.8.7'
59
59
  gem 'net-smtp', '0.5.1'
60
60
  gem 'nexpose', '7.3.0'
61
- gem 'nokogiri', '1.18.10'
61
+ gem 'nokogiri', '1.19.0'
62
62
  gem 'nokogiri-diff', '0.3.0'
63
63
  gem 'oily_png', '1.2.1'
64
64
  gem 'open3', '0.2.1'
@@ -66,9 +66,9 @@ gem 'os', '1.1.4'
66
66
  gem 'ostruct', '0.6.3'
67
67
  gem 'packetfu', '2.0.0'
68
68
  gem 'packetgen', '4.1.1'
69
- gem 'pdf-reader', '2.15.0'
70
- gem 'pg', '1.6.2'
71
- gem 'pry', '0.15.2'
69
+ gem 'pdf-reader', '2.15.1'
70
+ gem 'pg', '1.6.3'
71
+ gem 'pry', '0.16.0'
72
72
  gem 'pry-doc', '1.6.0'
73
73
  gem 'rake', '13.3.1'
74
74
  gem 'rb-readline', '0.5.5'
@@ -76,13 +76,13 @@ gem 'rbvmomi2', '3.8.0'
76
76
  gem 'rdoc', '7.0.3'
77
77
  gem 'rest-client', '2.1.0'
78
78
  gem 'rex', '2.0.13'
79
- gem 'rmagick', '6.1.4'
80
- gem 'rqrcode', '3.1.1'
79
+ gem 'rmagick', '6.1.5'
80
+ gem 'rqrcode', '3.2.0'
81
81
  gem 'rspec', '3.13.2'
82
82
  gem 'rtesseract', '3.1.4'
83
83
  gem 'rubocop', '1.82.1'
84
84
  gem 'rubocop-rake', '0.7.1'
85
- gem 'rubocop-rspec', '3.8.0'
85
+ gem 'rubocop-rspec', '3.9.0'
86
86
  gem 'ruby-audio', '1.6.1'
87
87
  gem 'ruby-nmap', '1.0.3'
88
88
  gem 'ruby-saml', '1.18.1'
@@ -93,7 +93,7 @@ gem 'selenium-webdriver', '4.39.0'
93
93
  gem 'slack-ruby-client', '3.1.0'
94
94
  gem 'socksify', '1.8.1'
95
95
  gem 'spreadsheet', '1.3.4'
96
- gem 'sqlite3', '2.8.1'
96
+ gem 'sqlite3', '2.9.0'
97
97
  gem 'thin', '2.0.1'
98
98
  gem 'tty-prompt', '0.23.1'
99
99
  gem 'tty-spinner', '0.9.3'
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.529]:001 >>> PWN.help
40
+ pwn[v0.5.531]: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-4.0.0@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.529]:001 >>> PWN.help
55
+ pwn[v0.5.531]: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-4.0.0@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.529]:001 >>> PWN.help
65
+ pwn[v0.5.531]: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_gqrx_scanner CHANGED
@@ -5,20 +5,16 @@ require 'pwn'
5
5
 
6
6
  opts = PWN::Env[:driver_opts]
7
7
  PWN::Driver::Parser.new do |options|
8
- options.on('-aPROFILE', '--assume-profile=PROFILE', '<Required if "--target-freq" is Nil - Profile to assume for common radio protocols. Use "--list-scan-profiles" to display supported protocols (Defaults to nil)') do |p|
8
+ options.on('-aPROFILE', '--assume-band-plan=PROFILE', '<Required if "--target-freq" is Nil - Band Plan Profile to assume for common radio protocols. Use "--list-band-plans" to display supported protocols (Defaults to nil)') do |p|
9
9
  opts[:profile] = p
10
10
  end
11
11
 
12
- options.on('-l', '--list-scan-profiles', '<Optional - List supported scan profiles and exit>') do |l|
13
- opts[:list_scan_profiles] = l
12
+ options.on('-l', '--list-band-plans', '<Optional - List supported band plan profiles and exit>') do |l|
13
+ opts[:list_band_plans] = l
14
14
  end
15
15
 
16
- options.on('-sFREQ', '--start-freq=FREQ', '<Required if "--assume-profile" is Nil - Frequency to Start Scanning (e.g. 800.000.000 == 800 mHz>') do |s|
17
- opts[:start_freq] = s
18
- end
19
-
20
- options.on('-tFREQ', '--target-freq=FREQ', '<Required if "--assume-profile" is Nil - Frequency to Conclude Scanning (e.g. 900.000.000 == 900 mHz>') do |e|
21
- opts[:target_freq] = e
16
+ options.on('-sFREQS', '--scan-ranges=FREQS', '<Required if "--assume-band-plan" is Nil - Comma-Delimited List of Frequency Ranges to Scan (e.g. 800.000.000 == 800 mHz>') do |s|
17
+ opts[:scan_ranges] = s
22
18
  end
23
19
 
24
20
  options.on('-hHOST', '--host=HOST', '<Optional - GQRX Host (Defaults to 127.0.0.1)>') do |h|
@@ -82,26 +78,36 @@ begin
82
78
  pwn_provider = 'ruby-gem'
83
79
  pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.any? { |s| s == 'PWN_PROVIDER' }
84
80
 
85
- profiles_available = PWN::SDR::FrequencyAllocation.profiles
81
+ band_plans = PWN::SDR::FrequencyAllocation.band_plans
86
82
 
87
- list_scan_profiles = opts[:list_scan_profiles]
88
- if list_scan_profiles
89
- puts JSON.pretty_generate(profiles_available)
83
+ list_band_plans = opts[:list_band_plans]
84
+ if list_band_plans
85
+ puts JSON.pretty_generate(band_plans)
90
86
  exit 0
91
87
  end
92
88
 
93
89
  profile = opts[:profile]
94
- opts.merge!(profiles_available[profile.to_sym]) unless profile.nil?
95
-
96
- start_freq = opts[:start_freq]
97
- start_freq = start_freq.to_s.delete('.') unless start_freq.nil?
98
- start_freq = start_freq.to_i
99
- raise 'ERROR: Invalid start frequency.' if !start_freq.nil? && start_freq.zero?
100
-
101
- target_freq = opts[:target_freq]
102
- target_freq = target_freq.to_s.delete('.') unless target_freq.nil?
103
- target_freq = target_freq.to_i
104
- raise 'ERROR: --assume-profile || --target-freq is required.' if target_freq.zero? && profile.nil?
90
+ # Merge opts with profile values if profile provided
91
+ opts.merge!(band_plans[profile.to_sym]) unless profile.nil?
92
+
93
+ scan_ranges = opts[:scan_ranges]
94
+ raise 'ERROR: --assume-band-plan || --scan-ranges is required.' if scan_ranges.nil? && profile.nil?
95
+
96
+ ranges = band_plans[profile.to_sym][:ranges] unless profile.nil?
97
+ if ranges.nil?
98
+ # Convert comma-delimited string to array of hashes
99
+ ranges = scan_ranges.split(',').map do |r|
100
+ range = r.split('-')
101
+ { start_freq: range.first, target_freq: range.last }
102
+ end
103
+ elsif scan_ranges
104
+ # Append scan_ranges to profile ranges if both provided
105
+ additional_ranges = scan_ranges.split(',').map do |r|
106
+ range = r.split('-')
107
+ { start_freq: range.first, target_freq: range.last }
108
+ end
109
+ ranges.concat(additional_ranges)
110
+ end
105
111
 
106
112
  host = opts[:host]
107
113
  port = opts[:port]
@@ -137,11 +143,12 @@ begin
137
143
  decoder = opts[:decoder]
138
144
  location = opts[:location]
139
145
 
140
- # Merge opts again to ensure we override profile values with CLI values
146
+ # Merge opts one last time to ensure parameters passed to the driver are included
147
+ opts.merge!(band_plans[profile.to_sym]) unless profile.nil?
148
+
141
149
  PWN::SDR::GQRX.scan_range(
142
150
  gqrx_sock: gqrx_sock,
143
- start_freq: start_freq,
144
- target_freq: target_freq,
151
+ ranges: ranges,
145
152
  demodulator_mode: demodulator_mode,
146
153
  bandwidth: bandwidth,
147
154
  audio_gain_db: audio_gain_db,
@@ -159,8 +166,8 @@ begin
159
166
  puts 'Scan Complete.'
160
167
  rescue StandardError => e
161
168
  raise e
162
- rescue Interrupt, SystemExit
169
+ rescue Interrupt
163
170
  puts "\nCTRL+C detected - goodbye."
164
171
  ensure
165
- PWN::SDR::GQRX.disconnect(gqrx_sock: gqrx_sock) unless gqrx_sock.closed?
172
+ PWN::SDR::GQRX.disconnect(gqrx_sock: gqrx_sock) unless gqrx_sock.nil?
166
173
  end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'tty-spinner'
5
+
6
+ module PWN
7
+ module SDR
8
+ module Decoder
9
+ # POCSAG Decoder Module for Pagers
10
+ module POCSAG
11
+ # Supported Method Parameters::
12
+ # pocsag_resp = PWN::SDR::Decoder::POCSAG.decode(
13
+ # freq_obj: 'required - GQRX socket object returned from #connect method'
14
+ # )
15
+
16
+ public_class_method def self.decode(opts = {})
17
+ freq_obj = opts[:freq_obj]
18
+ gqrx_sock = freq_obj[:gqrx_sock]
19
+ record_path = freq_obj[:record_path]
20
+ freq_obj = freq_obj.dup
21
+ freq_obj.delete(:gqrx_sock)
22
+ skip_freq_char = "\n"
23
+ puts JSON.pretty_generate(freq_obj)
24
+ puts "\n*** Pager POCSAG Decoder ***"
25
+ puts 'Press [ENTER] to continue...'
26
+
27
+ # Toggle POCSAG off and on to reset the decoder
28
+ PWN::SDR::GQRX.cmd(
29
+ gqrx_sock: gqrx_sock,
30
+ cmd: 'U RECORD 0',
31
+ resp_ok: 'RPRT 0'
32
+ )
33
+
34
+ PWN::SDR::GQRX.cmd(
35
+ gqrx_sock: gqrx_sock,
36
+ cmd: 'U RECORD 1',
37
+ resp_ok: 'RPRT 0'
38
+ )
39
+
40
+ # Spinner setup with dynamic terminal width awareness
41
+ spinner = TTY::Spinner.new(
42
+ '[:spinner] :decoding',
43
+ format: :arrow_pulse,
44
+ clear: true,
45
+ hide_cursor: true
46
+ )
47
+
48
+ record_header_size = 44
49
+ wav_header = File.binread(record_path, record_header_size)
50
+ raise 'ERROR: WAV file header is invalid!' unless wav_header[0, 4] == 'RIFF' && wav_header[8, 4] == 'WAVE'
51
+
52
+ bytes_read = wav_header_size
53
+
54
+ # Conservative overhead for spinner animation, colors, and spacing
55
+ spinner_overhead = 12
56
+ max_title_length = [TTY::Screen.width - spinner_overhead, 50].max
57
+
58
+ initial_title = 'INFO: Decoding Pager POCSAG data...'
59
+ initial_title = initial_title[0...max_title_length] if initial_title.length > max_title_length
60
+ spinner.update(title: initial_title)
61
+ spinner.auto_spin
62
+
63
+ last_resp = {}
64
+
65
+ loop do
66
+ current_wav_size = File.size?(record_path) ||= 0
67
+ pocsag_resp = {}
68
+
69
+ # Only update when we have valid new data
70
+ if current_wav_size > bytes_read
71
+ new_bytes = current_wav_size - bytes_read
72
+ # Ensure full I/Q pairs (8 bytes each)
73
+ new_bytes -= new_bytes % 8
74
+ data = File.binread(record_path, new_bytes, bytes_read)
75
+
76
+ msg = "DECODED DATA"
77
+
78
+ spinner.update(decoding: msg)
79
+ last_resp = pocsag_resp.dup
80
+ end
81
+
82
+ # Non-blocking check for ENTER key to exit
83
+ if $stdin.wait_readable(0)
84
+ begin
85
+ char = $stdin.read_nonblock(1)
86
+ break if char == skip_freq_char
87
+ rescue IO::WaitReadable, EOFError
88
+ # No-op
89
+ end
90
+ end
91
+
92
+ sleep 0.01
93
+ end
94
+ rescue StandardError => e
95
+ spinner.error('Decoding failed') if defined?(spinner)
96
+ raise e
97
+ ensure
98
+ File.unlink(record_path) if File.exist?(record_path)
99
+ PWN::SDR::GQRX.cmd(
100
+ gqrx_sock: gqrx_sock,
101
+ cmd: 'U RECORD 0',
102
+ resp_ok: 'RPRT 0'
103
+ )
104
+
105
+ spinner.stop if defined?(spinner) && spinner
106
+ end
107
+
108
+ # Author(s):: 0day Inc. <support@0dayinc.com>
109
+
110
+ public_class_method def self.authors
111
+ "AUTHOR(S):
112
+ 0day Inc. <support@0dayinc.com>
113
+ "
114
+ end
115
+
116
+ # Display Usage for this Module
117
+
118
+ public_class_method def self.help
119
+ puts "USAGE:
120
+ #{self}.decode(
121
+ freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq method'
122
+ )
123
+
124
+ #{self}.authors
125
+ "
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -9,7 +9,7 @@ module PWN
9
9
  # RDS Decoder Module for FM Radio Signals
10
10
  module RDS
11
11
  # Supported Method Parameters::
12
- # rds_resp = PWN::SDR::GQRX.decode_rds(
12
+ # rds_resp = PWN::SDR::Decoder::RDS.decode(
13
13
  # freq_obj: 'required - GQRX socket object returned from #connect method'
14
14
  # )
15
15
 
@@ -19,19 +19,19 @@ module PWN
19
19
 
20
20
  freq_obj = freq_obj.dup
21
21
  freq_obj.delete(:gqrx_sock)
22
- skip_rds = "\n"
22
+ skip_freq_char = "\n"
23
23
  puts JSON.pretty_generate(freq_obj)
24
24
  puts "\n*** FM Radio RDS Decoder ***"
25
25
  puts 'Press [ENTER] to continue...'
26
26
 
27
27
  # Toggle RDS off and on to reset the decoder
28
- PWN::SDR::GQRX.gqrx_cmd(
28
+ PWN::SDR::GQRX.cmd(
29
29
  gqrx_sock: gqrx_sock,
30
30
  cmd: 'U RDS 0',
31
31
  resp_ok: 'RPRT 0'
32
32
  )
33
33
 
34
- PWN::SDR::GQRX.gqrx_cmd(
34
+ PWN::SDR::GQRX.cmd(
35
35
  gqrx_sock: gqrx_sock,
36
36
  cmd: 'U RDS 1',
37
37
  resp_ok: 'RPRT 0'
@@ -58,9 +58,9 @@ module PWN
58
58
 
59
59
  loop do
60
60
  rds_resp = {
61
- rds_pi: PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PI').to_s.strip.chomp.delete('.'),
62
- rds_ps_name: PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PS_NAME').to_s.strip.chomp,
63
- rds_radiotext: PWN::SDR::GQRX.gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_RADIOTEXT').to_s.strip.chomp
61
+ rds_pi: PWN::SDR::GQRX.cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PI').to_s.strip.chomp.delete('.'),
62
+ rds_ps_name: PWN::SDR::GQRX.cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_PS_NAME').to_s.strip.chomp,
63
+ rds_radiotext: PWN::SDR::GQRX.cmd(gqrx_sock: gqrx_sock, cmd: 'p RDS_RADIOTEXT').to_s.strip.chomp
64
64
  }
65
65
 
66
66
  # Only update when we have valid new data
@@ -81,13 +81,13 @@ module PWN
81
81
  prefix = "Program ID: #{rds_pi} | Station Name: #{rds_ps} | Radio Txt: "
82
82
 
83
83
  # minimum visibility
84
- available_for_rt = max_title_length - prefix.length
85
- available_for_rt = [available_for_rt, 10].max
84
+ available_for_term = max_title_length - prefix.length
85
+ available_for_term = [available_for_term, 10].max
86
86
 
87
87
  rt_display = rds_rt
88
- rt_display = "#{rt_display[0...available_for_rt]}..." if rt_display.length > available_for_rt
88
+ rt_display = "#{rt_display[0...available_for_term]}..." if rt_display.length > available_for_term
89
89
 
90
- msg = prefix + rt_display
90
+ msg = "#{prefix}#{rt_display}"
91
91
  spinner.update(decoding: msg)
92
92
  last_resp = rds_resp.dup
93
93
  end
@@ -96,7 +96,7 @@ module PWN
96
96
  if $stdin.wait_readable(0)
97
97
  begin
98
98
  char = $stdin.read_nonblock(1)
99
- break if char == skip_rds
99
+ break if char == skip_freq_char
100
100
  rescue IO::WaitReadable, EOFError
101
101
  # No-op
102
102
  end
@@ -124,7 +124,7 @@ module PWN
124
124
  public_class_method def self.help
125
125
  puts "USAGE:
126
126
  #{self}.decode(
127
- freq_obj: 'required - freq_obj returned from PWN::SDR::Receiver::GQRX.init_freq method'
127
+ freq_obj: 'required - freq_obj returned from PWN::SDR::GQRX.init_freq method'
128
128
  )
129
129
 
130
130
  #{self}.authors
@@ -8,6 +8,7 @@ module PWN
8
8
  # Deocder Module for SDR signals.
9
9
  module Decoder
10
10
  autoload :GSM, 'pwn/sdr/decoder/gsm'
11
+ autoload :POCSAG, 'pwn/sdr/decoder/pocsag'
11
12
  autoload :RDS, 'pwn/sdr/decoder/rds'
12
13
 
13
14
  # Display a List of Every PWN::AI Module