pwn 0.5.75 → 0.5.76

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cba5aa01f8984c7ba1ce83fa78dc1d095b4d861396b9232ab3f76b3016006a3
4
- data.tar.gz: 7f485302aa1bf96ce268673fb81b954146de4c2ccc9689019e7f511b2f9e025e
3
+ metadata.gz: 6341c999a95a8ef1867905f07a60fd054d0ad217912b5b50dbafa1d42c8c1aa9
4
+ data.tar.gz: dc476c26b6f833f7c78850e8a32f9ad5b68cb36f0110ca5b739b2d5e8a690a55
5
5
  SHA512:
6
- metadata.gz: f7f4289fa20980acead88c2fe8d4229e4e264fd19781b9bfe36992eeff5f9fecabbc8d90d65b508d0eee73ae0277d97a54818cf2c8f9eadac6fbf4ee6719bd05
7
- data.tar.gz: 8ed257b5ecf62599422d90dea3fba4e2bf03a8bf5831e793cd91e2fc138bd5cecf820abd477b6f8689b55934e4d4629ab72c9387b62ec812ab35d881591a9bbc
6
+ metadata.gz: 30126968532893656b7d1db6bd1afb32a46b59831d9156fe7d1b4eaa317609b5c8e5a268e468ab4c7bc922b0731049485db14a703d24f958c600c6da564d77d3
7
+ data.tar.gz: a6a8d6b2d84a71bf9730885b1a7b1c2d746d1e6ac8c22183e089f03260cc57eeed8ed79f619093e11e087c4267dd3ca113fd9175bc9837d685c4b6795ea099e0
data/Gemfile CHANGED
@@ -81,7 +81,7 @@ gem 'ruby-nmap', '1.0.3'
81
81
  gem 'ruby-saml', '1.16.0'
82
82
  gem 'rvm', '1.11.3.9'
83
83
  gem 'savon', '2.15.0'
84
- gem 'selenium-devtools', '0.122.0'
84
+ gem 'selenium-devtools', '0.123.0'
85
85
  gem 'serialport', '1.3.2'
86
86
  # gem 'sinatra', '4.0.0'
87
87
  gem 'slack-ruby-client', '2.3.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.75]:001 >>> PWN.help
40
+ pwn[v0.5.76]: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.0@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.75]:001 >>> PWN.help
55
+ pwn[v0.5.76]: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.0@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.75]:001 >>> PWN.help
65
+ pwn[v0.5.76]: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
@@ -73,282 +73,6 @@ if opts.empty?
73
73
  exit 1
74
74
  end
75
75
 
