pwn 0.5.52 → 0.5.54

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: 0f9d1c877c0b0d4a074cff09b2b7f8c1fcb4dbb741f0477f8ae200bad601b68c
4
- data.tar.gz: 2a92813b9ca894105d89bc468c1cd8c45ab1b11393f7fffea6c6c1ff23ba46e7
3
+ metadata.gz: 60eef74930533185419b5dbf2c7615322d773c7903976ceb024b5c253f9a0671
4
+ data.tar.gz: 4106f259eac7b4900786364aa925da5129f4708becfd1a0c22567b5060fbcf08
5
5
  SHA512:
6
- metadata.gz: 2ef418cb373ff1e3fb95826cd98b47be932e70f0e87f4ce7e9694972441adc203f0b1dd67acc2341e9ab78170706550f4f39c06664acbeb3313b132641326db9
7
- data.tar.gz: 88fc2a90c23beeb8a352bc41e48ef211150b50e9555d0534013c143dd66b9ee38952b68bf9d89f1636ddc15258ba76724946f128ebd7ad6f1dabd78102619aa2
6
+ metadata.gz: 60882fc81a2a5d5fb051468b59b03363b930e9e13f3ec843663c726c7c57fc7e2fcc58fc578b9d40b3b5e7aa4fd93cf5245fa82e1fbc075371f5136cd81b900d
7
+ data.tar.gz: 79e0900f4cd455674753db56441e2d87bef11f86a1d976f8a2a6424369e15636e883bb8ef18da4f5fabba6205289dabd7979886b0409f39a5fe17bd8fd44b35b
data/Gemfile CHANGED
@@ -52,7 +52,7 @@ gem 'net-ldap', '0.19.0'
52
52
  gem 'net-openvpn', '0.8.7'
53
53
  gem 'net-smtp', '0.4.0.1'
54
54
  gem 'nexpose', '7.3.0'
55
- gem 'nokogiri', '1.16.2'
55
+ gem 'nokogiri', '1.16.3'
56
56
  gem 'nokogiri-diff', '0.3.0'
57
57
  gem 'oily_png', '1.2.1'
58
58
  gem 'open3', '0.2.1'
@@ -87,7 +87,7 @@ gem 'serialport', '1.3.2'
87
87
  gem 'slack-ruby-client', '2.3.0'
88
88
  gem 'socksify', '1.7.1'
89
89
  gem 'spreadsheet', '1.3.1'
90
- gem 'sqlite3', '1.7.2'
90
+ gem 'sqlite3', '1.7.3'
91
91
  gem 'thin', '1.8.2'
92
92
  gem 'tty-prompt', '0.23.1'
93
93
  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.52]:001 >>> PWN.help
40
+ pwn[v0.5.54]: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.52]:001 >>> PWN.help
55
+ pwn[v0.5.54]: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.52]:001 >>> PWN.help
65
+ pwn[v0.5.54]: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
@@ -15,6 +15,10 @@ OptionParser.new do |options|
15
15
  opts[:target_freq] = e
16
16
  end
17
17
 
18
+ options.on('-sFREQ', '--start-freq=FREQ', '<Optional - Frequency to Set when Scanning Begins (Defaults to last known frequency)>') do |s|
19
+ opts[:start_freq] = s
20
+ end
21
+
18
22
  options.on('-hHOST', '--host=HOST', '<Optional - GQRX Host (Defaults to 127.0.0.1)>') do |h|
19
23
  opts[:host] = h
20
24
  end
@@ -23,27 +27,31 @@ OptionParser.new do |options|
23
27
  opts[:port] = p
24
28
  end
25
29
 
