ronin-vulns 0.1.5 → 0.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/ChangeLog.md +43 -0
  4. data/Gemfile +14 -4
  5. data/README.md +7 -3
  6. data/Rakefile +9 -0
  7. data/data/completions/ronin-vulns +139 -0
  8. data/gemspec.yml +7 -1
  9. data/lib/ronin/vulns/cli/command.rb +1 -1
  10. data/lib/ronin/vulns/cli/commands/command_injection.rb +163 -0
  11. data/lib/ronin/vulns/cli/commands/completion.rb +63 -0
  12. data/lib/ronin/vulns/cli/commands/irb.rb +59 -0
  13. data/lib/ronin/vulns/cli/commands/lfi.rb +21 -9
  14. data/lib/ronin/vulns/cli/commands/open_redirect.rb +13 -1
  15. data/lib/ronin/vulns/cli/commands/reflected_xss.rb +13 -1
  16. data/lib/ronin/vulns/cli/commands/rfi.rb +13 -1
  17. data/lib/ronin/vulns/cli/commands/scan.rb +21 -9
  18. data/lib/ronin/vulns/cli/commands/sqli.rb +13 -1
  19. data/lib/ronin/vulns/cli/commands/ssti.rb +13 -1
  20. data/lib/ronin/vulns/cli/importable.rb +76 -0
  21. data/lib/ronin/vulns/cli/printing.rb +184 -0
  22. data/lib/ronin/vulns/cli/ruby_shell.rb +53 -0
  23. data/lib/ronin/vulns/cli/web_vuln_command.rb +216 -20
  24. data/lib/ronin/vulns/cli.rb +3 -2
  25. data/lib/ronin/vulns/command_injection.rb +267 -0
  26. data/lib/ronin/vulns/importer.rb +116 -0
  27. data/lib/ronin/vulns/lfi/test_file.rb +1 -1
  28. data/lib/ronin/vulns/lfi.rb +1 -1
  29. data/lib/ronin/vulns/open_redirect.rb +1 -1
  30. data/lib/ronin/vulns/reflected_xss/context.rb +1 -1
  31. data/lib/ronin/vulns/reflected_xss/test_string.rb +1 -1
  32. data/lib/ronin/vulns/reflected_xss.rb +1 -1
  33. data/lib/ronin/vulns/rfi.rb +64 -9
  34. data/lib/ronin/vulns/root.rb +1 -1
  35. data/lib/ronin/vulns/sqli/error_pattern.rb +1 -1
  36. data/lib/ronin/vulns/sqli.rb +36 -28
  37. data/lib/ronin/vulns/ssti/test_expression.rb +1 -1
  38. data/lib/ronin/vulns/ssti.rb +69 -53
  39. data/lib/ronin/vulns/url_scanner.rb +10 -1
  40. data/lib/ronin/vulns/version.rb +2 -2
  41. data/lib/ronin/vulns/vuln.rb +1 -1
  42. data/lib/ronin/vulns/web_vuln/http_request.rb +40 -1
  43. data/lib/ronin/vulns/web_vuln.rb +86 -16
  44. data/man/ronin-vulns-command-injection.1 +109 -0
  45. data/man/ronin-vulns-command-injection.1.md +112 -0
  46. data/man/ronin-vulns-completion.1 +76 -0
  47. data/man/ronin-vulns-completion.1.md +78 -0
  48. data/man/ronin-vulns-irb.1 +27 -0
  49. data/man/ronin-vulns-irb.1.md +26 -0
  50. data/man/ronin-vulns-lfi.1 +54 -51
  51. data/man/ronin-vulns-lfi.1.md +52 -20
  52. data/man/ronin-vulns-open-redirect.1 +51 -47
  53. data/man/ronin-vulns-open-redirect.1.md +50 -18
  54. data/man/ronin-vulns-reflected-xss.1 +50 -45
  55. data/man/ronin-vulns-reflected-xss.1.md +49 -17
  56. data/man/ronin-vulns-rfi.1 +54 -52
  57. data/man/ronin-vulns-rfi.1.md +52 -20
  58. data/man/ronin-vulns-scan.1 +68 -69
  59. data/man/ronin-vulns-scan.1.md +61 -29
  60. data/man/ronin-vulns-sqli.1 +54 -52
  61. data/man/ronin-vulns-sqli.1.md +52 -20
  62. data/man/ronin-vulns-ssti.1 +52 -48
  63. data/man/ronin-vulns-ssti.1.md +50 -18
  64. data/man/ronin-vulns.1 +73 -0
  65. data/man/ronin-vulns.1.md +69 -0
  66. data/scripts/setup +58 -0
  67. metadata +36 -5
  68. data/lib/ronin/vulns/cli/logging.rb +0 -81
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-vulns - A Ruby library for blind vulnerability testing.
4
4
  #