76
- def gqrx_cmd(opts = {})
77
- gqrx_sock = opts[:gqrx_sock]
78
- cmd = opts[:cmd]
79
- resp_ok = opts[:resp_ok]
80
-
81
- # Most Recent GQRX Command Set:
82
- # https://raw.githubusercontent.com/gqrx-sdr/gqrx/master/resources/remote-control.txt
83
- # Supported commands:
84
- # f Get frequency [Hz]
85
- # F <frequency> Set frequency [Hz]
86
- # m Get demodulator mode and passband
87
- # M <mode> [passband]
88
- # Set demodulator mode and passband [Hz]
89
- # Passing a '?' as the first argument instead of 'mode' will return
90
- # a space separated list of radio backend supported modes.
91
- # l|L ?
92
- # Get a space separated list of settings available for reading (l) or writing (L).
93
- # l STRENGTH
94
- # Get signal strength [dBFS]
95
- # l SQL
96
- # Get squelch threshold [dBFS]
97
- # L SQL <sql>
98
- # Set squelch threshold to <sql> [dBFS]
99
- # l AF
100
- # Get audio gain [dB]
101
- # L AF <gain>
102
- # Set audio gain to <gain> [dB]
103
- # l <gain_name>_GAIN
104
- # Get the value of the gain setting with the name <gain_name>
105
- # L <gain_name>_GAIN <value>
106
- # Set the value of the gain setting with the name <gain_name> to <value>
107
- # p RDS_PI
108
- # Get the RDS PI code (in hexadecimal). Returns 0000 if not applicable.
109
- # u RECORD
110
- # Get status of audio recorder
111
- # U RECORD <status>
112
- # Set status of audio recorder to <status>
113
- # u DSP
114
- # Get DSP (SDR receiver) status
115
- # U DSP <status>
116
- # Set DSP (SDR receiver) status to <status>
117
- # u RDS
118
- # Get RDS decoder to <status>. Only functions in WFM mode.
119
- # U RDS <status>
120
- # Set RDS decoder to <status>. Only functions in WFM mode.
121
- # q|Q
122
- # Close connection
123
- # AOS
124
- # Acquisition of signal (AOS) event, start audio recording
125
- # LOS
126
- # Loss of signal (LOS) event, stop audio recording
127
- # LNB_LO [frequency]
128
- # If frequency [Hz] is specified set the LNB LO frequency used for
129
- # display. Otherwise print the current LNB LO frequency [Hz].
130
- # \chk_vfo
131
- # Get VFO option status (only usable for hamlib compatibility)
132
- # \dump_state
133
- # Dump state (only usable for hamlib compatibility)
134
- # \get_powerstat
135
- # Get power status (only usable for hamlib compatibility)
136
- # v
137
- # Get 'VFO' (only usable for hamlib compatibility)
138
- # V
139
- # Set 'VFO' (only usable for hamlib compatibility)
140
- # s
141
- # Get 'Split' mode (only usable for hamlib compatibility)
142
- # S
143
- # Set 'Split' mode (only usable for hamlib compatibility)
144
- # _
145
- # Get version
146
- #
147
- # Reply:
148
- # RPRT 0
149
- # Command successful
150
- # RPRT 1
151
- # Command failed
152
-
153
- gqrx_sock.write("#{cmd}\n")
154
- response = []
155
- got_freq = false
156
- # Read all responses from gqrx_sock.write
157
- timeout = 0.001 if timeout.nil?
158
-
159
- begin
160
- response.push(gqrx_sock.readline.chomp) while gqrx_sock.wait_readable(timeout)
161
- raise IOError if response.empty?
162
- rescue IOError
163
- timeout += 0.001
164
- retry
165
- end
166
-
167
- got_int_value_in_resp = true if response.first.to_i.positive?
168
- response = response.first if response.length == 1
169
-
170
- raise "ERROR!!! Command: #{cmd} Expected Resp: #{resp_ok}, Got: #{response}" if resp_ok && response != resp_ok
171
-
172
- if got_int_value_in_resp
173
- fixed_len_freq = format('%0.12d', response.to_i)
174
- freq_segments = fixed_len_freq.scan(/.{3}/)
175
- first_non_zero_index = freq_segments.index { |s| s.to_i.positive? }
176
- freq_segments = freq_segments[first_non_zero_index..-1]
177
- freq_segments[0] = freq_segments.first.to_i.to_s
178
- response = freq_segments.join('.')
179
- end
180
-
181
- # DEBUG
182
- # puts response.inspect
183
- # puts response.length
184
-
185
- response
186
- rescue RuntimeError => e
187
- puts 'WARNING: RF Gain is not supported by the radio backend.' if e.message.include?('Command: L RF_GAIN')
188
- puts 'WARNING: Intermediate Gain is not supported by the radio backend.' if e.message.include?('Command: L IF_GAIN')
189
- puts 'WARNING: Baseband Gain is not supported by the radio backend.' if e.message.include?('Command: L BB_GAIN')
190
-
191
- raise e unless e.message.include?('Command: L RF_GAIN') ||
192
- e.message.include?('Command: L IF_GAIN') ||
193
- e.message.include?('Command: L BB_GAIN')
194
- end
195
-
196
- def init_freq(opts = {})
197
- gqrx_sock = opts[:gqrx_sock]
198
- demodulator_mode = opts[:demodulator_mode]
199
- bandwidth = opts[:bandwidth]
200
- this_freq = opts[:this_freq]
201
- lock_freq_duration = opts[:lock_freq_duration]
202
- strength_lock = opts[:strength_lock]
203
-
204
- demod_n_passband = gqrx_cmd(
205
- gqrx_sock: gqrx_sock,
206
- cmd: 'm'
207
- )
208
-
209
- change_freq_resp = gqrx_cmd(
210
- gqrx_sock: gqrx_sock,
211
- cmd: "F #{this_freq}",
212
- resp_ok: 'RPRT 0'
213
- )
214
-
215
- current_freq = gqrx_cmd(
216
- gqrx_sock: gqrx_sock,
217
- cmd: 'f'
218
- )
219
-
220
- audio_gain_db = gqrx_cmd(
221
- gqrx_sock: gqrx_sock,
222
- cmd: 'l AF'
223
- ).to_f
224
-
225
- current_strength = gqrx_cmd(
226
- gqrx_sock: gqrx_sock,
227
- cmd: 'l STRENGTH'
228
- ).to_f
229
-
230
- current_squelch = gqrx_cmd(
231
- gqrx_sock: gqrx_sock,
232
- cmd: 'l SQL'
233
- ).to_f
234
-
235
- rf_gain = gqrx_cmd(
236
- gqrx_sock: gqrx_sock,
237
- cmd: 'l RF_GAIN'
238
- ).to_f
239
-
240
- if_gain = gqrx_cmd(
241
- gqrx_sock: gqrx_sock,
242
- cmd: 'l IF_GAIN'
243
- ).to_f
244
-
245
- bb_gain = gqrx_cmd(
246
- gqrx_sock: gqrx_sock,
247
- cmd: 'l BB_GAIN'
248
- ).to_f
249
-
250
- init_freq_hash = {
251
- demod_mode_n_passband: demod_n_passband,
252
- frequency: current_freq,
253
- bandwidth: bandwidth,
254
- audio_gain_db: audio_gain_db,
255
- squelch: current_squelch,
256
- rf_gain: rf_gain,
257
- if_gain: if_gain,
258
- bb_gain: bb_gain,
259
- strength: current_strength,
260
- strength_lock: strength_lock,
261
- lock_freq_duration: lock_freq_duration
262
- }
263
-
264
- print '.'
265
- sleep lock_freq_duration if current_strength > strength_lock
266
-
267
- init_freq_hash
268
- end
269
-
270
- def scan_range(opts = {})
271
- gqrx_sock = opts[:gqrx_sock]
272
- demodulator_mode = opts[:demodulator_mode]
273
- bandwidth = opts[:bandwidth]
274
- start_freq = opts[:start_freq]
275
- target_freq = opts[:target_freq]
276
- precision = opts[:precision]
277
- lock_freq_duration = opts[:lock_freq_duration]
278
- strength_lock = opts[:strength_lock]
279
-
280
- multiplier = 10**(precision - 1)
281
- prev_freq_hash = {
282
- demod_mode_n_passband: demodulator_mode,
283
- frequency: start_freq,
284
- bandwidth: bandwidth,
285
- audio_gain_db: 0.0,
286
- squelch: 0.0,
287
- rf_gain: 0.0,
288
- if_gain: 0.0,
289
- bb_gain: 0.0,
290
- strength: 0.0,
291
- strength_lock: strength_lock,
292
- lock_freq_duration: lock_freq_duration
293
- }
294
- if start_freq > target_freq
295
- start_freq.downto(target_freq) do |this_freq|
296
- next unless (this_freq % multiplier).zero?
297
-
298
- init_freq_hash = init_freq(
299
- gqrx_sock: gqrx_sock,
300
- demodulator_mode: demodulator_mode,
301
- bandwidth: bandwidth,
302
- this_freq: this_freq,
303
- lock_freq_duration: lock_freq_duration,
304
- strength_lock: strength_lock
305
- )
306
-
307
- current_strength = init_freq_hash[:strength]
308
- prev_strength = prev_freq_hash[:strength]
309
- prev_freq = prev_freq_hash[:frequency]
310
-
311
- approaching_detection = true if current_strength > prev_strength &&
312
- current_strength > strength_lock
313
- if approaching_detection && current_strength <= prev_strength
314
- puts "\n**** Found a signal ~ #{prev_freq} Hz ****"
315
- puts JSON.pretty_generate(prev_freq_hash)
316
- approaching_detection = false
317
- end
318
-
319
- prev_freq_hash = init_freq_hash
320
- end
321
- else
322
- this_freq = start_freq
323
- while this_freq <= target_freq
324
- init_freq_hash = init_freq(
325
- gqrx_sock: gqrx_sock,
326
- demodulator_mode: demodulator_mode,
327
- bandwidth: bandwidth,
328
- this_freq: this_freq,
329
- lock_freq_duration: lock_freq_duration,
330
- strength_lock: strength_lock
331
- )
332
-
333
- current_strength = init_freq_hash[:strength]
334
- prev_strength = prev_freq_hash[:strength]
335
- prev_freq = prev_freq_hash[:frequency]
336
-
337
- approaching_detection = true if current_strength > prev_strength &&
338
- current_strength > strength_lock
339
- if approaching_detection && current_strength < prev_strength
340
- puts "\n**** Discovered a signal ~ #{prev_freq} Hz ****"
341
- puts JSON.pretty_generate(prev_freq_hash)
342
- approaching_detection = false
343
- end
344
-
345
- prev_freq_hash = init_freq_hash
346
-
347
- this_freq += multiplier
348
- end
349
- end
350
- end
351
-
352
76
  begin
