ronin-vulns 0.1.5 → 0.2.0.rc1

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.
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