26
- options.on('-dMODE', '--demodulator-mode=MODE', '<Optional - Set Demodulator ModeOFF | RAW | AM | FM | WFM | WFM_ST | WFM_ST_OIRT | LSB |USB | CW | CWL | CWU (Defaults to AM)>') do |d|
30
+ options.on('-AFLOAT', '--audio-gain=FLOAT', '<Optional - Set audio gain -80.0 to 50.0 (Defaults to 1.0)>') do |a|
31
+ opts[:audio_gain_db] = a
32
+ end
33
+
34
+ options.on('-BHZ', '--bandwidth=HZ', '<Optional - Set Bandwidth (Defaults to 200.000)>') do |b|
35
+ opts[:bandwidth] = b
36
+ end
37
+
38
+ options.on('-DMODE', '--demodulator-mode=MODE', '<Optional - Set Demodulator ModeOFF | RAW | AM | FM | WFM | WFM_ST | WFM_ST_OIRT | LSB |USB | CW | CWL | CWU (Defaults to WFM_ST)>') do |d|
27
39
  opts[:demodulator_mode] = d
28
40
  end
29
41
 
30
- options.on('-sFREQ', '--start-freq=FREQ', '<Optional - Frequency to Set when Scanning Begins (Defaults to last known frequency)>') do |s|
31
- opts[:start_freq] = s
42
+ options.on('-LFLOAT', '--lock-freq-duration=FLOAT', '<Optional - Duration to lock onto Freqency when Strength < --strength value (Defaults to 3)>') do |l|
43
+ opts[:lock_on_freq_duration] = l
32
44
  end
33
45
 
34
- options.on('-qFLOAT', '--squelch=FLOAT', '<Optional - Squelch Threshold (Defaults to -63)>') do |q|
46
+ options.on('-QFLOAT', '--squelch=FLOAT', '<Optional - Squelch Threshold -150 to 0(Defaults to -63.0)>') do |q|
35
47
  opts[:squelch] = q
36
48
  end
37
49
 
38
- options.on('-PPLACE', '--precision=PLACE', '<Optional - Precision of Frequency 1-12 (Defaults to 3)>') do |p|
50
+ options.on('-PINT', '--precision=INT', '<Optional - Precision of Frequency 1-12 (Defaults to 6)>') do |p|
39
51
  opts[:precision] = p
40
52
  end
41
53
 
42
- options.on('-LFLOAT', '--lock-on-freq-duration=FLOAT', '<Optional - Duration to lock onto Freqency when Strength < --strength value (Defaults to -63)>') do |l|
43
- opts[:lock_on_freq_duration] = l
44
- end
45
-
46
- options.on('-SFLOAT', '--strength=FLOAT', '<Optional - Strength to trigger sleep (Defaults to 0)>') do |s|
54
+ options.on('-SFLOAT', '--strength=FLOAT', '<Optional - Strength to trigger sleep (Defaults to -63.3)>') do |s|
47
55
  opts[:strength] = s
48
56
  end
49
57
  end.parse!
@@ -54,78 +62,174 @@ if opts.empty?
54
62
  end
55
63
 
56
64
  def gqrx_cmd(opts = {})
57
- # f - Get frequency [Hz]
58
- # F - Set frequency [Hz]
59
- # m - Get demodulator mode
60
- # M - Set demodulator mode (OFF, RAW, AM, FM, WFM, WFM_ST,
61
- # WFM_ST_OIRT, LSB, USB, CW, CWL, CWU)
62
- # l STRENGTH - Get signal strength [dBFS]
63
- # l SQL - Get squelch threshold [dBFS]
64
- # L SQL <sql> - Set squelch threshold to <sql> [dBFS]
65
- # u RECORD - Get status of audio recorder
66
- # U RECORD <status> - Set status of audio recorder to <status>
67
- # c - Close connection
68
- # AOS - Acquisition of signal (AOS) event, start audio recording
69
- # LOS - Loss of signal (LOS) event, stop audio recording
70
- # \dump_state - Dump state (only usable for compatibility)
71
65
  gqrx_sock = opts[:gqrx_sock]
72
66
  cmd = opts[:cmd]
