Class: Ronin::Vulns::RFI

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

Overview

Represents a Remote File Inclusion (RFI) vulnerability.

Constant Summary collapse

URL_EXTS =

The script extensions and their languages

{
  '.asp'  => :asp,
  '.aspx' => :asp_net,
  '.cfm'  => :cold_fusion,
  '.cfml' => :cold_fusion,
  '.jsp'  => :jsp,
  '.php'  => :php,
  '.pl'   => :perl
}
GITHUB_BASE_URL =

The github.com base URL for all RFI test scripts.

"https://raw.githubusercontent.com/ronin-rb/ronin-vulns/#{VERSION}/data"
TEST_SCRIPT_URLS =

Mapping of scripting languages to RFI test scripts.

{
  php:         "#{GITHUB_BASE_URL}/rfi_test.php",
  asp:         "#{GITHUB_BASE_URL}/rfi_test.asp",
  asp_net:     "#{GITHUB_BASE_URL}/rfi_test.aspx",
  jsp:         "#{GITHUB_BASE_URL}/rfi_test.jsp",
  cold_fusion: "#{GITHUB_BASE_URL}/rfi_test.cfm",
  perl:        "#{GITHUB_BASE_URL}/rfi_test.pl"
}
VULN_RESPONSE_STRING =

The string that will be returned if the Remote File Inclusion (RFI) script is executed.

"Security Alert: Remote File Inclusion Detected!"

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, test_param, #to_curl, #to_http, #to_s

Constructor Details

#initialize(url, script_lang: nil, test_script_url: nil, filter_bypass: nil, **kwargs) ⇒ RFI

Creates a new Remote File Inclusion (RFI) object.

Parameters:

  • url (String, URI::HTTP)

    The URL to attempt to exploit.

  • filter_bypass (:null_byte, :double_encode, nil) (defaults to: nil)

    Specifies which filter bypass technique to use.

    • :double_encode - will cause the inclusion URL to be URI escaped twice.
    • :suffix_escape - escape any appended suffix (ex: param + ".php") by adding a URI fragment character (#) to the end of the RFI script URL. The fragment component of the URI is not sent to the web server.
    • :null_byte - will cause the inclusion URL to be appended with a %00 character. *Note: this technique only works on PHP < 5.3.
  • script_lang (:asp, :asp_net, :cold_fusion, :jsp, :php, :perl, nil) (defaults to: nil)

    Explicitly specifies the scripting language that the URL uses.

  • test_script_url (String, URI::HTTP, nil) (defaults to: nil)

    The URL of the RFI test script. If not specified, it will default to test_script_for.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ronin/vulns/rfi.rb', line 103

def initialize(url, script_lang:     nil,
                    test_script_url: nil,
                    filter_bypass:   nil,
                    **kwargs)
  super(url,**kwargs)

  @script_lang = script_lang || self.class.infer_script_lang(@url)

  @test_script_url = if test_script_url
                       test_script_url
                     elsif @script_lang
                       self.class.test_script_url_for(@script_lang)
                     end

  @filter_bypass = filter_bypass
end

Instance Attribute Details

#filter_bypassnil, ... (readonly)

The filter bypass technique to use.

Returns:

  • (nil, :double_encode, :suffix_escape, :null_byte)


72
73
74
# File 'lib/ronin/vulns/rfi.rb', line 72

def filter_bypass
  @filter_bypass
end

#script_lang:asp, ... (readonly)

The scripting language that the URL is using.

Returns:

  • (:asp, :asp_net, :cold_fusion, :jsp, :php, :perl, nil)

Since:

  • 0.2.0



67
68
69
# File 'lib/ronin/vulns/rfi.rb', line 67

def script_lang
  @script_lang
end

#test_script_urlURI::HTTP, String (readonly)

URL of the Remote File Inclusion (RFI) Test script

Returns:

  • (URI::HTTP, String)


77
78
79
# File 'lib/ronin/vulns/rfi.rb', line 77

def test_script_url
  @test_script_url
end

Class Method Details

.infer_script_lang(url) ⇒ :asp, ...

Attempts to infer the programming language used for the web page at the given URL.

Parameters:

  • url (String, URI::HTTP)

    The URL to infer from.

Returns:

  • (:asp, :cold_fusion, :jsp, :php, :perl, nil)

    The programming language inferred from the URL.



148
149
150
151
152
# File 'lib/ronin/vulns/rfi.rb', line 148

def self.infer_script_lang(url)
  url = URI(url)

  return URL_EXTS[File.extname(url.path)]
end

.test_script_for(url) ⇒ String?

Selects the RFI test script for the scripting language used by the given URL.

Parameters:

  • url (String, URI::HTTP)

    The URL to test.

Returns:

  • (String, nil)

    The RFI test script URL or nil if the scripting language could not be inferred from the URL.



165
166
167
168
169
# File 'lib/ronin/vulns/rfi.rb', line 165

def self.test_script_for(url)
  if (lang = infer_script_lang(url))
    TEST_SCRIPT_URLS.fetch(lang)
  end
end

.test_script_url_for(script_lang) ⇒ String

Returns the test script URL for the given scripting language.

Parameters:

  • script_lang (:asp, :asp_net, :cold_fusion, :jsp, :php, :perl)

    The scripting language.

Returns:

  • (String)

    The test script URL for the given scripting language.

Raises:

  • (ArgumentError)

    An unknown scripting language value was given.



132
133
134
135
136
# File 'lib/ronin/vulns/rfi.rb', line 132

def self.test_script_url_for(script_lang)
  TEST_SCRIPT_URLS.fetch(script_lang) do
    raise(ArgumentError,"unknown scripting language: #{script_lang.inspect}")
  end
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)