5
- # Copyright (c) 2022-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-vulns is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Lesser General Public License as published
@@ -19,9 +19,11 @@
19
19
  #
20
20
 
21
21
  require 'ronin/vulns/cli/command'
22
- require 'ronin/vulns/cli/logging'
22
+ require 'ronin/vulns/cli/importable'
23
+ require 'ronin/vulns/cli/printing'
23
24
 
24
25
  require 'ronin/support/network/http/cookie'
26
+ require 'ronin/support/network/http/user_agents'
25
27
 
26
28
  require 'set'
27
29
 
@@ -33,8 +35,10 @@ module Ronin
33
35
  #
34
36
  class WebVulnCommand < Command
35
37
 
36
- include Logging
38
+ include Printing
39
+ include Importable
37
40
 
41
+ option :import, desc: 'Imports discovered vulnerabilities into the database'
38
42
  option :first, short: '-F',
39
43
  desc: 'Only find the first vulnerability for each URL' do
40
44
  @scan_mode = :first
@@ -45,6 +49,34 @@ module Ronin
45
49
  @scan_mode = :all
46
50
  end
47
51
 
52
+ option :print_curl, desc: 'Also prints an example curl command for each vulnerability'
53
+
54
+ option :print_http, desc: 'Also prints an example HTTP request for each vulnerability'
55
+
56
+ option :request_method, short: '-M',
57
+ value: {
58
+ type: {
59
+ 'COPY' => :copy,
60
+ 'DELETE' => :delete,
61
+ 'GET' => :get,
62
+ 'HEAD' => :head,
63
+ 'LOCK' => :lock,
64
+ 'MKCOL' => :mkcol,
65
+ 'MOVE' => :move,
66
+ 'OPTIONS' => :options,
67
+ 'PATCH' => :patch,
68
+ 'POST' => :post,
69
+ 'PROPFIND' => :propfind,
70
+ 'PROPPATCH' => :proppatch,
71
+ 'PUT' => :put,
72
+ 'TRACE' => :trace,
73
+ 'UNLOCK' => :unlock
74
+ }
75
+ },
76
+ desc: 'The HTTP request method to use' do |verb|
77
+ self.request_method = verb
78
+ end
79
+
48
80
  option :header, short: '-H',