67
+ resp_ok = opts[:resp_ok]
68
+
69
+ # Most Recent GQRX Command Set:
70
+ # https://raw.githubusercontent.com/gqrx-sdr/gqrx/master/resources/remote-control.txt
71
+ # Supported commands:
72
+ # f Get frequency [Hz]
73
+ # F <frequency> Set frequency [Hz]
74
+ # m Get demodulator mode and passband
75
+ # M <mode> [passband]
76
+ # Set demodulator mode and passband [Hz]
77
+ # Passing a '?' as the first argument instead of 'mode' will return
78
+ # a space separated list of radio backend supported modes.
79
+ # l|L ?
80
+ # Get a space separated list of settings available for reading (l) or writing (L).
81
+ # l STRENGTH
82
+ # Get signal strength [dBFS]
83
+ # l SQL
84
+ # Get squelch threshold [dBFS]
85
+ # L SQL <sql>
86
+ # Set squelch threshold to <sql> [dBFS]
87
+ # l AF
88
+ # Get audio gain [dB]
89
+ # L AF <gain>
90
+ # Set audio gain to <gain> [dB]
91
+ # l <gain_name>_GAIN
92
+ # Get the value of the gain setting with the name <gain_name>
93
+ # L <gain_name>_GAIN <value>
94
+ # Set the value of the gain setting with the name <gain_name> to <value>
95
+ # p RDS_PI
96
+ # Get the RDS PI code (in hexadecimal). Returns 0000 if not applicable.
97
+ # u RECORD
98
+ # Get status of audio recorder
99
+ # U RECORD <status>
100
+ # Set status of audio recorder to <status>
101
+ # u DSP
102
+ # Get DSP (SDR receiver) status
103
+ # U DSP <status>
104
+ # Set DSP (SDR receiver) status to <status>
105
+ # u RDS
106
+ # Get RDS decoder to <status>. Only functions in WFM mode.
107
+ # U RDS <status>
108
+ # Set RDS decoder to <status>. Only functions in WFM mode.
109
+ # q|Q
110
+ # Close connection
111
+ # AOS
112
+ # Acquisition of signal (AOS) event, start audio recording
113
+ # LOS
114
+ # Loss of signal (LOS) event, stop audio recording
115
+ # LNB_LO [frequency]
116
+ # If frequency [Hz] is specified set the LNB LO frequency used for
117
+ # display. Otherwise print the current LNB LO frequency [Hz].
118
+ # \chk_vfo
119
+ # Get VFO option status (only usable for hamlib compatibility)
120
+ # \dump_state
121
+ # Dump state (only usable for hamlib compatibility)
122
+ # \get_powerstat
123
+ # Get power status (only usable for hamlib compatibility)
124
+ # v
125
+ # Get 'VFO' (only usable for hamlib compatibility)
126
+ # V
127
+ # Set 'VFO' (only usable for hamlib compatibility)
128
+ # s
129
+ # Get 'Split' mode (only usable for hamlib compatibility)
130
+ # S
131
+ # Set 'Split' mode (only usable for hamlib compatibility)
132
+ # _
133
+ # Get version
134
+ #
135
+ # Reply:
136
+ # RPRT 0
137
+ # Command successful
138
+ # RPRT 1
139
+ # Command failed
73
140
 
74
141
  gqrx_sock.write("#{cmd}\n")
75
- does_respond = gqrx_sock.wait_readable
76
- gqrx_sock.readline.chomp if does_respond
142
+ response = []
143
+ got_freq = false
144
+ # Read all responses from gqrx_sock.write
145
+ timeout = 0.01 if timeout.nil?
146
+ begin
147
+ response.push(gqrx_sock.readline.chomp) while gqrx_sock.wait_readable(timeout)
148
+ raise IOError if response.empty?
149
+ rescue IOError
150
+ timeout += 0.001
151
+ retry
152
+ end
153
+
154
+ got_int_value_in_resp = true if response.first.to_i.positive?
155
+ response = response.first if response.length == 1
156
+
157
+ raise "ERROR!!! Command: #{cmd} Expected Resp: #{resp_ok}, Got: #{response}" if resp_ok && response != resp_ok
158
+
159
+ if got_int_value_in_resp
160
+ fixed_len_freq = format('%0.12d', response.to_i)
161
+ freq_segments = fixed_len_freq.scan(/.{3}/)
162
+ first_non_zero_index = freq_segments.index { |s| s.to_i.positive? }
163
+ freq_segments = freq_segments[first_non_zero_index..-1]
164
+ freq_segments[0] = freq_segments.first.to_i.to_s
165
+ response = freq_segments.join('.')
166
+ end
167
+
168
+ # DEBUG
169
+ # puts response.inspect
170
+ # puts response.length
171
+
172
+ response
77
173
  end
