Class: Ronin::Vulns::CommandInjection

Inherits:
WebVuln show all
Defined in:
lib/ronin/vulns/command_injection.rb

Overview

Represents a Command Injection vulnerability.

Features

  • Supports using ;, |, &, and \n escape characters.
  • Supports escaping single and double-quoted strings.
  • Supports using ;, #, and \n terminator characters.

Since:

  • 0.2.0

Constant Summary collapse

ID_OUTPUT_REGEX =

Regular expression to match the output of the id command.

Since:

  • 0.2.0

/uid=\d+\([^\)]+\) gid=\d+\([^\)]+\) groups=\d+\([^\)]+\)/

Instance Attribute Summary collapse

Attributes inherited from WebVuln

#cookie, #cookie_param, #form_data, #form_param, #header_name, #headers, #http, #password, #query_param, #query_params, #referer, #request_method, #url, #user, #user_agent

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from WebVuln

#exploit, #exploit_cookie, #exploit_form_data, #exploit_headers, #exploit_query_params, #original_value, #random_value, #request, scan, scan_cookie_params, scan_form_params, scan_headers, scan_query_params, test, #to_curl, #to_http, #to_s

Constructor Details

#initialize(url, escape_quote: nil, escape_operator: nil, terminator: nil, **kwargs) ⇒ CommandInjection

Initializes the command injection vulnerability.

Parameters:

  • url (URI::HTTP, String)

    The URL to test or exploit.

  • escape_quote (String, nil) (defaults to: nil)

    The optional character to use to escape a quoted string.

  • escape_operator (String) (defaults to: nil)

    The escape character or string to use to escape the command and execute another.

  • terminator (String, nil) (defaults to: nil)

    The optional terminator character to terminate the injected command with.

Since:

  • 0.2.0



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ronin/vulns/command_injection.rb', line 73

def initialize(url, escape_quote:    nil,
                    escape_operator: nil,
                    terminator:      nil,
                    **kwargs)
  super(url,**kwargs)

  @escape_quote    = escape_quote
  @escape_operator = escape_operator
  @terminator      = terminator

  @escape_string = build_escape_string
end

Instance Attribute Details

#escape_operatorString (readonly)

The escape character or string to use to escape the command and execute another.

Returns:

  • (String)

Since:

  • 0.2.0



49
50
51
# File 'lib/ronin/vulns/command_injection.rb', line 49

def escape_operator
  @escape_operator
end

#escape_quoteString? (readonly)

The character to use to escape a quoted string.

Returns:

  • (String, nil)

Since:

  • 0.2.0



43
44
45
# File 'lib/ronin/vulns/command_injection.rb', line 43

def escape_quote
  @escape_quote
end

#terminatorString? (readonly)

The terminator charactor to terminate the injected command with.

Returns:

  • (String, nil)

Since:

  • 0.2.0



54
55
56
# File 'lib/ronin/vulns/command_injection.rb', line 54

def terminator
  @terminator
end

Class Method Details

.test_param(url, escape_quote: [nil, "'", '"', '`'], escape_operator: [';', '|', '&', "\n"], terminator: [nil, ';', '#', "\n"], http:, **kwargs) ⇒ CommandInjection?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Scans the URL for command injections.

Tests the URL and a specific query param, header name, cookie param, or form param for Command Injection by enumerating over various Command Injection escape syntaxes.

Parameters:

  • url (URI::HTTP)

    The URL to test.

  • escape_quote (Array<String, nil>, String, nil) (defaults to: [nil, "'", '"', '`'])

    The optional escape quote character(s) to test.

  • escape_operator (Array<String, nil>, String, nil) (defaults to: [';', '|', '&', "\n"])

    The optional escape operator character(s) to test.

  • terminator (Array<String, nil>, String, nil) (defaults to: [nil, ';', '#', "\n"])

    The optional command termination character(s) to test.

  • http (Ronin::Support::Network::HTTP, nil)

    An HTTP session to use for testing the URL.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for #initialize.

Options Hash (**kwargs):

  • :query_param (Symbol, String, true, nil)

    The query param name to test.

  • :header_name (Symbol, String, nil)

    The header name to test.

  • :cookie_param (Symbol, String, true, nil)

    The cookie param name to test.

  • :form_param (Symbol, String, nil)

    The form param name to test.

Returns:

  • (CommandInjection, nil)

    The first discovered Command Injection vulnerability for the specific query param, header name, cookie param, or form param.

Since:

  • 0.2.0



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/ronin/vulns/command_injection.rb', line 146

def self.test_param(url, escape_quote:    [nil, "'", '"', '`'],
                         escape_operator: [';', '|', '&', "\n"],
                         terminator:      [nil, ';', '#', "\n"],
                         # keyword arguments for initialize
                         http: , **kwargs)
  Array(escape_quote).each do |escape_quote_char|
    Array(escape_operator).each do |escape_operator_char|
      Array(terminator).each do |terminator_char|
        vuln = new(url, escape_quote:    escape_quote_char,
                        escape_operator: escape_operator_char,
                        terminator:      terminator_char,
                        http:            http,
                        **kwargs)

        return vuln if vuln.vulnerable?
      end
    end
  end

  return nil
end

.vuln_typeSymbol

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method is abstract.
Note:

This is used internally to map an vulnerability class to a printable type.

Returns the type or kind of vulnerability.

Returns:

  • (Symbol)

Since:

  • 0.2.0



261
262
263
# File 'lib/ronin/vulns/command_injection.rb', line 261

def self.vuln_type
  :command_injection
end

Instance Method Details

#encode_payload(sql) ⇒ Object

Encodes the command injection payload.

See Also:

Since:

  • 0.2.0



194
195
196
# File 'lib/ronin/vulns/command_injection.rb', line 194

def encode_payload(sql)
  escape(sql)
end

#escape(command) ⇒ String

Escapes the given SQL and turns it into a SQL injection.

Parameters:

  • command (#to_s)

    The command to escape.

Returns:

  • (String)

    The escaped SQL expression.

Since:

  • 0.2.0



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/ronin/vulns/command_injection.rb', line 177

def escape(command)
  cmdi = "#{@escape_string}#{command}"

  if @terminator
    cmdi << @terminator
  elsif (@escape_quote && cmdi.end_with?(@escape_quote))
    cmdi.chop!
  end

  return cmdi
end

#test_command_outputBoolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Tests whether the URL is vulnerable to command injection, by executing the id command and the output is included in the response body.

Returns:

  • (Boolean)

Since:

  • 0.2.0



218
219
220
221
222
223
224
# File 'lib/ronin/vulns/command_injection.rb', line 218

def test_command_output
  response = exploit('id')

  if response.body =~ ID_OUTPUT_REGEX
    return true
  end
end

#test_sleepBoolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Tests whether the URL is vulnerable to command injection, by calling the sleep command to see if it takes longer for the response to be returned.

Returns:

  • (Boolean)

Since:

  • 0.2.0



235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/ronin/vulns/command_injection.rb', line 235

def test_sleep
  start_time = Time.now

  exploit("sleep 5")

  stop_time = Time.now
  delta     = (stop_time - start_time)

  # if the response took more than 5 seconds, our SQL sleep function
  # probably worked.
  return delta > 5.0
end

#vulnerable?Boolean

Tests whether the URL is vulnerable to command injection.

Returns:

  • (Boolean)

Since:

  • 0.2.0



203
204
205
# File 'lib/ronin/vulns/command_injection.rb', line 203

def vulnerable?
  test_command_output || test_sleep
end