353
77
  pwn_provider = 'ruby-gem'
354
78
  pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.any? { |s| s == 'PWN_PROVIDER' }
@@ -358,11 +82,11 @@ begin
358
82
  target_freq = target_freq.to_i
359
83
  raise "ERROR: Invalid target frequency #{target_freq}" if target_freq.zero?
360
84
 
361
- host = opts[:host] ||= '127.0.0.1'
362
- port = opts[:port] ||= 7356
85
+ host = opts[:host]
86
+ port = opts[:port]
363
87
 
364
88
  puts "Connecting to GQRX at #{host}:#{port}..."
365
- gqrx_sock = PWN::Plugins::Sock.connect(target: host, port: port)
89
+ gqrx_sock = PWN::Plugins::GQRX.connect(target: host, port: port)
366
90
 
367
91
  start_freq = opts[:start_freq]
368
92
  start_freq = start_freq.to_s.delete('.') unless start_freq.nil?
@@ -377,7 +101,7 @@ begin
377
101
 
378
102
  puts "Setting demodulator mode to #{demodulator_mode} and bandwidth to #{bandwidth}..."
379
103
  bandwidth = bandwidth.to_s.delete('.').to_i unless bandwidth.nil?
380
- demod_resp = gqrx_cmd(
104
+ demod_resp = PWN::Plugins::GQRX.gqrx_cmd(
381
105
  gqrx_sock: gqrx_sock,
382
106
  cmd: "M #{demodulator_mode} #{bandwidth}",
383
107
  resp_ok: 'RPRT 0'
@@ -385,7 +109,7 @@ begin
385
109
 
386
110
  audio_gain_db = opts[:audio_gain_db] ||= 1.0
387
111
  audio_gain_db = audio_gain_db.to_f
388
- audio_gain_db_resp = gqrx_cmd(
112
+ audio_gain_db_resp = PWN::Plugins::GQRX.gqrx_cmd(
389
113
  gqrx_sock: gqrx_sock,
390
114
  cmd: "L AF #{audio_gain_db}",
391
115
  resp_ok: 'RPRT 0'
@@ -393,7 +117,7 @@ begin
393
117
 
394
118
  squelch = opts[:squelch] ||= -63.0
395
119
  squelch = squelch.to_f
396
- squelch_resp = gqrx_cmd(
120
+ squelch_resp = PWN::Plugins::GQRX.gqrx_cmd(
397
121
  gqrx_sock: gqrx_sock,
398
122
  cmd: "L SQL #{squelch}",
399
123
  resp_ok: 'RPRT 0'
@@ -411,7 +135,7 @@ begin
411
135
 
412
136
  rf_gain = opts[:rf_gain] ||= 0.0
413
137
  rf_gain = rf_gain.to_f
414
- rf_gain_resp = gqrx_cmd(
138
+ rf_gain_resp = PWN::Plugins::GQRX.gqrx_cmd(
415
139
  gqrx_sock: gqrx_sock,
416
140
  cmd: "L RF_GAIN #{rf_gain}",
417
141
  resp_ok: 'RPRT 0'
@@ -419,7 +143,7 @@ begin
419
143
 
420
144
  intermediate_gain = opts[:intermediate_gain] ||= 32.0
421
145
  intermediate_gain = intermediate_gain.to_f
422
- intermediate_resp = gqrx_cmd(
146
+ intermediate_resp = PWN::Plugins::GQRX.gqrx_cmd(
423
147
  gqrx_sock: gqrx_sock,
424
148
  cmd: "L IF_GAIN #{intermediate_gain}",
425
149
  resp_ok: 'RPRT 0'
@@ -427,7 +151,7 @@ begin
427
151
 
428
152
  baseband_gain = opts[:baseband_gain] ||= 10.0
429
153
  baseband_gain = baseband_gain.to_f
430
- baseband_resp = gqrx_cmd(
154
+ baseband_resp = PWN::Plugins::GQRX.gqrx_cmd(
431
155
  gqrx_sock: gqrx_sock,
432
156
  cmd: "L BB_GAIN #{baseband_gain}",
433
157
  resp_ok: 'RPRT 0'
@@ -437,7 +161,7 @@ begin
437
161
  t_freq_pretty = target_freq.to_s.chars.insert(-4, '.').insert(-8, '.').join
438
162
  puts "*** Scanning from #{s_freq_pretty} to #{t_freq_pretty}\n\n\n"
439
163
 
440
- scan_range(
164
+ PWN::Plugins::GQRX.scan_range(
441
165
  gqrx_sock: gqrx_sock,
442
166
  demodulator_mode: demodulator_mode,
443
167
  bandwidth: bandwidth,
@@ -454,5 +178,5 @@ rescue StandardError => e
454
178
  rescue Interrupt, SystemExit
455
179
  puts "\nGoodbye."
456
180
  ensure
457
- gqrx_sock = PWN::Plugins::Sock.disconnect(sock_obj: gqrx_sock)
181
+ gqrx_sock = PWN::Plugins::GQRX.disconnect(gqrx_sock: gqrx_sock)
458
182
  end
@@ -0,0 +1,361 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module PWN
6
+ module Plugins
7
+ # This plugin interacts with the remote control interface of GQRX.
8
+ module GQRX
9
+ # Supported Method Parameters::
10
+ # gqrx_sock = PWN::Plugins::GQRX.connect(
11
+ # target: 'optional - GQRX target IP address (defaults to 127.0.0.1)',
12
+ # port: 'optional - GQRX target port (defaults to 7356)'
13
+ # )
14
+ public_class_method def self.connect(opts = {})
15
+ target = opts[:target] ||= '127.0.0.1'
16
+ port = opts[:port] ||= 7356
17
+
18
+ PWN::Plugins::Sock.connect(target: target, port: port)
19
+ rescue StandardError => e
20
+ raise e
21
+ end
22
+
23
+ # Supported Method Parameters::
24
+ # gqrx_resp = PWN::Plugins::GQRX.gqrx_cmd(
25
+ # gqrx_sock: 'required - GQRX socket object returned from #connect method',
26
+ # cmd: 'required - GQRX command to execute'
27
+ # resp_ok: 'optional - Expected response from GQRX to indicate success'
28
+ # )
29
+
30
+ public_class_method def self.gqrx_cmd(opts = {})
31
+ gqrx_sock = opts[:gqrx_sock]
32
+ cmd = opts[:cmd]
33
+ resp_ok = opts[:resp_ok]
34
+
35
+ # Most Recent GQRX Command Set:
36
+ # https://raw.githubusercontent.com/gqrx-sdr/gqrx/master/resources/remote-control.txt
37
+ # Supported commands:
38
+ # f Get frequency [Hz]
39
+ # F <frequency> Set frequency [Hz]
40
+ # m Get demodulator mode and passband
41
+ # M <mode> [passband]
42
+ # Set demodulator mode and passband [Hz]
43
+ # Passing a '?' as the first argument instead of 'mode' will return
44
+ # a space separated list of radio backend supported modes.
45
+ # l|L ?
46
+ # Get a space separated list of settings available for reading (l) or writing (L).
47
+ # l STRENGTH
48
+ # Get signal strength [dBFS]
49
+ # l SQL
50
+ # Get squelch threshold [dBFS]
51
+ # L SQL <sql>
52
+ # Set squelch threshold to <sql> [dBFS]
53
+ # l AF
54
+ # Get audio gain [dB]
55
+ # L AF <gain>
56
+ # Set audio gain to <gain> [dB]
57
+ # l <gain_name>_GAIN
58
+ # Get the value of the gain setting with the name <gain_name>
59
+ # L <gain_name>_GAIN <value>
60
+ # Set the value of the gain setting with the name <gain_name> to <value>
61
+ # p RDS_PI
62
+ # Get the RDS PI code (in hexadecimal). Returns 0000 if not applicable.
63
+ # u RECORD
64
+ # Get status of audio recorder
65
+ # U RECORD <status>
66
+ # Set status of audio recorder to <status>
67
+ # u DSP
68
+ # Get DSP (SDR receiver) status
69
+ # U DSP <status>
70
+ # Set DSP (SDR receiver) status to <status>
71
+ # u RDS
72
+ # Get RDS decoder to <status>. Only functions in WFM mode.
73
+ # U RDS <status>
74
+ # Set RDS decoder to <status>. Only functions in WFM mode.
75
+ # q|Q
76
+ # Close connection
77
+ # AOS
78
+ # Acquisition of signal (AOS) event, start audio recording
79
+ # LOS
80
+ # Loss of signal (LOS) event, stop audio recording
81
+ # LNB_LO [frequency]
82
+ # If frequency [Hz] is specified set the LNB LO frequency used for
83
+ # display. Otherwise print the current LNB LO frequency [Hz].
84
+ # \chk_vfo
85
+ # Get VFO option status (only usable for hamlib compatibility)
86
+ # \dump_state
87
+ # Dump state (only usable for hamlib compatibility)
88
+ # \get_powerstat
89
+ # Get power status (only usable for hamlib compatibility)
90
+ # v
91
+ # Get 'VFO' (only usable for hamlib compatibility)
92
+ # V
93
+ # Set 'VFO' (only usable for hamlib compatibility)
94
+ # s
95
+ # Get 'Split' mode (only usable for hamlib compatibility)
96
+ # S
97
+ # Set 'Split' mode (only usable for hamlib compatibility)
98
+ # _
99
+ # Get version
100
+ #
101
+ # Reply:
102
+ # RPRT 0
103
+ # Command successful
104
+ # RPRT 1
105
+ # Command failed
106
+
107
+ gqrx_sock.write("#{cmd}\n")
108
+ response = []
109
+ got_freq = false
110
+ # Read all responses from gqrx_sock.write
111
+ timeout = 0.001 if timeout.nil?
112
+
113
+ begin
114
+ response.push(gqrx_sock.readline.chomp) while gqrx_sock.wait_readable(timeout)
115
+ raise IOError if response.empty?
116
+ rescue IOError
117
+ timeout += 0.001
118
+ retry
119
+ end
120
+
121
+ got_int_value_in_resp = true if response.first.to_i.positive?
122
+ response = response.first if response.length == 1
123
+
124
+ raise "ERROR!!! Command: #{cmd} Expected Resp: #{resp_ok}, Got: #{response}" if resp_ok && response != resp_ok
125
+
126
+ if got_int_value_in_resp
127
+ fixed_len_freq = format('%0.12d', response.to_i)
128
+ freq_segments = fixed_len_freq.scan(/.{3}/)
129
+ first_non_zero_index = freq_segments.index { |s| s.to_i.positive? }
130
+ freq_segments = freq_segments[first_non_zero_index..-1]
131
+ freq_segments[0] = freq_segments.first.to_i.to_s
132
+ response = freq_segments.join('.')
133
+ end
134
+
135
+ # DEBUG
136
+ # puts response.inspect
137
+ # puts response.length
138
+
139
+ response
140
+ rescue RuntimeError => e
141
+ puts 'WARNING: RF Gain is not supported by the radio backend.' if e.message.include?('Command: L RF_GAIN')
142
+ puts 'WARNING: Intermediate Gain is not supported by the radio backend.' if e.message.include?('Command: L IF_GAIN')
143
+ puts 'WARNING: Baseband Gain is not supported by the radio backend.' if e.message.include?('Command: L BB_GAIN')
144
+
145
+ raise e unless e.message.include?('Command: L RF_GAIN') ||
146
+ e.message.include?('Command: L IF_GAIN') ||
147
+ e.message.include?('Command: L BB_GAIN')
148
+ rescue StandardError => e
149
+ raise e
150
+ end
151
+
152
+ # Supported Method Parameters::
153
+ # PWN::Plugins::GQRX.init_freq(
154
+ # gqrx_sock: 'required - GQRX socket object returned from #connect method',
155
+ # freq: 'required - Frequency to set',
156
+ # demodulator_mode: 'optional - Demodulator mode (defaults to WFM)',
157
+ # bandwidth: 'optional - Bandwidth (defaults to 200000)',
158
+ # lock_freq_duration: 'optional - Lock frequency duration (defaults to 0.5)',
159
+ # strength_lock: 'optional - Strength lock (defaults to -60.0)'
160
+ # )
161
+ public_class_method def self.init_freq(opts = {})
162
+ gqrx_sock = opts[:gqrx_sock]
163
+ freq = opts[:freq]
164
+ demodulator_mode = opts[:demodulator_mode]
165
+ bandwidth = opts[:bandwidth]
166
+ lock_freq_duration = opts[:lock_freq_duration]
167
+ strength_lock = opts[:strength_lock]
168
+
169
+ demod_n_passband = gqrx_cmd(
170
+ gqrx_sock: gqrx_sock,
171
+ cmd: 'm'
172
+ )
173
+
174
+ change_freq_resp = gqrx_cmd(
175
+ gqrx_sock: gqrx_sock,
176
+ cmd: "F #{freq}",
177
+ resp_ok: 'RPRT 0'
178
+ )
179
+
180
+ current_freq = gqrx_cmd(
181
+ gqrx_sock: gqrx_sock,
182
+ cmd: 'f'
183
+ )
184
+
185
+ audio_gain_db = gqrx_cmd(
186
+ gqrx_sock: gqrx_sock,
187
+ cmd: 'l AF'
188
+ ).to_f
189
+
190
+ current_strength = gqrx_cmd(
191
+ gqrx_sock: gqrx_sock,
192
+ cmd: 'l STRENGTH'
193
+ ).to_f
194
+
195
+ current_squelch = gqrx_cmd(
196
+ gqrx_sock: gqrx_sock,
197
+ cmd: 'l SQL'
198
+ ).to_f
199
+
200
+ rf_gain = gqrx_cmd(
201
+ gqrx_sock: gqrx_sock,
202
+ cmd: 'l RF_GAIN'
203
+ ).to_f
204
+
205
+ if_gain = gqrx_cmd(
206
+ gqrx_sock: gqrx_sock,
207
+ cmd: 'l IF_GAIN'
208
+ ).to_f
209
+
210
+ bb_gain = gqrx_cmd(
211
+ gqrx_sock: gqrx_sock,
212
+ cmd: 'l BB_GAIN'
213
+ ).to_f
214
+
215
+ init_freq_hash = {
216
+ demod_mode_n_passband: demod_n_passband,
217
+ frequency: current_freq,
218
+ bandwidth: bandwidth,
219
+ audio_gain_db: audio_gain_db,
220
+ squelch: current_squelch,
221
+ rf_gain: rf_gain,
222
+ if_gain: if_gain,
223
+ bb_gain: bb_gain,
224
+ strength: current_strength,
225
+ strength_lock: strength_lock,
226
+ lock_freq_duration: lock_freq_duration
227
+ }
228
+
229
+ print '.'
230
+ sleep lock_freq_duration if current_strength > strength_lock
231
+
232
+ init_freq_hash
233
+ rescue StandardError => e
234
+ raise e
235
+ end
236
+
237
+ # Supported Method Parameters::
238
+ # PWN::Plugins::GQRX.scan_range(
239
+ # gqrx_sock: 'required - GQRX socket object returned from #connect method',
240
+ # demodulator_mode: 'required - Demodulator mode',
241
+ # bandwidth: 'required - Bandwidth',
242
+ # start_freq: 'required - Starting frequency',
243
+ # target_freq: 'required - Target frequency',
244
+ # precision: 'required - Precision',
245
+ # lock_freq_duration: 'optional - Lock frequency duration (defaults to 0.5)',
246
+ # strength_lock: 'optional - Strength lock (defaults to -60.0)'
247
+ # )
248
+
249
+ public_class_method def self.scan_range(opts = {})
250
+ gqrx_sock = opts[:gqrx_sock]
251
+ demodulator_mode = opts[:demodulator_mode]
252
+ bandwidth = opts[:bandwidth]
253
+ start_freq = opts[:start_freq]
254
+ target_freq = opts[:target_freq]
255
+ precision = opts[:precision]
256
+ lock_freq_duration = opts[:lock_freq_duration]
257
+ strength_lock = opts[:strength_lock]
258
+
259
+ multiplier = 10**(precision - 1)
260
+ prev_freq_hash = {
261
+ demod_mode_n_passband: demodulator_mode,
262
+ frequency: start_freq,
263
+ bandwidth: bandwidth,
264
+ audio_gain_db: 0.0,
265
+ squelch: 0.0,
266
+ rf_gain: 0.0,
267
+ if_gain: 0.0,
268
+ bb_gain: 0.0,
269
+ strength: 0.0,
270
+ strength_lock: strength_lock,
271
+ lock_freq_duration: lock_freq_duration
272
+ }
273
+ if start_freq > target_freq
274
+ start_freq.downto(target_freq) do |freq|
275
+ next unless (freq % multiplier).zero?
276
+
277
+ init_freq_hash = init_freq(
278
+ gqrx_sock: gqrx_sock,
279
+ freq: freq,
280
+ demodulator_mode: demodulator_mode,
281
+ bandwidth: bandwidth,
282
+ lock_freq_duration: lock_freq_duration,
283
+ strength_lock: strength_lock
284
+ )
285
+
286
+ current_strength = init_freq_hash[:strength]
287
+ prev_strength = prev_freq_hash[:strength]
288
+ prev_freq = prev_freq_hash[:frequency]
289
+
290
+ approaching_detection = true if current_strength > prev_strength &&
291
+ current_strength > strength_lock
292
+ if approaching_detection && current_strength <= prev_strength
293
+ puts "\n**** Found a signal ~ #{prev_freq} Hz ****"
294
+ puts JSON.pretty_generate(prev_freq_hash)
295
+ approaching_detection = false
296
+ end
297
+
298
+ prev_freq_hash = init_freq_hash
299
+ end
300
+ else
301
+ freq = start_freq
302
+ while freq <= target_freq
303
+ init_freq_hash = init_freq(
304
+ gqrx_sock: gqrx_sock,
305
+ demodulator_mode: demodulator_mode,
306
+ bandwidth: bandwidth,
307
+ freq: freq,
308
+ lock_freq_duration: lock_freq_duration,
309
+ strength_lock: strength_lock
310
+ )
311
+
312
+ current_strength = init_freq_hash[:strength]
313
+ prev_strength = prev_freq_hash[:strength]
314
+ prev_freq = prev_freq_hash[:frequency]
315
+
316
+ approaching_detection = true if current_strength > prev_strength &&
317
+ current_strength > strength_lock
318
+ if approaching_detection && current_strength < prev_strength
319
+ puts "\n**** Discovered a signal ~ #{prev_freq} Hz ****"
320
+ puts JSON.pretty_generate(prev_freq_hash)
321
+ approaching_detection = false
322
+ end
323
+
324
+ prev_freq_hash = init_freq_hash
325
+
326
+ freq += multiplier
327
+ end
328
+ end
329
+ end
330
+
331
+ # Supported Method Parameters::
332
+ # PWN::Plugins::GQRX.disconnect(
333
+ # gqrx_sock: 'required - GQRX socket object returned from #connect method'
334
+ # )
335
+ public_class_method def self.disconnect(opts = {})
336
+ gqrx_sock = opts[:gqrx_sock]
337
+
338
+ PWN::Plugins::Sock.disconnect(sock_obj: gqrx_sock)
339
+ rescue StandardError => e
340
+ raise e
341
+ end
342
+
343
+ # Author(s):: 0day Inc. <request.pentest@0dayinc.com>
344
+
345
+ public_class_method def self.authors
346
+ "AUTHOR(S):
347
+ 0day Inc. <request.pentest@0dayinc.com>
348
+ "
349
+ end
350
+
351
+ # Display Usage for this Module
352
+
353
+ public_class_method def self.help
354
+ puts "USAGE:
355
+
356
+ #{self}.authors
357
+ "
358
+ end
359
+ end
360
+ end
361
+ end
data/lib/pwn/plugins.rb CHANGED
@@ -28,6 +28,7 @@ module PWN
28
28
  autoload :Fuzz, 'pwn/plugins/fuzz'
29
29
  autoload :Git, 'pwn/plugins/git'
30
30
  autoload :Github, 'pwn/plugins/github'
31
+ autoload :GQRX, 'pwn/plugins/gqrx'
31
32
  autoload :HackerOne, 'pwn/plugins/hacker_one'
32
33
  autoload :IBMAppscan, 'pwn/plugins/ibm_appscan'
33
34
  autoload :IPInfo, 'pwn/plugins/ip_info'
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.75'
4
+ VERSION = '0.5.76'
5
5
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe PWN::Plugins::GQRX do
6
+ it 'should display information for authors' do
7
+ authors_response = PWN::Plugins::GQRX
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::Plugins::GQRX
13
+ expect(help_response).to respond_to :help
14
+ end
15
+ 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.75
4
+ version: 0.5.76
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-03-26 00:00:00.000000000 Z
11
+ date: 2024-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -968,14 +968,14 @@ dependencies:
968
968
  requirements:
969
969
  - - '='
970
970
  - !ruby/object:Gem::Version
971
- version: 0.122.0
971
+ version: 0.123.0
972
972
  type: :runtime
973
973
  prerelease: false
974
974
  version_requirements: !ruby/object:Gem::Requirement
975
975
  requirements:
976
976
  - - '='
977
977
  - !ruby/object:Gem::Version
978
- version: 0.122.0
978
+ version: 0.123.0
979
979
  - !ruby/object:Gem::Dependency
980
980
  name: serialport
981
981
  requirement: !ruby/object:Gem::Requirement
@@ -1758,6 +1758,7 @@ files:
1758
1758
  - lib/pwn/plugins/fuzz.rb
1759
1759
  - lib/pwn/plugins/git.rb
1760
1760
  - lib/pwn/plugins/github.rb
1761
+ - lib/pwn/plugins/gqrx.rb
1761
1762
  - lib/pwn/plugins/hacker_one.rb
1762
1763
  - lib/pwn/plugins/ibm_appscan.rb
1763
1764
  - lib/pwn/plugins/ip_info.rb
@@ -2087,6 +2088,7 @@ files:
2087
2088
  - spec/lib/pwn/plugins/fuzz_spec.rb
2088
2089
  - spec/lib/pwn/plugins/git_spec.rb
2089
2090
  - spec/lib/pwn/plugins/github_spec.rb
2091
+ - spec/lib/pwn/plugins/gqrx_spec.rb
2090
2092
  - spec/lib/pwn/plugins/hacker_one_spec.rb
2091
2093
  - spec/lib/pwn/plugins/ibm_appscan_spec.rb
2092
2094
  - spec/lib/pwn/plugins/ip_info_spec.rb