78
174
 
79
175
  def init_freq(opts = {})
80
176
  gqrx_sock = opts[:gqrx_sock]
177
+ demodulator_mode = opts[:demodulator_mode]
178
+ bandwidth = opts[:bandwidth]
81
179
  this_freq = opts[:this_freq]
82
180
  lock_on_freq_duration = opts[:lock_on_freq_duration]
83
181
  strength = opts[:strength]
84
182
 
85
- change_frreq_resp = gqrx_cmd(
183
+ demod_n_passband = gqrx_cmd(
86
184
  gqrx_sock: gqrx_sock,
87
- cmd: "F #{this_freq}"
185
+ cmd: 'm'
88
186
  )
89
- raise "ERROR: Failed to set frequency to #{this_freq}" unless change_frreq_resp == 'RPRT 0'
90
187
 
91
- raw_freq = gqrx_cmd(
188
+ change_freq_resp = gqrx_cmd(
92
189
  gqrx_sock: gqrx_sock,
93
- cmd: 'f'
190
+ cmd: "F #{this_freq}",
191
+ resp_ok: 'RPRT 0'
94
192
  )
95
193
 
96
- # Split the response from NNNNNNNNN
97
- # to NNN.NNN.NNN
98
- this_freq = raw_freq.to_s.chars.insert(-4, '.').insert(-8, '.').join
194
+ current_freq = gqrx_cmd(
195
+ gqrx_sock: gqrx_sock,
196
+ cmd: 'f'
197
+ )
99
198
 
100
- strength_resp = gqrx_cmd(
199
+ current_strength = gqrx_cmd(
101
200
  gqrx_sock: gqrx_sock,
102
201
  cmd: 'l STRENGTH'
103
- )
104
- current_strength = strength_resp.to_f
202
+ ).to_f
105
203
 
106
- squelch_resp = gqrx_cmd(
204
+ current_squelch = gqrx_cmd(
107
205
  gqrx_sock: gqrx_sock,
108
206
  cmd: 'l SQL'
109
- )
110
- current_squelch = squelch_resp.to_f
207
+ ).to_f
208
+
209
+ audio_gain_db = gqrx_cmd(
210
+ gqrx_sock: gqrx_sock,
211
+ cmd: 'l AF'
212
+ ).to_f
111
213
 
112
214
  init_freq_hash = {
113
- frequency: this_freq,
215
+ demod_mode_n_passband: demod_n_passband,
216
+ frequency: current_freq,
217
+ audio_gain_db: audio_gain_db,
218
+ squelch: current_squelch,
114
219
  strength: current_strength,
115
- squelch: current_squelch
220
+ trigger_lock_on_freq_strength: strength
116
221
  }
117
- # puts JSON.parse(init_freq_hash)
118
- puts init_freq_hash.to_json
222
+ puts JSON.pretty_generate(init_freq_hash)
119
223
 
120
224
  sleep lock_on_freq_duration if current_strength < strength
121
- # This helps level out strength
122
- sleep 0.03
123
225
 
124
226
  init_freq_hash
125
227
  end
126
228
 
127
229
  def scan_range(opts = {})
128
230
  gqrx_sock = opts[:gqrx_sock]
231
+ demodulator_mode = opts[:demodulator_mode]
232
+ bandwidth = opts[:bandwidth]
129
233
  start_freq = opts[:start_freq]
130
234
  target_freq = opts[:target_freq]
131
235
  precision = opts[:precision]
@@ -139,17 +243,20 @@ def scan_range(opts = {})
139
243
 
140
244
  init_freq_hash = init_freq(
141
245
  gqrx_sock: gqrx_sock,
246
+ demodulator_mode: demodulator_mode,
247
+ bandwidth: bandwidth,
142
248
  this_freq: this_freq,
143
249
  lock_on_freq_duration: lock_on_freq_duration,
144
250
  strength: strength
145
251
  )
146
- puts init_freq_hash.to_json
147
252
  end
148
253
  else
149
254
  this_freq = start_freq
150
255
  while this_freq <= target_freq
151
256
  init_freq_hash = init_freq(
152
257
  gqrx_sock: gqrx_sock,
258
+ demodulator_mode: demodulator_mode,
259
+ bandwidth: bandwidth,
153
260
  this_freq: this_freq,
154
261
  lock_on_freq_duration: lock_on_freq_duration,
155
262
  strength: strength
@@ -165,8 +272,9 @@ begin
165
272
  pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.any? { |s| s == 'PWN_PROVIDER' }
166
273
 
167
274
  target_freq = opts[:target_freq]
168
- target_freq = target_freq.to_s.delete('.').to_i unless target_freq.nil?
169
- raise 'ERROR: Invalid end frequency' if target_freq.nil?
275
+ target_freq = target_freq.to_s.delete('.') unless target_freq.nil?
276
+ target_freq = target_freq.to_i
277
+ raise "ERROR: Invalid target frequency #{target_freq}" if target_freq.zero?
170
278
 
171
279
  host = opts[:host] ||= '127.0.0.1'
172
280
  port = opts[:port] ||= 7356
@@ -174,46 +282,70 @@ begin
174
282
  puts "Connecting to GQRX at #{host}:#{port}..."
175
283
  gqrx_sock = PWN::Plugins::Sock.connect(target: host, port: port)
176
284
 
177
- demodulator_mode = opts[:demodulator_mode] ||= 'AM'
285
+ start_freq = opts[:start_freq]
286
+ start_freq = start_freq.to_s.delete('.') unless start_freq.nil?
287
+ start_freq = start_freq.to_i
288
+ start_freq = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f', resp_ok: 'RPRT 0').to_i if start_freq.zero?
289
+
290
+ demodulator_mode = opts[:demodulator_mode] ||= 'WFM_ST'
178
291
  demodulator_mode.upcase!
179
292
  raise "ERROR: Invalid demodulator mode: #{demodulator_mode}" unless %w[OFF RAW AM FM WFM WFM_ST WFM_ST_OIRT LSB USB CW CWL CWU].include?(demodulator_mode)
180
293
 
181
- puts "Setting demodulator mode to #{demodulator_mode}..."
182
- demod_resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: "M #{demodulator_mode}")
183
- raise "ERROR: Failed to set demodulator mode to #{demodulator_mode}" unless demod_resp == 'RPRT 0'
294
+ bandwidth = opts[:bandwidth] ||= '200.000'
184
295
 
185
- start_freq = opts[:start_freq]
186
- start_freq = start_freq.to_s.delete('.').to_i unless start_freq.nil?
187
- start_freq = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f').to_i if start_freq.nil?
296
+ puts "Setting demodulator mode to #{demodulator_mode} and bandwidth to #{bandwidth}..."
297
+ bandwidth = bandwidth.to_s.delete('.').to_i unless bandwidth.nil?
298
+ demod_resp = gqrx_cmd(
299
+ gqrx_sock: gqrx_sock,
300
+ cmd: "M #{demodulator_mode} #{bandwidth}",
301
+ resp_ok: 'RPRT 0'
302
+ )
188
303
 
189
- squelch = opts[:squelch] ||= -63
304
+ squelch = opts[:squelch] ||= -63.0
190
305
  squelch = squelch.to_f
191
- squelch_resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: "L SQL #{squelch}")
192
- raise "ERROR: Failed to set squelch to #{squelch}" unless squelch_resp == 'RPRT 0'
306
+ squelch_resp = gqrx_cmd(
307
+ gqrx_sock: gqrx_sock,
308
+ cmd: "L SQL #{squelch}",
309
+ resp_ok: 'RPRT 0'
310
+ )
193
311
 
194
- precision = opts[:precision] ||= 3
312
+ precision = opts[:precision] ||= 6
195
313
  precision = precision.to_i
196
314
  raise "ERROR: Invalid precision: #{precision}" unless (1..12).include?(precision)
197
315
 
198
- lock_on_freq_duration = opts[:lock_on_freq_duration] ||= 0
316
+ lock_on_freq_duration = opts[:lock_on_freq_duration] ||= 3
199
317
  lock_on_freq_duration = lock_on_freq_duration.to_f
200
318
 
201
- strength = opts[:strength] ||= -63
319
+ strength = opts[:strength] ||= -63.3
202
320
  strength = strength.to_f
203
321
 
204
- puts "Scanning from #{start_freq} to #{target_freq}..."
322
+ audio_gain_db = opts[:audio_gain_db] ||= 1.0
323
+ audio_gain_db = audio_gain_db.to_f
324
+ audio_gain_db_resp = gqrx_cmd(
325
+ gqrx_sock: gqrx_sock,
326
+ cmd: "L AF #{audio_gain_db}",
327
+ resp_ok: 'RPRT 0'
328
+ )
329
+
330
+ s_freq_pretty = start_freq.to_s.chars.insert(-4, '.').insert(-8, '.').join
331
+ t_freq_pretty = target_freq.to_s.chars.insert(-4, '.').insert(-8, '.').join
332
+ puts "*** Scanning from #{s_freq_pretty} to #{t_freq_pretty}"
205
333
 
206
334
  scan_range(
207
335
  gqrx_sock: gqrx_sock,
336
+ demodulator_mode: demodulator_mode,
208
337
  start_freq: start_freq,
209
338
  target_freq: target_freq,
210
339
  precision: precision,
211
340
  lock_on_freq_duration: lock_on_freq_duration,
212
- strength: strength
341
+ strength: strength,
342
+ squelch: squelch
213
343
  )
214
- rescue SystemExit, Interrupt
344
+ puts 'Scan Complete.'
345
+ rescue StandardError => e
346
+ raise e
347
+ rescue Interrupt, SystemExit
215
348
  puts "\nGoodbye."
216
349
  ensure
217
- resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'c')
218
350
  gqrx_sock = PWN::Plugins::Sock.disconnect(sock_obj: gqrx_sock)
