lib/msf/core/exploit/remote/http/wordpress/admin.rb
# -*- coding: binary -*-
require 'rex/mime/message'
module Msf::Exploit::Remote::HTTP::Wordpress::Admin
# Uploads a plugin using a valid admin session.
#
# @param name [String] The name of the plugin
# @param zip [String] The plugin zip file as a string
# @param cookie [String] A valid admin session cookie
# @return [Boolean] true on success, false on error
def wordpress_upload_plugin(name, zip, cookie)
nonce = wordpress_helper_get_plugin_upload_nonce(cookie)
if nonce.nil?
vprint_error("Failed to acquire the plugin upload nonce")
return false
end
vprint_status("Acquired a plugin upload nonce: #{nonce}")
referer_uri = normalize_uri(wordpress_url_backend, 'plugin-install.php?tab=upload')
data = Rex::MIME::Message.new
data.add_part(nonce, nil, nil, 'form-data; name="_wpnonce"')
data.add_part(referer_uri, nil, nil, 'form-data; name="_wp_http_referer"')
data.add_part(zip, 'application/octet-stream', 'binary', "form-data; name=\"pluginzip\"; filename=\"#{name}.zip\"")
data.add_part('Install Now', nil, nil, 'form-data; name="install-plugin-submit"')
res = send_request_cgi(
'method' => 'POST',
'uri' => wordpress_url_admin_update,
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s,
'cookie' => cookie,
'vars_get' => { 'action' => 'upload-plugin' }
)
if res && res.code == 200
vprint_status("Uploaded plugin #{name}")
return true
else
vprint_error("Server responded with code #{res.code}") if res
vprint_error("Failed to upload plugin #{name}")
return false
end
end
# Edits a plugin file (relative to plugins dir) using a valid admin session.
#
# @param file [String] The plugin file to edit (relative to plugins dir)
# @param contents [String] The plugin file contents to overwrite with
# @param cookie [String] A valid admin session cookie
# @return [Boolean] true on success, false on error
def wordpress_edit_plugin(file, contents, cookie)
unless (nonce = wordpress_helper_get_plugin_edit_nonce(cookie, file))
vprint_error('Failed to acquire the plugin edit nonce')
return false
end
vprint_status("Acquired a plugin edit nonce: #{nonce}")
# https://github.com/WordPress/WordPress/blob/master/wp-admin/plugin-editor.php
res = send_request_cgi(
'method' => 'POST',
'uri' => wordpress_url_admin_plugin_editor,
'cookie' => cookie,
'vars_post' => {
'action' => 'update',
'_wpnonce' => nonce,
'file' => file,
'newcontent' => contents
}
)
unless res && res.redirect?
vprint_error("Server responded with code #{res.code}") if res
vprint_error("Failed to edit plugin file #{file}")
return false
end
# NOTE: send_request_cgi! doesn't change the method
res = send_request_cgi(
'method' => 'GET',
'uri' => res.redirection.to_s,
'cookie' => cookie
)
unless res && res.code == 200 && res.body.include?('edited successfully')
vprint_error("Server responded with code #{res.code}") if res
vprint_error("Failed to edit plugin file #{file}")
return false
end
vprint_status("Edited plugin file #{file}")
true
end
end