49
81
  value: {
50
82
  type: /[A-Za-z0-9-]+:\s*\w+/,
@@ -56,6 +88,25 @@ module Ronin
56
88
  self.headers[name] = value
57
89
  end
58
90
 
91
+ option :user_agent_string, short: '-U',
92
+ value: {
93
+ type: String,
94
+ usage: 'STRING'
95
+ },
96
+ desc: 'Sets the User-Agent header' do |ua|
97
+ self.user_agent = ua
98
+ end
99
+
100
+ option :user_agent, short: '-u',
101
+ value: {
102
+ type: Support::Network::HTTP::UserAgents::ALIASES.transform_keys { |key|
103
+ key.to_s.tr('_','-')
104
+ }
105
+ },
106
+ desc: 'Sets the User-Agent to use' do |name|
107
+ self.user_agent = name
108
+ end
109
+
59
110
  option :cookie, short: '-C',
60
111
  value: {
61
112
  type: String,
@@ -148,6 +199,10 @@ module Ronin
148
199
  self.test_form_params << name
149
200
  end
150
201
 
202
+ option :test_all_form_params, desc: 'Tests all form param names' do
203
+ self.test_form_params = true
204
+ end
205
+
151
206
  option :input, short: '-i',
152
207
  value: {
153
208
  type: String,
@@ -197,23 +252,68 @@ module Ronin
197
252
  exit(-1)
198
253
  end
199
254
 
200
- vulns_discovered = false
255
+ db_connect if options[:import]
256
+
257
+ vulns = []
201
258
 
202
259
  if options[:input]
203
260
  File.open(options[:input]) do |file|
204
261
  file.each_line(chomp: true) do |url|
205
- vulns_discovered ||= process_url(url)
262
+ process_url(url) do |vuln|
263
+ vulns << vuln
264
+ end
206
265
  end
207
266
  end
208
267
  elsif !urls.empty?
209
268
  urls.each do |url|
210
- vulns_discovered ||= process_url(url)
269
+ process_url(url) do |vuln|
270
+ vulns << vuln
271
+ end
211
272
  end
212
273
  end
213
274
 
214
- unless vulns_discovered
215
- puts colors.green("No vulnerabilities found")
216
- end
275
+ puts unless vulns.empty?
276
+ print_vulns(vulns)
277
+ end
278
+
279
+ #
280
+ # Print a summary of all web vulnerabilities found.
281
+ #
282
+ # @param [Array<WebVuln>] vulns
283
+ # The discovered web vulnerabilities.
284
+ #
285
+ # @param [Boolean] print_curl
286
+ # Prints an example `curl` command to trigger the web vulnerability.
287
+ #
288
+ # @param [Boolean] print_http
289
+ # Prints an example HTTP request to trigger the web vulnerability.
290
+ #
291
+ # @since 0.2.0
292
+ #
293
+ def print_vulns(vulns, print_curl: options[:print_curl],
294
+ print_http: options[:print_http])
295
+ super(vulns, print_curl: print_curl,
296
+ print_http: print_http)
297
+ end
298
+
299
+ #
300
+ # Prints detailed information about a discovered web vulnerability.
301
+ #
302
+ # @param [WebVuln] vuln
303
+ # The web vulnerability to log.
304
+ #
305
+ # @param [Boolean] print_curl
306
+ # Prints an example `curl` command to trigger the web vulnerability.
307
+ #
308
+ # @param [Boolean] print_http
309
+ # Prints an example HTTP request to trigger the web vulnerability.
310
+ #
311
+ # @since 0.2.0
312
+ #
313
+ def print_vuln(vuln, print_curl: options[:print_curl],
314
+ print_http: options[:print_http])
315
+ super(vuln, print_curl: print_curl,
316
+ print_http: print_http)
217
317
  end
218
318
 
219
319
  #
@@ -222,8 +322,12 @@ module Ronin
222
322
  # @param [String] url
223
323
  # A URL to scan.
224
324
  #
225
- # @return [Boolean]
226
- # Indicates whether a vulnerability was discovered in the URL.
325
+ # @yield [vuln]
326
+ # The given block will be passed each newly discovered web
327
+ # vulnerability.
328
+ #
329
+ # @yieldparam [WebVuln] vuln
330
+ # A newly discovered web vulnerability.
227
331
  #
228
332
  def process_url(url)
229
333
  unless url.start_with?('http://') || url.start_with?('https://')
@@ -231,23 +335,60 @@ module Ronin
231
335
  exit(-1)
232
336
  end
233
337
 
234
- vuln_discovered = false
235
-
236
338
  if @scan_mode == :first
237
339
  if (first_vuln = test_url(url))
238
- log_vuln(first_vuln)
239
-
240
- vuln_discovered = true
340
+ process_vuln(first_vuln)
341
+ yield first_vuln
241
342
  end
242
343
  else
243
344
  scan_url(url) do |vuln|
244
- log_vuln(vuln)
245
-
246
- vuln_discovered = true
345
+ process_vuln(vuln)
346
+ yield vuln
247
347
  end
248
348
  end
349
+ end
249
350
 
250
- return vuln_discovered
351
+ #
352
+ # Logs and optioanlly imports a new discovered web vulnerability.
353
+ #
354
+ # @param [WebVuln] vuln
355
+ # The discovered web vulnerability.
356
+ #
357
+ # @since 0.2.0
358
+ #
359
+ def process_vuln(vuln)
360
+ log_vuln(vuln)
361
+ import_vuln(vuln) if options[:import]
362
+ end
363
+
364
+ #
365
+ # The HTTP request method to use.
366
+ #
367
+ # @return [:copy, :delete, :get, :head, :lock, :mkcol, :move,
368
+ # :options, :patch, :post, :propfind, :proppatch, :put,
369
+ # :trace, :unlock]
370
+ #
371
+ # @since 0.2.0
372
+ #
373
+ def request_method
374
+ @scan_kwargs[:request_method]
375
+ end
376
+
377
+ #
378
+ # Sets the HTTP request method to use.
379
+ #
380
+ # @param [:copy, :delete, :get, :head, :lock, :mkcol, :move,
381
+ # :options, :patch, :post, :propfind, :proppatch, :put,
382
+ # :trace, :unlock] new_request_method
383
+ #
384
+ # @return [:copy, :delete, :get, :head, :lock, :mkcol, :move,
385
+ # :options, :patch, :post, :propfind, :proppatch, :put,
386
+ # :trace, :unlock]
387
+ #
388
+ # @since 0.2.0
389
+ #
390
+ def request_method=(new_request_method)
391
+ @scan_kwargs[:request_method] = new_request_method
251
392
  end
252
393
 
253
394
  #
@@ -259,6 +400,49 @@ module Ronin
259
400
  @scan_kwargs[:headers] ||= {}
260
401
  end
261
402
 
403
+ #
404
+ # The optional HTTP `User-Agent` header to send.
405
+ #
406
+ # @return [String, :random, :chrome, :chrome_linux, :chrome_macos,
407
+ # :chrome_windows, :chrome_iphone, :chrome_ipad,
408
+ # :chrome_android, :firefox, :firefox_linux, :firefox_macos,
409
+ # :firefox_windows, :firefox_iphone, :firefox_ipad,
410
+ # :firefox_android, :safari, :safari_macos, :safari_iphone,
411
+ # :safari_ipad, :edge, :linux, :macos, :windows, :iphone,
412
+ # :ipad, :android, nil]
413
+ #
414
+ # @since 0.2.0
415
+ #
416
+ def user_agent
417
+ @scan_kwargs[:user_agent]
418
+ end
419
+
420
+ #
421
+ # Sets the HTTP `User-Agent` header.
422
+ #
423
+ # @param [String, :random, :chrome, :chrome_linux, :chrome_macos,
424
+ # :chrome_windows, :chrome_iphone, :chrome_ipad,
425
+ # :chrome_android, :firefox, :firefox_linux, :firefox_macos,
426
+ # :firefox_windows, :firefox_iphone, :firefox_ipad,
427
+ # :firefox_android, :safari, :safari_macos, :safari_iphone,
428
+ # :safari_ipad, :edge, :linux, :macos, :windows, :iphone,
429
+ # :ipad, :android] new_user_agent
430
+ # The new `User-Agent` value to send.
431
+ #
432
+ # @return [String, :random, :chrome, :chrome_linux, :chrome_macos,
433
+ # :chrome_windows, :chrome_iphone, :chrome_ipad,
434
+ # :chrome_android, :firefox, :firefox_linux, :firefox_macos,
435
+ # :firefox_windows, :firefox_iphone, :firefox_ipad,
436
+ # :firefox_android, :safari, :safari_macos, :safari_iphone,
437
+ # :safari_ipad, :edge, :linux, :macos, :windows, :iphone,
438
+ # :ipad, :android]
439
+ #
440
+ # @since 0.2.0
441
+ #
442
+ def user_agent=(new_user_agent)
443
+ @scan_kwargs[:user_agent] = new_user_agent
444
+ end
445
+
262
446
  #
263
447
  # The optional `Cookie` header to send.
264
448
  #
@@ -358,6 +542,18 @@ module Ronin
358
542
  @scan_kwargs[:form_params] ||= Set.new
359
543
  end
360
544
 
545
+ #
546
+ # Sets the form params to test.
547
+ #
548
+ # @param [Set<String>, true] new_form_params
549
+ # The new form param names to test.
550
+ #
551
+ # @return [Set<String>, true]
552
+ #
553
+ def test_form_params=(new_form_params)
554
+ @scan_kwargs[:form_params] = new_form_params
555
+ end
556
+
361
557
  #
362
558
  # Scans a URL for web vulnerabilities.
363
559
  #
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-vulns - A Ruby library for blind vulnerability testing.
4
4
  #
5
- # Copyright (c) 2022-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-vulns is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Lesser General Public License as published
@@ -43,7 +43,8 @@ module Ronin
43
43
  command_name 'ronin-vulns'
44
44
  version Ronin::Vulns::VERSION
45
45
 
46
- command_aliases['xss'] = 'reflected-xss'
46
+ command_aliases['xss'] = 'reflected-xss'
47
+ command_aliases['cmdi'] = 'command-injection'
47
48
 
48
49
  end
49
50
  end
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-vulns is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-vulns is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/vulns/web_vuln'
22
+
23
+ require 'time'
24
+
25
+ module Ronin
26
+ module Vulns
27
+ #
28
+ # Represents a Command Injection vulnerability.
29
+ #
30
+ # ## Features
31
+ #
32
+ # * Supports using `;`, `|`, `&`, and `\n` escape characters.
33
+ # * Supports escaping single and double-quoted strings.
34
+ # * Supports using `;`, `#`, and `\n` terminator characters.
35
+ #
36
+ # @since 0.2.0
37
+ #
38
+ class CommandInjection < WebVuln
39
+
40
+ # The character to use to escape a quoted string.
41
+ #
42
+ # @return [String, nil]
43
+ attr_reader :escape_quote
44
+
45
+ # The escape character or string to use to escape the command and execute
46
+ # another.
47
+ #
48
+ # @return [String]
49
+ attr_reader :escape_operator
50
+
51
+ # The terminator charactor to terminate the injected command with.
52
+ #
53
+ # @return [String, nil]
54
+ attr_reader :terminator
55
+
56
+ #
57
+ # Initializes the command injection vulnerability.
58
+ #
59
+ # @param [URI::HTTP, String] url
60
+ # The URL to test or exploit.
61
+ #
62
+ # @param [String, nil] escape_quote
63
+ # The optional character to use to escape a quoted string.
64
+ #
65
+ # @param [String] escape_operator
66
+ # The escape character or string to use to escape the command
67
+ # and execute another.
68
+ #
69
+ # @param [String, nil] terminator
70
+ # The optional terminator character to terminate the injected command
71
+ # with.
72
+ #
73
+ def initialize(url, escape_quote: nil,
74
+ escape_operator: nil,
75
+ terminator: nil,
76
+ **kwargs)
77
+ super(url,**kwargs)
78
+
79
+ @escape_quote = escape_quote
80
+ @escape_operator = escape_operator
81
+ @terminator = terminator
82
+
83
+ @escape_string = build_escape_string
84
+ end
85
+
86
+ private
87
+
88
+ #
89
+ # Builds the command escape String.
90
+ #
91
+ # @return [String, nil]
92
+ #
93
+ def build_escape_string
94
+ if @escape_quote || @escape_operator
95
+ "#{original_value}#{@escape_quote}#{@escape_operator}"
96
+ end
97
+ end
98
+
99
+ public
100
+
101
+ #
102
+ # Scans the URL for command injections.
103
+ #
104
+ # Tests the URL and a specific query param, header name, cookie param, or
105
+ # form param for Command Injection by enumerating over various Command
106
+ # Injection escape syntaxes.
107
+ #
108
+ # @param [URI::HTTP] url
109
+ # The URL to test.
110
+ #
111
+ # @param [Array<String, nil>, String, nil] escape_quote
112
+ # The optional escape quote character(s) to test.
113
+ #
114
+ # @param [Array<String, nil>, String, nil] escape_operator
115
+ # The optional escape operator character(s) to test.
116
+ #
117
+ # @param [Array<String, nil>, Stirng, nil] terminator
118
+ # The optional command termination character(s) to test.
119
+ #
120
+ # @param [Ronin::Support::Network::HTTP, nil] http
121
+ # An HTTP session to use for testing the URL.
122
+ #
123
+ # @param [Hash{Symbol => Object}] kwargs
124
+ # Additional keyword arguments for {#initialize}.
125
+ #
126
+ # @option kwargs [Symbol, String, true, nil] :query_param
127
+ # The query param name to test.
128
+ #
129
+ # @option kwargs [Symbol, String, nil] :header_name
130
+ # The header name to test.
131
+ #
132
+ # @option kwargs [Symbol, String, true, nil] :cookie_param
133
+ # The cookie param name to test.
134
+ #
135
+ # @option kwargs [Symbol, String, nil] :form_param
136
+ # The form param name to test.
137
+ #
138
+ # @return [CommandInjection, nil]
139
+ # The first discovered Command Injection vulnerability for the specific
140
+ # query param, header name, cookie param, or form param.
141
+ #
142
+ # @api private
143
+ #
144
+ # @since 0.2.0
145
+ #
146
+ def self.test_param(url, escape_quote: [nil, "'", '"', '`'],
147
+ escape_operator: [';', '|', '&', "\n"],
148
+ terminator: [nil, ';', '#', "\n"],
149
+ # keyword arguments for initialize
150
+ http: , **kwargs)
151
+ Array(escape_quote).each do |escape_quote_char|
152
+ Array(escape_operator).each do |escape_operator_char|
153
+ Array(terminator).each do |terminator_char|
154
+ vuln = new(url, escape_quote: escape_quote_char,
155
+ escape_operator: escape_operator_char,
156
+ terminator: terminator_char,
157
+ http: http,
158
+ **kwargs)
159
+
160
+ return vuln if vuln.vulnerable?
161
+ end
162
+ end
163
+ end
164
+
165
+ return nil
166
+ end
167
+
168
+ #
169
+ # Escapes the given SQL and turns it into a SQL injection.
170
+ #
171
+ # @param [#to_s] command
172
+ # The command to escape.
173
+ #
174
+ # @return [String]
175
+ # The escaped SQL expression.
176
+ #
177
+ def escape(command)
178
+ cmdi = "#{@escape_string}#{command}"
179
+
180
+ if @terminator
181
+ cmdi << @terminator
182
+ elsif (@escape_quote && cmdi.end_with?(@escape_quote))
183
+ cmdi.chop!
184
+ end
185
+
186
+ return cmdi
187
+ end
188
+
189
+ #
190
+ # Encodes the command injection payload.
191
+ #
192
+ # @see #escape
193
+ #
194
+ def encode_payload(sql)
195
+ escape(sql)
196
+ end
197
+
198
+ #
199
+ # Tests whether the URL is vulnerable to command injection.
200
+ #
201
+ # @return [Boolean]
202
+ #
203
+ def vulnerable?
204
+ test_command_output || test_sleep
205
+ end
206
+
207
+ # Regular expression to match the output of the `id` command.
208
+ ID_OUTPUT_REGEX = /uid=\d+\([^\)]+\) gid=\d+\([^\)]+\) groups=\d+\([^\)]+\)/
209
+
210
+ #
211
+ # Tests whether the URL is vulnerable to command injection, by executing
212
+ # the `id` command and the output is included in the response body.
213
+ #
214
+ # @return [Boolean]
215
+ #
216
+ # @api private
217
+ #
218
+ def test_command_output
219
+ response = exploit('id')
220
+
221
+ if response.body =~ ID_OUTPUT_REGEX
222
+ return true
223
+ end
224
+ end
225
+
226
+ #
227
+ # Tests whether the URL is vulnerable to command injection, by calling the
228
+ # sleep command to see if it takes longer for the response to be
229
+ # returned.
230
+ #
231
+ # @return [Boolean]
232
+ #
233
+ # @api private
234
+ #
235
+ def test_sleep
236
+ start_time = Time.now
237
+
238
+ exploit("sleep 5")
239
+
240
+ stop_time = Time.now
241
+ delta = (stop_time - start_time)
242
+
243
+ # if the response took more than 5 seconds, our SQL sleep function
244
+ # probably worked.
245
+ return delta > 5.0
246
+ end
247
+
248
+ #
249
+ # Returns the type or kind of vulnerability.
250
+ #
251
+ # @return [Symbol]
252
+ #
253
+ # @note
254
+ # This is used internally to map an vulnerability class to a printable
255
+ # type.
256
+ #
257
+ # @api private
258
+ #
259
+ # @abstract
260
+ #
261
+ def self.vuln_type
262
+ :command_injection
263
+ end
264
+
265
+ end
266
+ end
267
+ end