273
274
275
# File 'lib/ronin/vulns/rfi.rb', line 273

def self.vuln_type
  :rfi
end

Instance Method Details

#encode_payload(url) ⇒ String

Optionally applies a filter bypass technique to the RFI URL.

Parameters:

  • url (URI::HTTP, String)

    The RFI URL to optionally encode before it will be injected into a HTTP request.

Returns:

  • (String)

    The optionally encoded RFI URL.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/ronin/vulns/rfi.rb', line 181

def encode_payload(url)
  url = url.to_s

  case @filter_bypass
  when :double_encode
    # Optionally double URI encodes the script URL
    url = URI::QueryParams.escape(url)
  when :suffix_escape
    # Optionally append a '#' character to escape any appended suffixes
    # (ex: `param + ".php"`).
    url = "#{url}#"
  when :null_byte
    # Optionally append a null-byte
    # NOTE: uri-query_params will automatically URI encode the null byte
    url = "#{url}\0"
  end

  return url
end

#test_a_test_script(test_script_url) ⇒ Boolean

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.

Determines if a specific test script URL can be remotely injected.

Parameters:

  • test_script_url (String)

    The test script URL to attempt injecting.

Returns:

  • (Boolean)

    Indicates whether the test script was successfully executed or not.



227
228
229
230
231
232
# File 'lib/ronin/vulns/rfi.rb', line 227

def test_a_test_script(test_script_url)
  response = exploit(test_script_url)
  body     = response.body

  return body.include?(VULN_RESPONSE_STRING)
end

#test_each_test_scriptBoolean

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.

Note:

If one of the test script URLs successfully executes, then #script_lang and #test_script_url will be updated accordingly.

Test each scripting language and RFI test payload in TEST_SCRIPT_URLS until one succeeds.

Returns:

  • (Boolean)

    Indicates whether one of the test script was successfully executed or not.



248
249
250
251
252
253
254
255
256
257
258
# File 'lib/ronin/vulns/rfi.rb', line 248

def test_each_test_script
  TEST_SCRIPT_URLS.each do |script_lang,test_script_url|
    if test_a_test_script(test_script_url)
      @script_lang     = script_lang
      @test_script_url = test_script_url
      return true
    end
  end

  return false
end

#vulnerable?Boolean

Tests whether the URL and query parameter are vulnerable to Remote File Inclusion (RFI).

Returns:

  • (Boolean)

    Specifies whether the URL and query parameter are vulnerable to RFI.



208
209
210
211
212
213
214
# File 'lib/ronin/vulns/rfi.rb', line 208

def vulnerable?
  if @test_script_url
    test_a_test_script(@test_script_url)
  else
    test_each_test_script
  end
end