219
351
  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.52'
4
+ VERSION = '0.5.54'
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.52
4
+ version: 0.5.54
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-15 00:00:00.000000000 Z
11
+ date: 2024-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -562,14 +562,14 @@ dependencies:
562
562
  requirements:
563
563
  - - '='
564
564
  - !ruby/object:Gem::Version
565
- version: 1.16.2
565
+ version: 1.16.3
566
566
  type: :runtime
567
567
  prerelease: false
568
568
  version_requirements: !ruby/object:Gem::Requirement
569
569
  requirements:
570
570
  - - '='
571
571
  - !ruby/object:Gem::Version
572
- version: 1.16.2
572
+ version: 1.16.3
573
573
  - !ruby/object:Gem::Dependency
574
574
  name: nokogiri-diff
575
575
  requirement: !ruby/object:Gem::Requirement
@@ -1038,14 +1038,14 @@ dependencies:
1038
1038
  requirements:
1039
1039
  - - '='
1040
1040
  - !ruby/object:Gem::Version
1041
- version: 1.7.2
1041
+ version: 1.7.3
1042
1042
  type: :runtime
1043
1043
  prerelease: false
1044
1044
  version_requirements: !ruby/object:Gem::Requirement
1045
1045
  requirements:
1046
1046
  - - '='
1047
1047
  - !ruby/object:Gem::Version
1048
- version: 1.7.2
1048
+ version: 1.7.3
1049
1049
  - !ruby/object:Gem::Dependency
1050
1050
  name: thin
1051
1051
  requirement: !ruby/object:Gem::Requirement